Prechádzať zdrojové kódy

Merge branch 'cygx/7.6'

hsun 2 rokov pred
rodič
commit
1b7c8ecf83

+ 43 - 15
controllers/activity.go

@@ -5044,7 +5044,10 @@ func (this *ActivityCoAntroller) ActivityVoiceHistoryAdd() {
 		br.ErrMsg = "参数解析失败,Err:" + err.Error()
 		return
 	}
+
 	activityId := req.ActivityId
+	playSeconds := req.PlaySeconds
+
 	activityInfo, errInfo := models.GetAddActivityInfoById(activityId)
 	if activityInfo == nil {
 		br.Msg = "操作失败"
@@ -5063,21 +5066,46 @@ func (this *ActivityCoAntroller) ActivityVoiceHistoryAdd() {
 		br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
 		return
 	}
-	item := new(models.CygxActivityVoiceHistory)
-	item.UserId = uid
-	item.ActivityId = activityId
-	item.CreateTime = time.Now()
-	item.Mobile = user.Mobile
-	item.Email = user.Email
-	item.CompanyId = user.CompanyId
-	item.CompanyName = user.CompanyName
-	item.SellerName = sellerName
-	item.RealName = user.RealName
-	err = models.AddCygxActivityVoiceHistory(item)
-	if err != nil {
-		br.Msg = "操作失败"
-		br.ErrMsg = "操作失败,Err:" + err.Error()
-		return
+	item := models.CygxActivityVoiceHistory{
+		ActivityId:  activityId,
+		UserId:      uid,
+		CreateTime:  time.Now(),
+		Mobile:      user.Mobile,
+		Email:       user.Email,
+		CompanyId:   user.CompanyId,
+		CompanyName: user.CompanyName,
+		RealName:    user.RealName,
+		SellerName:  sellerName,
+		PlaySeconds: strconv.Itoa(req.PlaySeconds),
+		ModifyTime:  time.Now(),
+	}
+
+	if playSeconds != 0 {
+		lastItem, err := models.GetLastCygxActivityVoiceHistory(activityId, user.UserId)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,GetLastCygxActivityVoiceHistory Err:" + err.Error()
+			return
+		}
+		err = models.UpdateLastCygxActivityVoiceHistory(strconv.Itoa(req.PlaySeconds), lastItem.Id)
+		if err != nil {
+			br.Msg = "更新失败"
+			br.ErrMsg = "更新失败,UpdateLastCygxActivityVoiceHistory Err:" + err.Error()
+			return
+		}
+	} else {
+		err = models.AddCygxActivityVoiceHistory(&item)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+		err = models.UpdateCygxActivityVoiceCounts(activityId)
+		if err != nil {
+			br.Msg = "更新失败"
+			br.ErrMsg = "更新失败,Err:" + err.Error()
+			return
+		}
 	}
 	br.Ret = 200
 	br.Success = true

+ 95 - 18
controllers/home.go

@@ -1,6 +1,7 @@
 package controllers
 
 import (
+	"encoding/json"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"hongze/hongze_cygx/models"
 	"hongze/hongze_cygx/services"
@@ -325,8 +326,58 @@ func (this *BaseHomeController) ListHomePublic() {
 	br.Data = resp
 }
 
-// @Title 首页列表接口v6版本
-// @Description 首页列表接口v6版本
+// @Title 首页/搜索头部导航接口
+// @Description 首页/搜索头部导航接口
+// @Param   SearchPage  query  int  false  "是否为搜索页面"
+// @Success 200 {object} models.HomeListResp
+// @router /header_tab [get]
+func (this *HomeController) HeaderTab() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	searchPage, _ := this.GetInt("SearchPage")
+
+	key := models.HomeHeaderTabConfigKey
+	conf, e := models.GetConfigByCode(key)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取首页头部导航失败, Err: " + e.Error()
+		return
+	}
+	if conf.ConfigValue == "" {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值有误"
+		return
+	}
+
+	list := new(models.HomeHeaderTabList)
+	if e = json.Unmarshal([]byte(conf.ConfigValue), &list); e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "首页头部导航配置值解析失败, Err: " + e.Error()
+		return
+	}
+	resp := list.Home
+	if searchPage == 1 {
+		resp = list.SearchPage
+	}
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 首页列表接口v7.6版本
+// @Description 首页列表接口v7.6版本
 // @Param   PageSize   query   int  true       "每页数据条数"
 // @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
 // @Param   ChartPermissionId   query   int  true       "品类id,最新传0"
@@ -373,6 +424,8 @@ func (this *HomeController) ListHomeArtAndChart() {
 	resp.HaveResearch = true
 	var chartList []*models.HomeChartListResp
 	var err error
+
+	// 最新
 	if listType == 1 {
 		if currentIndex <= 2 {
 			listCtagId := [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
@@ -396,9 +449,11 @@ func (this *HomeController) ListHomeArtAndChart() {
 				br.ErrMsg = "获取用户信息失败,Err:" + err.Error()
 				return
 			}
-
 		}
-	} else if listType == 3 {
+	}
+
+	// 图表
+	if listType == 3 {
 		if chartPermissionId > 0 {
 			condition += ` AND a.ptag_id =? `
 			pars = append(pars, chartPermissionId)
@@ -438,6 +493,7 @@ func (this *HomeController) ListHomeArtAndChart() {
 	}
 	resp.ChartList = chartList
 
+	// 最新/纪要
 	if listType != 3 {
 		userType, _, err := services.GetUserType(user.CompanyId)
 		if err != nil {
@@ -453,13 +509,13 @@ func (this *HomeController) ListHomeArtAndChart() {
 				br.ErrMsg = "获取分类权限信息失败,Err:" + err.Error()
 				return
 			}
-			categoryinfo, err := models.GetChartPermissionById(chartPermissionId)
+			categoryInfo, err := models.GetChartPermissionById(chartPermissionId)
 			if err != nil {
 				br.Msg = "获取信息失败"
 				br.ErrMsg = "获取信息失败,Err:" + err.Error()
 				return
 			}
-			if userType == 1 && strings.Contains(categoryinfo.PermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
+			if userType == 1 && strings.Contains(categoryInfo.PermissionName, utils.CHART_PERMISSION_NAME_YANXUAN) {
 				resp.HaveResearch = false
 				resp.Paging = page
 				br.Ret = 200
@@ -480,19 +536,36 @@ func (this *HomeController) ListHomeArtAndChart() {
 		if userType == 1 {
 			condition += ` AND  category_name  NOT LIKE '%` + utils.CHART_PERMISSION_NAME_YANXUAN + `%'`
 		}
-		total, err = models.GetHomeCount(condition, pars)
-		if err != nil {
-			br.Msg = "获取信息失败"
-			br.Msg = "获取帖子总数失败,Err:" + err.Error()
-			return
-		}
 
-		list, err := models.GetHomeList(condition, pars, startSize, pageSize)
-		if err != nil {
-			br.Msg = "获取信息失败"
-			br.Msg = "获取帖子数据失败,Err:" + err.Error()
-			return
+		list := make([]*models.HomeArticle, 0)
+		// 7.6-与音频作联合查询, 整体进行发布时间的排序(代码写的嘎嘎烂, 将就着用吧=_=!)
+		if listType == 1 {
+			var unionPars []interface{}
+			unionList, unionTotal, e := services.GetHomeNewestList(user.UserId, user.CompanyId, startSize, pageSize, condition, unionPars)
+			if e != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取纪要音频联合列表失败, Err: " + e.Error()
+				return
+			}
+			total = unionTotal
+			list = unionList
+		} else {
+			total, err = models.GetHomeCount(condition, pars)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取帖子总数失败,Err:" + err.Error()
+				return
+			}
+
+			homeList, err := models.GetHomeList(condition, pars, startSize, pageSize)
+			if err != nil {
+				br.Msg = "获取信息失败"
+				br.Msg = "获取帖子数据失败,Err:" + err.Error()
+				return
+			}
+			list = homeList
 		}
+
 		//研选的五张图片
 		detailResearch, err := models.GetConfigByCode("category_research_img_url")
 		if err != nil {
@@ -520,6 +593,9 @@ func (this *HomeController) ListHomeArtAndChart() {
 		}
 
 		for k, v := range list {
+			if v.HomeType != 0 {
+				continue
+			}
 			item := list[k]
 			//如果文章一开始的内容是图片,优先展示第一张图片
 			imgurl, _ := services.FixArticleImgUrl(html.UnescapeString(list[k].Body))
@@ -528,7 +604,7 @@ func (this *HomeController) ListHomeArtAndChart() {
 			if imgurl != "" {
 				list[k].BodyHtml = imgurl
 			}
-			list[k].PublishDate = utils.StrTimeToTime(item.PublishDate).Format(utils.FormatDateTimeNoSecond) //时间字符串格式转时间格式
+			list[k].PublishDate = utils.StrTimeToTime(item.PublishDate).Format(utils.FormatDate) //时间字符串格式转时间格式
 			if strings.Contains(item.CategoryName, utils.CHART_PERMISSION_NAME_YANXUAN) {
 				list[k].IsResearch = true
 			}
@@ -553,6 +629,7 @@ func (this *HomeController) ListHomeArtAndChart() {
 	if chartTotal > total {
 		total = chartTotal
 	}
+
 	page = paging.GetPaging(currentIndex, pageSize, total)
 	resp.Paging = page
 	br.Ret = 200

+ 217 - 0
controllers/micro_roadshow.go

@@ -0,0 +1,217 @@
+package controllers
+
+import (
+	"encoding/json"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/services"
+	"hongze/hongze_cygx/utils"
+	"strconv"
+	"time"
+)
+
+// 微路演
+type MicroRoadShowController struct {
+	BaseAuthController
+}
+
+// @Title 微路演列表
+// @Description 微路演列表接口
+// @Param   PageSize		query	int		true	"每页数据条数"
+// @Param   CurrentIndex	query	int		true	"当前页页码,从1开始"
+// @Param   KeyWord			query	string	false	"搜索关键词"
+// @Param   AudioId			query	int		false	"音频ID"
+// @Param   VideoId			query	int		false	"视频ID"
+// @Success 200 {object} models.HomeListResp
+// @router /list [get]
+func (this *MicroRoadShowController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	keywords := this.GetString("KeyWord")
+	audioId, _ := this.GetInt("AudioId")
+	videoId, _ := this.GetInt("VideoId")
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+
+	// 微路演列表
+	list, total, e := services.GetMicroRoadShowPageList(pageSize, currentIndex, audioId, videoId, keywords)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取微路演列表失败, Err: " + e.Error()
+		return
+	}
+
+	// 用户权限
+	authInfo, permissionArr, e := services.GetUserRaiPermissionInfo(user.UserId, user.CompanyId)
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取用户权限失败, Err: " + e.Error()
+		return
+	}
+
+	// 获取默认图配置
+	audioMap, videoMap, audioShareMap, videoShareMap, e := services.GetMicroRoadShowDefaultImgConfig()
+	if e != nil {
+		br.Msg = "获取失败"
+		br.ErrMsg = "获取微路演列表失败, Err: " + e.Error()
+		return
+	}
+
+	for i := range list {
+		// 权限
+		au := new(models.UserPermissionAuthInfo)
+		au.SellerName = authInfo.SellerName
+		au.SellerMobile = authInfo.SellerMobile
+		au.HasPermission = authInfo.HasPermission
+		au.OperationMode = authInfo.OperationMode
+		if au.HasPermission == 1 {
+			// 非宏观权限进一步判断是否有权限
+			if list[i].ChartPermissionId != utils.HONG_GUAN_ID && !utils.InArrayByStr(permissionArr, list[i].ChartPermissionName) {
+				au.HasPermission = 2
+			}
+		}
+		// 无权限的弹框提示
+		if au.HasPermission != 1 {
+			if au.OperationMode == services.UserPermissionOperationModeCall {
+				if list[i].Type == 1 {
+					au.PopupMsg = services.UserPermissionPopupMsgCallActivity
+				} else {
+					au.PopupMsg = services.UserPermissionPopupMsgCallMicroVideo
+				}
+			} else {
+				if list[i].Type == 1 {
+					au.PopupMsg = services.UserPermissionPopupMsgApplyActivity
+				} else {
+					au.PopupMsg = services.UserPermissionPopupMsgApplyMicroVideo
+				}
+			}
+		}
+		list[i].AuthInfo = au
+		list[i].PublishTime = utils.StrTimeToTime(list[i].PublishTime).Format(utils.FormatDate)
+		// 默认图
+		if list[i].BackgroundImg == "" {
+			if list[i].Type == 1 {
+				list[i].BackgroundImg = audioMap[list[i].ChartPermissionId]
+			} else {
+				list[i].BackgroundImg = videoMap[list[i].ChartPermissionId]
+			}
+		}
+		// 分享图
+		if list[i].Type == 1 {
+			list[i].ShareImg = audioShareMap[list[i].ChartPermissionId]
+		} else {
+			list[i].ShareImg = videoShareMap[list[i].ChartPermissionId]
+		}
+	}
+
+	resp := new(models.MicroRoadShowListResp)
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp.List = list
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "获取成功"
+	br.Data = resp
+}
+
+// @Title 记录用户浏览音频回放接口
+// @Description 记录用户浏览音频回放接口
+// @Param	request	body models.ActivityIdRep true "type json string"
+// @Success Ret=200 {object} models.AppointmentResp
+// @router /videoHistory/add [post]
+func (this *MicroRoadShowController) VideoHistoryAdd() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	user := this.User
+	if user == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,用户信息为空"
+		br.Ret = 408
+		return
+	}
+	uid := user.UserId
+	var req models.AddVideoHistoryReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	videoId := req.VideoId
+	playSeconds := req.PlaySeconds
+
+	var sellerName string
+	sellerName, err = models.GetCompanySellerName(user.CompanyId)
+	if err != nil {
+		br.Msg = "报名失败!"
+		br.ErrMsg = "获取对应销售失败,Err:" + err.Error()
+		return
+	}
+	item := models.CygxMicroRoadshowVideoHistory{
+		VideoId:     videoId,
+		UserId:      uid,
+		Mobile:      user.Mobile,
+		Email:       user.Email,
+		CompanyId:   user.CompanyId,
+		CompanyName: user.CompanyName,
+		RealName:    user.RealName,
+		SellerName:  sellerName,
+		PlaySeconds: strconv.Itoa(playSeconds),
+		CreateTime:  time.Now(),
+		ModifyTime:  time.Now(),
+	}
+
+	if playSeconds != 0 {
+		lastItem, err := models.GetLastCygxMicroRoadshowVideoHistory(videoId, user.UserId)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,GetLastCygxMicroRoadshowVideoHistory Err:" + err.Error()
+			return
+		}
+		err = models.UpdateLastCygxActivityVideoHistory(strconv.Itoa(playSeconds), lastItem.Id)
+		if err != nil {
+			br.Msg = "更新失败"
+			br.ErrMsg = "更新失败,UpdateLastCygxActivityVideoHistory Err:" + err.Error()
+			return
+		}
+	} else {
+		err = models.AddCygxMicroRoadshowVideoHistory(&item)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "操作失败,Err:" + err.Error()
+			return
+		}
+		err = models.UpdateCygxActivityVideoCounts(videoId)
+		if err != nil {
+			br.Msg = "更新失败"
+			br.ErrMsg = "更新失败,Err:" + err.Error()
+			return
+		}
+	}
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "操作成功"
+	return
+}

+ 1 - 0
controllers/search.go

@@ -450,6 +450,7 @@ func (this *SearchController) ListHomeArtAndChart() {
 				result[k].ImgUrlPc = mapCategoryUrl[v.CategoryId]
 			}
 			result[k].Source = 1
+			result[k].PublishDate = utils.StrTimeToTime(result[k].PublishDate).Format(utils.FormatDate)
 		}
 	}
 	// ListType   query   int  true       "列表类型,1最新/全部,2 纪要 ,3图表 默认1"

+ 23 - 0
controllers/user.go

@@ -802,6 +802,7 @@ func (this *UserController) ApplyTryOut() {
 	var title string
 	tryType := req.TryType
 	detailId := req.DetailId
+
 	if tryType == "Article" {
 		detail, err := models.GetArticleDetailById(detailId)
 		if err != nil {
@@ -818,6 +819,28 @@ func (this *UserController) ApplyTryOut() {
 			return
 		}
 		title = detail.ActivityName
+	} else if tryType == "MicroAudio" {
+		// 微路演音频
+		microAudio, e := models.GetCygxActivityVoiceById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "微路演音频信息有误, 不存在的VoiceId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = microAudio.VoiceName
+	} else if tryType == "MicroVideo" {
+		// 微路演视频
+		microVideo, e := models.GetMicroRoadshowVideoById(detailId)
+		if e != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "微路演视频信息有误, 不存在的VideoId: " + strconv.Itoa(detailId)
+			return
+		}
+		title = microVideo.VideoName
+	} else {
+		br.Msg = "提交类型有误"
+		br.ErrMsg = "提交类型有误, 当前提交类型: " + tryType
+		return
 	}
 
 	fmt.Println(title)

+ 1 - 0
models/activity.go

@@ -75,6 +75,7 @@ type Activity struct {
 }
 type ActivityIdRep struct {
 	ActivityId int `description:"活动id"`
+	PlaySeconds int `description:"播放时长"`
 }
 
 type ActivitySingnupRep struct {

+ 16 - 0
models/activity_voice.go

@@ -13,6 +13,8 @@ type CygxActivityVoice struct {
 	VoiceUrl         string    `description:"音频地址"`
 	VoiceName        string    `description:"音频名称"`
 	VoicePlaySeconds string    `description:"音频时长"`
+	VoiceCounts         int    `description:"播放量"`
+	ModifyTime          string `description:"更新时间"`
 	CreateTime       time.Time `description:"创建时间"`
 }
 
@@ -39,3 +41,17 @@ func GetCygxActivityVoiceReqList(activityIds []int) (items []*CygxActivityVoiceR
 	_, err = o.Raw(sql, activityIds).QueryRows(&items)
 	return
 }
+
+func UpdateCygxActivityVoiceCounts(activityId int) (err error) {
+	sql := `UPDATE cygx_activity_voice SET voice_counts = voice_counts+1 WHERE activity_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}
+
+// GetCygxActivityVoiceById 主键获取活动音频
+func GetCygxActivityVoiceById(videoId int) (item *CygxActivityVoice, err error) {
+	sql := `SELECT * FROM cygx_activity_voice WHERE activity_voice_id = ? LIMIT 1`
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&item)
+	return
+}

+ 17 - 1
models/activity_voice_history.go

@@ -15,7 +15,9 @@ type CygxActivityVoiceHistory struct {
 	CompanyId   int       `description:"公司id"`
 	CompanyName string    `description:"公司名称"`
 	RealName    string    `description:"用户实际名称"`
-	SellerName  string    `description:"所属销售"`
+	SellerName      string    `description:"所属销售"`
+	PlaySeconds     string    `description:"播放时间 单位s"`
+	ModifyTime      time.Time `description:"视频修改时间"`
 }
 
 //添加
@@ -24,3 +26,17 @@ func AddCygxActivityVoiceHistory(item *CygxActivityVoiceHistory) (err error) {
 	_, err = o.Insert(item)
 	return
 }
+
+func GetLastCygxActivityVoiceHistory(activityId, userId int) (item *CygxActivityVoiceHistory, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_activity_voice_history WHERE activity_id=? AND user_id=? ORDER BY create_time DESC limit 1 `
+	err = o.Raw(sql, activityId, userId).QueryRow(&item)
+	return
+}
+
+func UpdateLastCygxActivityVoiceHistory(playSeconds string, lastId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_activity_voice_history SET play_seconds =? WHERE id=? `
+	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+	return
+}

+ 22 - 20
models/article.go

@@ -82,26 +82,28 @@ func AddCygxArticle(item *CygxArticle) (lastId int64, err error) {
 }
 
 type HomeArticle struct {
-	ArticleId        int    `description:"文章id"`
-	Title            string `description:"标题"`
-	TitleEn          string `description:"英文标题 "`
-	UpdateFrequency  string `description:"更新周期"`
-	CreateDate       string `description:"创建时间"`
-	PublishDate      string `description:"发布时间"`
-	Body             string `description:"内容"`
-	BodyHtml         string `description:"内容带有HTML标签"`
-	Abstract         string `description:"摘要"`
-	CategoryName     string `description:"一级分类"`
-	SubCategoryName  string `description:"二级分类"`
-	ExpertBackground string `description:"专家背景"`
-	IsResearch       bool   `description:"是否属于研选"`
-	Pv               int    `description:"PV"`
-	ImgUrlPc         string `description:"图片链接"`
-	CategoryId       string `description:"文章分类"`
-	HttpUrl          string `description:"文章链接跳转地址"`
-	IsNeedJump       bool   `description:"是否需要跳转链接地址"`
-	Source           int    `description:"来源  1:文章, 2:图表"`
-	Annotation       string `description:"核心观点"`
+	ArticleId        int                  `description:"文章id"`
+	Title            string               `description:"标题"`
+	TitleEn          string               `description:"英文标题 "`
+	UpdateFrequency  string               `description:"更新周期"`
+	CreateDate       string               `description:"创建时间"`
+	PublishDate      string               `description:"发布时间"`
+	Body             string               `description:"内容"`
+	BodyHtml         string               `description:"内容带有HTML标签"`
+	Abstract         string               `description:"摘要"`
+	CategoryName     string               `description:"一级分类"`
+	SubCategoryName  string               `description:"二级分类"`
+	ExpertBackground string               `description:"专家背景"`
+	IsResearch       bool                 `description:"是否属于研选"`
+	Pv               int                  `description:"PV"`
+	ImgUrlPc         string               `description:"图片链接"`
+	CategoryId       string               `description:"文章分类"`
+	HttpUrl          string               `description:"文章链接跳转地址"`
+	IsNeedJump       bool                 `description:"是否需要跳转链接地址"`
+	Source           int                  `description:"来源  1:文章, 2:图表"`
+	Annotation       string               `description:"核心观点"`
+	HomeType         int                  `description:"数据类型:0-纪要(默认); 1-微路演音频"`
+	MicroAudio       *MicroAudioUnionList `description:"微路演音频"`
 }
 
 type ArticleDetail struct {

+ 34 - 0
models/config.go

@@ -5,6 +5,13 @@ import (
 	"time"
 )
 
+var (
+	HomeHeaderTabConfigKey              = "home_header_tab"
+	MicroRoadShowListDataRatioConfigKey = "micro_roadshow_list_data_ratio"
+	HomeNewListAudioNumKey              = "home_new_list_audio_num"
+	MicroRoadshowDefaultImgKey          = "micro_roadshow_default_img"
+)
+
 type CygxConfig struct {
 	ConfigId    int    `json:"-" orm:"column(config_id);pk"`
 	ConfigCode  string `json:"-"`
@@ -63,3 +70,30 @@ func GetHotSearch() (permission string, err error) {
 	err = o.Raw(sql).QueryRow(&permission)
 	return
 }
+
+// HomeHeaderTabList 首页头部导航列表
+type HomeHeaderTabList struct {
+	Home       []*HomeHeaderTab `description:"首页"`
+	SearchPage []*HomeHeaderTab `description:"搜索页"`
+}
+
+// HomeHeaderTab 首页头部导航
+type HomeHeaderTab struct {
+	Id     int    `description:"导航ID"`
+	Name   string `description:"导航名称"`
+	IsShow bool   `description:"是否展示"`
+}
+
+// MicroRoadShowDefaultImgList 微路演行业默认背景图列表
+type MicroRoadShowDefaultImgList struct {
+	Audio []*MicroRoadShowDefaultImg `description:"音频"`
+	Video []*MicroRoadShowDefaultImg `description:"视频"`
+}
+
+// MicroRoadShowDefaultImg 微路演行业默认背景图
+type MicroRoadShowDefaultImg struct {
+	ChartPermissionId   int    `description:"行业ID"`
+	ChartPermissionName string `description:"行业名称"`
+	ImgUrl              string `description:"背景图"`
+	ShareImg            string `description:"分享图"`
+}

+ 2 - 0
models/db.go

@@ -122,6 +122,8 @@ func init() {
 		new(ArticleTopHistoryRecord),
 		new(CygxActivitySignupDetail),
 		new(CygxActivitySignupDetailCopy),
+		new(CygxMicroRoadshowVideoHistory),
+		new(MicroRoadshowVideo),
 	)
 	// 记录ORM查询日志
 	orm.Debug = true

+ 266 - 0
models/micro_roadshow.go

@@ -0,0 +1,266 @@
+package models
+
+import (
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/rdlucklib/rdluck_tools/paging"
+	"time"
+)
+
+// MicroRoadShowListResp 微路演列表响应体
+type MicroRoadShowListResp struct {
+	Paging *paging.PagingItem
+	List   []*MicroRoadShowPageList
+}
+
+// MicroRoadShowPageList 微路演列表
+type MicroRoadShowPageList struct {
+	Id                  int    `description:"音视频ID"`
+	Title               string `description:"标题"`
+	ResourceUrl         string `description:"链接"`
+	Type                int    `description:"类型: 1-音频; 2-视频"`
+	PublishTime         string `description:"发布时间"`
+	BackgroundImg       string `description:"背景图"`
+	ShareImg            string `description:"分享封面图"`
+	ChartPermissionId   int    `description:"行业ID"`
+	ChartPermissionName string `description:"行业名称"`
+	PlaySeconds         string `description:"音视频时长"`
+	ActivityId          int    `description:"活动ID"`
+	AuthInfo            *UserPermissionAuthInfo
+}
+
+// GetMicroRoadShowAudioPageList 获取微路演音频列表-分页
+func GetMicroRoadShowAudioPageList(startSize, pageSize int, condition string, pars []interface{}) (total int, list []*MicroRoadShowPageList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				a.activity_voice_id AS id,
+				a.voice_name AS title,
+				a.voice_url AS resource_url,
+				1 AS type,
+				b.activity_time AS publish_time,
+				b.chart_permission_id,
+				b.chart_permission_name,
+				a.voice_play_seconds AS play_seconds,
+				a.img_url AS background_img,
+				a.activity_id
+			FROM
+				cygx_activity_voice AS a
+			JOIN cygx_activity AS b ON a.activity_id = b.activity_id
+			WHERE 1 = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` ORDER BY publish_time DESC`
+
+	totalSql := `SELECT COUNT(1) total FROM (` + sql + `) z `
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// GetMicroRoadShowVideoPageList 获取微路演视频列表-分页
+func GetMicroRoadShowVideoPageList(startSize, pageSize int, condition string, pars []interface{}) (total int, list []*MicroRoadShowPageList, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				video_id AS id,
+				video_name AS title,
+				video_url AS resource_url,
+				2 AS type,
+				publish_date AS publish_time,
+				chart_permission_id,
+				chart_permission_name,
+				video_duration AS play_seconds,
+				img_url AS background_img
+			FROM
+				cygx_micro_roadshow_video
+			WHERE
+				publish_status = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` ORDER BY publish_time DESC`
+
+	totalSql := `SELECT COUNT(1) total FROM (` + sql + `) z `
+	err = o.Raw(totalSql, pars).QueryRow(&total)
+	if err != nil {
+		return
+	}
+
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+type AddVideoHistoryReq struct {
+	VideoId     int `description:"视频ID"`
+	PlaySeconds int `description:"播放时长"`
+}
+
+type CygxMicroRoadshowVideoHistory struct {
+	Id          int       `orm:"column(id);pk"description:"微路演视频浏览记录表id"`
+	VideoId     int       `description:"微路演视频id"`
+	UserId      int       `description:"用户id"`
+	Mobile      string    `description:"手机号"`
+	Email       string    `description:"邮箱"`
+	CompanyId   int       `description:"公司Id"`
+	CompanyName string    `description:"公司名称"`
+	RealName    string    `description:"用户实际名称"`
+	SellerName  string    `description:"所属销售"`
+	PlaySeconds string    `description:"播放时间 单位s"`
+	CreateTime  time.Time `description:"视频创建时间"`
+	ModifyTime  time.Time `description:"视频修改时间"`
+}
+
+func GetLastCygxMicroRoadshowVideoHistory(videoId, userId int) (item *CygxMicroRoadshowVideoHistory, err error) {
+	o := orm.NewOrm()
+	sql := ` SELECT * FROM cygx_micro_roadshow_video_history WHERE video_id=? AND user_id=? ORDER BY create_time DESC limit 1 `
+	err = o.Raw(sql, videoId, userId).QueryRow(&item)
+	return
+}
+
+func AddCygxMicroRoadshowVideoHistory(item *CygxMicroRoadshowVideoHistory) (err error) {
+	o := orm.NewOrm()
+	_, err = o.Insert(item)
+	return
+}
+
+// MicroAudioUnionList 微路演音频联合列表
+type MicroAudioUnionList struct {
+	Id                       int    `description:"音视频ID"`
+	AudioTitle               string `description:"标题"`
+	AudioResourceUrl         string `description:"链接"`
+	AudioType                int    `description:"类型: 1-音频; 2-视频"`
+	AudioPublishTime         string `description:"发布时间"`
+	AudioImgUrl              string `description:"背景图"`
+	AudioShareImg            string `description:"分享图"`
+	AudioChartPermissionId   int    `description:"行业ID"`
+	AudioChartPermissionName string `description:"行业名称"`
+	AudioPlaySeconds         string `description:"音视频时长"`
+	AudioActivityId          int    `description:"活动ID"`
+	AuthInfo                 *UserPermissionAuthInfo
+}
+
+// HomeNewestUnionList 首页最新纪要-音频联合查询结果
+type HomeNewestUnionList struct {
+	ArticleId        int    `description:"文章id"`
+	Title            string `description:"标题"`
+	TitleEn          string `description:"英文标题 "`
+	UpdateFrequency  string `description:"更新周期"`
+	CreateDate       string `description:"创建时间"`
+	PublishDate      string `description:"发布时间"`
+	Body             string `description:"内容"`
+	BodyHtml         string `description:"内容带有HTML标签"`
+	Abstract         string `description:"摘要"`
+	CategoryName     string `description:"一级分类"`
+	SubCategoryName  string `description:"二级分类"`
+	ExpertBackground string `description:"专家背景"`
+	IsResearch       bool   `description:"是否属于研选"`
+	Pv               int    `description:"PV"`
+	ImgUrlPc         string `description:"图片链接"`
+	CategoryId       string `description:"文章分类"`
+	HttpUrl          string `description:"文章链接跳转地址"`
+	IsNeedJump       bool   `description:"是否需要跳转链接地址"`
+	Source           int    `description:"来源  1:文章, 2:图表"`
+	Annotation       string `description:"核心观点"`
+	HomeType         int    `description:"数据类型:0-纪要(默认); 1-微路演音频"`
+	MicroAudioUnionList
+}
+
+// GetHomeNewestListUnionList 首页最新纪要-音频联合查询
+func GetHomeNewestListUnionList(condition string, pars []interface{}, startSize, pageSize int) (list []*HomeNewestUnionList, err error) {
+	sql := `SELECT
+				id, article_id, title, title_en, update_frequency, create_date, publish_date, body, abstract, category_name, sub_category_name, expert_background, category_id, source, annotation,
+				(SELECT count(1) FROM cygx_article_history_record_newpv as h WHERE h.article_id = art.article_id ) as pv,
+				0 AS home_type, "" AS audio_title, "" AS audio_resource_url, 0 AS audio_type, "" AS audio_publish_time, 0 AS audio_chart_permission_id, "" AS audio_chart_permission_name,
+				"" AS audio_play_seconds, "" AS audio_img_url, 0 AS audio_activity_id
+			FROM
+				cygx_article AS art
+			WHERE
+				art.publish_status = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` UNION ALL
+			
+			SELECT
+				a.activity_voice_id, 0, "", "", "", "", b.activity_time, "", "", "", "", "", 0, 0, "",
+				0, 1, a.voice_name, a.voice_url, 1, b.activity_time,
+				b.chart_permission_id, b.chart_permission_name, a.voice_play_seconds AS audio_play_seconds, a.img_url AS audio_img_url, a.activity_id AS audio_activity_id
+			FROM
+				cygx_activity_voice AS a
+			JOIN cygx_activity AS b ON a.activity_id = b.activity_id`
+	sql += ` ORDER BY publish_date DESC`
+	sql += ` LIMIT ?,?`
+	_, err = orm.NewOrm().Raw(sql, pars, startSize, pageSize).QueryRows(&list)
+	return
+}
+
+// GetHomeNewestListUnionCount 首页最新纪要-音频联合查询总数
+func GetHomeNewestListUnionCount(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT
+				COUNT(1) AS count
+			FROM
+				(
+					SELECT
+						art.id
+					FROM
+						cygx_article AS art
+					WHERE
+						art.publish_status = 1 `
+	if condition != `` {
+		sql += condition
+	}
+	sql += ` UNION ALL
+				SELECT
+					a.activity_voice_id
+				FROM
+					cygx_activity_voice AS a
+				JOIN cygx_activity AS b ON a.activity_id = b.activity_id
+			) z `
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func UpdateLastCygxActivityVideoHistory(playSeconds string, lastId int) (err error) {
+	o := orm.NewOrm()
+	sql := ` UPDATE cygx_micro_roadshow_video_history SET play_seconds =? WHERE id=? `
+	_, err = o.Raw(sql, playSeconds, lastId).Exec()
+	return
+}
+
+// MicroRoadshowVideo 微路演视频
+type MicroRoadshowVideo struct {
+	VideoId             int       `orm:"column(video_id);pk" description:"视频ID"`
+	VideoName           string    `description:"视频标题"`
+	ChartPermissionId   int       `description:"行业ID"`
+	ChartPermissionName string    `description:"行业名称"`
+	IndustryId          int       `description:"产业ID"`
+	IndustryName        string    `description:"产业名称"`
+	PublishStatus       int       `description:"发布状态:0-未发布;1-已发布"`
+	ModifyDate          time.Time `description:"更新时间"`
+	PublishDate         time.Time `description:"发布时间"`
+	VideoCounts         int       `description:"视频播放量"`
+	VideoDuration       int       `description:"视频时长"`
+	VideoUrl            string    `description:"视频地址"`
+	CreateTime          time.Time `description:"创建时间"`
+	ImgUrl              string    `description:"背景图链接"`
+}
+
+// GetMicroRoadshowVideoById 主键获取微路演视频
+func GetMicroRoadshowVideoById(videoId int) (item *MicroRoadshowVideo, err error) {
+	sql := `SELECT * FROM cygx_micro_roadshow_video WHERE video_id = ? LIMIT 1`
+	err = orm.NewOrm().Raw(sql, videoId).QueryRow(&item)
+	return
+}
+
+func UpdateCygxActivityVideoCounts(activityId int) (err error) {
+	sql := `UPDATE cygx_micro_roadshow_video SET video_counts = video_counts+1 WHERE video_id = ?  `
+	o := orm.NewOrm()
+	_, err = o.Raw(sql, activityId).Exec()
+	return
+}

+ 10 - 1
models/user.go

@@ -211,7 +211,7 @@ type ApplyTryReq struct {
 	RealName        string `description:"姓名"`
 	CompanyName     string `description:"公司名称"`
 	ApplyMethod     int    `description:"1:已付费客户申请试用,2:非客户申请试用,3:非客户申请试用(ficc下,不需要进行数据校验)"`
-	TryType         string `description:"提交类型,Article:文章、Activity:活动"`
+	TryType         string `description:"提交类型,Article:文章、Activity:活动; MicroVideo-微路演视频"`
 	DetailId        int    `description:"详情ID"`
 }
 
@@ -463,3 +463,12 @@ func UpdateUserInteractionNum(interactionNum, userId int) (err error) {
 	_, err = o.Raw(sql, interactionNum, userId).Exec()
 	return
 }
+
+// UserPermissionAuthInfo 用户通用权限信息
+type UserPermissionAuthInfo struct {
+	HasPermission int    `description:"是否有权限:1-有权限; 2-无权限; 3-潜在客户未提交申请; 4-潜在客户已提交申请 5-仅有FICC权限"`
+	SellerMobile  string `description:"销售手机号"`
+	SellerName    string `description:"销售名称"`
+	OperationMode string `description:"操作方式:Apply-立即申请; Call-拨号"`
+	PopupMsg      string `description:"权限弹窗信息"`
+}

+ 27 - 0
routers/commentsRouter.go

@@ -547,6 +547,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:HomeController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:HomeController"],
+        beego.ControllerComments{
+            Method: "HeaderTab",
+            Router: `/header_tab`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:HomeController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:HomeController"],
         beego.ControllerComments{
             Method: "ListHome",
@@ -556,6 +565,24 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MicroRoadShowController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MicroRoadShowController"],
+        beego.ControllerComments{
+            Method: "List",
+            Router: `/list`,
+            AllowHTTPMethods: []string{"get"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
+    beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MicroRoadShowController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:MicroRoadShowController"],
+        beego.ControllerComments{
+            Method: "VideoHistoryAdd",
+            Router: `/videoHistory/add`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ReportBillboardController"] = append(beego.GlobalControllerRouter["hongze/hongze_cygx/controllers:ReportBillboardController"],
         beego.ControllerComments{
             Method: "FllowList",

+ 5 - 0
routers/router.go

@@ -119,6 +119,11 @@ func init() {
 				&controllers.BaseYidongController{},
 			),
 		),
+		web.NSNamespace("/micro_roadshow",
+			web.NSInclude(
+				&controllers.MicroRoadShowController{},
+			),
+		),
 	)
 	web.AddNamespace(ns)
 }

+ 324 - 0
services/micro_roadshow.go

@@ -0,0 +1,324 @@
+package services
+
+import (
+	"encoding/json"
+	"errors"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"math"
+	"strconv"
+	"strings"
+	"sync"
+)
+
+// GetMicroRoadShowPageList 获取微路演列表
+func GetMicroRoadShowPageList(pageSize, currentIndex, audioId, videoId int, keywords string) (respList []*models.MicroRoadShowPageList, total int, err error) {
+	var e error
+	// 根据每页数据量获取音视频配比
+	audioRatio, videoRatio, audioPageNum, videoPageNum, sliceNum, e := getMicroRoadShowDataRatio(pageSize)
+	if e != nil {
+		err = errors.New("获取微路演列表数据音视频配比失败, Err: " + e.Error())
+		return
+	}
+
+	audioTotal := 0
+	videoTotal := 0
+	audioList := make([]*models.MicroRoadShowPageList, 0)
+	videoList := make([]*models.MicroRoadShowPageList, 0)
+	if keywords != "" {
+		keywords = "%" + keywords + "%"
+	}
+	// 查询指定音频/视频时, 调整比例为1方便后面组合数据
+	if audioId > 0 || videoId > 0 {
+		audioRatio = 1
+		videoRatio = 1
+	}
+
+	wg := sync.WaitGroup{}
+
+	wg.Add(2)
+
+	// 分页查询音频
+	go func() {
+		defer wg.Done()
+		// 如果筛选条件为指定视频ID则不做音频查询
+		if videoId > 0 {
+			return
+		}
+		var audioCond string
+		var audioPars []interface{}
+		// 活动已发布且已结束
+		audioCond += ` AND b.publish_status = 1 AND b.active_state = 3`
+		if keywords != "" {
+			audioCond += ` AND a.voice_name LIKE ? OR b.label LIKE ?`
+			audioPars = append(audioPars, keywords, keywords)
+		}
+		if audioId > 0 {
+			audioCond += ` AND a.activity_voice_id = ?`
+			audioPars = append(audioPars, audioId)
+		}
+		audioStartSize := 0
+		if currentIndex > 1 {
+			audioStartSize = (currentIndex - 1) * audioPageNum
+		}
+		audioTotal, audioList, e = models.GetMicroRoadShowAudioPageList(audioStartSize, audioPageNum, audioCond, audioPars)
+	}()
+
+	// 分页查询视频
+	go func() {
+		defer wg.Done()
+		// 如果筛选条件为指定音频ID则不做视频查询
+		if audioId > 0 {
+			return
+		}
+		var videoCond string
+		var videoPars []interface{}
+		if keywords != "" {
+			videoCond += ` AND video_name LIKE ?`
+			videoPars = append(videoPars, keywords)
+		}
+		if videoId > 0 {
+			videoCond += ` AND video_id = ?`
+			videoPars = append(videoPars, videoId)
+		}
+		videoCond += ` AND publish_status = 1`
+		videoStartSize := 0
+		if currentIndex > 1 {
+			videoStartSize = (currentIndex - 1) * videoPageNum
+		}
+		videoTotal, videoList, e = models.GetMicroRoadShowVideoPageList(videoStartSize, videoPageNum, videoCond, videoPars)
+	}()
+
+	wg.Wait()
+
+	if e != nil {
+		err = errors.New("获取微路演音视频列表失败, Err: " + e.Error())
+		return
+	}
+
+	// 按比例组合列表
+	audioNum := 0
+	videoNum := 0
+	audioLen := len(audioList)
+	videoLen := len(videoList)
+	for i := 0; i < sliceNum; i++ {
+		// 音频-每次取对应比例的数据直至取完
+		for a := 0; a < audioRatio; a++ {
+			if audioNum >= audioLen {
+				break
+			}
+			respList = append(respList, audioList[audioNum])
+			audioNum += 1
+		}
+		// 视频
+		for b := 0; b < videoRatio; b++ {
+			if videoNum >= videoLen {
+				break
+			}
+			respList = append(respList, videoList[videoNum])
+			videoNum += 1
+		}
+	}
+	total = audioTotal + videoTotal
+	return
+}
+
+// getMicroRoadShowDataRatio 获取微路演列表数据音视频配比
+func getMicroRoadShowDataRatio(pageSize int) (audioRatio, videoRatio, audioPageNum, videoPageNum, sliceNum int, err error) {
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	key := models.MicroRoadShowListDataRatioConfigKey
+	config, e := models.GetConfigByCode(key)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("获取微路演列表数据量配置失败, Err: " + e.Error())
+		return
+	}
+
+	// 默认音频视频展示比例为4:1
+	ratio := "4:1"
+	if config != nil {
+		ratio = config.ConfigValue
+	}
+	ratioArr := strings.Split(ratio, ":")
+	if len(ratioArr) != 2 {
+		err = errors.New("微路演列表数据量配比有误")
+		return
+	}
+	audioRatio, e = strconv.Atoi(ratioArr[0])
+	if e != nil {
+		err = errors.New("微路演列表数据量配比有误")
+		return
+	}
+	videoRatio, e = strconv.Atoi(ratioArr[1])
+	if e != nil {
+		err = errors.New("微路演列表数据量配比有误")
+		return
+	}
+	totalRatio := audioRatio + videoRatio
+	if totalRatio == 0 {
+		err = errors.New("微路演列表数据量配比有误")
+		return
+	}
+
+	// 每比率对应数量(向上取整)
+	sliceNum = int(math.Ceil(float64(pageSize) / float64(totalRatio)))
+	audioPageNum = audioRatio * sliceNum
+	videoPageNum = videoRatio * sliceNum
+
+	return
+}
+
+// GetMicroRoadShowDefaultImgConfig 获取微路演默认图/分享图配置
+func GetMicroRoadShowDefaultImgConfig() (audioMap, videoMap, audioShareMap, videoShareMap map[int]string, err error) {
+	audioMap = make(map[int]string, 0)
+	videoMap = make(map[int]string, 0)
+	audioShareMap = make(map[int]string, 0)
+	videoShareMap = make(map[int]string, 0)
+	key := models.MicroRoadshowDefaultImgKey
+	conf, e := models.GetConfigByCode(key)
+	if e != nil {
+		err = errors.New("获取微路演默认图配置失败, Err: " + e.Error())
+		return
+	}
+	if conf.ConfigValue == "" {
+		err = errors.New("获取微路演默认图配置有误")
+		return
+	}
+	list := new(models.MicroRoadShowDefaultImgList)
+	if e = json.Unmarshal([]byte(conf.ConfigValue), &list); e != nil {
+		err = errors.New("微路演默认图配置配置值解析失败, Err: " + e.Error())
+		return
+	}
+	audioList := list.Audio
+	for i := range audioList {
+		audioMap[audioList[i].ChartPermissionId] = audioList[i].ImgUrl
+		audioShareMap[audioList[i].ChartPermissionId] = audioList[i].ShareImg
+	}
+	videoList := list.Video
+	for i := range videoList {
+		videoMap[videoList[i].ChartPermissionId] = videoList[i].ImgUrl
+		videoShareMap[videoList[i].ChartPermissionId] = videoList[i].ShareImg
+	}
+	return
+}
+
+// GetHomeNewestList 获取首页最新列表
+func GetHomeNewestList(userId, companyId, startSize, pageSize int, condition string, pars []interface{}) (resp []*models.HomeArticle, total int, err error) {
+	resp = make([]*models.HomeArticle, 0)
+	unionList, e := models.GetHomeNewestListUnionList(condition, pars, startSize, pageSize)
+	if e != nil {
+		err = errors.New("获取首页最新列表失败")
+		return
+	}
+	unionTotal, e := models.GetHomeNewestListUnionCount(condition, pars)
+	if e != nil {
+		err = errors.New("获取首页最新列表总数失败")
+		return
+	}
+	total = unionTotal
+
+	// 用户权限
+	authInfo, permissionArr, e := GetUserRaiPermissionInfo(userId, companyId)
+	if e != nil {
+		err = errors.New("获取用户权限失败, Err: " + e.Error())
+		return
+	}
+
+	// 获取默认图配置
+	audioMap, videoMap, audioShareMap, videoShareMap, e := GetMicroRoadShowDefaultImgConfig()
+	if e != nil {
+		err = errors.New("获取微路演默认图配置失败, Err: " + e.Error())
+		return
+	}
+
+	// 此处没有直接使用HomeArticle结构体而是多加了一层, 纯粹是为了方便前端区分纪要和微路演音频=_=!
+	for _, v := range unionList {
+		item := new(models.HomeArticle)
+		item.HomeType = v.HomeType
+		// 纪要
+		if item.HomeType == 0 {
+			item.ArticleId = v.ArticleId
+			item.Title = v.Title
+			item.TitleEn = v.TitleEn
+			item.UpdateFrequency = v.UpdateFrequency
+			item.CreateDate = v.CreateDate
+			item.PublishDate = v.PublishDate
+			item.Body = v.Body
+			item.BodyHtml = v.BodyHtml
+			item.Abstract = v.Abstract
+			item.CategoryName = v.CategoryName
+			item.SubCategoryName = v.SubCategoryName
+			item.ExpertBackground = v.ExpertBackground
+			item.IsResearch = v.IsResearch
+			item.Pv = v.Pv
+			item.ImgUrlPc = v.ImgUrlPc
+			item.CategoryId = v.CategoryId
+			item.HttpUrl = v.HttpUrl
+			item.IsNeedJump = v.IsNeedJump
+			item.Source = v.Source
+			item.Annotation = v.Annotation
+		}
+		// 音频
+		if v.HomeType == 1 {
+			ad := new(models.MicroAudioUnionList)
+			ad.Id = v.Id
+			ad.AudioTitle = v.AudioTitle
+			ad.AudioResourceUrl = v.AudioResourceUrl
+			ad.AudioType = v.AudioType
+			ad.AudioPublishTime = utils.StrTimeToTime(v.AudioPublishTime).Format(utils.FormatDate)
+			ad.AudioImgUrl = v.AudioImgUrl
+			ad.AudioChartPermissionId = v.AudioChartPermissionId
+			ad.AudioChartPermissionName = v.AudioChartPermissionName
+			ad.AudioPlaySeconds = v.AudioPlaySeconds
+			ad.AudioPlaySeconds = v.AudioPlaySeconds
+			ad.AudioActivityId = v.AudioActivityId
+			item.MicroAudio = ad
+			// 默认图
+			if ad.AudioImgUrl == "" {
+				if ad.AudioType == 1 {
+					ad.AudioImgUrl = audioMap[ad.AudioChartPermissionId]
+				} else {
+					ad.AudioImgUrl = videoMap[ad.AudioChartPermissionId]
+				}
+			}
+			// 分享图
+			if ad.AudioType == 1 {
+				ad.AudioShareImg = audioShareMap[ad.AudioChartPermissionId]
+			} else {
+				ad.AudioShareImg = videoShareMap[ad.AudioChartPermissionId]
+			}
+			// 权限
+			au := new(models.UserPermissionAuthInfo)
+			au.SellerName = authInfo.SellerName
+			au.SellerMobile = authInfo.SellerMobile
+			au.HasPermission = authInfo.HasPermission
+			au.OperationMode = authInfo.OperationMode
+			if au.HasPermission == 1 {
+				// 非宏观权限进一步判断是否有权限
+				if ad.AudioChartPermissionId != utils.HONG_GUAN_ID && !utils.InArrayByStr(permissionArr, ad.AudioChartPermissionName) {
+					au.HasPermission = 2
+				}
+			}
+			// 无权限的弹框提示
+			if au.HasPermission != 1 {
+				if au.OperationMode == UserPermissionOperationModeCall {
+					if ad.AudioType == 1 {
+						au.PopupMsg = UserPermissionPopupMsgCallActivity
+					} else {
+						au.PopupMsg = UserPermissionPopupMsgCallMicroVideo
+					}
+				} else {
+					if ad.AudioType == 1 {
+						au.PopupMsg = UserPermissionPopupMsgApplyActivity
+					} else {
+						au.PopupMsg = UserPermissionPopupMsgApplyMicroVideo
+					}
+				}
+			}
+			ad.AuthInfo = au
+		}
+		resp = append(resp, item)
+	}
+	return
+}

+ 87 - 0
services/user_permission.go

@@ -0,0 +1,87 @@
+package services
+
+import (
+	"errors"
+	"hongze/hongze_cygx/models"
+	"hongze/hongze_cygx/utils"
+	"strings"
+)
+
+var (
+	UserPermissionOperationModeApply      = "Apply"
+	UserPermissionOperationModeCall       = "Call"
+	UserPermissionPopupMsgApplyActivity   = "您暂无权限参加此活动,若想参加可以申请开通对应的试用权限"
+	UserPermissionPopupMsgCallActivity    = "您暂无权限参加此活动,若想参加可以联系对口销售"
+	UserPermissionPopupMsgApplyMicroVideo = "您暂无权限查看此视频,若想查看可以申请开通对应的试用权限"
+	UserPermissionPopupMsgCallMicroVideo  = "您暂无权限查看此视频若想查看可以联系对口销售"
+)
+
+// GetUserRaiPermissionInfo 获取权限类型及信息
+// HasPermission 是否有权限:1-有权限; 2-无权限; 3-潜在客户未提交申请; 4-潜在客户已提交申请 5-仅有FICC权限
+func GetUserRaiPermissionInfo(userId, companyId int) (authInfo models.UserPermissionAuthInfo, permissionArr []string, err error) {
+	// 用户申请记录
+	applyCount, e := models.GetApplyRecordCount(userId)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("获取用户申请信息失败, Err: " + e.Error())
+		return
+	}
+
+	// 潜在用户
+	if companyId <= 1 {
+		authInfo.HasPermission = 3
+		if applyCount > 0 {
+			authInfo.HasPermission = 4
+		}
+		authInfo.OperationMode = UserPermissionOperationModeApply
+		authInfo.PopupMsg = UserPermissionPopupMsgApplyActivity
+		return
+	}
+
+	// 销售信息
+	ficcSeller, e := models.GetSellerByCompanyIdCheckFicc(companyId, utils.COMPANY_PRODUCT_FICC_ID)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("获取FICC销售信息失败, Err: " + e.Error())
+		return
+	}
+	raiSeller, e := models.GetSellerByCompanyIdCheckFicc(companyId, utils.COMPANY_PRODUCT_RAI_ID)
+	if e != nil && e.Error() != utils.ErrNoRow() {
+		err = errors.New("获取权益销售信息失败, Err: " + e.Error())
+		return
+	}
+	if raiSeller != nil {
+		authInfo.SellerMobile = raiSeller.Mobile
+		authInfo.SellerName = raiSeller.RealName
+	}
+	// 仅有FICC权限
+	if ficcSeller != nil && raiSeller == nil {
+		authInfo.HasPermission = 5
+		authInfo.OperationMode = UserPermissionOperationModeApply
+		authInfo.PopupMsg = UserPermissionPopupMsgApplyActivity
+		return
+	}
+
+	// permissions示例: 医药,消费,科技,智造,策略,专家,买方研选
+	permissions, e := models.GetCompanyPermission(companyId)
+	if e != nil {
+		err = errors.New("获取客户权限失败, Err: " + e.Error())
+		return
+	}
+	if permissions == "" {
+		// 无权益权限
+		if raiSeller != nil {
+			// 有销售信息
+			authInfo.HasPermission = 2
+			authInfo.OperationMode = UserPermissionOperationModeCall
+			authInfo.PopupMsg = UserPermissionPopupMsgCallActivity
+			return
+		}
+		// 无销售信息, 无申请, 视作潜在用户
+		authInfo.HasPermission = 3
+		authInfo.OperationMode = UserPermissionOperationModeApply
+		return
+	}
+	// 有基本的权益权限
+	authInfo.HasPermission = 1
+	permissionArr = strings.Split(permissions, ",")
+	return
+}

+ 0 - 1
utils/common.go

@@ -733,7 +733,6 @@ func ReplaceSpaceAndWrap(str string) string {
 	return str
 }
 
-
 // InArrayByInt php中的in_array(判断Int类型的切片中是否存在该int值)
 func InArrayByInt(idIntList []int, searchId int) (has bool) {
 	for _, id := range idIntList {

+ 9 - 0
utils/constants.go

@@ -90,6 +90,8 @@ const (
 	ZHI_ZAO_ID                       int    = 19
 	LINK_WX_EXPLAIN                         = "https://mp.weixin.qq.com/s?__biz=Mzg2OTYzODk0Nw==&mid=2247483662&idx=1&sn=3752df99025189b9d77fe658bfc0edbd&chksm=ce98b742f9ef3e54b49986e647dd951a3aad74f323174b252174e0938c264c0562c8ec455106#rd" //用户阅读数据
 	HZ_COMPANY_ID                    int    = 16                                                                                                                                                                                                 // 弘则公司的ID
+	HONG_GUAN_NAME                   string = "宏观"
+	HONG_GUAN_ID                     int    = 1
 )
 
 const (
@@ -122,3 +124,10 @@ const (
 const (
 	YI_YAO_QI_TA = "https://hzstatic.hzinsights.com/static/temp/20220922202209/20220922/2OQMBFplQE1R3bX1y3obX7JSwSuA.png"
 )
+
+const (
+	COMPANY_PRODUCT_FICC_ID   = 1
+	COMPANY_PRODUCT_FICC_NAME = "ficc"
+	COMPANY_PRODUCT_RAI_ID    = 2
+	COMPANY_PRODUCT_RAI_NAME  = "权益"
+)