소스 검색

Merge branch 'yb/9.3' into debug

hsun 2 년 전
부모
커밋
40cd3a00e0

+ 97 - 0
controller/collection/collection.go

@@ -0,0 +1,97 @@
+package collection
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/models/request"
+	responseModel "hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/services"
+	"hongze/hongze_yb/services/collection"
+	"hongze/hongze_yb/services/user"
+)
+
+// List 收藏列表
+// @Description 收藏列表
+// @Param from_type query int false "来源类型:0-全部; 1-研报; 2-线上路演; 3-视频社区"
+// @Param keywords query string false "搜索关键词"
+// @Param curr_page query int false "当前页码"
+// @Param page_size query int false "每页数量"
+// @Success 200 {object}
+// @failure 400 {string} string "活动获取失败"
+// @Router /collection/list [get]
+func List(c *gin.Context) {
+	var req request.CollectionListReq
+	if err := c.Bind(&req); err != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+
+	userInfo := user.GetInfoByClaims(c)
+	page := services.GetCurrPageByClaims(c)
+	pageSize := services.GetPageSizeByClaims(c)
+
+	total, list, e := collection.GetCollectionList(int(userInfo.UserID), req.FromType, page, pageSize, req.Keywords)
+	if e != nil {
+		fmt.Println(e.Error())
+		response.FailMsg("获取收藏列表失败", "获取收藏列表失败, Err: "+e.Error(), c)
+		return
+	}
+
+	response.OkData("获取成功", &responseModel.CollectionListResp{
+		List:   list,
+		Paging: responseModel.GetPaging(page, pageSize, total),
+	}, c)
+}
+
+// Collect
+// @Description 加入收藏
+// @Success 200 {string} string "操作成功"
+// @Router /collection/collect [post]
+func Collect(c *gin.Context) {
+	var req request.CollectionCollectReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.CollectionType <= 0 {
+		response.Fail("收藏类型有误", c)
+		return
+	}
+	if req.PrimaryId <= 0 {
+		response.Fail("参数有误", c)
+		return
+	}
+
+	userInfo := user.GetInfoByClaims(c)
+	if e := collection.AddCollection(int(userInfo.UserID), req.CollectionType, req.PrimaryId, req.ExtendId, req.SourceAgent); e != nil {
+		response.FailMsg("操作失败", "加入收藏失败, Err: "+e.Error(), c)
+		return
+	}
+
+	response.Ok("操作成功", c)
+}
+
+// Cancel
+// @Description 取消收藏
+// @Success 200 {string} string "操作成功"
+// @Router /collection/cancel [post]
+func Cancel(c *gin.Context) {
+	var req request.CollectionCancelReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.CollectionId <= 0 {
+		response.Fail("参数有误", c)
+		return
+	}
+
+	userInfo := user.GetInfoByClaims(c)
+	if e := collection.CancelCollection(int(userInfo.UserID), req.CollectionId); e != nil {
+		response.FailMsg("操作失败", "取消收藏失败, Err: "+e.Error(), c)
+		return
+	}
+
+	response.Ok("操作成功", c)
+}

+ 2 - 0
init_serve/router.go

@@ -73,5 +73,7 @@ func InitRouter() (r *gin.Engine) {
 	routers.InitVoiceBroadcast(r)
 	//线上路演
 	routers.InitRoad(r)
+	// 收藏路由
+	routers.InitCollection(r)
 	return
 }

+ 22 - 0
models/request/collection.go

@@ -0,0 +1,22 @@
+package request
+
+// CollectionCollectReq 收藏请求体
+type CollectionCollectReq struct {
+	CollectionType int `json:"collection_type" description:"收藏类型:1-研报; 2-视频社区; 3-微路演视频"`
+	PrimaryId      int `json:"primary_id" description:"收藏类型主ID"`
+	ExtendId       int `json:"extend_id" description:"扩展ID-如研报章节"`
+	SourceAgent    int `json:"source_agent" description:"操作来源:1-小程序 2-小程序 PC 3-弘则研究公众号 4-Web PC"`
+}
+
+// CollectionCancelReq 取消收藏请求体
+type CollectionCancelReq struct {
+	CollectionId int `json:"collection_id" description:"收藏ID"`
+}
+
+// CollectionListReq 收藏列表请求体
+type CollectionListReq struct {
+	CurrPage int    `json:"curr_page" form:"curr_page" description:"当前页码"`
+	PageSize int    `json:"page_size" form:"page_size" description:"每页数据量"`
+	FromType int    `json:"from_type" form:"from_type" description:"来源类型:0-全部; 1-研报; 2-线上路演; 3-视频社区"`
+	Keywords string `json:"keywords" form:"keywords" description:"搜索关键词"`
+}

+ 20 - 0
models/response/collection.go

@@ -0,0 +1,20 @@
+package response
+
+// CollectionListResp 问答留言列表接口返回
+type CollectionListResp struct {
+	List   []*CollectionList `json:"list"`
+	Paging *PagingItem       `json:"paging"`
+}
+
+// CollectionList 收藏列表
+type CollectionList struct {
+	CollectionId   int    `description:"收藏ID"`
+	CollectionType int    `description:"收藏类型: 1-研报; 2-视频社区; 3-微路演视频"`
+	PrimaryId      int    `description:"不同收藏类型的ID"`
+	ExtendId       int    `description:"扩展ID: 如晨周报章节的ID, 大于0则详情页跳转章节详情"`
+	PublishTime    string `description:"发布时间"`
+	CreateTime     string `description:"收藏时间"`
+	ClassifyName   string `description:"报告类型名称"`
+	Author         string `description:"作者"`
+	ImgUrl         string `description:"图片地址"`
+}

+ 32 - 33
models/response/paging.go

@@ -13,50 +13,49 @@ type PagingItem struct {
 	PageSize      int  `description:"每页数据条数" json:"page_size"`
 }
 
-func GetPaging(currentIndex,pageSize,total int)(item *PagingItem)  {
-	if pageSize<=0 {
-		pageSize=utils.PageSize20
+func GetPaging(currentIndex, pageSize, total int) (item *PagingItem) {
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
 	}
-	if currentIndex<=0 {
-		currentIndex=1
+	if currentIndex <= 0 {
+		currentIndex = 1
 	}
-	item=new(PagingItem)
-	item.PageSize=pageSize
-	item.Totals=total
-	item.CurrentIndex=currentIndex
+	item = new(PagingItem)
+	item.PageSize = pageSize
+	item.Totals = total
+	item.CurrentIndex = currentIndex
 
-	if total<=0 {
-		item.IsStart=true
-		item.IsEnd=true
+	if total <= 0 {
+		item.IsStart = true
+		item.IsEnd = true
 		return
 	}
-	pages:=utils.PageCount(total,pageSize)
-	item.Pages=pages
-	if pages<=1 {
-		item.IsStart=true
-		item.IsEnd=true
-		item.PreviousIndex=1
-		item.NextIndex=1
+	pages := utils.PageCount(total, pageSize)
+	item.Pages = pages
+	if pages <= 1 {
+		item.IsStart = true
+		item.IsEnd = true
+		item.PreviousIndex = 1
+		item.NextIndex = 1
 		return
 	}
 	if pages == currentIndex {
-		item.IsStart=false
-		item.IsEnd=true
-		item.PreviousIndex=currentIndex-1
-		item.NextIndex=currentIndex
+		item.IsStart = false
+		item.IsEnd = true
+		item.PreviousIndex = currentIndex - 1
+		item.NextIndex = currentIndex
 		return
 	}
-	if currentIndex==1 {
-		item.IsStart=true
-		item.IsEnd=false
-		item.PreviousIndex=1
-		item.NextIndex=currentIndex+1
+	if currentIndex == 1 {
+		item.IsStart = true
+		item.IsEnd = false
+		item.PreviousIndex = 1
+		item.NextIndex = currentIndex + 1
 		return
 	}
-	item.IsStart=false
-	item.IsEnd=false
-	item.PreviousIndex=currentIndex-1
-	item.NextIndex=currentIndex+1
+	item.IsStart = false
+	item.IsEnd = false
+	item.PreviousIndex = currentIndex - 1
+	item.NextIndex = currentIndex + 1
 	return
 }
-

+ 20 - 1
models/tables/rddp/report/query.go

@@ -139,7 +139,10 @@ func GetByReportId(id int) (item *Report, err error) {
 
 // GetByReportIds 根据id获取报告
 func GetByReportIds(ids []int) (list []*Report, err error) {
-	err = global.MYSQL["rddp"].Model(Report{}).Where("id in (?) and state = 2", ids).Select("id, create_time").Scan(&list).Error
+	err = global.MYSQL["rddp"].Model(Report{}).
+		Where("id in (?) and state = 2", ids).
+		Select("id, create_time").
+		Scan(&list).Error
 	if err == utils.ErrNoRow {
 		err = nil
 	}
@@ -404,4 +407,20 @@ ORDER BY
 	sql = fmt.Sprintf(sql, firstName, secondId)
 	err = global.MYSQL["rddp"].Raw(sql).First(&items).Error
 	return
+}
+
+
+// GetListByReportIds 根据IDs获取列表
+func GetListByReportIds(reportIds []int) (list []*Report, err error) {
+	var where string
+	where = `state = 2`
+	if len(reportIds) > 0 {
+		where += ` AND id IN (?)`
+	}
+
+	err = global.MYSQL["rddp"].Model(Report{}).
+		Where(where, reportIds).
+		Order("id asc").
+		Scan(&list).Error
+	return
 }

+ 46 - 22
models/tables/rddp/report_chapter/query.go

@@ -24,11 +24,11 @@ ORDER BY
 }
 
 // GetListByReportId 根据报告ID获取章节列表
-func GetListByReportId(reportId int, classifyNameFirst string) (list []*ReportChapter, err error)  {
+func GetListByReportId(reportId int, classifyNameFirst string) (list []*ReportChapter, err error) {
 	var where string
-	if  classifyNameFirst == "周报"{
+	if classifyNameFirst == "周报" {
 		where = "report_id = ? AND is_edit = 1 AND publish_state = 2"
-	}else{
+	} else {
 		where = "report_id = ? AND publish_state = 2"
 	}
 
@@ -41,11 +41,11 @@ func GetListByReportId(reportId int, classifyNameFirst string) (list []*ReportCh
 }
 
 // GetListByReportIdTypeIds 根据报告ID、章节类型ID获取章节列表
-func GetListByReportIdTypeIds(reportId int, typeIds []int, classifyNameFirst string) (list []*ReportChapter, err error)  {
+func GetListByReportIdTypeIds(reportId int, typeIds []int, classifyNameFirst string) (list []*ReportChapter, err error) {
 	var where string
-	if  classifyNameFirst == "周报"{
+	if classifyNameFirst == "周报" {
 		where = "report_id = ? AND type_id in (?) AND is_edit = 1 AND publish_state = 2 "
-	}else{
+	} else {
 		where = "report_id = ? AND type_id in (?) AND publish_state = 2 "
 	}
 
@@ -82,7 +82,7 @@ func GetReportIdsByTypeIdsAndClass(typeIds []int, classifyNameFirst string) (rep
 }
 
 // GetTypeIdById 根据ID获取章节类型
-func GetTypeIdById(id int) (info *ReportChapter, err error)  {
+func GetTypeIdById(id int) (info *ReportChapter, err error) {
 	err = global.MYSQL["rddp"].Model(ReportChapter{}).Select("report_chapter_id, report_id, type_id").
 		Where("report_chapter_id = ? AND publish_state = 2 ", id).
 		First(&info).Error
@@ -92,13 +92,12 @@ func GetTypeIdById(id int) (info *ReportChapter, err error)  {
 	return
 }
 
-
 // GetByTypeIdsAndReportIds 根据章节ID和ReportIds查询报告
-func GetByTypeIdsAndReportIds(typeIds []int,  reportIds []int, classifyNameFirst string) (list []*ReportChapter, err error) {
+func GetByTypeIdsAndReportIds(typeIds []int, reportIds []int, classifyNameFirst string) (list []*ReportChapter, err error) {
 	var where string
-	if  classifyNameFirst == "周报"{
+	if classifyNameFirst == "周报" {
 		where = "report_id in (?) AND type_id in (?) AND is_edit = 1 AND publish_state = 2 "
-	}else{
+	} else {
 		where = "report_id in (?) AND type_id in (?) AND publish_state = 2 "
 	}
 
@@ -116,6 +115,18 @@ func GetByTypeIdsAndReportIds(typeIds []int,  reportIds []int, classifyNameFirst
 	return
 }
 
+// GetChapterByReportIdTypeId 根据报告ID和章节类型ID查找章节
+func GetChapterByReportIdTypeId(reportId, typeId int) (chapter *ReportChapter, err error) {
+	err = global.MYSQL["rddp"].Model(ReportChapter{}).
+		Select("report_id, type_id, report_chapter_id").
+		Where("report_id = ? and type_id = ?", reportId, typeId).
+		First(&chapter).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}
+
 func GetWeekRecommendList(reportId int, firstName string) (items []*ReportChapter, err error) {
 	sql := `SELECT * FROM (SELECT
 	a.report_id,
@@ -141,17 +152,6 @@ ORDER BY
 	err = global.MYSQL["rddp"].Raw(sql).Scan(&items).Error
 	return
 }
-// GetChapterByReportIdTypeId 根据报告ID和章节类型ID查找章节
-func GetChapterByReportIdTypeId(reportId, typeId int) (chapter *ReportChapter, err error) {
-	err = global.MYSQL["rddp"].Model(ReportChapter{}).
-		Select("report_id, type_id, report_chapter_id").
-		Where("report_id = ? and type_id = ?", reportId, typeId).
-		First(&chapter).Error
-	if err == utils.ErrNoRow {
-		err =nil
-	}
-	return
-}
 
 func GetLatestChapterByClassifyName(firstName string) (items *ReportChapter, err error) {
 	sql := `SELECT
@@ -169,4 +169,28 @@ ORDER BY
 	sql = fmt.Sprintf(sql, firstName)
 	err = global.MYSQL["rddp"].Raw(sql).First(&items).Error
 	return
+}
+
+// GetItemById 主键获取章节
+func GetItemById(chapterId int) (item *ReportChapter, err error) {
+	err = global.MYSQL["rddp"].Model(ReportChapter{}).
+		Where("report_chapter_id = ? AND publish_state = 2", chapterId).
+		First(&item).Error
+	return
+}
+
+// GetListByChapterIds 根据章节IDs获取列表
+func GetListByChapterIds(chapterIds []int) (list []*ReportChapter, err error) {
+	var where string
+	where = `publish_state = 2`
+	if len(chapterIds) > 0 {
+		where += ` AND report_chapter_id IN (?)`
+	}
+
+	err = global.MYSQL["rddp"].Model(ReportChapter{}).
+		//Select("report_id, type_id, report_chapter_id, classify_name_first, classify_id_first, video_url, video_name, video_play_seconds, video_size, sort").
+		Where(where, chapterIds).
+		Order("sort asc, report_chapter_id asc").
+		Scan(&list).Error
+	return
 }

+ 15 - 0
models/tables/yb_community_video/model.go

@@ -39,3 +39,18 @@ func GetItemById(videoId int) (item *YbCommunityVideo, err error) {
 		First(&item).Error
 	return
 }
+
+// GetListByVideoIds 根据视频IDs获取列表
+func GetListByVideoIds(videoIds []int) (list []*YbCommunityVideo, err error) {
+	var where string
+	where = `publish_state = 1 AND is_deleted = 0`
+	if len(videoIds) > 0 {
+		where += ` AND community_video_id IN (?)`
+	}
+
+	err = global.DEFAULT_MYSQL.Model(YbCommunityVideo{}).
+		Where(where, videoIds).
+		Order("community_video_id asc").
+		Scan(&list).Error
+	return
+}

+ 15 - 0
models/tables/yb_road_video/model.go

@@ -37,3 +37,18 @@ func GetItemById(videoId int) (item *YbRoadVideo, err error) {
 		First(&item).Error
 	return
 }
+
+// GetListByVideoIds 根据视频IDs获取列表
+func GetListByVideoIds(videoIds []int) (list []*YbRoadVideo, err error) {
+	var where string
+	where = `publish_state = 1 AND is_deleted = 0`
+	if len(videoIds) > 0 {
+		where += ` AND road_video_id IN (?)`
+	}
+
+	err = global.DEFAULT_MYSQL.Model(YbRoadVideo{}).
+		Where(where, videoIds).
+		Order("road_video_id asc").
+		Scan(&list).Error
+	return
+}

+ 52 - 0
models/tables/yb_user_collection/entity.go

@@ -0,0 +1,52 @@
+package yb_user_collection
+
+import (
+	"time"
+)
+
+// YbUserCollection 研报-用户收藏表
+type YbUserCollection struct {
+	CollectionID   int       `gorm:"primaryKey;column:collection_id;type:int(10) unsigned;not null" json:"-"`
+	CollectionType int       `gorm:"column:collection_type;type:tinyint(4) unsigned;not null;default:0" json:"collectionType"`         // 收藏类型:1-研报; 2-视频社区; 3-微路演视频
+	UserID         int       `gorm:"index:idx_user_id;column:user_id;type:int(10) unsigned;not null;default:0" json:"userId"`          // 用户ID
+	PrimaryID      int       `gorm:"index:idx_primary_id;column:primary_id;type:int(10) unsigned;not null;default:0" json:"primaryId"` // 不同类型的主ID
+	ExtendID       int       `gorm:"index:idx_extend_id;column:extend_id;type:int(10) unsigned;not null;default:0" json:"extendId"`    // 扩展ID-如晨周报章节ID
+	State          int       `gorm:"column:state;type:tinyint(4) unsigned;not null;default:0" json:"state"`                            // 状态:1-已收藏;0-取消收藏;
+	SourceAgent    int       `gorm:"column:source_agent;type:tinyint(4) unsigned;not null;default:0" json:"sourceAgent"`               // 操作来源:1-小程序 2-小程序 PC 3-弘则研究公众号 4-Web PC
+	Title          string    `gorm:"column:title;type:varchar(255);not null;default:''" json:"title"`                                  // 研报/视频标题-冗余
+	PublishTime    time.Time `gorm:"column:publish_time;type:datetime" json:"publishTime"`                                             // 研报/视频发布时间-冗余
+	CreateTime     time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`                                               // 创建时间
+	ModifyTime     time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`                                               // 修改时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *YbUserCollection) TableName() string {
+	return "yb_user_collection"
+}
+
+// YbUserCollectionColumns get sql column name.获取数据库列名
+var YbUserCollectionColumns = struct {
+	CollectionID   string
+	CollectionType string
+	UserID         string
+	PrimaryID      string
+	ExtendID       string
+	State          string
+	SourceAgent    string
+	Title          string
+	PublishTime    string
+	CreateTime     string
+	ModifyTime     string
+}{
+	CollectionID:   "collection_id",
+	CollectionType: "collection_type",
+	UserID:         "user_id",
+	PrimaryID:      "primary_id",
+	ExtendID:       "extend_id",
+	State:          "state",
+	SourceAgent:    "source_agent",
+	Title:          "title",
+	PublishTime:    "publish_time",
+	CreateTime:     "create_time",
+	ModifyTime:     "modify_time",
+}

+ 40 - 0
models/tables/yb_user_collection/model.go

@@ -0,0 +1,40 @@
+package yb_user_collection
+
+import "hongze/hongze_yb/global"
+
+func (item *YbUserCollection) Create() (err error) {
+	err = global.DEFAULT_MYSQL.Create(item).Error
+	return
+}
+
+func (item *YbUserCollection) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(item).Select(updateCols).Updates(*item).Error
+	return
+}
+
+// GetPageListByCondition 获取收藏列表-分页
+func GetPageListByCondition(condition string, pars []interface{}, pageIndex, pageSize int) (list []*YbUserCollection, err error) {
+	offset := (pageIndex - 1) * pageSize
+	err = global.DEFAULT_MYSQL.Model(YbUserCollection{}).
+		Where(condition, pars...).
+		Offset(offset).Limit(pageSize).
+		Order("create_time DESC").
+		Scan(&list).Error
+	return
+}
+
+// GetPageListTotalByCondition 获取收藏列表总数-分页
+func GetPageListTotalByCondition(condition string, pars []interface{}) (total int64, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbUserCollection{}).
+		Where(condition, pars...).
+		Count(&total).Error
+	return
+}
+
+// GetItemById 主键获取收藏
+func GetItemById(collectionId int) (item *YbUserCollection, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbUserCollection{}).
+		Where("collection_id = ? AND state = 1", collectionId).
+		First(&item).Error
+	return
+}

+ 14 - 0
routers/collection.go

@@ -0,0 +1,14 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/collection"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitCollection(r *gin.Engine) {
+	rGroup := r.Group("/api/collection").Use(middleware.Token())
+	rGroup.GET("/list", collection.List)
+	rGroup.POST("/collect", collection.Collect)
+	rGroup.POST("/cancel", collection.Cancel)
+}

+ 321 - 0
services/collection/collection.go

@@ -0,0 +1,321 @@
+package collection
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/models/tables/rddp/report"
+	"hongze/hongze_yb/models/tables/rddp/report_chapter"
+	"hongze/hongze_yb/models/tables/yb_community_video"
+	"hongze/hongze_yb/models/tables/yb_road_video"
+	"hongze/hongze_yb/models/tables/yb_user_collection"
+	"hongze/hongze_yb/utils"
+	"sync"
+	"time"
+)
+
+// 收藏类型
+const (
+	CollectionTypeReport    = iota + 1 // 研报
+	CollectionTypeVideo                // 视频社区
+	CollectionTypeRoadVideo            // 微路演视频
+)
+
+// AddCollection 加入收藏
+func AddCollection(userId, collectionType, primaryId, extendId, sourceAgent int) (err error) {
+	title := ""
+	nowTime := time.Now().Local()
+	publishTime := nowTime
+
+	// 收藏类型:1-研报; 2-视频社区; 3-微路演视频
+	switch collectionType {
+	case CollectionTypeReport:
+		// 晨周报章节
+		if extendId > 0 {
+			chapter, e := report_chapter.GetItemById(extendId)
+			if e != nil {
+				err = errors.New("获取章节失败, Err: " + e.Error())
+				return
+			}
+			title = chapter.Title
+			publishTime = chapter.PublishTime
+			break
+		}
+		rp, e := report.GetPublishByReportId(primaryId)
+		if e != nil {
+			err = errors.New("获取报告失败, Err: " + e.Error())
+			return
+		}
+		title = rp.Title
+		publishTime = rp.PublishTime
+	case CollectionTypeVideo:
+		video, e := yb_community_video.GetItemById(primaryId)
+		if e != nil {
+			err = errors.New("获取视频失败, Err: " + e.Error())
+			return
+		}
+		title = video.Title
+		publishTime = video.PublishTime
+	case CollectionTypeRoadVideo:
+		roadVideo, e := yb_road_video.GetItemById(primaryId)
+		if e != nil {
+			err = errors.New("获取路演视频失败, Err: " + e.Error())
+			return
+		}
+		title = roadVideo.Title
+		publishTime = roadVideo.PublishTime
+	default:
+		err = errors.New(fmt.Sprintf("收藏类型有误, 当前收藏类型%d", collectionType))
+		return
+	}
+
+	item := &yb_user_collection.YbUserCollection{
+		CollectionType: collectionType,
+		UserID:         userId,
+		PrimaryID:      primaryId,
+		ExtendID:       extendId,
+		State:          1,
+		SourceAgent:    sourceAgent,
+		Title:          title,
+		PublishTime:    publishTime,
+		CreateTime:     nowTime,
+		ModifyTime:     nowTime,
+	}
+	if e := item.Create(); e != nil {
+		err = errors.New("新增收藏失败, Err: " + e.Error())
+		return
+	}
+	return
+}
+
+// CancelCollection 取消收藏
+func CancelCollection(userId, collectionId int) (err error) {
+	item, e := yb_user_collection.GetItemById(collectionId)
+	if e != nil {
+		err = errors.New("获取收藏失败, Err: " + e.Error())
+		return
+	}
+	if item.CollectionID <= 0 {
+		err = errors.New("收藏信息有误")
+		return
+	}
+	if item.State != 1 {
+		err = errors.New("收藏状态有误")
+		return
+	}
+	if item.UserID != userId {
+		err = errors.New(fmt.Sprintf("收藏人信息有误, 操作人ID: %d, 被操作人ID: %d", userId, item.UserID))
+		return
+	}
+	updateCols := []string{"State", "ModifyTime"}
+	item.State = 0
+	item.ModifyTime = time.Now().Local()
+	if e = item.Update(updateCols); e != nil {
+		err = errors.New("更新收藏失败, Err: " + e.Error())
+		return
+	}
+	return
+}
+
+// GetCollectionList 收藏列表
+func GetCollectionList(userId, fromType, currPage, pageSize int, keywords string) (total int, respList []*response.CollectionList, err error) {
+	respList = make([]*response.CollectionList, 0)
+	if fromType <= 0 {
+		fromType = 0
+	}
+
+	// 查询收藏列表
+	var cond string
+	var pars []interface{}
+	cond += `user_id = ?`
+	pars = append(pars, userId)
+	if fromType > 0 {
+		cond += ` AND collection_type = ?`
+		pars = append(pars, fromType)
+	}
+	if keywords != "" {
+		keywords = "%" + keywords + "%"
+		cond += ` AND title LIKE ?`
+		pars = append(pars, keywords)
+	}
+	collectionTotal, e := yb_user_collection.GetPageListTotalByCondition(cond, pars)
+	if e != nil {
+		err = errors.New("获取收藏列表总数失败, Err: " + e.Error())
+		return
+	}
+	total = int(collectionTotal)
+	collections, e := yb_user_collection.GetPageListByCondition(cond, pars, currPage, pageSize)
+	if e != nil {
+		err = errors.New("获取收藏列表失败, Err: " + e.Error())
+		return
+	}
+
+	// 遍历收藏列表取出各类型的ID
+	reportIdArr := make([]int, 0)
+	chapterIdArr := make([]int, 0)
+	videoIdArr := make([]int, 0)
+	roadVideoIdArr := make([]int, 0)
+	for i := range collections {
+		switch collections[i].CollectionType {
+		case CollectionTypeReport:
+			if collections[i].ExtendID > 0 {
+				chapterIdArr = append(chapterIdArr, collections[i].ExtendID)
+				break
+			}
+			reportIdArr = append(reportIdArr, collections[i].PrimaryID)
+		case CollectionTypeVideo:
+			videoIdArr = append(videoIdArr, collections[i].PrimaryID)
+		case CollectionTypeRoadVideo:
+			roadVideoIdArr = append(roadVideoIdArr, collections[i].PrimaryID)
+		}
+	}
+
+	// 查询相应收藏类型详情
+	var chapterErr, reportErr, videoErr, roadVideoErr error
+	chapterMap := make(map[int]*report_chapter.ReportChapter, 0)
+	reportMap := make(map[int]*report.Report, 0)
+	videoMap := make(map[int]*yb_community_video.YbCommunityVideo, 0)
+	roadVideoMap := make(map[int]*yb_road_video.YbRoadVideo, 0)
+
+	wg := sync.WaitGroup{}
+
+	// 章节
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+
+		if len(chapterIdArr) == 0 {
+			return
+		}
+		chapters, e := report_chapter.GetListByChapterIds(chapterIdArr)
+		if e != nil {
+			chapterErr = errors.New("获取章节失败, Err: " + e.Error())
+			return
+		}
+		for i := range chapters {
+			chapterMap[chapters[i].ReportChapterId] = chapters[i]
+		}
+	}()
+
+	// 报告
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+
+		if len(reportIdArr) == 0 {
+			return
+		}
+		reports, e := report.GetListByReportIds(reportIdArr)
+		if e != nil {
+			reportErr = errors.New("获取报告失败, Err: " + e.Error())
+			return
+		}
+		for i := range reports {
+			reportMap[reports[i].Id] = reports[i]
+		}
+	}()
+
+	// 视频
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+
+		if len(videoIdArr) == 0 {
+			return
+		}
+		videos, e := yb_community_video.GetListByVideoIds(videoIdArr)
+		if e != nil {
+			videoErr = errors.New("获取视频失败, Err: " + e.Error())
+			return
+		}
+		for i := range videos {
+			videoMap[videos[i].CommunityVideoID] = videos[i]
+		}
+	}()
+
+	// 路演视频
+	wg.Add(1)
+	go func() {
+		defer wg.Done()
+
+		if len(roadVideoIdArr) == 0 {
+			return
+		}
+		roadVideos, e := yb_road_video.GetListByVideoIds(roadVideoIdArr)
+		if e != nil {
+			roadVideoErr = errors.New("获取视频失败, Err: " + e.Error())
+			return
+		}
+		for i := range roadVideos {
+			roadVideoMap[roadVideos[i].RoadVideoID] = roadVideos[i]
+		}
+	}()
+
+	wg.Wait()
+
+	if chapterErr != nil {
+		err = chapterErr
+		return
+	}
+	if reportErr != nil {
+		err = reportErr
+		return
+	}
+	if videoErr != nil {
+		err = videoErr
+		return
+	}
+	if roadVideoErr != nil {
+		err = roadVideoErr
+		return
+	}
+
+	// 响应列表
+	for i := range collections {
+		v := &response.CollectionList{
+			CollectionId:   collections[i].CollectionID,
+			CollectionType: collections[i].CollectionType,
+			PrimaryId:      collections[i].PrimaryID,
+			ExtendId:       collections[i].ExtendID,
+			CreateTime:     collections[i].CreateTime.Format(utils.FormatDate),
+		}
+		// 收藏类型:1-研报; 2-视频社区; 3-微路演视频
+		switch collections[i].CollectionType {
+		case CollectionTypeReport:
+			// 晨周报章节
+			if collections[i].ExtendID > 0 {
+				cp := chapterMap[collections[i].ExtendID]
+				if cp != nil {
+					v.PublishTime = cp.PublishTime.Format(utils.FormatDate)
+					v.ClassifyName = utils.REPORT_CHAPTER_TYPE_NAME_MAP[cp.ReportType]
+					v.Author = cp.Author
+				}
+				break
+			}
+			rp := reportMap[collections[i].PrimaryID]
+			if rp != nil {
+				v.PublishTime = rp.PublishTime.Format(utils.FormatDate)
+				v.ClassifyName = rp.ClassifyNameFirst
+				v.Author = rp.Author
+			}
+		case CollectionTypeVideo:
+			vd := videoMap[collections[i].PrimaryID]
+			if vd != nil {
+				v.PublishTime = vd.PublishTime.Format(utils.FormatDate)
+				v.ImgUrl = vd.CoverImgURL
+			}
+		case CollectionTypeRoadVideo:
+			rv := roadVideoMap[collections[i].PrimaryID]
+			if rv != nil {
+				v.PublishTime = rv.PublishTime.Format(utils.FormatDate)
+				v.ImgUrl = rv.CoverImgURL
+				v.Author = rv.AdminRealName
+			}
+		default:
+			break
+		}
+		respList = append(respList, v)
+	}
+
+	return
+}

+ 11 - 0
utils/constants.go

@@ -221,3 +221,14 @@ const (
 	CACHE_CHART_CLASSIFY         = "chart:classify"                  //图表分类数据
 	CACHE_IMPORT_MANUAL_DATA     = "import:manual:data"              //手工数据导入后刷新
 )
+
+// 研报类型标识
+var (
+	REPORT_TYPE_DAY  = "day"
+	REPORT_TYPE_WEEK = "week"
+)
+
+var REPORT_CHAPTER_TYPE_NAME_MAP = map[string]string{
+	REPORT_TYPE_DAY:  "晨报",
+	REPORT_TYPE_WEEK: "周报",
+}