瀏覽代碼

Merge branch 'master' into yb/6.0

hsun 2 年之前
父節點
當前提交
54aa672c24

+ 2 - 0
controller/chart/chart_info.go

@@ -116,6 +116,8 @@ func GetChartInfoDetail(c *gin.Context) {
 		startDate = "2019-01-01"
 	case 9:
 		startDate = "2020-01-01"
+	case 11:
+		startDate = "2022-01-01"
 	}
 
 	if chartType == 2 {

+ 30 - 0
controller/community/question.go

@@ -293,4 +293,34 @@ func ResearchGroupList(c *gin.Context)  {
 		return
 	}
 	response.OkData("获取成功", list, c)
+}
+
+// AddAudioLog 添加用户点击音频日志
+// @Tags 问答社区模块
+// @Description 添加用户点击音频日志
+// @Param community_question_audio_id  query  int  true  "音频ID"
+// @Param source_agent  query  int  true  "操作来源,1:小程序,2:小程序 pc 3:弘则研究公众号,4:web pc"
+// @Success 200 {string} string "操作成功"
+// @failure 400 {string} string "操作失败"
+// @Router /AddAudioLog [post]
+func AddAudioLog(c *gin.Context) {
+	var req request.CommunityAudioListenLogReq
+	if err := c.ShouldBind(&req); err != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.CommunityQuestionAudioID == 0 {
+		response.Fail("请输入音频ID", c)
+		return
+	}
+	if req.SourceAgent == 0 {
+		response.Fail("请输入操作来源", c)
+		return
+	}
+	userinfo := user.GetInfoByClaims(c)
+	if err := community.AddAudioListenLog(userinfo, req.CommunityQuestionAudioID, req.SourceAgent); err != nil {
+		response.Fail("操作失败: "+err.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
 }

+ 174 - 0
controller/sandbox/sandbox.go

@@ -0,0 +1,174 @@
+package sandbox
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	sandboxLogic "hongze/hongze_yb/logic/sandbox"
+	sandboxReq "hongze/hongze_yb/models/request/sandbox"
+	responseModel "hongze/hongze_yb/models/response"
+	sandboxModel "hongze/hongze_yb/models/tables/sandbox"
+	"hongze/hongze_yb/services"
+	"hongze/hongze_yb/services/company"
+	"hongze/hongze_yb/services/user"
+	"strconv"
+	"strings"
+)
+
+// List 获取沙盘逻辑图列表
+// @Tags 沙盘模块
+// @Summary  获取沙盘逻辑图列表
+// @Description 获取沙盘逻辑图列表
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param chart_permission query int false "品种权限id"
+// @Param keyword query string false "关键字"
+// @Param is_high_light query bool false "是否高亮显示"
+// @Param curr_page query int false "当前页码"
+// @Param page_size query int false "每页返回数据"
+// @Success 200 {object} sandbox.SandboxListResp
+// @failure 400 {string} string "获取失败"
+// @Router /sandbox/list [get]
+func List(c *gin.Context) {
+	var req sandboxReq.ListReq
+	if err := c.Bind(&req); err != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	// 品种id
+	chartPermissionId := req.ChartPermissionId
+
+	// 关键字
+	keyword := req.Keyword
+	// 是否高亮
+	isHighLight := req.IsHighLight
+
+	page := services.GetCurrPageByClaims(c)
+	pageSize := services.GetPageSizeByClaims(c)
+
+	userInfo := user.GetInfoByClaims(c)
+
+	//权限验证
+	checkOk, companyPermissionIdList, permissionCheckInfo, tempErr := company.CheckUserSandboxPermission(userInfo.CompanyID, int(userInfo.UserID), chartPermissionId)
+	if tempErr != nil {
+		response.FailMsg("沙盘权限验证失败", "沙盘权限验证失败:"+tempErr.Error(), c)
+		c.Abort()
+		return
+	}
+	if !checkOk {
+		response.AuthError(permissionCheckInfo, "暂无权限", c)
+		c.Abort()
+		return
+	}
+
+	//获取指标信息
+	total, list, err, errMsg := sandboxLogic.GetList(chartPermissionId, companyPermissionIdList, keyword, page, pageSize)
+	if err != nil {
+		response.FailMsg(errMsg, err.Error(), c)
+		return
+	}
+
+	// 如果要高亮,且有输入关键字搜索,那么就返回高亮显示字符串
+	if isHighLight && keyword != `` {
+		for index, v := range list {
+			tmpKeyword := `<span style="color:#E3B377">` + keyword + `</span>`
+			list[index].Name = strings.Replace(v.Name, keyword, tmpKeyword, -1)
+		}
+	}
+
+	resp := responseModel.SandboxListResp{
+		List:   list,
+		Paging: responseModel.GetPaging(page, pageSize, int(total)),
+	}
+	response.OkData("获取成功", resp, c)
+}
+
+// Detail 获取沙盘逻辑图详情
+// @Tags 沙盘模块
+// @Summary  获取沙盘逻辑图详情
+// @Description 获取沙盘逻辑图详情
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param sandbox_id query int false "沙盘逻辑id"
+// @Success 200 {object} sandbox.SandboxItem
+// @failure 400 {string} string "获取失败"
+// @Router /sandbox/detail [get]
+func Detail(c *gin.Context) {
+	// 沙盘id
+	sandboxIdStr := c.DefaultQuery("sandbox_id", "0")
+	sandboxId, _ := strconv.Atoi(sandboxIdStr)
+
+	userInfo := user.GetInfoByClaims(c)
+
+	sandboxInfo, err := sandboxModel.GetBySandboxId(uint32(sandboxId))
+	if err != nil {
+		response.FailMsg("获取沙盘失败", "获取沙盘失败:"+err.Error(), c)
+		c.Abort()
+		return
+	}
+	//权限验证
+	checkOk, _, permissionCheckInfo, tempErr := company.CheckUserSandboxPermission(userInfo.CompanyID, int(userInfo.UserID), int(sandboxInfo.ChartPermissionID))
+	if tempErr != nil {
+		response.FailMsg("沙盘权限验证失败", "沙盘权限验证失败:"+tempErr.Error(), c)
+		c.Abort()
+		return
+	}
+	if !checkOk {
+		response.AuthError(permissionCheckInfo, "暂无权限", c)
+		c.Abort()
+		return
+	}
+
+	response.OkData("获取成功", sandboxLogic.SandboxItem{
+		SandboxID:           sandboxInfo.SandboxID,
+		Name:                sandboxInfo.Name,
+		ChartPermissionID:   sandboxInfo.ChartPermissionID,
+		ChartPermissionName: sandboxInfo.ChartPermissionName,
+		CurrVersion:         sandboxInfo.CurrVersion,
+		Code:                sandboxInfo.Code,
+		PicURL:              sandboxInfo.PicURL,
+		OpUserName:          sandboxInfo.OpUserName,
+		ModifyTime:          sandboxInfo.ModifyTime,
+	}, c)
+}
+
+// PermissionCountList 获取各个品种下的沙盘图数量列表
+// @Tags 沙盘模块
+// @Summary  获取各个品种下的沙盘图数量列表
+// @Description 获取各个品种下的沙盘图数量列表
+// @Security ApiKeyAuth
+// @Param Authorization	header string true "Bearer 31a165baebe6dec616b1f8f3207b4273"
+// @Accept  json
+// @Product json
+// @Param sandbox_id query int false "沙盘逻辑id"
+// @Success 200 {object} []sandboxModel.PermissionSandboxCount
+// @failure 400 {string} string "获取失败"
+// @Router /sandbox/permission_count [get]
+func PermissionCountList(c *gin.Context) {
+	userInfo := user.GetInfoByClaims(c)
+
+	//权限验证
+	checkOk, companyPermissionIdList, permissionCheckInfo, tempErr := company.CheckUserSandboxPermission(userInfo.CompanyID, int(userInfo.UserID), 0)
+	if tempErr != nil {
+		response.FailMsg("沙盘权限验证失败", "沙盘权限验证失败:"+tempErr.Error(), c)
+		c.Abort()
+		return
+	}
+	if !checkOk {
+		response.AuthError(permissionCheckInfo, "暂无权限", c)
+		c.Abort()
+		return
+	}
+
+	//获取指标信息
+	list, err, errMsg := sandboxLogic.GetPermissionCountList(companyPermissionIdList)
+	if err != nil {
+		response.FailMsg(errMsg, err.Error(), c)
+		return
+	}
+
+	response.OkData("获取成功", list, c)
+}

+ 25 - 0
controller/user/user.go

@@ -292,4 +292,29 @@ func SetUserInfo(c *gin.Context) {
 		return
 	}
 	response.Ok("更新成功", c)
+}
+
+// GetTopTab 获取首页顶部Tab
+// @Tags 用户模块
+// @Summary  获取首页顶部Tab
+// @Description 获取首页顶部Tab
+// @Security ApiKeyAuth
+// @securityDefinitions.basic BasicAuth
+// @Param Authorization	header string true "微信登录后获取到的token"
+// @Accept  json
+// @Product json
+// @Success 200 {object} []string "获取成功"
+// @failure 400 {string} string "获取失败"
+// @Router /user/get_top_tab [get]
+func GetTopTab(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	version := c.Request.Header.Get("version")
+	tabBarList, err := userLogic.GetTopTab(userInfo, version)
+
+	if err != nil {
+		response.Fail("获取失败", c)
+		return
+	}
+
+	response.OkData("获取成功", tabBarList, c)
 }

+ 5 - 0
init_serve/router.go

@@ -21,6 +21,9 @@ func InitRouter() (r *gin.Engine) {
 	//r.Use(gin.Recovery())
 	r.Use(middleware.Recover())
 
+	// 公共的中间件
+	r.Use(middleware.Common())
+
 	//swagger界面访问地址
 	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
 
@@ -64,5 +67,7 @@ func InitRouter() (r *gin.Engine) {
 	routers.InitPc(r)
 	// 价格驱动相关路由
 	routers.InitPriceDriven(r)
+	//沙盘逻辑推演路由
+	routers.InitSandbox(r)
 	return
 }

+ 91 - 0
logic/sandbox/sandbox.go

@@ -0,0 +1,91 @@
+package sandbox
+
+import (
+	sandboxModel "hongze/hongze_yb/models/tables/sandbox"
+	"time"
+)
+
+// SandboxItem 沙盘图
+type SandboxItem struct {
+	SandboxID           uint32    `gorm:"primaryKey;column:sandbox_id;type:int(9) unsigned;not null" json:"sandbox_id"`                                                   // 沙盘id
+	Name                string    `gorm:"index:idx_name;column:name;type:varchar(64);not null;default:''" json:"name"`                                                    // 沙盘名称
+	ChartPermissionID   uint32    `gorm:"column:chart_permission_id;type:int(9) unsigned;not null;default:0" json:"chart_permission_id"`                                  // 品种id
+	ChartPermissionName string    `gorm:"index:idx_chart_permission_name;column:chart_permission_name;type:varchar(32);not null;default:''" json:"chart_permission_name"` // 品种名称(冗余字段,避免列表页查询时再去关联表查询)
+	CurrVersion         uint32    `gorm:"column:curr_version;type:int(9) unsigned;not null;default:0" json:"curr_version"`                                                // 当前版本
+	Code                string    `gorm:"column:code;type:varchar(255);not null" json:"code"`                                                                             // 沙盘code
+	PicURL              string    `gorm:"column:pic_url;type:varchar(255);not null;default:''" json:"pic_url"`                                                            // 沙盘图片
+	OpUserName          string    `gorm:"index:idx_op_user_name;column:op_user_name;type:varchar(32);not null;default:''" json:"op_user_name"`                            // 最近一次编辑的用户名称(冗余字段,避免查表)
+	ModifyTime          time.Time `gorm:"column:modify_time;type:timestamp;default:CURRENT_TIMESTAMP" json:"modify_time"`                                                 // 最近一次更新时间
+}
+
+// GetList 获取沙盘列表数据
+func GetList(chartPermissionId int, companyPermissionIdList []int, keyword string, page, pageSize int) (total int64, list []SandboxItem, err error, errMsg string) {
+	errMsg = `获取失败`
+	var condition string
+	var pars []interface{}
+
+	condition = ` is_delete = ? `
+	pars = append(pars, 0)
+
+	// 客户拥有的品种权限
+	if len(companyPermissionIdList) > 0 {
+		condition += " AND chart_permission_id in (?) "
+		pars = append(pars, companyPermissionIdList)
+	}
+
+	if chartPermissionId > 0 {
+		condition += " AND chart_permission_id=? "
+		pars = append(pars, chartPermissionId)
+	}
+
+	if keyword != "" {
+		//condition += ` AND  ( name LIKE '%` + keyword + `%'  OR  chart_permission_name LIKE '%` + keyword + `%' )`
+		condition += ` AND  ( name LIKE '%` + keyword + `%' )`
+	}
+
+	//获取指标信息
+	tmpTotal, tmpList, tmpErr := sandboxModel.GetPageListByWhere(condition, pars, (page-1)*pageSize, pageSize)
+	if tmpErr != nil {
+		err = tmpErr
+		return
+	}
+
+	total = tmpTotal
+
+	for _, v := range tmpList {
+		tmpSandBox := SandboxItem{
+			SandboxID:           v.SandboxID,
+			Name:                v.Name,
+			ChartPermissionID:   v.ChartPermissionID,
+			ChartPermissionName: v.ChartPermissionName,
+			CurrVersion:         v.CurrVersion,
+			Code:                v.Code,
+			PicURL:              v.PicURL,
+			OpUserName:          v.OpUserName,
+			ModifyTime:          v.ModifyTime,
+			//CreateTime:          time.Time{},
+		}
+		list = append(list, tmpSandBox)
+	}
+	return
+}
+
+// GetPermissionCountList 获取沙盘列表数据
+func GetPermissionCountList(companyPermissionIdList []int) (list []*sandboxModel.PermissionSandboxCount, err error, errMsg string) {
+	errMsg = `获取失败`
+	var condition string
+	var pars []interface{}
+
+	condition = ` is_delete = ? `
+	pars = append(pars, 0)
+
+	// 客户拥有的品种权限
+	if len(companyPermissionIdList) > 0 {
+		condition += " AND chart_permission_id in (?) "
+		pars = append(pars, companyPermissionIdList)
+	}
+
+	//获取指标信息
+	list, err = sandboxModel.GetPermissionCountListByWhere(condition, pars)
+	return
+}

+ 72 - 18
logic/user/user.go

@@ -11,6 +11,7 @@ import (
 	"hongze/hongze_yb/models/tables/research_group_relation"
 	"hongze/hongze_yb/models/tables/wx_user"
 	"hongze/hongze_yb/models/tables/yb_apply_record"
+	"hongze/hongze_yb/models/tables/yb_index_tab"
 	"hongze/hongze_yb/models/tables/yb_message"
 	"hongze/hongze_yb/services"
 	companyService "hongze/hongze_yb/services/company"
@@ -399,29 +400,34 @@ func Apply(userId int, companyId int64, mobile, email string, applyInfo userReq.
 
 // GetUserTabBar 获取用户小程序TabBar
 func GetUserTabBar(userInfo user.UserInfo, version string) (list []string, err error) {
-	// user-我的; activity-活动; chart-图表; report-研报; buy-已购; question-问答; pricedriven-价格驱动;
-	list = []string{"activity", "user", "chart"}
-	if version == "yb3.0" {
-		list = []string{"activity", "user", "chart", "report"}
-	}
-	if version == "yb5.0" {
-		list = []string{"activity", "question", "chart", "report"}
+	where := make(map[string]interface{})
+	where["version"] = version
+	where["position"] = 2
+	where["is_show"] = 1
+	tabs, e := yb_index_tab.GetListByCondition(where)
+	if e != nil {
+		err = errors.New("获取TabBar失败, Err: " + e.Error())
+		return
 	}
-	if version == "yb6.0" {
-		list = []string{"report", "pricedriven", "activity", "question", "chart"}
+	if len(tabs) == 0 {
+		return
 	}
-	companyProduct, tmpErr := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
-	if tmpErr != nil {
-		if tmpErr == utils.ErrNoRow {
-			err = nil
-		}
+	authOk := false
+	companyProduct, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
+	if e != nil && e != utils.ErrNoRow {
+		err = errors.New("获取客户信息失败, Err: " + e.Error())
 		return
 	}
-	// 已购仅付费用户可见
-	if version != "yb6.0" {
+	if companyProduct != nil {
 		if strings.Contains("永续,正式", companyProduct.Status) {
-			list = append(list, "buy")
+			authOk = true
+		}
+	}
+	for _, v := range tabs {
+		if v.AuthCheck == 1 && !authOk {
+			continue
 		}
+		list = append(list, v.Mark)
 	}
 	return
 }
@@ -485,8 +491,56 @@ func PcSendEmailCode(email string) (err error, errMsg string) {
 		}
 		err = item.Create()
 	} else {
-		err = errors.New("发送失败,Err:" + err.Error())
+		err = errors.New("发送失败")
 	}
 
 	return
 }
+
+// TopTab
+type TopTab struct {
+	Tab  string `json:"tab" description:"选项卡名称"`
+	Mark string `json:"mark" description:"选项卡标识"`
+	Icon string `json:"icon" description:"icon图标"`
+	Sort int    `json:"sort" description:"排序"`
+}
+
+// GetTopTab 获取小程序首页顶部选项卡
+func GetTopTab(userInfo user.UserInfo, version string) (list []*TopTab, err error) {
+	where := make(map[string]interface{})
+	where["version"] = version
+	where["position"] = 1
+	where["is_show"] = 1
+	tabs, e := yb_index_tab.GetListByCondition(where)
+	if e != nil {
+		err = errors.New("获取TabBar失败, Err: " + e.Error())
+		return
+	}
+	if len(tabs) == 0 {
+		return
+	}
+	authOk := false
+	companyProduct, e := company_product.GetByCompany2ProductId(userInfo.CompanyID, 1)
+	if e != nil && e != utils.ErrNoRow {
+		err = errors.New("获取客户信息失败, Err: " + e.Error())
+		return
+	}
+	if companyProduct != nil {
+		if strings.Contains("永续,正式", companyProduct.Status) {
+			authOk = true
+		}
+	}
+	list = make([]*TopTab, 0)
+	for _, v := range tabs {
+		if v.AuthCheck == 1 && !authOk {
+			continue
+		}
+		list = append(list, &TopTab{
+			Tab: v.Tab,
+			Mark: v.Mark,
+			Icon: v.DefaultIcon,
+			Sort: v.Sort,
+		})
+	}
+	return
+}

+ 27 - 0
middleware/common.go

@@ -0,0 +1,27 @@
+package middleware
+
+import (
+	"github.com/gin-gonic/gin"
+	"strconv"
+)
+
+// Common 公共中间件
+func Common() gin.HandlerFunc {
+	return func(c *gin.Context) {
+		var currPage, pageSize int
+		reqPage := c.DefaultQuery("curr_page", "0")
+		currPage, _ = strconv.Atoi(reqPage)
+		if currPage <= 0 {
+			currPage = 1
+		}
+
+		reqPageSize := c.DefaultQuery("page_size", "0")
+		pageSize, _ = strconv.Atoi(reqPageSize)
+		if pageSize <= 0 {
+			pageSize = 20
+		}
+		c.Set("curr_page", currPage)
+		c.Set("page_size", pageSize)
+		c.Next()
+	}
+}

+ 5 - 0
models/request/community.go

@@ -36,3 +36,8 @@ type QuestionReadReq struct {
 type ReplyListTotalReq struct {
 	ReplierUserId int `json:"replier_user_id" form:"replier_user_id"`
 }
+
+type CommunityAudioListenLogReq struct {
+	CommunityQuestionAudioID int `json:"community_question_audio_id"` //音频ID
+	SourceAgent              int `json:"source_agent"`                //操作来源,1:小程序,2:小程序 pc 3:弘则研究公众号,4:web pc
+}

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

@@ -0,0 +1,9 @@
+package sandbox
+
+type ListReq struct {
+	ChartPermissionId int    `json:"chart_permission_id" form:"chart_permission_id" description:"品种id"`
+	Keyword           string `json:"keyword" form:"keyword" description:"关键字"`
+	IsHighLight       bool   `json:"is_high_light" form:"is_high_light" description:"是否高亮显示"`
+	CurrPage          int    `json:"curr_page" form:"curr_page"`
+	PageSize          int    `json:"page_size" form:"page_size"`
+}

+ 6 - 5
models/response/community.go

@@ -23,11 +23,12 @@ type CommunityQuestionItem struct {
 }
 
 type CommunityQuestionAudioItem struct {
-	CommunityQuestionID int    `json:"community_question_id"`
-	AudioURL            string `json:"audio_url"`
-	AudioPlaySeconds    string `json:"audio_play_seconds"`
-	AudioSize           string `json:"audio_size"`
-	Sort                int    `json:"sort"`
+	CommunityQuestionAudioID int    `json:"community_question_audio_id"`
+	CommunityQuestionID      int    `json:"community_question_id"`
+	AudioURL                 string `json:"audio_url"`
+	AudioPlaySeconds         string `json:"audio_play_seconds"`
+	AudioSize                string `json:"audio_size"`
+	Sort                     int    `json:"sort"`
 }
 
 type CommunityQuestionListTotal struct {

+ 17 - 16
models/response/report.go

@@ -11,6 +11,7 @@ type ReportDetail struct {
 	AuthOk            bool                     `json:"auth_ok"`
 	LikeNum           int64                    `description:"点赞总数" json:"like_num"`
 	LikeEnabled       int8                     `description:"是否已点赞: 0-未点赞 1-已点赞" json:"like_enabled"`
+	ReportShowType    int                      `descritpion:"展示形式:1-列表 2-专栏" json:"report_show_type"`
 }
 
 type ReportChapterListItem struct {
@@ -36,22 +37,22 @@ type ReportItem struct {
 	Author             string    `description:"作者" json:"author"`
 	Frequency          string    `description:"频度" json:"frequency"`
 	PublishTime        time.Time `description:"发布时间" json:"publish_time"`
-	Stage              int    `description:"期数" json:"stage"`
-	Content            string `description:"内容" json:"content"`
-	VideoUrl           string `description:"音频文件URL" json:"video_url"`
-	VideoName          string `description:"音频文件名称" json:"video_name"`
-	VideoSize          string `description:"音频文件大小,单位M" json:"video_size"`
-	VideoPlaySeconds   string `description:"音频播放时长" json:"video_play_seconds"`
+	Stage              int       `description:"期数" json:"stage"`
+	Content            string    `description:"内容" json:"content"`
+	VideoUrl           string    `description:"音频文件URL" json:"video_url"`
+	VideoName          string    `description:"音频文件名称" json:"video_name"`
+	VideoSize          string    `description:"音频文件大小,单位M" json:"video_size"`
+	VideoPlaySeconds   string    `description:"音频播放时长" json:"video_play_seconds"`
 	VideoImg           string    `description:"音频播放条的图片" json:"video_img"`
-	ContentSub         string `description:"内容前两个章节" json:"content_sub"`
-	BannerUrl          string `description:"详情页banner" json:"banner_url"`
+	ContentSub         string    `description:"内容前两个章节" json:"content_sub"`
+	BannerUrl          string    `description:"详情页banner" json:"banner_url"`
 }
 
 type ReportChapterItem struct {
 	ReportChapterId       int       `json:"report_chapter_id"`
 	ReportId              int       `json:"report_id"`
 	Title                 string    `json:"title"`
-	Abstract string `json:"abstract"`
+	Abstract              string    `json:"abstract"`
 	TypeId                int       `json:"type_id"`
 	TypeName              string    `json:"type_name"`
 	Trend                 string    `json:"trend"`
@@ -80,13 +81,13 @@ type ReportChapterDetail struct {
 }
 
 type ReportChapterMenu struct {
-	ReportChapterId    int    `json:"report_chapter_id"`
-	ReportId        int    `json:"report_id"`
-	ReportChapterTypeName   string       `json:"report_chapter_type_name"`
-	ReportChapterTypeThumb  string	    `json:"report_chapter_type_thumb"`
-	PcSelectedThumb  string	    `json:"pc_selected_thumb"`
-	PcUnselectedThumb  string	    `json:"pc_unselected_thumb"`
-	Sort             int  `json:"sort"`
+	ReportChapterId        int    `json:"report_chapter_id"`
+	ReportId               int    `json:"report_id"`
+	ReportChapterTypeName  string `json:"report_chapter_type_name"`
+	ReportChapterTypeThumb string `json:"report_chapter_type_thumb"`
+	PcSelectedThumb        string `json:"pc_selected_thumb"`
+	PcUnselectedThumb      string `json:"pc_unselected_thumb"`
+	Sort                   int    `json:"sort"`
 }
 
 type ReportListItem struct {

+ 9 - 0
models/response/sandbox.go

@@ -0,0 +1,9 @@
+package response
+
+import "hongze/hongze_yb/logic/sandbox"
+
+// SandboxListResp 沙盘逻辑数据反馈
+type SandboxListResp struct {
+	List   []sandbox.SandboxItem `json:"list"`
+	Paging *PagingItem           `json:"paging"`
+}

+ 41 - 0
models/tables/sandbox/query.go

@@ -0,0 +1,41 @@
+package sandbox
+
+import (
+	"hongze/hongze_yb/global"
+)
+
+// GetBySandboxId 根据沙盘ID查询详情
+func GetBySandboxId(id uint32) (item *Sandbox, err error) {
+	err = global.DEFAULT_MYSQL.Where("sandbox_id = ? and is_delete=0 ", id).Order("sandbox_id desc").First(&item).Error
+	return
+}
+
+// GetPageListByWhere 分页获取活动列表
+func GetPageListByWhere(condition string, pars []interface{}, startSize, pageSize int) (total int64, list []*Sandbox, err error) {
+	// 获取查询总数量
+	err = global.DEFAULT_MYSQL.Model(Sandbox{}).Where(condition, pars...).Count(&total).Error
+	if err != nil {
+		return
+	}
+
+	// 获取列表数据
+	err = global.DEFAULT_MYSQL.Model(Sandbox{}).Where(condition, pars...).Order("modify_time desc,sandbox_id desc").Offset(startSize).Limit(pageSize).Find(&list).Error
+	return
+}
+
+// PermissionSandboxCount 品种下沙盘数
+type PermissionSandboxCount struct {
+	ChartPermissionID   uint32 `gorm:"column:chart_permission_id;type:int(9) unsigned;not null;default:0" json:"chart_permission_id"`                                  // 品种id
+	ChartPermissionName string `gorm:"index:idx_chart_permission_name;column:chart_permission_name;type:varchar(32);not null;default:''" json:"chart_permission_name"` // 品种名称(冗余字段,避免列表页查询时再去关联表查询)
+	Total               int64  `json:"total"`                                                                                                                          // 汇总数
+}
+
+// GetPermissionCountListByWhere 获取各品种的沙盘数
+func GetPermissionCountListByWhere(condition string, pars []interface{}) (list []*PermissionSandboxCount, err error) {
+
+	//err = global.DEFAULT_MYSQL.Model(ResearchReport{}).Where("research_report_id IN (?)", ids).Scan(&list).Error
+
+	// 获取列表数据
+	err = global.DEFAULT_MYSQL.Model(Sandbox{}).Select("chart_permission_id,chart_permission_name,count(1) total").Where(condition, pars...).Order("modify_time desc,sandbox_id desc").Group("chart_permission_id").Scan(&list).Error
+	return
+}

+ 58 - 0
models/tables/sandbox/sandbox.go

@@ -0,0 +1,58 @@
+package sandbox
+
+import (
+	"time"
+)
+
+// Sandbox 沙盘推演主表
+type Sandbox struct {
+	SandboxID           uint32    `gorm:"primaryKey;column:sandbox_id;type:int(9) unsigned;not null" json:"-"`                                                          // 沙盘id
+	Name                string    `gorm:"index:idx_name;column:name;type:varchar(64);not null;default:''" json:"name"`                                                  // 沙盘名称
+	ChartPermissionID   uint32    `gorm:"column:chart_permission_id;type:int(9) unsigned;not null;default:0" json:"chartPermissionId"`                                  // 品种id
+	ChartPermissionName string    `gorm:"index:idx_chart_permission_name;column:chart_permission_name;type:varchar(32);not null;default:''" json:"chartPermissionName"` // 品种名称(冗余字段,避免列表页查询时再去关联表查询)
+	CurrVersion         uint32    `gorm:"column:curr_version;type:int(9) unsigned;not null;default:0" json:"currVersion"`                                               // 当前版本
+	Code                string    `gorm:"column:code;type:varchar(255);not null" json:"code"`                                                                           // 沙盘code
+	Content             string    `gorm:"column:content;type:text;not null" json:"content"`                                                                             // 沙盘内容
+	PicURL              string    `gorm:"column:pic_url;type:varchar(255);not null;default:''" json:"picUrl"`                                                           // 沙盘图片
+	OpUserID            uint32    `gorm:"column:op_user_id;type:int(10) unsigned;not null;default:0" json:"opUserId"`                                                   // 最近一次编辑操作的用户id
+	OpUserName          string    `gorm:"index:idx_op_user_name;column:op_user_name;type:varchar(32);not null;default:''" json:"opUserName"`                            // 最近一次编辑的用户名称(冗余字段,避免查表)
+	IsDelete            uint8     `gorm:"column:is_delete;type:tinyint(9) unsigned;not null;default:0" json:"isDelete"`                                                 // 是否删除,0:未删除,1:已删除
+	ModifyTime          time.Time `gorm:"column:modify_time;type:timestamp;default:CURRENT_TIMESTAMP" json:"modifyTime"`                                                // 最近一次更新时间
+	CreateTime          time.Time `gorm:"column:create_time;type:timestamp;default:CURRENT_TIMESTAMP" json:"createTime"`                                                // 沙盘创建时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *Sandbox) TableName() string {
+	return "sandbox"
+}
+
+// SandboxColumns get sql column name.获取数据库列名
+var SandboxColumns = struct {
+	SandboxID           string
+	Name                string
+	ChartPermissionID   string
+	ChartPermissionName string
+	CurrVersion         string
+	Code                string
+	Content             string
+	PicURL              string
+	OpUserID            string
+	OpUserName          string
+	IsDelete            string
+	ModifyTime          string
+	CreateTime          string
+}{
+	SandboxID:           "sandbox_id",
+	Name:                "name",
+	ChartPermissionID:   "chart_permission_id",
+	ChartPermissionName: "chart_permission_name",
+	CurrVersion:         "curr_version",
+	Code:                "code",
+	Content:             "content",
+	PicURL:              "pic_url",
+	OpUserID:            "op_user_id",
+	OpUserName:          "op_user_name",
+	IsDelete:            "is_delete",
+	ModifyTime:          "modify_time",
+	CreateTime:          "create_time",
+}

+ 19 - 0
models/tables/yb_community_audio_listen_log/entity.go

@@ -0,0 +1,19 @@
+package yb_community_audio_listen_log
+
+import "time"
+
+// YbCommunityAudioListenLog 社区语音回答点击日志
+type YbCommunityAudioListenLog struct {
+	Id                       int       `gorm:"primaryKey;column:id;type:int(10) unsigned;not null" json:"-"`
+	CommunityQuestionAudioID int       `gorm:"column:community_question_audio_id;type:int(10) unsigned;not null" json:"community_question_audio_id"` //问答音频ID
+	CommunityQuestionID      int       `gorm:"column:community_question_id;type:int(10) unsigned;not null;default:0" json:"community_question_id"`   // 社区问题ID
+	UserID                   int       `gorm:"index:idx_user_id;column:user_id;type:int(10) unsigned;not null;default:0" json:"user_id"`             // 点击音频的用户ID
+	SourceAgent              int       `gorm:"column:source_agent;type:tinyint(4);default:1" json:"source_agent"`                                    // 操作来源,1:小程序,2:小程序 pc 3:弘则研究公众号,4:web pc
+	CreateTime               time.Time `gorm:"column:create_time;type:datetime;default:CURRENT_TIMESTAMP" json:"create_time"`                        // 创建日志时间
+}
+
+// TableName get sql table name.获取数据库表名
+func (l *YbCommunityAudioListenLog) TableName() string {
+	return "yb_community_audio_listen_log"
+}
+

+ 8 - 0
models/tables/yb_community_audio_listen_log/model.go

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

+ 12 - 2
models/tables/yb_community_question_audio/model.go

@@ -15,7 +15,7 @@ func GetListByQuestrionIds(idArr []int) (list []*YbCommunityQuestionAudio, err e
 	}
 	err = global.DEFAULT_MYSQL.
 		Model(YbCommunityQuestionAudio{}).
-		Select("community_question_id, audio_url, audio_play_seconds, audio_size, sort").
+		Select("community_question_audio_id, community_question_id, audio_url, audio_play_seconds, audio_size, sort").
 		Where("community_question_id IN ?", idArr).
 		Order("community_question_id ASC, sort ASC").
 		Scan(&list).Error
@@ -25,9 +25,19 @@ func GetListByQuestrionIds(idArr []int) (list []*YbCommunityQuestionAudio, err e
 func GetListByQuestionId(questionId int) (list []*YbCommunityQuestionAudio, err error) {
 	err = global.DEFAULT_MYSQL.
 		Model(YbCommunityQuestionAudio{}).
-		Select("community_question_id, audio_url, audio_play_seconds, audio_size, sort").
+		Select("community_question_audio_id, community_question_id, audio_url, audio_play_seconds, audio_size, sort").
 		Where("community_question_id = ?", questionId).
 		Order("sort ASC").
 		Scan(&list).Error
 	return
+}
+
+// GetByAudioId 根据问答音频ID, 查询音频详情
+func GetByAudioId(audioId int)(item *YbCommunityQuestionAudio, err error)  {
+	err = global.DEFAULT_MYSQL.
+		Model(YbCommunityQuestionAudio{}).
+		Select("community_question_audio_id, community_question_id, audio_url, audio_play_seconds, audio_size, sort").
+		Where("community_question_audio_id = ?", audioId).
+		First(&item).Error
+	return
 }

+ 45 - 0
models/tables/yb_index_tab/entity.go

@@ -0,0 +1,45 @@
+package yb_index_tab
+
+// YbIndexTab 研报-首页选项卡
+type YbIndexTab struct {
+	ID           int    `gorm:"primaryKey;column:id;type:int(10) unsigned;not null" json:"-"`
+	Tab          string `gorm:"column:tab;type:varchar(30);not null;default:''" json:"tab"`                     // 选项卡名
+	Mark         string `gorm:"column:mark;type:varchar(30);not null;default:''" json:"mark"`                   // 枚举值
+	DefaultIcon  string `gorm:"column:default_icon;type:varchar(255);not null;default:''" json:"defaultIcon"`   // 默认icon
+	SelectedIcon string `gorm:"column:selected_icon;type:varchar(255);not null;default:''" json:"selectedIcon"` // 选中icon
+	Sort         int    `gorm:"column:sort;type:int(10) unsigned;not null;default:0" json:"sort"`               // 排序
+	IsShow       int    `gorm:"column:is_show;type:tinyint(4) unsigned;not null;default:0" json:"isShow"`       // 是否显示:0-隐藏 1-显示
+	AuthCheck    int    `gorm:"column:auth_check;type:tinyint(4) unsigned;not null;default:0" json:"authCheck"` // 是否需要检验权限:0-否 1-是
+	Position     int    `gorm:"column:position;type:tinyint(4) unsigned;not null;default:0" json:"position"`    // 位置:1-顶部 2-底部
+	Version      string `gorm:"column:version;type:varchar(30);not null;default:''" json:"version"`             // 版本号
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *YbIndexTab) TableName() string {
+	return "yb_index_tab"
+}
+
+// YbIndexTabColumns get sql column name.获取数据库列名
+var YbIndexTabColumns = struct {
+	ID           string
+	Tab          string
+	Mark         string
+	DefaultIcon  string
+	SelectedIcon string
+	Sort         string
+	IsShow       string
+	AuthCheck    string
+	Position     string
+	Version      string
+}{
+	ID:           "id",
+	Tab:          "tab",
+	Mark:         "mark",
+	DefaultIcon:  "default_icon",
+	SelectedIcon: "selected_icon",
+	Sort:         "sort",
+	IsShow:       "is_show",
+	AuthCheck:    "auth_check",
+	Position:     "position",
+	Version:      "version",
+}

+ 21 - 0
models/tables/yb_index_tab/model.go

@@ -0,0 +1,21 @@
+package yb_index_tab
+
+import (
+	"errors"
+	"hongze/hongze_yb/global"
+	"hongze/hongze_yb/utils"
+)
+
+// GetListByCondition 条件获取列表
+func GetListByCondition(where map[string]interface{}) (list []*YbIndexTab, err error) {
+	cond, vals, e := utils.WhereBuild(where)
+	if e != nil {
+		err = errors.New("系统异常,生成查询语句失败")
+		return
+	}
+	err = global.DEFAULT_MYSQL.Model(YbIndexTab{}).
+		Where(cond, vals...).
+		Order("sort ASC").
+		Scan(&list).Error
+	return
+}

+ 1 - 0
routers/community.go

@@ -17,4 +17,5 @@ func InitCommunity(r *gin.Engine)  {
 	rGroup.POST("/question/reply/upload_audio", community.QuestionUploadAudio)
 	rGroup.GET("/question/unread", community.QuestionUnread)
 	rGroup.GET("/question/research_group", community.ResearchGroupList)
+	rGroup.POST("/question/audio/log", community.AddAudioLog)
 }

+ 15 - 0
routers/sandbox.go

@@ -0,0 +1,15 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/sandbox"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitSandbox(r *gin.Engine) {
+	rGroup := r.Group("api/sandbox").Use(middleware.Token())
+	rGroup.GET("/list", sandbox.List)
+	rGroup.GET("/detail", sandbox.Detail)
+	rGroup.GET("/permission_count", sandbox.PermissionCountList)
+
+}

+ 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.GET("/get_top_tab", user.GetTopTab)
 		rGroup2.POST("/set", user.SetUserInfo)
 	}
 

+ 7 - 8
services/activity/activity.go

@@ -23,8 +23,8 @@ import (
 
 // ActivityList 活动列表
 type ActivityList struct {
-	yb_activity.ActivityItem							// 活动信息
-	VoiceList	[]*yb_activity_voice.YbActivityVoice	// 音频列表
+	yb_activity.ActivityItem                                      // 活动信息
+	VoiceList                []*yb_activity_voice.YbActivityVoice // 音频列表
 }
 
 // PageList 活动分页列表
@@ -79,7 +79,7 @@ func PageList(condition string, pars []interface{}, page, limit int, order strin
 			for _, voice := range voices {
 				if temp.ActivityID == int(voice.ActivityID) {
 					voiceMap = append(voiceMap, voice)
-					temp.HasPlayBack = 1	// 有回放
+					temp.HasPlayBack = 1 // 有回放
 				}
 			}
 			temp.VoiceList = voiceMap
@@ -203,7 +203,7 @@ func GetUserAuthActivityIds(userInfo user.UserInfo) (acrivityIds []int, err erro
 }
 
 // GetLatestActivity 从用户有权限参与的活动中,筛选出最新的活动
-func GetLatestActivity(permissionIds []int, userId uint64) (purchaseItem *purchase.PurchaseListItem, err error)  {
+func GetLatestActivity(permissionIds []int, userId uint64) (purchaseItem *purchase.PurchaseListItem, err error) {
 	var errMsg string
 	defer func() {
 		if sysErr := recover(); sysErr != nil {
@@ -232,7 +232,7 @@ func GetLatestActivity(permissionIds []int, userId uint64) (purchaseItem *purcha
 	}
 	//统计未读数
 	unRead, err := GetUnRead(activityIds, userId)
-	if err != nil{
+	if err != nil {
 		errMsg = err.Error()
 		err = errors.New("查询活动未读数错误")
 		return
@@ -250,9 +250,8 @@ func GetLatestActivity(permissionIds []int, userId uint64) (purchaseItem *purcha
 	return
 }
 
-
 // GetList 从用户有权限参与的活动中,筛选出最新的活动
-func GetPurchaseDetail(permissionIds []int, userId uint64,  pageIndex, pageSize int) (ret *purchase.DetailResp, err error)  {
+func GetPurchaseDetail(permissionIds []int, userId uint64, pageIndex, pageSize int) (ret *purchase.DetailResp, err error) {
 	// 获取用户权限可参与的活动ID
 	var activityIds []int
 	permissions, err := yb_activity_permission.GetPermissionsByPermissionIds(permissionIds)
@@ -310,4 +309,4 @@ func GetPurchaseDetail(permissionIds []int, userId uint64,  pageIndex, pageSize
 		return
 	}
 	return
-}
+}

+ 43 - 10
services/community/question.go

@@ -7,6 +7,7 @@ import (
 	"hongze/hongze_yb/models/response"
 	"hongze/hongze_yb/models/tables/research_group"
 	"hongze/hongze_yb/models/tables/user_record"
+	"hongze/hongze_yb/models/tables/yb_community_audio_listen_log"
 	"hongze/hongze_yb/models/tables/yb_community_question"
 	"hongze/hongze_yb/models/tables/yb_community_question_audio"
 	"hongze/hongze_yb/services/user"
@@ -88,11 +89,12 @@ func GetQuestionList(pageIndex, pageSize, onlyMine, chartPermissionId, replyStat
 		for _, a := range audioList {
 			if a.CommunityQuestionID == v.CommunityQuestionID {
 				audios = append(audios, &response.CommunityQuestionAudioItem{
-					CommunityQuestionID: a.CommunityQuestionID,
-					AudioURL:            a.AudioURL,
-					AudioPlaySeconds:    a.AudioPlaySeconds,
-					AudioSize:           a.AudioSize,
-					Sort:                a.Sort,
+					CommunityQuestionAudioID: a.CommunityQuestionAudioID,
+					CommunityQuestionID:      a.CommunityQuestionID,
+					AudioURL:                 a.AudioURL,
+					AudioPlaySeconds:         a.AudioPlaySeconds,
+					AudioSize:                a.AudioSize,
+					Sort:                     a.Sort,
 				})
 			}
 		}
@@ -148,11 +150,12 @@ func GetQuestionDetail(questionId int, userInfo user.UserInfo) (item *response.C
 	audios := make([]*response.CommunityQuestionAudioItem, 0)
 	for _, a := range audioList {
 		audios = append(audios, &response.CommunityQuestionAudioItem{
-			CommunityQuestionID: a.CommunityQuestionID,
-			AudioURL:            a.AudioURL,
-			AudioPlaySeconds:    a.AudioPlaySeconds,
-			AudioSize:           a.AudioSize,
-			Sort:                a.Sort,
+			CommunityQuestionAudioID: a.CommunityQuestionAudioID,
+			CommunityQuestionID:      a.CommunityQuestionID,
+			AudioURL:                 a.AudioURL,
+			AudioPlaySeconds:         a.AudioPlaySeconds,
+			AudioSize:                a.AudioSize,
+			Sort:                     a.Sort,
 		})
 	}
 	replierRank := fmt.Sprintf("弘则%s研究员", detail.ResearchGroupFirstName)
@@ -412,3 +415,33 @@ func GetResearchGroupTree() (respList []*response.ResearchGroupItem, err error)
 	respList = firstList
 	return
 }
+
+// AddAudioListenLog 添加用户点击音频日志
+func AddAudioListenLog(userInfo user.UserInfo, audioId int, sourceAgent int) (err error)  {
+	//1. 查询音频是否存在
+	audio, err := yb_community_question_audio.GetByAudioId(audioId)
+	if err != nil && err != utils.ErrNoRow {
+		err = errors.New("查询音频信息失败 Err:" + err.Error())
+		return
+	}
+	if err == utils.ErrNoRow {
+		err = errors.New("音频不存在")
+		return
+	}
+	if audio == nil {
+		err = errors.New("音频不存在")
+		return
+	}
+	//3. 添加点击日志
+	item := &yb_community_audio_listen_log.YbCommunityAudioListenLog{
+		CommunityQuestionAudioID: audio.CommunityQuestionAudioID,
+		CommunityQuestionID:      audio.CommunityQuestionID,
+		UserID:                   int(userInfo.UserID),
+		SourceAgent:              sourceAgent,
+	}
+	if err = item.Create(); err != nil {
+		err = errors.New("新增点击日志失败 Err:" + err.Error())
+		return
+	}
+	return
+}

+ 124 - 0
services/company/permission.go

@@ -779,3 +779,127 @@ func GetHomeFiccPermissions(user user.UserInfo) (ret response.PermissionFiccResp
 	ret.ContactInfo = contactInfo
 	return
 }
+
+// CheckUserSandboxPermission 验证用户/联系人的沙盘权限
+func CheckUserSandboxPermission(companyId int64, userId, permissionId int) (ok bool, companyPermissionIdList []int, permissionCheckInfo ChartPermissionCheckInfo, err error) {
+	defer func() {
+		// 如果无权限,那么就去查询是否申请过
+		if ok == false && permissionCheckInfo.Type == CheckTypeApply {
+			_, err = yb_apply_record.GetLastNotOpRecordByUserId(userId) // 图库申请
+			// 查询是否有申请过,如果有申请过的话,那么err是nil
+			if err != nil {
+				if err == utils.ErrNoRow {
+					err = nil
+					return
+				}
+				return
+			}
+			permissionCheckInfo.CustomerInfo.HasApply = true
+		}
+	}()
+
+	var productId int64
+	productId = 1
+	if companyId > 1 {
+		// 查询是否开通FICC
+		companyProductInfo, tmpErr := company_product.GetByCompany2ProductId(companyId, productId)
+		if tmpErr != nil {
+			// 没有开通FICC
+			if tmpErr == utils.ErrNoRow {
+				permissionCheckInfo.Type = CheckTypeApply
+				return
+			}
+			err = tmpErr
+			return
+		}
+
+		wxUser, tmpErr := wx_user.GetByUserId(userId)
+		if tmpErr != nil {
+			permissionCheckInfo.Type = CheckTypeApply
+			err = tmpErr
+			return
+		}
+
+		// 查询用户是否为弘则研究已禁用的联系人
+		if companyId == 16 {
+			if wxUser.Enabled != 1 {
+				permissionCheckInfo.Type = CheckTypeApply
+				return
+			}
+		}
+
+		// 客户信息
+		companyInfo, tmpErr := company.GetByCompanyId(companyId)
+		if tmpErr != nil {
+			// 没有开通FICC
+			if tmpErr == utils.ErrNoRow {
+				permissionCheckInfo.Type = CheckTypeApply
+				return
+			}
+			err = tmpErr
+			return
+		}
+		customerInfo := CustomerInfo{
+			CompanyName: companyInfo.CompanyName,
+			Status:      companyProductInfo.Status,
+			Name:        wxUser.RealName,
+			IsSuspend:   companyProductInfo.IsSuspend,
+			Mobile:      wxUser.Mobile,
+		}
+		permissionCheckInfo.CustomerInfo = customerInfo
+
+		// 如果客户FICC产品的状态是流失-申请
+		if companyProductInfo.Status == "流失" {
+			permissionCheckInfo.Type = CheckTypeApply
+			return
+		}
+
+		// 查找对应客户的销售信息
+		adminInfo, tmpErr := admin.GetByAdminId(companyProductInfo.SellerID)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		// 客户状态为冻结/试用暂停-联系销售
+		permissionCheckInfo.Name = adminInfo.RealName
+		permissionCheckInfo.Mobile = adminInfo.Mobile
+		if companyProductInfo.Status == "冻结" || (companyProductInfo.Status == "试用" && companyProductInfo.IsSuspend == 1) {
+			permissionCheckInfo.Type = CheckTypeContact
+			return
+		}
+
+		// 验证用户的沙盘权限
+
+		//获取所有的权限分类列表
+		companyPermissionList, tmpErr := GetValidPermissionByCompany2ProductId(companyId, productId)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+
+		//客户品种权限赋值
+		for _, chartPermission := range companyPermissionList {
+			companyPermissionIdList = append(companyPermissionIdList, chartPermission.ChartPermissionID)
+		}
+		if permissionId > 0 {
+			for _, chartPermission := range companyPermissionList {
+				if chartPermission.ChartPermissionID == permissionId {
+					ok = true
+				}
+			}
+		} else {
+			// 不校验品种权限的话,那么就是认为有权限的
+			if len(companyPermissionList) > 0 {
+				ok = true
+			}
+		}
+
+		// 都不是默认联系销售
+		permissionCheckInfo.Type = CheckTypeContact
+	} else {
+		permissionCheckInfo.Type = CheckTypeApply
+	}
+
+	return
+}

+ 19 - 0
services/page.go

@@ -0,0 +1,19 @@
+package services
+
+import "github.com/gin-gonic/gin"
+
+// GetCurrPageByClaims 从Claims中获取当前页码
+func GetCurrPageByClaims(c *gin.Context) (currPage int) {
+	//获取jwt数据失败
+	claims, _ := c.Get("curr_page")
+	currPage = claims.(int)
+	return
+}
+
+// GetPageSizeByClaims 从Claims中获取当前每页数据量
+func GetPageSizeByClaims(c *gin.Context) (pageSize int) {
+	//获取jwt数据失败
+	claims, _ := c.Get("page_size")
+	pageSize = claims.(int)
+	return
+}

+ 7 - 0
services/report/report.go

@@ -393,6 +393,12 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 		err = errors.New("报告未发布")
 		return
 	}
+	// 判断报告是否属于专栏报告
+	firstClassify, e := classify.GetByClassifyId(reportInfo.ClassifyIdFirst)
+	if e != nil {
+		err = errors.New("报告一级分类有误")
+		return
+	}
 
 	//判断权限
 
@@ -486,6 +492,7 @@ func GetReportDetail(userinfo user.UserInfo, reportId int) (reportDetail respons
 	reportDetail.AuthOk = authOk
 	reportDetail.LikeNum = likeNum
 	reportDetail.LikeEnabled = likeEnabled
+	reportDetail.ReportShowType = int(firstClassify.ShowType)
 	return
 }