浏览代码

Merge branch 'cygx_12.0' of http://8.136.199.33:3000/cxzhang/hongze_clpt

xingzai 1 年之前
父节点
当前提交
64a7414eb4

+ 8 - 2
controllers/banner.go

@@ -218,16 +218,22 @@ func (this *BaseBannerController) ListYx() {
 	resp := new(models.BannerUrlYxListResp)
 	var listA []*models.BannerUrlYxResp
 	var listB []*models.BannerUrlYxResp
+	var listC []*models.BannerUrlYxResp
 	listA = []*models.BannerUrlYxResp{
-		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_1.png", Path: "/index/"},
-		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_2.png", Path: ""},
+		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_5.png", Path: "/index/"},
+		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_6.png", Path: ""},
 	}
 
 	listB = []*models.BannerUrlYxResp{
 		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_3.png", Path: "/index/"},
 	}
+
+	listC =  []*models.BannerUrlYxResp{
+		&models.BannerUrlYxResp{IndexImg: "https://hzstatic.hzinsights.com/banner/yx/web_4.png", Path: ""},
+	}
 	resp.ListA = listA
 	resp.ListB = listB
+	resp.ListC = listC
 	br.Ret = 200
 	br.Success = true
 	br.Msg = "获取成功"

+ 28 - 2
controllers/report.go

@@ -863,7 +863,7 @@ func (this *MobileReportController) SearchReport() {
 			br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
 			return
 		}
-		listYx, err := models.GetArticleResearchList(conditionYx, pars, startSize, pageSize, user.UserId)
+		listYx, err := models.GetArticleResearchList(conditionYx, pars, startSize, pageSize, user.UserId, true)
 		if err != nil {
 			br.Msg = "获取信息失败"
 			br.ErrMsg = "获取品种信息失败,Err:" + err.Error()
@@ -945,7 +945,7 @@ func (this *MobileReportController) SearchReport() {
 		if articleType == 1 {
 			list, err = models.GetArticleResearchListHz(condition, pars, startSize, pageSize, user.UserId)
 		} else {
-			list, err = models.GetArticleResearchList(condition, pars, startSize, pageSize, user.UserId)
+			list, err = models.GetArticleResearchList(condition, pars, startSize, pageSize, user.UserId, true)
 		}
 		if err != nil {
 			br.Msg = "获取信息失败"
@@ -978,6 +978,32 @@ func (this *MobileReportController) SearchReport() {
 				ButtonStyle:     styleMap[v.ArticleTypeId],
 				List:            v.List,
 			}
+			if v.IsSpecial == 1 {
+				//去除图片标签
+				item.Annotation = utils.ArticleRemoveImgUrl(item.Annotation)
+
+				item.IsSpecial = true
+				item.ImgUrlPc = utils.CYGX_YANXUAN_SPECIAL_IMG_PC
+				if v.CompanyTags != "" {
+					item.CompanyTags = strings.Split(v.CompanyTags, ",")
+				} else {
+					item.CompanyTags = []string{}
+				}
+				if v.IndustryTags != "" {
+					item.IndustryTags = strings.Split(v.IndustryTags, ",")
+				} else {
+					item.IndustryTags = []string{}
+				}
+				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.MyCollectNum > 0 {
+					item.IsCollect = true
+				}
+			}
 			if articleType == 1 {
 				resp.ListHz = append(resp.ListHz, &item)
 			} else {

+ 52 - 6
controllers/research.go

@@ -91,7 +91,7 @@ func (this *MobileResearchController) 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 + `) `
@@ -102,19 +102,28 @@ func (this *MobileResearchController) 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()
@@ -153,10 +162,38 @@ func (this *MobileResearchController) ArticleNewList() {
 			ArticleTypeName: nameMap[v.ArticleTypeId],
 			ButtonStyle:     styleMap[v.ArticleTypeId],
 			List:            v.List,
+			SpecialColumnId: v.SpecialColumnId,
+		}
+		if v.IsSpecial == 1 {
+			//去除图片标签
+			item.Annotation = utils.ArticleRemoveImgUrl(item.Annotation)
+			item.Annotation, err = utils.ExtractText(item.Annotation)
+			item.IsSpecial = true
+			item.ImgUrlPc = utils.CYGX_YANXUAN_SPECIAL_IMG_PC
+			if v.CompanyTags != "" {
+				item.CompanyTags = strings.Split(v.CompanyTags, ",")
+			} else {
+				item.CompanyTags = []string{}
+			}
+			if v.IndustryTags != "" {
+				item.IndustryTags = strings.Split(v.IndustryTags, ",")
+			} else {
+				item.IndustryTags = []string{}
+			}
+			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.MyCollectNum > 0 {
+				item.IsCollect = true
+			}
 		}
+
 		if item.ArticleTypeName == "纪要" || item.ArticleTypeName == "沙龙" || item.ArticleTypeName == "专家访谈" {
 			item.Annotation = "核心结论:" + item.Annotation
-		} else {
+		} else if !item.IsSpecial {
 			item.Annotation = "核心观点:" + item.Annotation
 		}
 
@@ -549,6 +586,15 @@ func (this *MobileResearchController) DepartmentIdDetail() {
 		br.ErrMsg = "GetYanXuanArticleTypeIds,Err:" + err.Error()
 		return
 	}
+	needYanxuanSpecial := true
+	if articleTypeIds != "" && !strings.Contains(articleTypeIds, "999") {
+		needYanxuanSpecial = false
+	}
+
+	//只勾选了研选专栏时去掉文章的统计
+	if articleTypeIds == "999" {
+		condition += ` AND 1<0 `
+	}
 	if articleTypeIds != "" {
 		condition = ` AND a.article_type_id IN (` + articleTypeIds + `)  `
 	} else {
@@ -574,13 +620,13 @@ func (this *MobileResearchController) DepartmentIdDetail() {
 	}
 
 	condition += `  AND a.department_id = ` + strconv.Itoa(departmentId)
-	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()

+ 72 - 0
controllers/resource.go

@@ -143,3 +143,75 @@ func (this *ResourceController) Upload() {
 	br.Data = resp
 	return
 }
+
+// @Title 文件上传
+// @Description 文件上传接口
+// @Param   file   query   file  true       "文件"
+// @Success 200 新增成功
+// @router /file/upload [post]
+func (this *ResourceController) FileUpload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	f, h, err := this.GetFile("file")
+	if err != nil {
+		br.Msg = "获取资源信息失败"
+		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
+		return
+	}
+	ext := path.Ext(h.Filename)
+	dateDir := time.Now().Format("20060102")
+	uploadDir := "static/temp/" + dateDir
+	err = os.MkdirAll(uploadDir, 777)
+	if err != nil {
+		br.Msg = "存储目录创建失败"
+		br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + ext
+	fpath := uploadDir + "/" + fileName
+	defer f.Close() //关闭上传文件
+	err = this.SaveToFile("file", fpath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	savePath := uploadDir + time.Now().Format("200601/20060102/")
+	savePath += fileName
+	//上传到阿里云
+	err = services.UploadFileToAliyun("", fpath, savePath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	fileHost := "https://hzstatic.hzinsights.com/"
+	resourceUrl := fileHost + savePath
+	defer func() {
+		os.Remove(fpath)
+	}()
+	item := new(models.Resource)
+	item.ResourceUrl = resourceUrl
+	item.ResourceType = 1
+	item.CreateTime = time.Now()
+	newId, err := models.AddResource(item)
+	if err != nil {
+		br.Msg = "资源上传失败"
+		br.ErrMsg = "资源上传失败,Err:" + err.Error()
+		return
+	}
+	resp := new(models.FileResourceResp)
+	resp.Id = newId
+	resp.ResourceUrl = resourceUrl
+	resp.ResourceName = h.Filename
+
+	br.Msg = "上传成功"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	return
+}

+ 39 - 11
controllers/user.go

@@ -926,21 +926,49 @@ 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
+		if list[i].IsSpecialInt != 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
+			}
 		} else {
-			list[i].Source = 2
+			//处理研选专栏
+			list[i].IsSpecial = true
+			if list[i].CompanyTagsStr != "" {
+				list[i].CompanyTags = strings.Split(list[i].CompanyTagsStr, ",")
+			} else {
+				list[i].CompanyTags = []string{}
+			}
+			if list[i].IndustryTagStr != "" {
+				list[i].IndustryTags = strings.Split(list[i].IndustryTagStr, ",")
+			} else {
+				list[i].IndustryTags = []string{}
+			}
 			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 item.ArticleTypeId == -1 {
+			list[i].ArticleTypeName = utils.CYGX_YANXUAN_SPECIAL
+		}
+		if item.SpecialType == 1 {
+			list[i].Title = "【笔记】" + list[i].Title
+		} else if list[i].SpecialType == 2 {
+			list[i].Title = "【观点】" + list[i].Title
 		}
+		if item.MyCollectNum > 0 {
+			list[i].IsCollect = true
+		}
+
 	}
 	page := paging.GetPaging(currentIndex, pageSize, total)
 	resp.List = list

+ 1120 - 0
controllers/yanxuan_special.go

@@ -0,0 +1,1120 @@
+package controllers
+
+import (
+	"encoding/json"
+	"hongze/hongze_clpt/models"
+	"hongze/hongze_clpt/services"
+	"hongze/hongze_clpt/utils"
+	"path"
+	"strings"
+	"time"
+)
+
+type YanxuanSpecialController struct {
+	BaseAuthController
+}
+
+type YanxuanSpecialNoLoginController struct {
+	BaseAuthMobileController
+}
+
+// @Title 专栏列表
+// @Description 专栏列表
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /list [get]
+func (this *YanxuanSpecialNoLoginController) 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
+	}
+
+	specialColumnId, _ := this.GetInt("SpecialColumnId", 0)
+	var condition string
+	var pars []interface{}
+
+	var specialUser *models.CygxYanxuanSpecialAuthorItem
+	var err error
+	if specialColumnId > 0 {
+		condition += ` AND b.id = ? `
+		pars = append(pars, specialColumnId)
+	}
+
+	specialUser, err = models.GetYanxuanSpecialAuthor(sysUser.UserId, sysUser.UserId)
+	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.ImgUrl = strings.TrimRight(v.ImgUrl, ",")
+		//去除图片标签
+		v.Content = utils.ArticleRemoveImgUrl(v.Content)
+		v.Content, err = utils.ExtractText(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.ImgUrl != "" {
+			imgList := strings.Split(v.ImgUrl, ",")
+			for _, s := range imgList {
+				v.ImgUrlList = append(v.ImgUrlList, s)
+			}
+		} else {
+			v.ImgUrlList = []string{}
+		}
+		if v.CompanyTags != "" {
+			tagList := strings.Split(v.CompanyTags, ",")
+			for _, s := range tagList {
+				v.TagList = append(v.TagList, s)
+			}
+		}
+		if v.IndustryTags != "" {
+			tagList := strings.Split(v.IndustryTags, ",")
+			for _, s := range tagList {
+				v.TagList = append(v.TagList, s)
+			}
+		}
+		if len(v.TagList) == 0 {
+			v.TagList = []string{}
+		}
+	}
+	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
+	}
+
+	//industryTagList, tmpErr := models.GetYanxuanSpecialIndustry("")
+	//if tmpErr != nil {
+	//	br.Msg = "获取失败"
+	//	br.ErrMsg = "获取失败, Err:" + tmpErr.Error()
+	//	return
+	//}
+	//industryTagMap := make(map[string]int, 0)
+	//for _, v := range industryTagList {
+	//	industryTagMap[v] = 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.ImgUrl != "" {
+		imgList := strings.Split(item.ImgUrl, ",")
+		for _, s := range imgList {
+			resp.ImgUrlList = append(resp.ImgUrlList, s)
+		}
+	} else {
+		resp.ImgUrlList = []string{}
+	}
+	if item.CompanyTags != "" {
+		cTagList := strings.Split(item.CompanyTags, ",")
+		for _, s := range cTagList {
+			resp.CompanyTags = append(resp.CompanyTags, s)
+		}
+	} else {
+		resp.CompanyTags = []string{}
+	}
+	if item.IndustryTags != "" {
+		iTagList := strings.Split(item.IndustryTags, ",")
+		for _, s := range iTagList {
+			resp.IndustryTags = append(resp.IndustryTags, s)
+		}
+	} else {
+		resp.IndustryTags = []string{}
+	}
+
+	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.SpecialColumnId <= 0 {
+		br.Msg = "栏目id有误"
+		return
+	}
+	if req.SpecialName == "" {
+		br.Msg = "请输入专栏名称"
+		return
+	}
+	if req.NickName == "" {
+		br.Msg = "请输入昵称"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		Id:           req.SpecialColumnId,
+		UserId:       sysUser.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 len(req.CompanyTags) == 0 && len(req.IndustryTags) == 0 && req.DoType == 2 {
+		br.Msg = "请至少输入一个标签"
+		return
+	}
+	if len(req.Docs) > 0 {
+		for i, doc := range req.Docs {
+			extMap := services.GetCloudDiskResourceFileTypeExtMap()
+			ext := path.Ext(doc.DocName)
+			req.Docs[i].DocIcon = extMap[ext]
+		}
+	}
+	docUrl, err := json.Marshal(req.Docs)
+	if err != nil {
+		return
+	}
+	imgUrls := strings.Join(req.ImgUrl, ",")
+	cTags := strings.Join(req.CompanyTags, ",")
+	iTags := strings.Join(req.IndustryTags, ",")
+	item := models.CygxYanxuanSpecial{
+		Id:           req.Id,
+		UserId:       sysUser.UserId,
+		CreateTime:   time.Now(),
+		ModifyTime:   time.Now(),
+		PublishTime:  time.Now(),
+		Content:      req.Content,
+		CompanyTags:  cTags,
+		IndustryTags: iTags,
+		ImgUrl:       imgUrls,
+		DocUrl:       string(docUrl),
+		Title:        req.Title,
+		Type:         req.Type,
+	}
+	if req.DoType == 1 {
+		item.Status = 1
+		br.Msg = "保存成功"
+	} else {
+		item.Status = 2
+		br.Msg = "已提交审核"
+	}
+
+	var newId int64
+	if req.Id == 0 {
+		newId, err = models.AddCygxYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		err = models.UpdateYanxuanSpecial(&item)
+		if err != nil {
+			br.Msg = "保存失败"
+			br.ErrMsg = "保存失败,Err:" + err.Error()
+			return
+		}
+		newId = int64(req.Id)
+	}
+
+	if req.DoType == 2 {
+		go services.SendReviewTemplateMsgAdmin(int(newId))
+		go services.UpdateYanxuanSpecialResourceData(int(newId)) //  写入首页最新  cygx_resource_data 表
+		go services.EsAddYanxuanSpecial(int(newId))              //  写入es 综合搜索
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Data = newId
+}
+
+// @Title 专栏作者详情
+// @Description 专栏作者详情
+// @Param	request	body help_doc.AddHelpDocReq true "type json string"
+// @Success 200 {object} models.AddEnglishReportResp
+// @router /author/detail [get]
+func (this *YanxuanSpecialNoLoginController) 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
+	}
+
+	specialColumnId, _ := this.GetInt("SpecialColumnId", 0)
+
+	item, tmpErr := models.GetYanxuanSpecialAuthorBySpecialColumnId(specialColumnId, 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.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
+
+	if req.Status == 1 {
+		sellerName, err = models.GetCompanySellerName(sysUser.CompanyId)
+		if err != nil {
+			br.Msg = "报名失败!"
+			br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+			return
+		}
+		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
+	}
+
+	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.FollowSpecialColumnId <= 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
+	}
+	authorItem, err := models.GetYanxuanSpecialAuthorById(req.FollowSpecialColumnId)
+	if err != nil {
+		br.Msg = "查询栏目详情失败!"
+		br.ErrMsg = "查询栏目详情失败,Err:" + err.Error()
+		return
+	}
+
+	if req.Status == 1 {
+		item := models.CygxYanxuanSpecialFollow{
+			UserId:           sysUser.UserId,
+			FollowUserId:     authorItem.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.SpecialId,
+		}
+		err = models.AddCygxYanxuanSpecialFollow(&item)
+		if err != nil {
+			br.Msg = "新增失败"
+			br.ErrMsg = "新增失败,Err:" + err.Error()
+			return
+		}
+		br.Msg = "关注成功"
+	} else {
+		err = models.DelCygxYanxuanSpecialFollow(sysUser.UserId, authorItem.UserId)
+		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 *YanxuanSpecialNoLoginController) 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
+
+	specialUser, err = models.GetYanxuanSpecialAuthor(sysUser.UserId, sysUser.UserId)
+	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
+	}
+
+	resp := new(models.SpecialAuthorListResp)
+
+	for _, v := range list {
+		v.LatestPublishDate = v.LatestPublishTime.Format(utils.FormatDate) + "更新"
+		if v.UserId == sysUser.UserId {
+			resp.List = append(resp.List, v)
+		}
+	}
+
+	for _, v := range list {
+		if v.UserId != sysUser.UserId {
+			resp.List = append(resp.List, v)
+		}
+	}
+
+	if specialUser != nil {
+		resp.IsAuthor = true
+	}
+
+	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.SpecialColumnId <= 0 {
+		br.Msg = "专栏栏目id错误"
+		return
+	}
+	if req.HeadImg == "" {
+		br.Msg = "头像图片错误"
+		return
+	}
+
+	item := models.CygxYanxuanSpecialAuthor{
+		Id:      req.SpecialColumnId,
+		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.DelCygxYanxuanSpecialReq
+	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 {
+		//		// 处理微信返回错误信息
+		//		br.Msg = "GetResponseError Err:" + err.Error()
+		//		return
+		//	}
+		//	err = os.RemoveAll(savePath)
+		//	if err != nil {
+		//		br.Msg = "RemoveAll Err:" + err.Error()
+		//		return
+		//	}
+		//}
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "校验成功"
+}

+ 4 - 0
models/article.go

@@ -178,6 +178,10 @@ type ArticleCollectionResp struct {
 	IsNeedJump      bool                        `description:"是否需要跳转链接地址"`
 	MyCollectNum    int                         `description:"本人是否收藏数量"`
 	ArticleTypeId   int                         `description:"文章类型ID"`
+	IsSpecial       int                         `description:"是否为研选专栏"`
+	SpecialTags     string                      `description:"研选专栏标签"`
+	UserId          int                         `description:"作者id"`
+	SpecialType     int                         `description:"专栏类型 1:笔记,2:观点"`
 }
 
 // 列表

+ 1 - 0
models/banner.go

@@ -84,6 +84,7 @@ type BannerUrlYxResp struct {
 type BannerUrlYxListResp struct {
 	ListA []*BannerUrlYxResp
 	ListB []*BannerUrlYxResp
+	ListC []*BannerUrlYxResp
 }
 
 // 列表

+ 231 - 0
models/cygx_yanxuan_special.go

@@ -0,0 +1,231 @@
+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    // 内容
+	CompanyTags  string    // 标签
+	IndustryTags string    // 标签
+	Status       int       // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl       string    // 图片链接
+	DocUrl       string    // 文档链接
+	Reason       string    // 理由
+	Title        string    // 标题
+	Type         int       // 类型1:笔记,2:观点
+}
+
+type CygxYanxuanSpecialItem struct {
+	Id              int      `orm:"column(id);pk"`
+	UserId          int      // 用户ID
+	SpecialColumnId int      // 专栏栏目ID
+	CreateTime      string   // 创建时间
+	ModifyTime      string   // 修改时间
+	PublishTime     string   // 提审过审或驳回时间
+	Content         string   // 内容
+	Tags            string   // 标签
+	TagList         []string // 标签
+	Status          int      // 1:未发布,2:审核中 3:已发布 4:驳回
+	ImgUrl          string   // 图片链接
+	ImgUrlList      []string // 图片链接
+	DocUrl          string   // 文档链接
+	SpecialName     string   // 专栏名称
+	Introduction    string   // 介绍
+	Label           string   // 标签
+	NickName        string   // 昵称
+	RealName        string   // 姓名
+	Mobile          string   // 手机号
+	HeadImg         string   // 头像
+	BgImg           string   // 背景图
+	Reason          string   // 理由
+	Title           string   // 标题
+	AuthorStatus    int      // 作者状态
+	Type            int      // 类型1:笔记,2:观点
+	CollectNum      int
+	MyCollectNum    int
+	IsCollect       int
+	ContentHasImg   int //正文是否包含图片 1包含 0不包含
+	CompanyTags     string
+	IndustryTags    string
+	Docs            []Doc
+	Annotation      string `description:"核心观点"`
+}
+
+type CygxYanxuanSpecialResp struct {
+	CygxYanxuanSpecialItem
+	Docs         []Doc
+	CompanyTags  []string
+	IndustryTags []string
+}
+
+type Doc struct {
+	DocName   string
+	DocSuffix string
+	DocUrl    string
+	DocIcon   string
+}
+
+type DocReq struct {
+	DocName   string
+	DocSuffix string
+	DocUrl    string
+}
+
+func GetYanxuanSpecialList(userId int, condition string, pars []interface{}) (items []*CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.id AS special_column_id,b.bg_img,b.head_img,b.introduction,b.label,b.mobile,b.nick_name,b.real_name,b.special_name,b.status AS author_status,
+( 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() WHERE id = ? `
+	_, err = o.Raw(sql, status, reason, id).Exec()
+	return
+}
+
+type SpecialListResp struct {
+	List     []*CygxYanxuanSpecialItem
+	IsAuthor bool
+}
+
+func GetYanxuanSpecialById(specialId, userId int) (item *CygxYanxuanSpecialItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT a.*,b.id AS special_column_id,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   // 内容
+	IndustryTags []string // 行业标签
+	CompanyTags  []string // 公司标签
+	DoType       int      // 1保存 2发布
+	ImgUrl       []string // 图片链接
+	Docs         []Doc    // 文档链接
+	Title        string   // 标题
+	Type         int      // 类型1:笔记,2:观点
+}
+
+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 {
+	FollowSpecialColumnId 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"`
+}

+ 158 - 0
models/cygx_yanxuan_special_user.go

@@ -0,0 +1,158 @@
+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    // 背景图
+	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    // 背景图
+	BgImgPc           string    // 背景图
+	Status            int       // 1启用2禁用
+	CollectNum        int       // 被收藏数
+	FollowNum         int       // 被关注数
+	SpecialArticleNum int       // 文章数
+	LatestPublishTime time.Time // 最近更新时间
+	LatestPublishDate string    // 最近更新时间
+	IsFollow          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) (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=? `
+	err = o.Raw(sql, reqUserId, sysUserId, reqUserId).QueryRow(&item)
+	return
+}
+
+func GetYanxuanSpecialAuthorBySpecialColumnId(specialColumnId, sysUserId int) (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  INNER JOIN cygx_yanxuan_special_author AS ca ON cf.follow_user_id=ca.user_id 
+	WHERE cf.user_id = ? AND ca.id = ? ) AS is_follow 
+FROM
+	cygx_yanxuan_special_author as a
+	 WHERE a.id=? `
+	err = o.Raw(sql, sysUserId, specialColumnId, specialColumnId).QueryRow(&item)
+	return
+}
+
+type SaveCygxYanxuanSpecialAuthorReq struct {
+	SpecialColumnId 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 id = ? `
+	_, err = o.Raw(sql, item.SpecialName, item.Introduction, item.Label, item.NickName, item.Id).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 {
+	SpecialColumnId 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() WHERE id = ? `
+	_, err = o.Raw(sql, item.HeadImg, item.Id).Exec()
+	return
+}
+
+func GetYanxuanSpecialAuthorById(specialColumnId int) (item *CygxYanxuanSpecialAuthorItem, err error) {
+	o := orm.NewOrm()
+	sql := ``
+	sql = `SELECT * FROM cygx_yanxuan_special_author WHERE id = ? `
+	err = o.Raw(sql, specialColumnId).QueryRow(&item)
+	return
+}

+ 6 - 0
models/db.go

@@ -90,6 +90,12 @@ func init() {
 		new(CygxBannerYxSurvey),
 		new(CygxReportSelectionLogApply),
 		new(CygxIndustryFllowLog),
+		new(CygxYanxuanSpecialRecord),
+		new(CygxYanxuanSpecialCollect),
+		new(CygxYanxuanSpecial),
+		new(CygxYanxuanSpecialFollow),
+		new(CygxYanxuanSpecialCompany),
+		new(CygxResourceData),
 	)
 	// 记录ORM查询日志
 	orm.Debug = true

+ 6 - 0
models/home.go

@@ -72,9 +72,15 @@ type ArticleListResp struct {
 	IsCollect           bool     `description:"本人是否收藏"`
 	IsRed               bool     `description:"是否标红"`
 	CollectNum          int      `description:"收藏人数"`
+	MyCollectNum        int      `description:"我收藏的数量"`
 	Resource            int      `description:"来源类型,1:文章、2:产品内测"`
 	Cover               string   `description:"封面图片"`
 	BodyHighlight       []string `description:"搜索高亮展示结果"`
+	IsSpecial           int      `description:"是否为研选专栏"`
+	IndustryTags        string   `description:"研选专栏行业标签"`
+	CompanyTags         string   `description:"研选专栏公司标签"`
+	SpecialColumnId     int      `description:"专栏栏目id"`
+	SpecialType         int      `description:"专栏类型 1:笔记,2:观点"`
 	List                []*IndustrialManagementIdInt
 }
 

+ 77 - 19
models/report.go

@@ -783,19 +783,31 @@ func GetTimeLineReportIndustrialPublishdateList(industrialIdArr []int) (items []
 
 // 报告榜单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:研选主题(报告)"`
-	ArticleTypeId  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:研选主题(报告)"`
+	ArticleTypeId   int      `description:"文章类型ID判断是否是研选使用"`
+	IsResearch      bool     `description:"是否属于研选"`
+	ArticleTypeName string   `description:"文章类型名称"`
+	IsSpecial       bool     `description:"是否为研选专栏"`
+	IsSpecialInt    int      `description:"是否为研选专栏"`
+	SpecialTags     string   `description:"研选专栏标签"`
+	MyCollectNum    int      `description:"本人是否收藏"`
+	SpecialType     int      `description:"专栏类型 1:笔记,2:观点"`
+	UserId          int      `description:"作者id"`
+	IndustryTagStr  string   `description:"研选专栏行业标签"`
+	CompanyTagsStr  string   `description:"研选专栏公司标签"`
+	IndustryTags    []string `description:"研选专栏行业标签"`
+	CompanyTags     []string `description:"研选专栏公司标签"`
+	SpecialColumnId int      `description:"专栏栏目id"`
+	List            []*IndustrialManagementIdInt
 }
 
 type ArticleReportBillboardLIstPageResp struct {
@@ -826,20 +838,31 @@ type ArticleResearchResp struct {
 	ImgUrlPc        string                       `description:"图片链接"`
 	List            []*IndustrialManagementIdInt `description:"产业列表"`
 	ListSubject     []*IndustrialSubject         `description:"标的列表"`
+	IsSpecial       bool                         `description:"是否为研选专栏"`
+	IndustryTags    []string                     `description:"研选专栏行业标签"`
+	CompanyTags     []string                     `description:"研选专栏公司标签"`
+	SpecialColumnId int                          `description:"专栏栏目id"`
 }
 
 // 获取数量
-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 []*ArticleListResp, err error) {
+func GetArticleResearchList(condition string, pars []interface{}, startSize, pageSize, userId int, needYanxuanSpecial bool) (items []*ArticleListResp, err error) {
 	o := orm.NewOrm()
 	sql := `SELECT
 			a.article_id,
@@ -853,8 +876,13 @@ func GetArticleResearchList(condition string, pars []interface{}, startSize, pag
 			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 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 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,
+			0 AS is_special,
+			0 AS special_type,
+			0 AS special_column_id,
+			'' AS company_tags, 
+			'' AS industry_tags
 		FROM
 			cygx_article AS a
 			LEFT JOIN cygx_industrial_article_group_management AS mg ON mg.article_id = a.article_id
@@ -865,8 +893,38 @@ func GetArticleResearchList(condition string, pars []interface{}, startSize, pag
 	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)
+	if needYanxuanSpecial {
+		sql += `UNION ALL
+	SELECT
+		a.id AS article_id,
+		a.title AS title,
+		'' AS body,
+		a.content AS annotation,
+		'' AS abstract,
+		a.publish_time AS publish_date,
+		-1 AS article_type_id,
+		b.nick_name AS nick_name,
+		0 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,
+		b.id AS special_column_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 += ` GROUP BY article_id ORDER  BY publish_date DESC  LIMIT ?,? `
+		_, err = o.Raw(sql, userId, userId, pars, startSize, pageSize).QueryRows(&items)
+	} else {
+		sql += ` GROUP BY a.article_id ORDER  BY a.publish_date DESC  LIMIT ?,? `
+		_, err = o.Raw(sql, userId, pars, startSize, pageSize).QueryRows(&items)
+	}
 	return
 }
 

+ 7 - 0
models/resource.go

@@ -30,3 +30,10 @@ func GetResourceById(id string) (item *Resource, err error) {
 	err = o.Raw(sql, id).QueryRow(&item)
 	return
 }
+
+type FileResourceResp struct {
+	Id           int64  `orm:"column(id);" description:"用户id"`
+	ResourceUrl  string `description:"资源地址"`
+	ResourceName string `description:"资源名称"`
+	PlaySeconds  uint32 `description:"播放时长,单位秒"`
+}

+ 44 - 0
models/resource_data.go

@@ -15,6 +15,7 @@ type CygxResourceData struct {
 	CreateTime  time.Time `description:"创建时间"`
 	PublishDate string    `description:"发布时间"`
 	Abstract    string    `description:"摘要"`
+	SearchTag   string    `description:"搜索标签"`
 }
 
 type CygxResourceDataResp struct {
@@ -105,6 +106,7 @@ type CygxResourceDataNewResp struct {
 	ProductInterior    *CygxProductInteriorResp                `description:"产品内测"`
 	IndustrialResource *IndustrialManagement                   `description:"产业资源包"`
 	ReportSelection    *CygxReportSelectionRep                 `description:"重点公司(原报告精选)"`
+	YanxuanSpecial     *CygxYanxuanSpecialItem                 `description:"研选专栏"`
 }
 
 // 列表
@@ -126,3 +128,45 @@ func GetResourceDataCount(condition string, pars []interface{}) (count int, err
 	err = o.Raw(sqlCount, pars).QueryRow(&count)
 	return
 }
+
+// 删除数据
+func DeleteResourceData(sourceId int, source string) (err error) {
+	o := orm.NewOrm()
+	sql := ` DELETE FROM cygx_resource_data WHERE source_id = ? AND source =?  `
+	_, err = o.Raw(sql, sourceId, source).Exec()
+	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
+}
+
+// 添加
+func AddCygxResourceData(item *CygxResourceData) (lastId int64, err error) {
+	o := orm.NewOrm()
+	lastId, err = o.Insert(item)
+	return
+}
+
+// 修改
+func UpdateResourceDataByItem(item *CygxResourceData) (err error) {
+	o := orm.NewOrm()
+	updateParams := make(map[string]interface{})
+	updateParams["PublishDate"] = item.PublishDate
+	updateParams["SearchTag"] = item.SearchTag
+	ptrStructOrTableName := "cygx_resource_data"
+	whereParam := map[string]interface{}{"source_id": item.SourceId, "source": item.Source}
+	qs := o.QueryTable(ptrStructOrTableName)
+	for expr, exprV := range whereParam {
+		qs = qs.Filter(expr, exprV)
+	}
+	_, err = qs.Update(updateParams)
+	if err != nil {
+		return
+	}
+	return
+}

+ 60 - 5
models/user.go

@@ -361,16 +361,71 @@ func UpdateUserEmail(email string, userId int) (err error) {
 }
 
 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.* 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_int,
+		'' 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,
+		'' AS company_tag_str, 
+		'' AS industry_tag_str, 
+		0 AS special_column_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_int,
+		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,
+		a.company_tags AS company_tag_str, 
+		a.industry_tags AS industry_tags_str, 
+		b.id AS special_column_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
 }
 

+ 21 - 0
models/user_record.go

@@ -141,3 +141,24 @@ func GetWxOpenIdByMobileSliceList(mobiles []string) (items []*OpenIdList, err er
 	_, err = o.Raw(sql, pars).QueryRows(&items)
 	return
 }
+
+// 根据手机号获取用户的openid
+func GetUserRecordListByMobile(platform int, bindAccount string) (items []*OpenIdList, err error) {
+	var sql string
+	//if utils.RunMode == "release" {
+	//	sql = `SELECT cr.open_id,user_id FROM user_record  as u
+	//		INNER JOIN cygx_user_record AS cr ON cr.union_id = u.union_id
+	//		WHERE create_platform=? AND bind_account IN (` + bindAccount + `)`
+	//} else {
+	//	platform = 1
+	//	sql = `SELECT open_id,user_id FROM	user_record  WHERE create_platform =? AND bind_account IN (` + bindAccount + `)`
+	//}
+	sql = `SELECT
+			cr.open_id,
+			cr.cygx_user_id as  user_id 
+		FROM
+		  cygx_user_record  as cr 
+		WHERE 1= 1	AND cygx_bind_account IN (` + bindAccount + `)`
+	_, err = orm.NewOrm().Raw(sql).QueryRows(&items)
+	return
+}

+ 68 - 11
models/wechat.go

@@ -6,6 +6,10 @@ import (
 	"github.com/beego/beego/v2/client/orm"
 	"github.com/rdlucklib/rdluck_tools/http"
 	"hongze/hongze_clpt/utils"
+	"io/ioutil"
+	netHttp "net/http"
+	"strconv"
+	"strings"
 	"time"
 )
 
@@ -54,17 +58,6 @@ type WxUsers struct {
 	NextOpenid 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"`
-}
-
 func GetWxAccessToken() (accessTokenStr string, err error) {
 	o := orm.NewOrmUsingDB("weekly_report")
 	sql := `SELECT * FROM wx_token LIMIT 1`
@@ -173,3 +166,67 @@ func GetWxTokenByXzs() (item *WxAccessToken, err error) {
 	}
 	return
 }
+
+type WxCheckContentJson struct {
+	Detail  []WxCheckContentJsonDetail `json:"detail"`
+	Errcode int                        `json:"errcode"`
+	Errmsg  string                     `json:"errmsg"`
+	Result  WxCheckContentJsonResult   `json:"result"`
+}
+
+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 {
+		return
+	}
+	req.Header.Add("Content-Type", "application/json")
+	postBody, err := client.Do(req)
+	if err != nil {
+		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(body, &item)
+	if err != nil {
+		fmt.Println("Unmarshal Err:", err.Error())
+		return
+	}
+	fmt.Println(item.Result.Label)
+	fmt.Println(item.Result.Suggest)
+	suggest = item.Result.Suggest
+	return
+}
+

+ 10 - 0
models/wx_user.go

@@ -194,3 +194,13 @@ func ModifyReportLastViewTime(uid int) (err error) {
 	_, err = o.Raw(sql, uid).Exec()
 	return
 }
+
+// GetWxUserListByUserIds 根据用户ID集合获取用户
+func GetWxUserListByUserIds(userIds string) (list []*WxUserItem, err error) {
+	o := orm.NewOrmUsingDB("weekly_report")
+	sql := ` SELECT u.*, c.company_name FROM wx_user AS u
+			INNER JOIN company AS c ON c.company_id = u.company_id 
+			WHERE user_id IN (` + userIds + `) `
+	_, err = o.Raw(sql).QueryRows(&list)
+	return
+}

+ 162 - 0
routers/commentsRouter.go

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

+ 8 - 0
routers/router.go

@@ -150,6 +150,14 @@ func init() {
 				&controllers.BaseCollectionController{},
 			),
 		),
+		web.NSNamespace("/yanxuan_special",
+			web.NSInclude(
+				&controllers.YanxuanSpecialController{},
+			),
+			web.NSInclude(
+				&controllers.YanxuanSpecialNoLoginController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 131 - 0
services/cygx_yanxuan_special.go

@@ -0,0 +1,131 @@
+package services
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_clpt/models"
+	"hongze/hongze_clpt/utils"
+	"strconv"
+	"time"
+)
+
+// SendReviewTemplateMsgAdmin 提交审核时给王芳,汪洋发消息
+func SendReviewTemplateMsgAdmin(specialId int) (err error) {
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg("处理试用申请给王芳,汪洋发消息失败, ErrMsg: "+err.Error(), 3)
+		}
+	}()
+	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
+}
+
+// 更新研选专栏  写入首页最新  cygx_resource_data 表
+func UpdateYanxuanSpecialResourceData(sourceId int) {
+	var err error
+	defer func() {
+		if err != nil {
+			go utils.SendAlarmMsg(fmt.Sprint("更新研选专栏失败ourceId: ", sourceId), 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_clpt/models"
+	"hongze/hongze_clpt/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
+	}
+}

+ 173 - 3
services/es_comprehensive.go

@@ -4,11 +4,14 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"github.com/PuerkitoBio/goquery"
+	"github.com/olivere/elastic/v7"
 	"hongze/hongze_clpt/models"
 	"hongze/hongze_clpt/utils"
 	"strconv"
 	//"strconv"
 	"errors"
+	"html"
 	"strings"
 	"time"
 )
@@ -28,8 +31,8 @@ type SearchComprehensiveItem struct {
 }
 
 type ElasticComprehensiveDetail struct {
-	SourceId int `description:"资源ID"`
-	//IsSummary    int    `description:"是否是纪要"`
+	SourceId     int    `description:"资源ID"`
+	IsSummary    int    `description:"是否是纪要"`
 	Source       string `description:"资源类型 报告 :article 、图表 :newchart、微路演 :roadshow、活动 :activity、活动视频:activityvideo、活动音频:activityvoice、专项调研活动:activityspecial 、 本周研究汇总: researchsummary 、 上周纪要汇总 :minutessummary 、晨会精华 :meetingreviewchapt  、 产品内测:productinterior 、 产业资源包:industrialsource"`
 	Title        string `description:"标题"`
 	BodyText     string `description:"内容"`
@@ -304,6 +307,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  、 产品内测:productinterior
 	for _, v := range list {
 		if v.Source == "article" {
@@ -332,6 +336,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)
 		}
 	}
 	detail, e := models.GetConfigByCode("city_img_url")
@@ -771,10 +777,30 @@ 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)
+			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 {
@@ -823,3 +849,147 @@ func GetResourceDataEsList(list []*SearchComprehensiveItem, user *models.WxUserI
 	}
 	return
 }
+
+// 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
+	//return
+	defer func() {
+		if err != nil {
+			fmt.Println(err, item.SourceId)
+			//go utils.SendAlarmMsg("更新综合页面数据Es失败"+err.Error()+fmt.Sprint(item), 2)
+		}
+	}()
+	client := utils.Client
+	mustMap := make([]interface{}, 0)
+	mustMap = append(mustMap, map[string]interface{}{
+		"term": map[string]interface{}{
+			"SourceId": item.SourceId,
+		},
+	})
+	mustMap = append(mustMap, map[string]interface{}{
+		"term": map[string]interface{}{
+			"Source": item.Source,
+		},
+	})
+	queryMap := map[string]interface{}{
+		"query": map[string]interface{}{
+			"bool": map[string]interface{}{
+				"must": mustMap,
+			},
+		},
+	}
+	requestTotalHits := client.Count(indexName).BodyJson(queryMap)
+	total, e := requestTotalHits.Do(context.Background())
+	if e != nil {
+		err = errors.New("requestTotalHits.Do(context.Background()), Err: " + e.Error())
+		return
+	}
+	//return
+	//根据来源以及ID ,判断内容是否存在,如果存在就新增,如果不存在就修改
+	if total == 0 {
+		resp, e := client.Index().Index(indexName).BodyJson(item).Do(context.Background())
+		if e != nil {
+			err = errors.New("client.Index().Index(indexName).BodyJson(item).Do(context.Background()), Err: " + e.Error())
+			return
+		}
+		if resp.Status == 0 && resp.Result == "created" {
+			//fmt.Println("新增成功")
+			//err = nil
+			return
+		} else {
+			//err = errors.New(fmt.Sprint(resp))
+			err = errors.New(fmt.Sprint("articleId", item.SourceId))
+			return
+		}
+	} else {
+		//拼接需要改动的前置条件
+		bool_query := elastic.NewBoolQuery()
+		bool_query.Must(elastic.NewTermQuery("SourceId", item.SourceId))
+		bool_query.Must(elastic.NewTermQuery("Source", item.Source))
+		//设置需要改动的内容
+		var script string
+		script += fmt.Sprint("ctx._source['SubjectNames'] = '", item.SubjectNames, "';")
+		script += fmt.Sprint("ctx._source['PublishDate'] = '", item.PublishDate, "';")
+		script += fmt.Sprint("ctx._source['IsSummary'] = ", item.IsSummary, ";")
+		script += fmt.Sprint("ctx._source['Abstract'] = '", item.Abstract, "';")
+		script += fmt.Sprint("ctx._source['Title'] = '", item.Title, "';")
+		script += fmt.Sprint("ctx._source['BodyText'] = '", item.BodyText, "';")
+		script += fmt.Sprint("ctx._source['Annotation'] = '", item.Annotation, "';")
+		script += fmt.Sprint("ctx._source['IndustryName'] = '", item.IndustryName, "'")
+
+		_, e = client.UpdateByQuery(indexName).
+			Query(bool_query).
+			Script(elastic.NewScriptInline(script)).
+			Refresh("true").
+			Do(context.Background())
+
+		if e != nil && e.Error() != "elastic: Error 400 (Bad Request): compile error [type=script_exception]" {
+			//文本内容过长的时候,修改会报 400 的错误,暂时先不处理
+			//fmt.Println("err", e.Error())
+			////err = e
+			//err = errors.New("client.UpdateByQuery(indexName), Err: " + e.Error())
+			return
+		}
+	}
+	return
+}
+
+// 删除数据
+func EsDeleteComprehensiveData(item *ElasticComprehensiveDetail) (err error) {
+	defer func() {
+		if err != nil {
+			fmt.Println(err)
+			go utils.SendAlarmMsg("删除数据综合页面数据Es失败"+err.Error()+fmt.Sprint(item), 2)
+		}
+	}()
+	indexName := utils.IndexNameComprehensive
+	client := utils.Client
+	//拼接需要删除的前置条件
+	bool_query := elastic.NewBoolQuery()
+	bool_query.Must(elastic.NewTermQuery("SourceId", item.SourceId))
+	bool_query.Must(elastic.NewTermQuery("Source", item.Source))
+	_, e := client.DeleteByQuery(indexName).
+		Query(bool_query).
+		Do(context.Background())
+	if e != nil {
+		err = errors.New(" client.DeleteByQuery(indexName), Err: " + e.Error())
+		return
+	}
+	return
+}

+ 35 - 0
services/oss.go

@@ -120,3 +120,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",
+	}
+}

+ 23 - 1
services/resource_data.go

@@ -44,6 +44,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  、 产品内测:productinterior
 	for _, v := range list {
 		if v.Source == "article" {
@@ -70,6 +71,8 @@ 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)
 		}
 	}
 	detail, e := models.GetConfigByCode("city_img_url")
@@ -439,10 +442,29 @@ 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)
+			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 {

+ 46 - 0
utils/common.go

@@ -7,6 +7,7 @@ import (
 	"encoding/hex"
 	"encoding/json"
 	"fmt"
+	"github.com/PuerkitoBio/goquery"
 	"image"
 	"image/png"
 	"math"
@@ -773,3 +774,48 @@ 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 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
+}

+ 30 - 7
utils/constants.go

@@ -173,13 +173,16 @@ const (
 
 // 模板消息地址路由
 const (
-	WX_MSG_PATH_ARTICLE_DETAIL           = "pageMy/reportDetail/reportDetail?id="            //文章详情模板消息地址
-	WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL  = "activityPages/specialDetail/specialDetail?id="   //专项调研活动模板消息地址
-	WX_MSG_PATH_ACTIVITY_INDUSTRYR_EPORT = "reportPages/IndustryReport/IndustryReport?id="   //产业文章列表模板消息地址
-	WX_MSG_PATH_ACTIVITY_DETAIL          = "activityPages/activityDetail/activityDetail?id=" //活动模板消息地址
-	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_ARTICLE_DETAIL           = "pageMy/reportDetail/reportDetail?id="                  //文章详情模板消息地址
+	WX_MSG_PATH_ACTIVITY_SPECIAL_DETAIL  = "activityPages/specialDetail/specialDetail?id="         //专项调研活动模板消息地址
+	WX_MSG_PATH_ACTIVITY_INDUSTRYR_EPORT = "reportPages/IndustryReport/IndustryReport?id="         //产业文章列表模板消息地址
+	WX_MSG_PATH_ACTIVITY_DETAIL          = "activityPages/activityDetail/activityDetail?id="       //活动模板消息地址
+	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"         //研选专栏内容中心
 )
 
 // 微信模板消息推送公共接口的秘钥
@@ -223,3 +226,23 @@ const (
 const (
 	COLLECTIONS_INFO_HTTP_URL = "https://vmp.hzinsights.com/v2/collections" // 上海策略平台精选看板路由
 )
+
+const (
+	CYGX_OBJ_ARTICLE            string = "article"            // 对象类型:文章
+	CYGX_OBJ_ACTIVITY           string = "activity"           // 对象类型:活动
+	CYGX_OBJ_ACTIVITYVIDEO      string = "activityvideo"      // 对象类型:活动视频
+	CYGX_OBJ_ACTIVITYVOICE      string = "activityvoice"      // 对象类型:活动音频
+	CYGX_OBJ_ACTIVITYSPECIAL    string = "activityspecial"    // 对象类型:专项调研活动
+	CYGX_OBJ_MEETINGREVIEWCHAPT string = "meetingreviewchapt" // 对象类型:晨会精华
+	CYGX_OBJ_ROADSHOW           string = "roadshow"           // 对象类型:路演
+	CYGX_OBJ_REPORTSELECTION    string = "reportselection"    // 对象类型:报告精选(重点公司)
+	CYGX_OBJ_PRODUCTINTERIOR    string = "productinterior"    // 对象类型:产品内测
+	CYGX_OBJ_RESEARCHSUMMARY    string = "researchsummary"    // 对象类型:本周研究汇总
+	CYGX_OBJ_MINUTESSUMMARY     string = "minutessummary"     // 对象类型:本周研究汇总
+	CYGX_OBJ_YANXUANSPECIAL     string = "yanxuanspecial"     // 对象类型:研选专栏
+)
+
+const (
+	CYGX_YANXUAN_SPECIAL               = "研选专栏" //用户阅读数据
+	CYGX_YANXUAN_SPECIAL_IMG_PC string = "https://hzstatic.hzinsights.com/cygx/yanxuan_special/special_img_pc.png"
+)