瀏覽代碼

Merge branch 'yb/4.0' into debug

# Conflicts:
#	init_serve/router.go
#	models/tables/rddp/report/query.go
#	models/tables/rddp/report_chapter/query.go
xiexiaoyuan 2 年之前
父節點
當前提交
b2544398b1
共有 44 個文件被更改,包括 1789 次插入16 次删除
  1. 3 3
      controller/chart/chart_info.go
  2. 170 0
      controller/comment/comment.go
  3. 27 0
      controller/like/like.go
  4. 113 0
      controller/message/message.go
  5. 29 0
      controller/user/user.go
  6. 6 0
      init_serve/router.go
  7. 15 1
      logic/report/research_report.go
  8. 33 0
      logic/user/user.go
  9. 15 0
      models/request/comment/comment.go
  10. 9 0
      models/request/like/like.go
  11. 9 0
      models/request/message/message.go
  12. 5 0
      models/request/user/user.go
  13. 34 0
      models/response/comment.go
  14. 6 0
      models/response/like.go
  15. 21 0
      models/response/message.go
  16. 12 8
      models/response/report.go
  17. 9 0
      models/tables/rddp/report/query.go
  18. 12 1
      models/tables/rddp/report_chapter/query.go
  19. 6 0
      models/tables/wx_user/query.go
  20. 8 0
      models/tables/yb_comment/create.go
  21. 89 0
      models/tables/yb_comment/query.go
  22. 43 0
      models/tables/yb_comment/update.go
  23. 32 0
      models/tables/yb_comment/yb_comment.go
  24. 8 0
      models/tables/yb_like/create.go
  25. 45 0
      models/tables/yb_like/query.go
  26. 9 0
      models/tables/yb_like/update.go
  27. 21 0
      models/tables/yb_like/yb_like.go
  28. 55 0
      models/tables/yb_message/query.go
  29. 25 0
      models/tables/yb_message/update.go
  30. 23 0
      models/tables/yb_message/yb_message.go
  31. 15 0
      routers/comment.go
  32. 12 0
      routers/like.go
  33. 15 0
      routers/message.go
  34. 1 0
      routers/user.go
  35. 292 0
      services/comment/comment.go
  36. 126 0
      services/like/like.go
  37. 148 0
      services/message/message.go
  38. 8 0
      services/report/report.go
  39. 8 1
      services/report/report_chapter.go
  40. 2 2
      services/user/user.go
  41. 77 0
      services/wx_app/security/security.go
  42. 14 0
      services/wx_app/wx_app.go
  43. 174 0
      services/yb_common.go
  44. 5 0
      utils/constants.go

+ 3 - 3
controller/chart/chart_info.go

@@ -214,7 +214,9 @@ func GetChartInfoDetail(c *gin.Context) {
 
 		var startDateReal string
 		var diffSeconds int64
-		if chartType == 1 {
+		if chartType == 2 { //季节性图表
+			startDateReal = startDate
+		} else {
 			if v.EdbInfoType == 0 && v.LeadUnit != "" && v.LeadValue > 0 {
 				// 领先指标
 				var startTimeRealTemp time.Time
@@ -241,8 +243,6 @@ func GetChartInfoDetail(c *gin.Context) {
 			} else {
 				startDateReal = startDate
 			}
-		} else {
-			startDateReal = startDate
 		}
 		//fmt.Println("line 1011 chart:", v.Source, v.EdbInfoId, startDateReal, endDate)
 		calendarPreYear := 0

+ 170 - 0
controller/comment/comment.go

@@ -0,0 +1,170 @@
+package comment
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	reqComment "hongze/hongze_yb/models/request/comment"
+	commentService "hongze/hongze_yb/services/comment"
+	userService "hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"strconv"
+)
+
+// Comment 发布留言
+func Comment(c *gin.Context)  {
+	var req reqComment.ReqComment
+	if c.ShouldBind(&req) !=nil {
+		response.Fail("入参错误", c)
+		return
+	}
+	userInfo := userService.GetInfoByClaims(c)
+	data, err := commentService.Comment(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(),c)
+		return
+	}
+	response.OkData("留言成功", data, c)
+	return
+}
+
+// Delete 删除留言
+func Delete(c *gin.Context) {
+	var req *reqComment.ReqDel
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	userInfo := userService.GetInfoByClaims(c)
+	err := commentService.Delete(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(),c)
+		return
+	}
+	response.Ok("删除留言成功", c)
+	return
+}
+
+// HotList 获取精选留言
+func HotList(c *gin.Context)  {
+	reqReportId := c.DefaultQuery("report_id", "")
+	reqReportChapterId := c.DefaultQuery("report_chapter_id", "")
+	reqOldReportId := c.DefaultQuery("old_report_id", "")
+	reqOldReportChapterId := c.DefaultQuery("old_report_chapter_id", "")
+	reqPageIndex := c.DefaultQuery("current_index", "1")
+	reqPageSize := c.DefaultQuery("page_size", strconv.Itoa(utils.PageSize20))
+
+	pageIndex, err := strconv.Atoi(reqPageIndex)
+	if err != nil {
+		response.Fail("请输入正确的条数限制", c)
+		return
+	}
+	pageSize, err := strconv.Atoi(reqPageSize)
+	if err != nil {
+		response.Fail("请输入正确的页码", c)
+		return
+	}
+	var (
+		reportId int
+		reportChapterId int
+		oldReportId int
+		oldReportChapterId int
+	)
+	if reqReportId != ""{
+		reportId, err = strconv.Atoi(reqReportId)
+		if err != nil {
+			response.Fail("报告ID格式有误", c)
+			return
+		}
+	}
+
+	if reqReportChapterId != "" {
+		reportChapterId, err = strconv.Atoi(reqReportChapterId)
+		if err != nil {
+			response.Fail("章节ID格式有误", c)
+			return
+		}
+	}
+
+	if reqOldReportId != ""{
+		oldReportId, err = strconv.Atoi(reqOldReportId)
+		if err != nil {
+			response.Fail("老报告ID格式有误", c)
+			return
+		}
+	}
+
+	if reqOldReportChapterId != "" {
+		oldReportChapterId, err = strconv.Atoi(reqOldReportChapterId)
+		if err != nil {
+			response.Fail("章节ID格式有误", c)
+			return
+		}
+	}
+
+	userinfo := userService.GetInfoByClaims(c)
+
+	list, err := commentService.List(userinfo, reportId, reportChapterId, oldReportId,oldReportChapterId,true, pageIndex, pageSize)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.OkData("查询成功", list, c )
+	return
+}
+
+// MyList 获取我的留言
+func MyList(c *gin.Context)  {
+	reqReportId := c.DefaultQuery("report_id", "")
+	reqReportChapterId := c.DefaultQuery("report_chapter_id", "")
+
+	reqOldReportId := c.DefaultQuery("old_report_id", "")
+	reqOldReportChapterId := c.DefaultQuery("old_report_chapter_id", "")
+	var (
+		reportId int
+		reportChapterId int
+		oldReportId int
+		oldReportChapterId int
+		err error
+	)
+	if reqReportId != ""{
+		reportId, err = strconv.Atoi(reqReportId)
+		if err != nil {
+			response.Fail("报告ID格式有误", c)
+			return
+		}
+	}
+
+	if reqReportChapterId != "" {
+		reportChapterId, err = strconv.Atoi(reqReportChapterId)
+		if err != nil {
+			response.Fail("章节ID格式有误", c)
+			return
+		}
+	}
+
+	if reqOldReportId != ""{
+		oldReportId, err = strconv.Atoi(reqOldReportId)
+		if err != nil {
+			response.Fail("老报告ID格式有误", c)
+			return
+		}
+	}
+
+	if reqOldReportChapterId != "" {
+		oldReportChapterId, err = strconv.Atoi(reqOldReportChapterId)
+		if err != nil {
+			response.Fail("章节ID格式有误", c)
+			return
+		}
+	}
+
+	userinfo := userService.GetInfoByClaims(c)
+
+	list, err := commentService.List(userinfo, reportId, reportChapterId, oldReportId,oldReportChapterId, false, 0, 0)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.OkData("查询成功", list, c )
+	return
+}

+ 27 - 0
controller/like/like.go

@@ -0,0 +1,27 @@
+package like
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/models/request/like"
+	likeService "hongze/hongze_yb/services/like"
+	userService "hongze/hongze_yb/services/user"
+)
+
+// SetLike 点赞设置
+func SetLike(c *gin.Context)  {
+	var req like.ReqLike
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	userinfo := userService.GetInfoByClaims(c)
+
+	data, err := likeService.SetLike(userinfo, req)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.OkData("操作成功", data, c )
+	return
+}

+ 113 - 0
controller/message/message.go

@@ -0,0 +1,113 @@
+package message
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	message2 "hongze/hongze_yb/models/request/message"
+	"hongze/hongze_yb/services/message"
+	userService "hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"strconv"
+	"strings"
+)
+
+func List(c *gin.Context)  {
+	reqType := c.DefaultQuery("type", "0")
+	reqPageIndex := c.DefaultQuery("current_index", "1")
+	reqPageSize := c.DefaultQuery("page_size", strconv.Itoa(utils.PageSize20))
+
+	if !strings.Contains("0,1,2", reqType) {
+		response.Fail("请输入正确的消息类型", c)
+		return
+	}
+	msgtype, err := strconv.Atoi(reqType)
+	if err != nil {
+		response.Fail("请输入正确的消息类型", c)
+		return
+	}
+
+	pageIndex, err := strconv.Atoi(reqPageIndex)
+	if err != nil {
+		response.Fail("请输入正确的条数限制", c)
+		return
+	}
+	pageSize, err := strconv.Atoi(reqPageSize)
+	if err != nil {
+		response.Fail("请输入正确的页码", c)
+		return
+	}
+	userInfo := userService.GetInfoByClaims(c)
+	data, err := message.GetList(userInfo, msgtype, pageIndex, pageSize)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.OkData("查询成功", data, c)
+	return
+}
+
+// BatchRead 一键已读
+func BatchRead(c *gin.Context)  {
+	var req message2.ReqMessageBatch
+	if c.ShouldBind(&req) !=nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	if !strings.Contains("0,1,2", strconv.Itoa(req.Type)) {
+		response.Fail("请输入正确的消息类型", c)
+		return
+	}
+
+	userInfo := userService.GetInfoByClaims(c)
+    err := message.BatchRead(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+	return
+}
+
+// SingleRead 设置单条消息已读
+func SingleRead(c *gin.Context)  {
+	var req message2.ReqMessage
+	if c.ShouldBind(&req) !=nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	if req.MsgId <=0 {
+		response.Fail("请输入正确的消息Id", c)
+		return
+	}
+
+	userInfo := userService.GetInfoByClaims(c)
+	err := message.SingleRead(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+	return
+}
+
+// SingleDelete 删除单条消息
+func SingleDelete(c *gin.Context)  {
+	var req message2.ReqMessage
+	if c.ShouldBind(&req) !=nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	if req.MsgId <=0 {
+		response.Fail("请输入正确的消息Id", c)
+		return
+	}
+
+	userInfo := userService.GetInfoByClaims(c)
+	err := message.SingleDelete(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+	return
+}

+ 29 - 0
controller/user/user.go

@@ -264,3 +264,32 @@ func GetTabBar(c *gin.Context) {
 
 	response.OkData("获取成功", tabBarList, c)
 }
+
+// SetUserInfo 设置用户个人信息(头像和昵称)
+func SetUserInfo(c *gin.Context) {
+	var req user.SetUserInfoReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数异常", c)
+		return
+	}
+	// 去掉首尾空格
+	req.NickName = strings.Trim(req.NickName, "")
+	req.HeadImgUrl = strings.Trim(req.HeadImgUrl, "")
+	if req.NickName == "" {
+		response.Fail("请输入昵称", c)
+		return
+	}
+
+	if req.HeadImgUrl == "" {
+		response.Fail("请上传头像", c)
+		return
+	}
+	userInfo := userService.GetInfoByClaims(c)
+
+	err := userLogic.SetUserInfo(userInfo, req)
+	if err != nil {
+		response.Fail(err.Error(), c)
+		return
+	}
+	response.Ok("更新成功", c)
+}

+ 6 - 0
init_serve/router.go

@@ -54,5 +54,11 @@ func InitRouter() (r *gin.Engine) {
 	r.StaticFS("/static", http.Dir("./static"))
 	//pc相关路由
 	routers.InitPc(r)
+	// 研报点赞相关路由
+	routers.InitLike(r)
+	// 研报留言相关路由
+	routers.InitComment(r)
+	// 研报消息相关路由
+	routers.InitMessage(r)
 	return
 }

+ 15 - 1
logic/report/research_report.go

@@ -12,6 +12,7 @@ import (
 	"hongze/hongze_yb/models/tables/research_report_type"
 	"hongze/hongze_yb/models/tables/user_view_history"
 	"hongze/hongze_yb/models/tables/wx_user"
+	"hongze/hongze_yb/services"
 	"hongze/hongze_yb/utils"
 	"strconv"
 	"time"
@@ -22,6 +23,8 @@ type ResearchReportInfo struct {
 	ResearchReportTypeList        []*company_report_permission.ResearchReportTypeList `json:"research_report_type_list"`
 	HasMenu                       int                                                 `json:"has_menu"`
 	ResearchReportTypeContentList []*research_report.ResearchReportTypeContent        `description:"报告详情"`
+	LikeNum                       int64                                               `description:"点赞总数" json:"like_num"`
+	LikeEnabled                   int8                                                `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
 }
 
 // GetResearchReportInfo 获取报告详情
@@ -122,14 +125,19 @@ func GetResearchReportInfo(researchReportId, userId uint64) (result ResearchRepo
 	//添加阅读日志的数据加入到redis
 	go PushViewRecordNewRedisData(userViewHistory, int(wxUserInfo.CompanyID))
 
+	//查询点赞数
+	likeNum,likeEnabled, _ := services.GetReportLikeByReportIdOldReportId(wxUserInfo.UserID, 0, 0, int(researchReportId),0)
+
 	result = ResearchReportInfo{
 		ResearchReportInfo:     reportInfo,
 		ResearchReportTypeList: researchReportTypeList,
 		HasMenu:                1,
+		LikeNum:                likeNum,
+		LikeEnabled:            likeEnabled,
 	}
 
 	if len(researchReportTypeList) <= 0 {
-
+		
 	} else if len(researchReportTypeList) == 1 {
 		//只有一个章节,即没有目录的时候,需要直接返回章节详情
 		result.HasMenu = 0
@@ -146,6 +154,8 @@ type ResearchReportTypeContentInfo struct {
 	ResearchReportTypeInfo        *research_report_type.ResearchReportTypeInfo `json:"research_report_type_info"`
 	Add                           int                                          `json:"add"`
 	ResearchReportTypeContentList []*research_report.ResearchReportTypeContent `description:"报告详情" json:"research_report_type_content_list"`
+	LikeNum                       int64                                        `description:"点赞总数" json:"like_num"`
+	LikeEnabled                   int8                                         `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
 }
 
 // GetResearchReportTypeContentInfo 获取报告章节详情
@@ -247,10 +257,14 @@ func GetResearchReportTypeContentInfo(researchReportTypeId, userId uint64) (resu
 	//添加阅读日志的数据加入到redis
 	go PushViewRecordNewRedisData(userViewHistory, int(wxUserInfo.CompanyID))
 
+	//查询点赞数
+	likeNum,likeEnabled, _ := services.GetReportLikeByReportIdOldReportId(wxUserInfo.UserID, 0, 0, int(researchReportTypeInfo.ResearchReportID), int(researchReportTypeInfo.ResearchReportTypeID))
 	result = ResearchReportTypeContentInfo{
 		ResearchReportTypeContentList: researchReportTypeContentList,
 		ResearchReportTypeInfo:        researchReportTypeInfo,
 		Add:                           add,
+		LikeNum:                       likeNum,
+		LikeEnabled:                   likeEnabled,
 	}
 	return
 }

+ 33 - 0
logic/user/user.go

@@ -10,6 +10,7 @@ import (
 	"hongze/hongze_yb/models/tables/rddp/msg_code"
 	"hongze/hongze_yb/models/tables/wx_user"
 	"hongze/hongze_yb/models/tables/yb_apply_record"
+	"hongze/hongze_yb/models/tables/yb_message"
 	"hongze/hongze_yb/services"
 	companyService "hongze/hongze_yb/services/company"
 	"hongze/hongze_yb/services/user"
@@ -109,6 +110,9 @@ type Detail struct {
 	PermissionList []CompanyPermission `json:"permission_list" description:"权限列表"`
 	IsInner		   int				   `json:"is_inner" description:"是否为内部员工"`
 	AdminInfo      *admin2.Admin	   `json:"admin_info" description:"系统管理员信息"`
+	UnRead         int64               `json:"un_read" description:"消息未读数"`
+	NickName       string              `json:"nick_name" description:"用户昵称"`
+	HeadImgUrl     string              `json:"headImgUrl" description:"用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空"`
 }
 
 // GetUserInfo 获取用户我的页面详情数据
@@ -205,6 +209,12 @@ func GetUserInfo(userInfo user.UserInfo) (userDetail Detail, err error, errMsg s
 		isInner = 1
 	}
 
+	// 查询消息未读数
+	unRead, err := yb_message.GetUnreadByUserId(userInfo.UserID)
+	if err != nil {
+		errMsg = "查询消息未读数失败"
+		return
+	}
 	userDetail = Detail{
 		CompanyName:    companyName, 		//客户名称(公司名称)
 		Status:         status,      		//产品状态
@@ -217,11 +227,34 @@ func GetUserInfo(userInfo user.UserInfo) (userDetail Detail, err error, errMsg s
 		PermissionList: list,				//权限列表
 		IsInner: 		isInner,			// 是否为内部员工
 		AdminInfo: 		adminInfo,			// 系统管理员信息
+		UnRead:         unRead,
+		NickName:       userInfo.NickName,
+		HeadImgUrl:     userInfo.Headimgurl,
 	}
 
 	return
 }
 
+// SetUserInfo 设置用户的个人信息,头像和昵称
+func SetUserInfo(userInfo user.UserInfo, req userReq.SetUserInfoReq) (err error) {
+	// todo 用户如果没有设置头像,用默认头像也允许上传
+	// 校验昵称长度
+	// 校验头像地址是否正确
+	if !strings.Contains(req.HeadImgUrl, "http://") && !strings.Contains(req.HeadImgUrl, "https://")  {
+		err = errors.New("上传头像出错")
+		return
+	}
+	wxUser := userInfo.WxUser
+	wxUser.NickName = req.NickName
+	wxUser.Headimgurl = req.HeadImgUrl
+	err = wxUser.Update([]string{"nick_name","headimgurl"})
+	if err != nil {
+		err = errors.New("更新用户信息操作失败")
+		return
+	}
+	return
+}
+
 type Record struct {
 	BusinessCardURL string `json:"business_card_url" description:"名片"`
 	RealName        string `json:"real_name" description:"姓名"`

+ 15 - 0
models/request/comment/comment.go

@@ -0,0 +1,15 @@
+package comment
+
+type ReqComment struct {
+	Content                string `description:"留言内容" json:"content"`
+	ReportId               int `description:"报告ID" json:"report_id" `
+	ReportChapterId        int `description:"报告章节ID" json:"report_chapter_id" `
+	IsShowName             int8 `description:"是否匿名 0-匿名,1-不匿名" json:"is_show_name"`
+	SourceAgent            int  `description:"留言入口来源,1:小程序,2:pc" json:"source_agent"`
+	OldReportId            int `description:"老后台报告ID (research_report_id)" json:"old_report_id" `
+	OldReportChapterId     int `description:"老后台报告章节ID(research_report_type_id)" json:"old_report_chapter_id" `
+}
+
+type ReqDel struct {
+	CommentId        uint64 `description:"留言ID" json:"comment_id"`
+}

+ 9 - 0
models/request/like/like.go

@@ -0,0 +1,9 @@
+package like
+
+type ReqLike struct {
+	ReportId               int `description:"报告ID" json:"report_id" `
+	ReportChapterId        int `description:"报告章节ID" json:"report_chapter_id" `
+	OldReportId            int `description:"老后台报告ID (research_report_id)" json:"old_report_id" `
+	OldReportChapterId     int `description:"老后台报告章节ID(research_report_type_id)" json:"old_report_chapter_id" `
+	SourceAgent            int `description:"点赞入口来源,1:小程序,2:小程序pc" json:"source_agent"`
+}

+ 9 - 0
models/request/message/message.go

@@ -0,0 +1,9 @@
+package message
+
+type ReqMessageBatch struct {
+	Type    int `description:"消息类型:1-留言回复通知,2-精选留言通知" json:"type"`
+}
+
+type ReqMessage struct {
+	MsgId   uint64 `description:"消息ID" json:"msg_id"`
+}

+ 5 - 0
models/request/user/user.go

@@ -17,3 +17,8 @@ type ApplyReq struct {
 	SourceAgent     int    `description:"申请入口来源,1:小程序,2:pc" json:"source_agent"`
 	FromPage        string `description:"申请来源页面" json:"from_page"`
 }
+
+type SetUserInfoReq struct {
+	NickName            string    `description:"用户昵称" json:"nick_name"`
+	HeadImgUrl          string    `description:"用户头像,最后一个数值代表正方形头像大小(有0、46、64、96、132数值可选,0代表640*640正方形头像),用户没有头像时该项为空" json:"head_img_url"`
+}

+ 34 - 0
models/response/comment.go

@@ -0,0 +1,34 @@
+package response
+
+import "time"
+
+type RespCommentList struct {
+	List       []*RespCommentItem   `json:"list"`
+	Paging     *PagingItem  		`json:"paging"`
+}
+type RespCommentItem struct {
+	CommentId         uint64 `description:"留言ID" json:"comment_id"`
+	UserId            uint64 `description:"用户id" json:"user_id"`
+	Content           string `description:"留言内容" json:"content"`
+	IsTop             int8 `description:"是否置顶(0-未置顶,1-置顶)json:"is_top""`
+	IsHot             int8 `description:"是否设置精选(0-未设置,1-已设置)json:"is_hot""`
+	HotTopTime        time.Time `description:"设置精选或者设置置顶的时间" json:"hot_top_time"`
+	UserName          string `description:"用户昵称" json:"user_name"`
+	UserImgUrl           string `description:"用户头像" json:"user_img_url"`
+	CreateTime        time.Time `description:"留言创建时间" json:"create_time"`
+	ReplyList        []*ReplyItem
+}
+
+type ReplyItem struct {
+	CommentId         uint64 `description:"留言ID" json:"comment_id"`
+	AdminId           uint64 `description:"发布留言回复的管理员ID" json:"admin_id"`
+	AdminName         string `description:"系统昵称" json:"admin_name"`
+	AdminImgUrl          string `description:"系统头像" json:"admin_img_url"`
+	Content           string `description:"回复内容" json:"content"`
+	ReplyCommentId    uint64 `description:"回复的留言ID" json:"reply_comment_id"`
+	CreateTime        time.Time `description:"留言创建时间" json:"create_time"`
+}
+
+type RespCommentAdd struct {
+	CommentId    uint64 `description:"留言ID" json:"comment_id"`
+}

+ 6 - 0
models/response/like.go

@@ -0,0 +1,6 @@
+package response
+
+type RespLike struct {
+	LikeNum  int64  `description:"点赞总数" json:"like_num"`
+	LikeEnabled  int8 `description:"本次点赞结果: 0-已取消赞 1-有效赞" json:"like_enabled"`
+}

+ 21 - 0
models/response/message.go

@@ -0,0 +1,21 @@
+package response
+
+import "time"
+
+type RespMessageItem struct {
+	MsgId               uint64 `description:"消息ID" json:"msg_id"`
+	UserId              uint64 `description:"用户ID" json:"user_id"`
+	Type                int8   `description:"消息类型:1-留言回复通知,2-精选留言通知" json:"type"`
+	CreateTime          time.Time `description:"创建时间" json:"create_time"`
+	ContentFirst        string `description:"消息第一行留言内容" json:"content_first"`
+	ContentSecond       string `description:"消息第二行内容" json:"content_second"`
+	IsRead              int8   `description:"是否已读 0-未读,1-已读" json:"is_read"`
+	ReportId            int `description:"报告ID"  json:"report_id" `
+	ReportChapterId     int `description:"报告章节ID" json:"report_chapter_id" `
+	Img                 string `description:"左边头像" json:"img"`
+}
+
+type RespMessageList struct {
+	List []*RespMessageItem         `json:"list"`
+	Paging     *PagingItem  		`json:"paging"`
+}

+ 12 - 8
models/response/report.go

@@ -5,10 +5,12 @@ import (
 )
 
 type ReportDetail struct {
-	ReportInfo        *ReportItem              `json:"report_info"`
-	ReportChapterList []*ReportChapterListItem `json:"report_chapter_list"`
-	PermissionCheck   *PermissionCheckInfo     `json:"permission_check"`
-	AuthOk            bool                     `json:"auth_ok"`
+	ReportInfo          *ReportItem              `json:"report_info"`
+	ReportChapterList   []*ReportChapterListItem `json:"report_chapter_list"`
+	PermissionCheck     *PermissionCheckInfo     `json:"permission_check"`
+	AuthOk              bool                     `json:"auth_ok"`
+	LikeNum             int64  `description:"点赞总数" json:"like_num"`
+	LikeEnabled         int8 `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
 }
 
 type ReportChapterListItem struct {
@@ -68,10 +70,12 @@ type ReportChapterItem struct {
 }
 
 type ReportChapterDetail struct {
-	ReportChapterItem     *ReportChapterItem   `json:"report_chapter_item"`
-	PermissionCheck       *PermissionCheckInfo `json:"permission_check"`
-	ReportChapterMenuList []*ReportChapterMenu `json:"report_chapter_menu_list"`
-	AuthOk                bool                 `json:"auth_ok"`
+	ReportChapterItem      *ReportChapterItem      `json:"report_chapter_item"`
+	PermissionCheck        *PermissionCheckInfo    `json:"permission_check"`
+	ReportChapterMenuList  []*ReportChapterMenu    `json:"report_chapter_menu_list"`
+	AuthOk                 bool                    `json:"auth_ok"`
+	LikeNum                int64  `description:"点赞总数" json:"like_num"`
+	LikeEnabled            int8 `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
 }
 
 type ReportChapterMenu struct {

+ 9 - 0
models/tables/rddp/report/query.go

@@ -365,4 +365,13 @@ WHERE
 	`
 	err = global.MYSQL["rddp"].Raw(sql).First(&list).Error
 	return
+}
+// GetReportByOldReportId 根据老后台的research_report_id查找新的报告ID
+func GetReportByOldReportId(oldReportId uint64)(item *Report, err error)  {
+	err = global.MYSQL["rddp"].Model(Report{}).
+		Where("old_report_id=?", oldReportId).First(&item).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
 }

+ 12 - 1
models/tables/rddp/report_chapter/query.go

@@ -83,7 +83,7 @@ func GetReportIdsByTypeIdsAndClass(typeIds []int, classifyNameFirst string) (rep
 
 // GetTypeIdById 根据ID获取章节类型
 func GetTypeIdById(id int) (info *ReportChapter, err error)  {
-	err = global.MYSQL["rddp"].Model(ReportChapter{}).Select("report_chapter_id, type_id").
+	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
 	if err == utils.ErrNoRow {
@@ -137,4 +137,15 @@ ORDER BY
 	sql = fmt.Sprintf(sql, reportId, firstName)
 	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
 }

+ 6 - 0
models/tables/wx_user/query.go

@@ -34,3 +34,9 @@ func GetByUserId(userId int) (wxUser *WxUser, err error) {
 	err = global.DEFAULT_MYSQL.Where("user_id =  ? ", userId).First(&wxUser).Error
 	return
 }
+
+// GetByUserIds 根据user_id获取用户信息
+func GetByUserIds(userIds []uint64) (list []*WxUser, err error) {
+	err = global.DEFAULT_MYSQL.Model(WxUser{}).Where("user_id in  ? ", userIds).Scan(&list).Error
+	return
+}

+ 8 - 0
models/tables/yb_comment/create.go

@@ -0,0 +1,8 @@
+package yb_comment
+
+import "hongze/hongze_yb/global"
+
+func (yc *YbComment) Create() (err error) {
+	err = global.DEFAULT_MYSQL.Create(yc).Error
+	return
+}

+ 89 - 0
models/tables/yb_comment/query.go

@@ -0,0 +1,89 @@
+package yb_comment
+
+import (
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+)
+
+
+// GetListByUserIdReportId 获取用户的留言列表
+func GetListByUserIdReportId(userId uint64, reportId, reportChapterId int) (list []*YbComment, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("user_id = ? and report_id = ? and report_chapter_id = ? and enabled = 1 ", userId, reportId, reportChapterId).
+		Order("create_time desc, comment_id desc").
+		Scan(&list).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}
+
+// GetListByUserIdOldReportId 获取用户的留言列表
+func GetListByUserIdOldReportId(userId uint64, oldReportId, oldReportChapterId int) (list []*YbComment, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("user_id = ? and old_report_id = ? and old_report_chapter_id = ? and enabled = 1 ", userId, oldReportId, oldReportChapterId).
+		Order("create_time desc, comment_id desc").
+		Scan(&list).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}
+
+// GetHotListByReportId 获取报告的精选留言列表
+func GetHotListByReportId(reportId, reportChapterId int, offset, limit int) (list []*YbComment, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("report_id = ? and report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId, reportChapterId).
+		Order("is_top desc, hot_top_time desc, comment_id desc").
+		Offset(offset).
+		Limit(limit).
+		Scan(&list).Error
+	return
+}
+
+// GetHotListTotalByReportId 获取精选留言总条数
+func GetHotListTotalByReportId(reportId, reportChapterId int)(total int64, err error)  {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("report_id = ? and report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", reportId, reportChapterId).
+		Count(&total).Error
+	return
+}
+
+// GetHotListByOldReportId 获取老报告的精选留言列表
+func GetHotListByOldReportId(oldReportId, oldReportChapterId int, offset, limit int) (list []*YbComment, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("old_report_id = ? and old_report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", oldReportId, oldReportChapterId).
+		Order("is_top desc, hot_top_time desc, comment_id desc").
+		Offset(offset).
+		Limit(limit).
+		Scan(&list).Error
+	return
+}
+
+// GetHotListTotalByOldReportId 获取老报告的精选留言总条数
+func GetHotListTotalByOldReportId(oldReportId, oldReportChapterId int)(total int64, err error)  {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("old_report_id = ? and old_report_chapter_id = ? and enabled = 1 and is_hot = 1 and type = 1", oldReportId, oldReportChapterId).
+		Count(&total).Error
+	return
+}
+
+// GetReplyListByReplyCommentId 获取报告的精选留言的回复列表
+func GetReplyListByReplyCommentId(reportId, reportChapterId int, replyCommentIds []uint64) (list []*YbComment, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Where("report_id = ? and report_chapter_id = ? and enabled = 1 and type = 2 and reply_comment_id in ?", reportId, reportChapterId, replyCommentIds).
+		Order("create_time desc, comment_id desc").
+		Scan(&list).Error
+	return
+}
+
+// GetSimpleByCommentId 根据评论ID,查询评论
+func GetSimpleByCommentId(commentId uint64)(item *YbComment, err error)  {
+	err = global.DEFAULT_MYSQL.Model(YbComment{}).
+		Select("comment_id, user_id, type, enabled").
+		Where("comment_id = ?", commentId).First(&item).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}

+ 43 - 0
models/tables/yb_comment/update.go

@@ -0,0 +1,43 @@
+package yb_comment
+
+import "hongze/hongze_yb/global"
+
+// Update 更新对应字段数据
+func (yc *YbComment) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(yc).Select(updateCols).Updates(*yc).Error
+	return
+}
+
+// Delete 软删除,隐藏评论
+func Delete(userId uint64, commentId uint64)(err error) {
+	tx := global.DEFAULT_MYSQL.Begin()
+	defer func() {
+		if err != nil {
+			tx.Rollback()
+		} else {
+			tx.Commit()
+		}
+	}()
+	sql1 := ` UPDATE yb_comment
+			SET
+            	enabled = 0,
+				modify_time = NOW(),
+				type = 1,
+				user_id = ?
+			WHERE comment_id = ?`
+	err = tx.Exec(sql1, userId, commentId).Error
+	if err != nil {
+		return
+	}
+	// 删除相关联的回复
+	sql2 := ` UPDATE yb_comment
+			SET
+            	enabled = 0,
+				type = 2,
+				modify_time = NOW()
+			WHERE reply_comment_id = ?`
+	err = tx.Exec(sql2, commentId).Error
+	return
+}
+
+

+ 32 - 0
models/tables/yb_comment/yb_comment.go

@@ -0,0 +1,32 @@
+package yb_comment
+
+import "time"
+
+// 研报 用户留言表
+type YbComment struct {
+	CommentId                 uint64 `gorm:"primaryKey;column:comment_id;type:bigint(20) unsigned;not null" ` //留言ID
+	UserId                    uint64 `gorm:"column:user_id"` //用户id
+	AdminId                   uint64 `gorm:"column:admin_id"` //发布留言回复的管理员ID
+	ReportId                  int `gorm:"column:report_id"` //报告ID
+	ReportChapterId           int `gorm:"column:report_chapter_id"` //报告章节ID
+	Content                   string `gorm:"column:content"` //留言内容
+	SysIsRead                 int8 `gorm:"column:sys_is_read"` //管理员是否已读 0-未读,1-已读
+	SysReadTime               time.Time `gorm:"column:sys_read_time"` //管理员已读时间
+	SysReadAdminId            int64 `gorm:"column:sys_read_admin_id"` //已读的管理员id
+	ReplyCommentId            uint64 `gorm:"column:reply_comment_id"` //回复的留言ID
+	IsTop                     int8 `gorm:"column:is_top"` //是否置顶(0-未置顶,1-置顶)
+	IsHot                     int8 `gorm:"column:is_hot"` //是否设置精选(0-未设置,1-已设置)
+	HotTopTime                time.Time `gorm:"column:hot_top_time"` //设置精选或者设置置顶的时间
+	Type                      int8 `gorm:"column:type"` //留言类型 1-评论 2-回复
+	Enabled                   int8 `gorm:"column:enabled"` //是否有效, 0-无效留言 1-有效留言
+	IsShowName                int8 `gorm:"column:is_show_name"` //是否匿名 0-匿名,1-不匿名
+	SourceAgent               int `gorm:"column:source_agent"` //留言入口来源,1:小程序,2:pc
+	CreateTime                time.Time `gorm:"column:create_time"` //创建时间
+	ModifyTime                time.Time `gorm:"column:modify_time"` //修改时间
+	OldReportId               int `gorm:"column:old_report_id"  json:"old_report_id" ` //老报告ID
+	OldReportChapterId        int `gorm:"column:old_report_chapter_id" json:"old_report_chapter_id" ` //老报告章节ID
+}
+
+func (yc *YbComment) TableName() string {
+	return "yb_comment"
+}

+ 8 - 0
models/tables/yb_like/create.go

@@ -0,0 +1,8 @@
+package yb_like
+
+import "hongze/hongze_yb/global"
+
+func (yl *YbLike) Create() (err error) {
+	err = global.DEFAULT_MYSQL.Create(yl).Error
+	return
+}

+ 45 - 0
models/tables/yb_like/query.go

@@ -0,0 +1,45 @@
+package yb_like
+
+import (
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+)
+
+
+// GetLikeByUserIdAndReportId 获取点赞记录
+func GetLikeByUserIdAndReportId(userId uint64, reportId, reportChapterId int) (item *YbLike, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbLike{}).
+		Where("user_id = ? and report_id = ? and report_chapter_id = ?", userId, reportId, reportChapterId).
+		First(&item).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}
+
+// GetLikeByUserIdAndOldReportId 获取点赞记录
+func GetLikeByUserIdAndOldReportId(userId uint64, oldReportId, oldReportChapterId int) (item *YbLike, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbLike{}).
+		Where("user_id = ? and old_report_id = ? and old_report_chapter_id = ?", userId, oldReportId, oldReportChapterId).
+		First(&item).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}
+
+// GetLikeNumByReportId 统计报告的点赞数
+func GetLikeNumByReportId(reportId, reportChapterId int) (num int64, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbLike{}).
+		Where("report_id = ? and report_chapter_id = ? and enabled=1", reportId, reportChapterId).
+		Count(&num).Error
+	return
+}
+
+// GetLikeNumByOldReportId 统计报告的点赞数
+func GetLikeNumByOldReportId(oldReportId, oldReportChapterId int) (num int64, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbLike{}).
+		Where("old_report_id = ? and old_report_chapter_id = ? and enabled=1", oldReportId, oldReportChapterId).
+		Count(&num).Error
+	return
+}

+ 9 - 0
models/tables/yb_like/update.go

@@ -0,0 +1,9 @@
+package yb_like
+
+import "hongze/hongze_yb/global"
+
+// Update 更新对应字段数据
+func (yl *YbLike) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(yl).Select(updateCols).Updates(*yl).Error
+	return
+}

+ 21 - 0
models/tables/yb_like/yb_like.go

@@ -0,0 +1,21 @@
+package yb_like
+
+import "time"
+
+// YbLike 研报 点赞
+type YbLike struct {
+	LikeId                 uint64 `gorm:"primaryKey;column:like_id;type:bigint(20) unsigned;not null" json:"like_id" ` //消息序号
+	UserId                 uint64 `gorm:"column:user_id"  json:"user_id" ` //用户id
+	Enabled                int8 `gorm:"column:enabled"  json:"enabled" ` //状态. 0-已取消赞 1-有效赞
+	CreateTime             time.Time `gorm:"column:create_time"  json:"create_time" ` //创建时间
+	ModifyTime             time.Time `gorm:"column:modify_time"  json:"modify_time" ` //修改时间
+	ReportId               int `gorm:"column:report_id"  json:"report_id" ` //报告ID
+	ReportChapterId        int `gorm:"column:report_chapter_id" json:"report_chapter_id" ` //报告章节ID
+	SourceAgent            int `gorm:"column:source_agent"` //留言入口来源,1:小程序,2:pc
+	OldReportId               int `gorm:"column:old_report_id"  json:"old_report_id" ` //老报告ID
+	OldReportChapterId        int `gorm:"column:old_report_chapter_id" json:"old_report_chapter_id" ` //老报告章节ID
+}
+
+func (yl *YbLike) TableName() string {
+	return "yb_like"
+}

+ 55 - 0
models/tables/yb_message/query.go

@@ -0,0 +1,55 @@
+package yb_message
+
+import (
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+)
+
+// GetUnreadByUserId 获取用户的未读数
+func GetUnreadByUserId(UserId uint64) (total int64, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbMessage{}).
+		Where("user_id = ? and enabled = 1 and is_read=0", UserId).
+		Count(&total).Error
+	return
+}
+
+// GetListByType 根据消息类型查询用户消息列表
+func GetListByType(userId uint64, msgType int, offset, limit int) (list []*YbMessage, err error) {
+	var pars []interface{}
+	pars = append(pars, userId)
+	sql := ` SELECT * FROM yb_message 
+WHERE user_id = ? and enabled = 1 `
+	if msgType > 0 {
+		sql += " and type= ?"
+		pars = append(pars, msgType)
+	}
+	sql += " GROUP BY create_time desc, msg_id desc LIMIT ?,? "
+	pars = append(pars, offset, limit)
+	err = global.DEFAULT_MYSQL.Raw(sql, pars...).Scan(&list).Error
+	return
+}
+
+// GetListTotalByType 根据消息类型查询用户消息列表总数
+func GetListTotalByType(userId uint64, msgType int) (total int64, err error) {
+	var pars []interface{}
+	pars = append(pars, userId)
+	sql := ` SELECT count(*) FROM yb_message 
+WHERE user_id = ? and enabled = 1 `
+	if msgType > 0 {
+		sql += " and type= ?"
+		pars = append(pars, msgType)
+	}
+	err = global.DEFAULT_MYSQL.Raw(sql, pars...).Count(&total).Error
+	return
+}
+
+// GetMsgByMsgId 根据消息ID查询消息详情
+func GetMsgByMsgId(userId, msgId uint64) (item *YbMessage, err error) {
+	err = global.DEFAULT_MYSQL.Model(YbMessage{}).
+		Where("user_id = ? and msg_id = ?", userId, msgId).
+		First(&item).Error
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	return
+}

+ 25 - 0
models/tables/yb_message/update.go

@@ -0,0 +1,25 @@
+package yb_message
+
+import (
+	"hongze/hongze_yb/global"
+)
+
+// Update 更新对应字段数据
+func (ym *YbMessage) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(ym).Select(updateCols).Updates(*ym).Error
+	return
+}
+
+// SetBatchRead 批量设置已读
+func SetBatchRead(userId uint64, msgType int)(err error) {
+	var pars []interface{}
+	pars = append(pars, userId)
+	sql := ` UPDATE yb_message set is_read = 0, modify_time=NOW()
+WHERE user_id = ? and is_read = 1 `
+	if msgType > 0 {
+		sql += " and type= ?"
+		pars = append(pars, msgType)
+	}
+	err = global.DEFAULT_MYSQL.Exec(sql, pars...).Error
+	return
+}

+ 23 - 0
models/tables/yb_message/yb_message.go

@@ -0,0 +1,23 @@
+package yb_message
+
+import "time"
+
+// 研报 消息表
+type YbMessage struct {
+	MsgId               uint64 `gorm:"primaryKey;column:msg_id"` //消息序号
+	UserId              uint64 `gorm:"column:user_id"` //用户id
+	Type                int8 `gorm:"column:type"` //消息类型:1-留言回复通知,2-精选留言通知
+	Enabled             int8 `gorm:"column:enabled"` //是否有效, 0-无效 1-有效
+	CreateTime          time.Time `gorm:"column:create_time"` //创建时间
+	ModifyTime          time.Time `gorm:"column:modify_time"` //修改时间
+	CommentId           uint64 `gorm:"column:comment_id"` //留言ID
+	IsRead              int8 `gorm:"column:is_read"` //是否已读 0-未读,1-已读
+	ContentFirst        string `gorm:"column:content_first"` //消息第一行留言内容
+	ContentSecond       string `gorm:"column:content_second"` //消息第二行内容
+	ReportId            int `gorm:"column:report_id"` //报告ID
+	ReportChapterId     int `gorm:"column:report_chapter_id"` //报告章节ID
+}
+
+func (ym *YbMessage) TableName() string {
+	return "yb_message"
+}

+ 15 - 0
routers/comment.go

@@ -0,0 +1,15 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/comment"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitComment(r *gin.Engine)  {
+	rGroup := r.Group("/api/comment").Use(middleware.Token())
+	rGroup.POST("/set", comment.Comment)
+	rGroup.POST("/del", comment.Delete)
+	rGroup.GET("/hot", comment.HotList)
+	rGroup.GET("/my", comment.MyList)
+}

+ 12 - 0
routers/like.go

@@ -0,0 +1,12 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/like"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitLike(r *gin.Engine)  {
+	rGroup := r.Group("api/like").Use(middleware.Token())
+	rGroup.POST("/set", like.SetLike)      //点赞设置
+}

+ 15 - 0
routers/message.go

@@ -0,0 +1,15 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/message"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitMessage(r *gin.Engine)  {
+	rGroup := r.Group("/api/message").Use(middleware.Token())
+	rGroup.GET("/list", message.List)
+	rGroup.POST("/batch/read", message.BatchRead)
+	rGroup.POST("/read", message.SingleRead)
+	rGroup.POST("/delete", message.SingleDelete)
+}

+ 1 - 0
routers/user.go

@@ -41,6 +41,7 @@ func initUser(r *gin.Engine) {
 		rGroup2.GET("/get_last_apply_record", user.GetLastApplyRecord)
 		rGroup2.POST("/apply", user.Apply)
 		rGroup2.GET("/get_tab_bar", user.GetTabBar)
+		rGroup2.POST("/set", user.SetUserInfo)
 	}
 
 }

+ 292 - 0
services/comment/comment.go

@@ -0,0 +1,292 @@
+package comment
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_yb/global"
+	reqComment "hongze/hongze_yb/models/request/comment"
+	"hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/models/tables/wx_user"
+	"hongze/hongze_yb/models/tables/yb_comment"
+	"hongze/hongze_yb/services"
+	"hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/services/wx_app"
+	"hongze/hongze_yb/utils"
+	"time"
+)
+
+// Comment 发布留言
+func Comment(user user.UserInfo, req reqComment.ReqComment) (ret response.RespCommentAdd, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+	//校验请求入参
+	if req.IsShowName != 0 && req.IsShowName != 1 {
+		err = errors.New("匿名设置出错")
+		return
+	}
+	if req.Content == "" {
+		err = errors.New("请输入留言内容")
+		return
+	}
+	reportId := req.ReportId
+	reportChapterId := req.ReportChapterId
+
+	if req.SourceAgent == 0 {
+		err = errors.New("请输入留言来源")
+		return
+	}
+	if req.ReportChapterId <=0 && req.ReportId <=0 && req.OldReportId <=0 && req.OldReportChapterId <=0{
+		err = errors.New("请输入报告ID")
+		return
+	}
+	// todo 判断是否有留言权限
+	err, errMsg = services.CheckSimpleCompanyProduct(user)
+	if err != nil {
+		return
+	}
+	//处理老报告, 转化成新报告ID
+	if req.ReportChapterId <=0 && req.ReportId <=0 && (req.OldReportId >0 || req.OldReportChapterId > 0) {
+		reportId, reportChapterId, err, errMsg = services.GetReportIdReportChapterIdByOldReportId(uint64(req.OldReportId), uint64(req.OldReportChapterId))
+		if err != nil {
+			return
+		}
+	} else {
+		// 判断报告ID是否正确
+		err, errMsg = services.CheckReportExistByReportIdReportChapterId(reportId, reportChapterId)
+		if err != nil {
+			return
+		}
+	}
+	// 敏感词过滤
+	checkResult, err := wx_app.MsgSecCheck(user.OpenID, req.Content)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("敏感词过滤失败")
+		return
+	}
+	if checkResult.Result.Suggest == "risky" {
+		err = errors.New(checkResult.Result.Suggest)
+		return
+	}
+	//新增留言
+	now := time.Now()
+	commentInfo := &yb_comment.YbComment{
+		UserId: user.UserID,
+		Content: req.Content,
+		ReportId: reportId,
+		ReportChapterId: reportChapterId,
+		IsShowName: req.IsShowName,
+		SourceAgent: req.SourceAgent,
+		Type: 1,
+		Enabled: 1,
+		CreateTime: now,
+		ModifyTime: now,
+		OldReportId:    req.OldReportId,
+		OldReportChapterId: req.OldReportChapterId,
+	}
+	err = commentInfo.Create()
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("新增留言出错")
+		return
+	}
+	ret.CommentId = commentInfo.CommentId
+	return
+}
+
+// Delete 删除留言
+func Delete(user user.UserInfo, req *reqComment.ReqDel) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+	if req.CommentId <= 0 {
+		err = errors.New("请输入留言ID")
+		return
+	}
+	//校验请求入参
+	commentInfo, err := yb_comment.GetSimpleByCommentId(req.CommentId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询留言出错")
+		return
+	}
+	if commentInfo.CommentId <= 0 {
+		err = errors.New("留言不存在")
+		return
+	}
+	if commentInfo.UserId != user.UserID {
+		err = errors.New("不允许删除他人的留言")
+		return
+	}
+	if commentInfo.Type != 1 {
+		err = errors.New("不允许删除回复")
+		return
+	}
+	if commentInfo.Enabled == 0 {
+		return
+	}
+	err = yb_comment.Delete(user.UserID, commentInfo.CommentId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("删除留言出错")
+		return
+	}
+	return
+}
+
+// List 查询精选留言列表或我的留言列表
+func List(user user.UserInfo,  reportId, reportChapterId, oldReportId, oldReportChapterId int, hotFlag bool, pageIndex, pageSize int) (ret response.RespCommentList, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+
+	if reportId <=0 && reportChapterId <=0 && oldReportId <=0 && oldReportChapterId <=0{
+		err = errors.New("请输入报告ID")
+		return
+	}
+
+	//处理老报告, 转化成新报告ID
+	if  reportId <=0 && reportChapterId <=0 && (oldReportId >0 || oldReportChapterId > 0) {
+		reportId, reportChapterId, err, errMsg = services.GetReportIdReportChapterIdByOldReportId(uint64(oldReportId), uint64(oldReportChapterId))
+		if err != nil {
+			return
+		}
+	}
+	offset := (pageIndex -1)*pageSize
+	var commentList []*yb_comment.YbComment
+	var total int64
+	//查询精选留言
+	if hotFlag {
+		if reportId > 0 {
+			commentList, err = yb_comment.GetHotListByReportId(reportId, reportChapterId, offset, pageSize)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言列表出错")
+				return
+			}
+			total, err = yb_comment.GetHotListTotalByReportId(reportId, reportChapterId)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言总数出错")
+				return
+			}
+		}else {
+			commentList, err = yb_comment.GetHotListByOldReportId(oldReportId, oldReportChapterId, offset, pageSize)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言列表出错")
+				return
+			}
+			total, err = yb_comment.GetHotListTotalByOldReportId(oldReportId, oldReportChapterId,)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言总数出错")
+				return
+			}
+		}
+	} else {
+		//查询个人留言
+		if reportId > 0{
+			commentList, err = yb_comment.GetListByUserIdReportId(user.UserID, reportId, reportChapterId)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言列表出错")
+				return
+			}
+		}else {
+			commentList, err = yb_comment.GetListByUserIdOldReportId(user.UserID, oldReportId, oldReportChapterId)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("查询精选留言列表出错")
+				return
+			}
+		}
+
+	}
+
+	var commentIds []uint64
+	var userIds []uint64
+	for _, v := range commentList {
+		commentIds = append(commentIds, v.CommentId)
+		userIds = append(userIds, v.UserId)
+	}
+	// 查询所有的回复列表
+	replyListMap := make(map[uint64][]*response.ReplyItem)
+	if len(commentIds) > 0 {
+		replyList, tErr := yb_comment.GetReplyListByReplyCommentId(reportId, reportChapterId, commentIds)
+		if tErr != nil {
+			errMsg = tErr.Error()
+			err = errors.New("查询回复出错")
+			return
+		}
+		for _, v := range replyList {
+			t := new(response.ReplyItem)
+			t.CommentId = v.CommentId
+			t.Content = v.Content
+			t.AdminId = v.AdminId
+			t.CreateTime = v.CreateTime
+			t.AdminName = "弘则研究"
+			t.AdminImgUrl = utils.DEFAULT_HONGZE_SYS_LOGO
+			replyListMap[v.ReplyCommentId] = append(replyListMap[v.ReplyCommentId], t)
+		}
+	}
+
+	// 查询精选留言相关的用户
+	var userOthers []*wx_user.WxUser
+	if len(userIds) > 0 {
+		userOthers, err = wx_user.GetByUserIds(userIds)
+		if err != nil {
+			errMsg = err.Error()
+			err = errors.New("查询精选留言用户出错")
+			return
+		}
+	}
+	usersMap := make(map[uint64]*wx_user.WxUser)
+	for _, v := range userOthers {
+		usersMap[v.UserID] = v
+	}
+	var list []*response.RespCommentItem
+	for _, v := range commentList {
+		tmp := new(response.RespCommentItem)
+		tmp.CommentId = v.CommentId
+		tmp.UserId = v.UserId
+		tmp.UserName = "匿名用户"
+		tmp.UserImgUrl = utils.DEFAULT_HONGZE_USER_LOGO
+		if info, ok := usersMap[v.UserId]; ok {
+			if v.IsShowName == 1 {   //是否匿名 0-匿名,1-不匿名
+				tmp.UserName = info.NickName
+				tmp.UserImgUrl = info.Headimgurl
+			}else{
+				if info.Mobile != "" {
+					tmp.UserName += info.Mobile[7:]
+				}else if info.OpenID != "" {
+					tmp.UserName += info.OpenID[3:8]
+				}
+			}
+		}
+		tmp.Content = v.Content
+		tmp.IsHot = v.IsHot
+		tmp.IsTop = v.IsTop
+		tmp.HotTopTime = v.HotTopTime
+		tmp.CreateTime = v.CreateTime
+		if existList, ok := replyListMap[v.CommentId]; ok {
+			tmp.ReplyList = existList
+		}
+		list = append(list, tmp)
+	}
+	ret.List = list
+	if hotFlag {
+		ret.Paging = response.GetPaging(pageIndex, pageSize, int(total))
+	}
+	return
+}

+ 126 - 0
services/like/like.go

@@ -0,0 +1,126 @@
+package like
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/models/request/like"
+	"hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/models/tables/yb_like"
+	"hongze/hongze_yb/services"
+	"hongze/hongze_yb/services/user"
+	"time"
+)
+
+// 设置点赞
+func SetLike(user user.UserInfo, req like.ReqLike) (resp response.RespLike, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+	reportId := req.ReportId
+	reportChapterId := req.ReportChapterId
+
+	if req.SourceAgent == 0 {
+		err = errors.New("请输入点赞来源")
+		return
+	}
+	if req.ReportChapterId <=0 && req.ReportId <=0 && req.OldReportId <=0 && req.OldReportChapterId <=0{
+		err = errors.New("请输入报告ID")
+		return
+	}
+	// todo 判断是否有点赞权限
+	err, errMsg = services.CheckSimpleCompanyProduct(user)
+	if err != nil {
+		return
+	}
+	//处理老报告, 转化成新报告ID
+	if req.ReportChapterId <=0 && req.ReportId <=0 && (req.OldReportId >0 || req.OldReportChapterId > 0) {
+		reportId, reportChapterId, err, errMsg = services.GetReportIdReportChapterIdByOldReportId(uint64(req.OldReportId), uint64(req.OldReportChapterId))
+		if err != nil {
+			return
+		}
+	} else {
+		// 判断报告ID是否正确
+		err, errMsg = services.CheckReportExistByReportIdReportChapterId(reportId, reportChapterId)
+		if err != nil {
+			return
+		}
+	}
+
+	//查询用户对研报的点赞状态
+	var likeItem *yb_like.YbLike
+	if reportId > 0 {
+		likeItem, err = yb_like.GetLikeByUserIdAndReportId(user.UserID, reportId, reportChapterId)
+	} else {
+		likeItem, err = yb_like.GetLikeByUserIdAndOldReportId(user.UserID, req.OldReportId, req.OldReportChapterId)
+	}
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询用户点赞记录出错")
+		return
+	}
+	//如果未点赞则新增点赞记录
+	now :=  time.Now()
+	if likeItem.LikeId <= 0 {
+		likeItem = &yb_like.YbLike{
+			ReportId:          reportId,
+			ReportChapterId:   reportChapterId,
+			UserId:            user.UserID,
+			Enabled:         1,
+			CreateTime:     now,
+			ModifyTime:     now,
+			SourceAgent:    req.SourceAgent,
+			OldReportId:    req.OldReportId,
+			OldReportChapterId: req.OldReportChapterId,
+		}
+		err = likeItem.Create()
+		if err != nil {
+			errMsg = err.Error()
+			err = errors.New("新增点赞记录出错")
+			return
+		}
+	} else {
+		//如果已点赞则更新成取消点赞
+		if likeItem.Enabled == 1 {
+			updates := []string{"enabled", "modify_time"}
+			likeItem.Enabled = 0
+			likeItem.ModifyTime = now
+			err = likeItem.Update(updates)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("更新点赞记录出错")
+				return
+			}
+		} else {
+			//如果取消点赞则更新成已点赞
+			updates := []string{"enabled", "modify_time"}
+			likeItem.Enabled = 1
+			likeItem.ModifyTime = now
+			err = likeItem.Update(updates)
+			if err != nil {
+				errMsg = err.Error()
+				err = errors.New("更新点赞记录出错")
+				return
+			}
+		}
+	}
+	//查询总的点赞数
+	var likeNum int64
+	if reportId > 0 {
+		likeNum, err = yb_like.GetLikeNumByReportId(reportId, reportChapterId)
+	}else{
+		likeNum, err = yb_like.GetLikeNumByOldReportId(req.OldReportId, req.OldReportChapterId)
+	}
+
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询点赞数出错")
+		return
+	}
+	resp.LikeEnabled = likeItem.Enabled
+	resp.LikeNum = likeNum
+	return
+}

+ 148 - 0
services/message/message.go

@@ -0,0 +1,148 @@
+package message
+
+import (
+	"errors"
+	"fmt"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/models/request/message"
+	"hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/models/tables/yb_message"
+	"hongze/hongze_yb/services/user"
+	"time"
+)
+
+// GetList 查询消息列表
+func GetList(user user.UserInfo, msgType, pageIndex, pageSize int) (ret response.RespMessageList, err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+
+	//校验入参
+	//查询消息列表
+	offset := (pageIndex - 1) * pageSize
+	msgList, err := yb_message.GetListByType(user.UserID, msgType, offset, pageSize)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询消息列表出错")
+		return
+	}
+
+	total, err := yb_message.GetListTotalByType(user.UserID, msgType)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询消息列表总数出错")
+		return
+	}
+
+	//处理列表返回值
+	var list []*response.RespMessageItem
+	for _, v := range msgList {
+		tmp := new(response.RespMessageItem)
+		tmp.MsgId = v.MsgId
+		tmp.IsRead = v.IsRead
+		tmp.UserId = v.UserId
+		tmp.Type = v.Type
+		tmp.CreateTime = v.CreateTime
+		tmp.ReportChapterId = v.ReportChapterId
+		tmp.ReportId = v.ReportId
+		tmp.ContentFirst = v.ContentFirst
+		tmp.ContentSecond = v.ContentSecond
+		tmp.Img = ""
+		list = append(list, tmp)
+	}
+	
+	ret.List = list
+	ret.Paging = response.GetPaging(pageIndex, pageSize, int(total))
+	return
+}
+
+// BatchRead 一键已读
+func BatchRead(user user.UserInfo, req message.ReqMessageBatch) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+
+	//根据类型设置一键已读
+    err = yb_message.SetBatchRead(user.UserID, req.Type)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("一键已读设置失败")
+		return
+	}
+	return
+}
+
+// SingleRead 单条消息设置已读
+func SingleRead(user user.UserInfo, req message.ReqMessage) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+	//查询当前消息
+	msgInfo, err := yb_message.GetMsgByMsgId(user.UserID, req.MsgId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询消息出错")
+		return
+	}
+	if msgInfo.MsgId <= 0 {
+		err = errors.New("消息不存在")
+		return
+	}
+	if msgInfo.IsRead == 0 {
+		return
+	}
+	msgInfo.IsRead = 0
+	msgInfo.ModifyTime = time.Now()
+	//根据类型设置一键已读
+	err = msgInfo.Update([]string{"is_read","modify_time"})
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("已读设置失败")
+		return
+	}
+	return
+}
+
+
+// SingleDelete 单条消息删除
+func SingleDelete(user user.UserInfo, req message.ReqMessage) (err error) {
+	var errMsg string
+	defer func() {
+		if err != nil {
+			global.LOG.Critical(fmt.Sprintf("GetReportList: userId=%d, err:%s, errMsg:%s", user.UserID, err.Error(), errMsg))
+		}
+	}()
+	//查询当前消息
+	msgInfo, err := yb_message.GetMsgByMsgId(user.UserID, req.MsgId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询消息出错")
+		return
+	}
+	if msgInfo.MsgId <= 0 {
+		err = errors.New("消息不存在")
+		return
+	}
+	if msgInfo.Enabled == 0 {
+		return
+	}
+	msgInfo.Enabled = 0
+	msgInfo.ModifyTime = time.Now()
+	//根据类型设置一键已读
+	err = msgInfo.Update([]string{"enabled","modify_time"})
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("删除消息失败")
+		return
+	}
+	return
+}

+ 8 - 0
services/report/report.go

@@ -19,6 +19,7 @@ import (
 	"hongze/hongze_yb/models/tables/rddp/report_chapter_ticker"
 	"hongze/hongze_yb/models/tables/report_chapter_type"
 	"hongze/hongze_yb/models/tables/report_chapter_type_permission"
+	"hongze/hongze_yb/services"
 	"hongze/hongze_yb/services/company"
 	elasticService "hongze/hongze_yb/services/elastic"
 	"hongze/hongze_yb/services/user"
@@ -467,17 +468,24 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 		}
 	}
 	//如果有权限则展示content
+	var likeNum int64
+	var likeEnabled int8
 	if authOk {
 		task.Task(AddViewRecord, userinfo, reportInfo.Id, reportInfo.ClassifyNameFirst, 0)
 		reportItem.Content = html.UnescapeString(reportInfo.Content)
 		reportItem.VideoUrl = reportInfo.VideoUrl
+		//查询点赞数
+		likeNum,likeEnabled, _ = services.GetReportLikeByReportIdOldReportId(userinfo.UserID, reportInfo.Id, 0,0,0)
 	}
+
 	//新增用户访问日志
 	task.Task(AddUserAccessRecord, userinfo, reportInfo.Id, reportInfo.ClassifyNameFirst, 0, authOk)
 	reportDetail.ReportInfo = reportItem
 	reportDetail.ReportChapterList = reportTypeList
 	reportDetail.PermissionCheck = &permissionCheckInfo
 	reportDetail.AuthOk = authOk
+	reportDetail.LikeNum = likeNum
+	reportDetail.LikeEnabled = likeEnabled
 	return
 }
 

+ 8 - 1
services/report/report_chapter.go

@@ -11,6 +11,7 @@ import (
 	"hongze/hongze_yb/models/tables/rddp/report"
 	"hongze/hongze_yb/models/tables/rddp/report_chapter"
 	"hongze/hongze_yb/models/tables/report_chapter_type"
+	"hongze/hongze_yb/services"
 	"hongze/hongze_yb/services/company"
 	"hongze/hongze_yb/services/user"
 	"hongze/hongze_yb/task"
@@ -258,6 +259,8 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 	reportChapterItem.Stage = reportChapter.Stage
 	reportChapterItem.ClassifyNameFirst = reportChapter.ClassifyNameFirst
 	reportChapterItem.ClassifyIdFirst = reportChapter.ClassifyIdFirst
+	var likeNum int64
+	var likeEnabled int8
 	if authOk {
 		reportChapterItem.Content = html.UnescapeString(reportChapter.Content)
 		reportChapterItem.VideoUrl = reportChapter.VideoUrl
@@ -267,17 +270,21 @@ func GetChapterDetail(user user.UserInfo, reportChapterId int) (reportChapterDet
 		}else{
 			chapterMenu, err = GetMenuChapter(reportInfo.Id, typeIds, reportInfo.ClassifyNameFirst, reportInfo.CreateTime)
 		}
-
+		//查询点赞数
+		likeNum,likeEnabled, _ = services.GetReportLikeByReportIdOldReportId(user.UserID, reportInfo.Id, reportChapter.ReportChapterId,0,0)
 		task.Task(AddViewRecord, user, reportInfo.Id, reportInfo.ClassifyNameFirst, reportChapterId)
 	}else{
 		reportChapterItem.ContentSub = html.UnescapeString(reportChapter.ContentSub)
 	}
+
 	task.Task(AddUserAccessRecord, user, reportInfo.Id, reportInfo.ClassifyNameFirst, reportChapterId, authOk)
 	reportChapterDetail = new(response.ReportChapterDetail)
 	reportChapterDetail.ReportChapterItem = reportChapterItem
 	reportChapterDetail.PermissionCheck = &permissionCheckInfo
 	reportChapterDetail.ReportChapterMenuList = chapterMenu
 	reportChapterDetail.AuthOk = authOk
+	reportChapterDetail.LikeNum = likeNum
+	reportChapterDetail.LikeEnabled = likeEnabled
 	return
 }
 

+ 2 - 2
services/user/user.go

@@ -232,10 +232,10 @@ func GetFirstWxUserItemByUnionId(unionId string) (userInfo UserInfo, err error)
 func formatWxUserAndUserRecord(wxUser *wx_user.WxUser, userRecord *user_record.UserRecord) (userInfo UserInfo) {
 	wxUser.OpenID = userRecord.OpenID
 	wxUser.UnionID = userRecord.UnionID
-	wxUser.NickName = userRecord.NickName
+	//wxUser.NickName = userRecord.NickName
 	//wxUser.RealName = userRecord.RealName
 	//wxUser.BindAccount = userRecord.BindAccount
-	wxUser.Headimgurl = userRecord.Headimgurl
+	//wxUser.Headimgurl = userRecord.Headimgurl
 
 	wxUserJson, _ := json.Marshal(wxUser)
 	_ = json.Unmarshal(wxUserJson, &userInfo)

+ 77 - 0
services/wx_app/security/security.go

@@ -0,0 +1,77 @@
+package security
+
+import (
+	"encoding/json"
+	"errors"
+	"fmt"
+	"github.com/silenceper/wechat/v2/miniprogram"
+	"github.com/silenceper/wechat/v2/miniprogram/content"
+	"github.com/silenceper/wechat/v2/util"
+)
+
+
+// 检查一段文本是否含有违法违规内容。
+// https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/sec-check/security.msgSecCheck.html
+const SecurityMsgCheckUrl = "https://api.weixin.qq.com/wxa/msg_sec_check"
+
+type Security struct {
+	*content.Content
+}
+
+type MyMiniprogram struct {
+       *miniprogram.MiniProgram
+}
+
+func NewMyMiniprogram(miniprogram *miniprogram.MiniProgram) *MyMiniprogram {
+	return &MyMiniprogram{miniprogram}
+}
+
+type BodyContent struct {
+	Version       int8    `json:"version"`    // 接口版本号,2.0版本为固定值2
+	Openid        string  `json:"openid"`     // 用户的openid(用户需在近两小时访问过小程序)
+	Scene         int8    `json:"scene"`      // 场景枚举值(1 资料;2 评论;3 论坛;4 社交日志)
+	Content       string  `json:"content"`    // 需检测的文本内容,文本字数的上限为2500字,需使用UTF-8编码
+	Nickname      string  `json:"nickname"`   // 用户昵称,需使用UTF-8编码
+	Title         string  `json:"title"`      // 文本标题,需使用UTF-8编码
+	Signature     string  `json:"signature"`  // 个性签名,该参数仅在资料类场景有效(scene=1),需使用UTF-8编码
+}
+
+func (s *MyMiniprogram) MsgSecCheckWithResult(bodyContent *BodyContent) (result Result, err error)  {
+	var accessToken string
+	accessToken, err = s.GetContentSecurity().GetAccessToken()
+	if err != nil {
+		return
+	}
+	uri := fmt.Sprintf("%s?access_token=%s", SecurityMsgCheckUrl, accessToken)
+	response, err := util.PostJSON(uri, bodyContent)
+	if err != nil {
+		return
+	}
+	return DecodeWithResult(response, "MsgSecCheck")
+}
+
+type Result struct {
+	Result *ResultBody
+}
+type ResultBody struct {
+	Suggest string  //建议,有risky、pass、review三种值
+	Label  int      //命中标签枚举值,100 正常;10001 广告;20001 时政;20002 色情;20003 辱骂;20006 违法犯罪;20008 欺诈;20012 低俗;20013 版权;21000 其他
+}
+
+func DecodeWithResult(response []byte, apiName string) (result Result, err error)  {
+	var commError util.CommonError
+	err = json.Unmarshal(response, &commError)
+	if err != nil {
+		return
+	}
+	if commError.ErrCode != 0 {
+		err = errors.New(fmt.Sprintf("%s Error , errcode=%d , errmsg=%s", apiName, commError.ErrCode, commError.ErrMsg))
+		return
+	}
+	err = json.Unmarshal(response, &result)
+	if err != nil {
+		return
+	}
+	return
+}
+

+ 14 - 0
services/wx_app/wx_app.go

@@ -11,6 +11,7 @@ import (
 	"github.com/silenceper/wechat/v2/miniprogram/qrcode"
 	"github.com/silenceper/wechat/v2/util"
 	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/services/wx_app/security"
 )
 
 //微信小程序配置信息
@@ -126,3 +127,16 @@ func GetSunCode(page, scene string) (resp []byte, err error) {
 	qr := wechatClient.GetQRCode()
 	return qr.GetWXACodeUnlimit(codePars)
 }
+
+// MsgSecCheck 检查一段文本是否含有违法违规内容。
+func MsgSecCheck(openid string,content string) (result security.Result, err error) {
+	wechatClient := GetWxApp()
+	myMiniprogram := security.NewMyMiniprogram(wechatClient)
+	bodyContent := &security.BodyContent{
+		Version: 2,
+		Content: content,
+		Openid: openid,
+		Scene: 2,
+	}
+	return myMiniprogram.MsgSecCheckWithResult(bodyContent)
+}

+ 174 - 0
services/yb_common.go

@@ -0,0 +1,174 @@
+package services
+
+import (
+	"errors"
+	"hongze/hongze_yb/models/tables/company_product"
+	"hongze/hongze_yb/models/tables/rddp/report"
+	"hongze/hongze_yb/models/tables/rddp/report_chapter"
+	"hongze/hongze_yb/models/tables/research_report_type"
+	"hongze/hongze_yb/models/tables/yb_like"
+	"hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"strings"
+)
+
+// GetReportIdReportChapterIdByOldReportId 根据老报告的ID查询对应的新报告ID
+func GetReportIdReportChapterIdByOldReportId(oldReportId, oldReportChapterId uint64) (reportId int, reportChapterId int, err error, errMsg string)  {
+	var reportNew *report.Report
+	if oldReportChapterId >0 {
+		//查询章节详情,根据章节类型ID和老报告ID,根据老报告ID,查询新报告ID,根据新报告ID和type_id 找到新的章节ID
+		var oldReportChapter *research_report_type.ResearchReportTypeInfo
+		var reportChapterNew *report_chapter.ReportChapter
+		oldReportChapter, err = research_report_type.GetResearchReportTypeInfo(oldReportChapterId)
+		if err != nil {
+			errMsg = err.Error()
+			err = errors.New("找不到报告章节")
+			return
+		}
+		if  oldReportChapter == nil {
+			err = errors.New("找不到报告章节")
+			return
+		}
+		if oldReportId != oldReportChapter.ResearchReportID {
+			err = errors.New("报告ID和章节ID不一致")
+			return
+		}
+		//判断是否是晨报或者周报的章节ID,双周报的章节ID不记录
+		if oldReportChapter.TypeID == 0 {
+			err = errors.New("只允许传晨报和周报的章节ID")
+			return
+		}
+		reportNew, err = report.GetReportByOldReportId(oldReportChapter.ResearchReportID)
+		if err != nil {
+			errMsg = err.Error()
+			//err = errors.New("找不到新版报告")
+			return
+		}
+		if reportNew.Id <=0 {
+			//err = errors.New("找不到新版报告")
+			return
+		}
+		reportChapterNew, err = report_chapter.GetChapterByReportIdTypeId(reportNew.Id, oldReportChapter.TypeID)
+		if err != nil {
+			errMsg = err.Error()
+			return
+		}
+		if reportChapterNew.ReportChapterId <= 0 {
+			//err = errors.New("找不到新版章节")
+			return
+		}
+		reportId = reportNew.Id
+		reportChapterId = reportChapterNew.ReportChapterId
+		return
+	}else if oldReportId > 0 {
+		// 查询新报告ID
+		reportNew, err = report.GetReportByOldReportId(oldReportId)
+		if err != nil {
+			errMsg = err.Error()
+			//err = errors.New("找不到新版报告")
+			return
+		}
+		reportId = reportNew.Id
+        return
+	}
+	return
+}
+// CheckReportExistByReportIdReportChapterId 评论和点赞时,校验传入的报告ID是否正确
+func CheckReportExistByReportIdReportChapterId(reportId, reportChapterId int)(err error, errMsg string) {
+	reportInfo, err := report.GetByReportId(reportId)
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询报告出错")
+		return
+	}
+	if reportInfo.Id <=0  {
+		err = errors.New("报告不存在")
+		return
+	}
+
+	if (reportInfo.ClassifyNameFirst == "晨报" || reportInfo.ClassifyNameFirst == "周报") && reportChapterId <=0 {
+		err = errors.New("请输入报告章节ID")
+		return
+	}
+
+	if reportChapterId > 0 {
+		reportChapterInfo, tErr := report_chapter.GetTypeIdById(reportChapterId)
+		if tErr != nil {
+			errMsg = tErr.Error()
+			err = errors.New("查询章节失败")
+			return
+		}
+
+		if reportChapterInfo.ReportChapterId == 0 {
+			err = errors.New("章节不存在或者未发布")
+			return
+		}
+
+		if reportChapterInfo.ReportId != reportId {
+			err = errors.New("章节ID和报告ID不匹配")
+			return
+		}
+	}
+	return
+}
+
+// CheckSimpleCompanyProduct 校验用户是否FICC产品的已购或者试用状态
+func CheckSimpleCompanyProduct(userinfo user.UserInfo) (err error, errMsg string){
+	// 判断用户状态是否是正常和永续
+	var productAuthOk bool
+	companyProduct, err := company_product.GetByCompany2ProductId(userinfo.CompanyID, 1)
+	if err == utils.ErrNoRow {
+		err = nil
+	}
+	if err != nil {
+		errMsg = err.Error()
+		err = errors.New("查询用户购买产品出错")
+		return
+	}
+	if companyProduct != nil {
+		// 无FICC权限的客户不可见
+		if companyProduct.CompanyProductID > 0 {
+			// 已购或者试用用户可见
+			if strings.Contains("永续,正式", companyProduct.Status) || (companyProduct.Status == "试用" && companyProduct.IsSuspend != 1) {
+				productAuthOk = true
+			}
+		}
+	}
+	if !productAuthOk {
+		err = errors.New("无权操作")
+		return
+	}
+	return
+}
+
+func GetReportLikeByReportIdOldReportId(userId uint64,reportId, reportChapterId int, oldReportId, oldReportChapterId int) (likeNum int64, likeEnabled int8, err error)  {
+	// 根据老报告找到新报告的ID
+	if reportId == 0 && oldReportId > 0{
+		reportId, reportChapterId, err, _ = GetReportIdReportChapterIdByOldReportId(uint64(oldReportId), uint64(oldReportChapterId))
+	}
+	//查询总的点赞数
+	if reportId > 0{
+		likeNum, err = yb_like.GetLikeNumByReportId(reportId, reportChapterId)
+	} else if oldReportId > 0{
+		likeNum, err = yb_like.GetLikeNumByOldReportId(oldReportId, oldReportChapterId)
+	}
+
+	if err != nil {
+		err = errors.New("查询点赞数出错")
+		return
+	}
+
+	//查询用户对研报的点赞状态
+	var likeItem *yb_like.YbLike
+	if reportId > 0 {
+		likeItem, err = yb_like.GetLikeByUserIdAndReportId(userId, reportId, reportChapterId)
+	} else {
+		likeItem, err = yb_like.GetLikeByUserIdAndOldReportId(userId, oldReportId, oldReportChapterId)
+	}
+	if err != nil {
+		err = errors.New("查询用户点赞记录出错")
+		return
+	}
+	likeEnabled = likeItem.Enabled
+	return
+}

+ 5 - 0
utils/constants.go

@@ -122,3 +122,8 @@ const ALIYUN_YBIMG_HOST = "https://hzstatic.hzinsights.com/static/yb_wx/"
 const HZ_DEFAULT_AVATAR = "https://hzstatic.hzinsights.com/static/yb_wx/hz_default_avatar.png"
 
 const HZPHONE = "057187186319"    //弘则电话
+
+const (
+	DEFAULT_HONGZE_USER_LOGO = "个人默认头像"    //个人中心默认头像、匿名用户留言默认头像
+	DEFAULT_HONGZE_SYS_LOGO = ""     //弘则官方默认头像
+)