Browse Source

用户图表分类

hsun 2 years ago
parent
commit
f55d1243b5

+ 233 - 0
controller/my_chart/my_chart.go

@@ -0,0 +1,233 @@
+package my_chart
+
+import (
+	"fmt"
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/models/request"
+	chartInfoModel "hongze/hongze_yb/models/tables/chart_info"
+	"hongze/hongze_yb/models/tables/yb_config"
+	"hongze/hongze_yb/models/tables/yb_my_chart"
+	userService "hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"strconv"
+	"time"
+)
+
+// MyChartController 用户-我的图表
+type MyChartController struct{}
+
+func (this *MyChartController) List(c *gin.Context) {
+
+}
+
+func (this *MyChartController) Detail(c *gin.Context) {
+
+}
+
+func (this *MyChartController) Collect(c *gin.Context) {
+	var req request.MyChartCollectReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.Authorization == "" {
+		response.Fail("用户身份有误", c)
+		return
+	}
+	if req.UniqueCode == "" {
+		response.Fail("请选择图表", c)
+		return
+	}
+	if req.ReportId <= 0 {
+		response.Fail("请选择报告", c)
+		return
+	}
+
+	// 获取用户信息
+	userInfo, e := userService.GetUserInfoByToken(req.Authorization)
+	if e != nil {
+		response.FailMsg("操作失败", "Token获取有效用户失败, Err: "+e.Error(), c)
+		return
+	}
+	if userInfo.UserID <= 0 {
+		response.FailMsg("操作失败", "Token获取有效用户失败", c)
+		return
+	}
+	userId := int(userInfo.UserID)
+
+	// 获取图表信息
+	chartInfo, e := chartInfoModel.GetChartInfoViewByUniqueCode(req.UniqueCode)
+	if e != nil {
+		response.FailMsg("操作失败", "UniqueCode获取图表信息失败, Err:"+e.Error(), c)
+		return
+	}
+	if chartInfo.ChartInfoId <= 0 {
+		response.FailMsg("操作失败", "图表信息有误", c)
+		return
+	}
+
+	// 图表收藏上限
+	ob := new(yb_my_chart.YbMyChart)
+	countCond := `user_id = ?`
+	countPars := make([]interface{}, 0)
+	countPars = append(countPars, userId)
+	count, e := ob.Count(countCond, countPars)
+	if e != nil {
+		response.FailMsg("操作失败", "获取用户图表收藏数量失败, Err: "+e.Error(), c)
+		return
+	}
+	// 获取图表收藏上限配置
+	configCond := `config_code = ?`
+	configPars := make([]interface{}, 0)
+	configPars = append(configPars, yb_config.UserChartCollectMax)
+	confOB := new(yb_config.YbConfig)
+	conf, e := confOB.Fetch(configCond, configPars)
+	if e != nil {
+		response.FailMsg("操作失败", "获取图表收藏上限配置失败, Err: "+e.Error(), c)
+		return
+	}
+	max, e := strconv.Atoi(conf.ConfigValue)
+	if e != nil {
+		response.FailMsg("操作失败", "图表收藏上限配置有误, Err: "+e.Error(), c)
+		return
+	}
+	if int(count) >= max {
+		response.Fail(fmt.Sprintf("图表最多可收藏%d张", max), c)
+		return
+	}
+
+	// 是否已收藏
+	cond := `user_id = ? AND chart_info_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, userId, chartInfo.ChartInfoId)
+	exists, e := ob.FetchByCondition(cond, pars)
+	if e != nil && e != utils.ErrNoRow {
+		response.FailMsg("操作失败", "获取用户图表失败, Err: "+e.Error(), c)
+		return
+	}
+	nowTime := time.Now().Local()
+	if exists != nil && exists.MyChartID > 0 {
+		// 更新收藏信息
+		exists.ChartName = chartInfo.ChartName
+		exists.ChartImage = chartInfo.ChartImage
+		exists.ReportID = req.ReportId
+		exists.ReportChapterID = req.ReportChapterId
+		exists.ModifyTime = nowTime
+		updateCols := []string{"ChartName", "ChartImage", "ReportID", "ReportChapterID", "ModifyTime"}
+		if e = exists.Update(updateCols); e != nil {
+			response.FailMsg("操作失败", "更新收藏失败, Err: "+e.Error(), c)
+			return
+		}
+	} else {
+		// 新增收藏
+		ob.ChartInfoID = chartInfo.ChartInfoId
+		ob.ChartName = chartInfo.ChartName
+		ob.UniqueCode = chartInfo.UniqueCode
+		ob.ChartImage = chartInfo.ChartImage
+		ob.UserID = userId
+		ob.ReportID = req.ReportId
+		ob.ReportChapterID = req.ReportChapterId
+		ob.CreateTime = nowTime
+		ob.ModifyTime = nowTime
+		if e = ob.Create(); e != nil {
+			response.FailMsg("操作失败", "新增收藏失败, Err: "+e.Error(), c)
+			return
+		}
+	}
+	response.Ok("操作成功", c)
+}
+
+func (this *MyChartController) CollectCancel(c *gin.Context) {
+	var req request.MyChartCollectCancelReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.Authorization == "" {
+		response.Fail("用户身份有误", c)
+		return
+	}
+	if req.UniqueCode == "" {
+		response.Fail("请选择图表", c)
+		return
+	}
+
+	// 获取用户信息
+	userInfo, e := userService.GetUserInfoByToken(req.Authorization)
+	if e != nil {
+		response.FailMsg("操作失败", "Token获取有效用户失败, Err: "+e.Error(), c)
+		return
+	}
+	if userInfo.UserID <= 0 {
+		response.FailMsg("操作失败", "Token获取有效用户失败", c)
+		return
+	}
+	userId := int(userInfo.UserID)
+
+	// 获取图表信息
+	chartInfo, e := chartInfoModel.GetChartInfoViewByUniqueCode(req.UniqueCode)
+	if e != nil {
+		response.FailMsg("操作失败", "UniqueCode获取图表信息失败, Err:"+e.Error(), c)
+		return
+	}
+	if chartInfo.ChartInfoId <= 0 {
+		response.FailMsg("操作失败", "图表信息有误", c)
+		return
+	}
+
+	cond := `user_id = ? AND chart_info_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, userId, chartInfo.ChartInfoId)
+	ob := new(yb_my_chart.YbMyChart)
+	item, e := ob.FetchByCondition(cond, pars)
+	if e != nil {
+		response.FailMsg("操作失败", "获取用户图表失败, Err: "+e.Error(), c)
+		return
+	}
+	if e = item.Delete(); e != nil {
+		response.FailMsg("操作失败", "取消用户图表收藏失败, Err: "+e.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+}
+
+func (this *MyChartController) RelateClassify(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后操作", c)
+		return
+	}
+	var req request.MyChartRelateClassifyReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.ChartInfoId <= 0 {
+		response.Fail("请选择图表", c)
+		return
+	}
+	if req.ClassifyId <= 0 {
+		response.Fail("请选择分类", c)
+		return
+	}
+
+	cond := `user_id = ? AND chart_info_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, userId, req.ChartInfoId)
+	ob := new(yb_my_chart.YbMyChart)
+	item, e := ob.FetchByCondition(cond, pars)
+	if e != nil {
+		response.FailMsg("请先收藏该图表", "获取用户图表失败, Err: "+e.Error(), c)
+		return
+	}
+
+	item.MyChartClassifyID = req.ClassifyId
+	item.ModifyTime = time.Now().Local()
+	if e = item.Update([]string{"MyChartClassifyID", "ModifyTime"}); e != nil {
+		response.FailMsg("操作失败", "更新用户图表关联分类失败, Err: "+e.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+}

+ 234 - 0
controller/my_chart/my_chart_classify.go

@@ -0,0 +1,234 @@
+package my_chart
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/response"
+	"hongze/hongze_yb/models/request"
+	responseModel "hongze/hongze_yb/models/response"
+	"hongze/hongze_yb/models/tables/yb_my_chart"
+	"hongze/hongze_yb/models/tables/yb_my_chart_classify"
+	userService "hongze/hongze_yb/services/user"
+	"hongze/hongze_yb/utils"
+	"time"
+)
+
+// MyChartClassifyController 用户-我的图表分类
+type MyChartClassifyController struct{}
+
+func (this *MyChartClassifyController) List(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后查看", c)
+		return
+	}
+
+	cond := `user_id = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, userId)
+	ob := new(yb_my_chart_classify.YbMyChartClassify)
+	list, e := ob.List(cond, pars)
+	if e != nil {
+		response.FailMsg("获取失败", "获取用户图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	respList := make([]*responseModel.MyChartClassifyItem, 0)
+	for i := range list {
+		respList = append(respList, &responseModel.MyChartClassifyItem{
+			MyChartClassifyID:   list[i].MyChartClassifyID,
+			MyChartClassifyName: list[i].MyChartClassifyName,
+			Sort:                list[i].Sort,
+			UserID:              list[i].UserID,
+			CreateTime:          utils.TimeTransferString(utils.FormatDateTime, list[i].CreateTime),
+		})
+	}
+	response.OkData("获取成功", respList, c)
+}
+
+func (this *MyChartClassifyController) Add(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后操作", c)
+		return
+	}
+	var req request.MyChartClassifyAddReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.ClassifyName == "" {
+		response.Fail("请输入分类名称", c)
+		return
+	}
+	if len([]rune(req.ClassifyName)) > 10 {
+		response.Fail("分类名称不可超过10个字符", c)
+		return
+	}
+
+	cond := `my_chart_classify_name = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.ClassifyName)
+	ob := new(yb_my_chart_classify.YbMyChartClassify)
+	exists, e := ob.FetchByCondition(cond, pars)
+	if e != nil && e != utils.ErrNoRow {
+		response.FailMsg("操作失败", "获取用户同名图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	if exists != nil && exists.MyChartClassifyID > 0 {
+		response.Fail("分类名称已存在", c)
+		return
+	}
+
+	nowTime := time.Now().Local()
+	ob.MyChartClassifyName = req.ClassifyName
+	ob.UserID = userId
+	ob.CreateTime = nowTime
+	ob.ModifyTime = nowTime
+	if e = ob.Create(); e != nil {
+		response.FailMsg("操作失败", "新增用户图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+}
+
+func (this *MyChartClassifyController) Edit(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后操作", c)
+		return
+	}
+	var req request.MyChartClassifyEditReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.ClassifyId <= 0 {
+		response.Fail("请选择分类", c)
+		return
+	}
+	if req.ClassifyName == "" {
+		response.Fail("请输入分类名称", c)
+		return
+	}
+	if len([]rune(req.ClassifyName)) > 10 {
+		response.Fail("分类名称不可超过10个字符", c)
+		return
+	}
+
+	cond := `my_chart_classify_name = ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, req.ClassifyName)
+	ob := new(yb_my_chart_classify.YbMyChartClassify)
+	exists, e := ob.FetchByCondition(cond, pars)
+	if e != nil && e != utils.ErrNoRow {
+		response.FailMsg("操作失败", "获取用户同名图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	if exists != nil && exists.MyChartClassifyID != req.ClassifyId {
+		response.Fail("分类名称已存在", c)
+		return
+	}
+
+	ob.MyChartClassifyName = req.ClassifyName
+	ob.ModifyTime = time.Now().Local()
+	if e = ob.Update([]string{"MyChartClassifyName", "ModifyTime"}); e != nil {
+		response.FailMsg("操作失败", "编辑用户图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+}
+
+func (this *MyChartClassifyController) Del(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后操作", c)
+		return
+	}
+	var req request.MyChartClassifyDelReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if req.ClassifyId <= 0 {
+		response.Fail("请选择分类", c)
+		return
+	}
+
+	ob := new(yb_my_chart_classify.YbMyChartClassify)
+	item, e := ob.Fetch(req.ClassifyId)
+	if e != nil {
+		response.FailMsg("分类不存在或已被删除", "获取用户图表分类失败, Err: "+e.Error(), c)
+		return
+	}
+	if item.UserID != userId {
+		response.Fail("无权操作", c)
+		return
+	}
+	// 是否存在关联图表
+	condRelate := `my_chart_classify_id = ?`
+	parsRelate := make([]interface{}, 0)
+	parsRelate = append(parsRelate, req.ClassifyId)
+	chartOB := new(yb_my_chart.YbMyChart)
+	count, e := chartOB.Count(condRelate, parsRelate)
+	if e != nil {
+		response.FailMsg("操作失败", "获取用户图表分类关联数失败, Err: "+e.Error(), c)
+		return
+	}
+	if count > 0 {
+		response.Fail("删除失败, 该分类下有图表", c)
+		return
+	}
+	if e = ob.Delete(); e != nil {
+		response.FailMsg("操作失败", "删除分类失败, Err: "+e.Error(), c)
+		return
+	}
+	response.Ok("操作成功", c)
+}
+
+func (this *MyChartClassifyController) Sort(c *gin.Context) {
+	userInfo := userService.GetInfoByClaims(c)
+	userId := int(userInfo.UserID)
+	if userId <= 0 {
+		response.Fail("请登录后操作", c)
+		return
+	}
+	var req []request.MyChartClassifySortReq
+	if c.ShouldBind(&req) != nil {
+		response.Fail("参数有误", c)
+		return
+	}
+	if len(req) == 0 {
+		response.Fail("请选择排序分类", c)
+		return
+	}
+	sortMap := make(map[int]int)
+	classifyIds := make([]int, 0)
+	for i := range req {
+		classifyIds = append(classifyIds, req[i].ClassifyId)
+		sortMap[req[i].ClassifyId] = req[i].Sort
+	}
+
+	cond := `my_chart_classify_id IN ?`
+	pars := make([]interface{}, 0)
+	pars = append(pars, classifyIds)
+	ob := new(yb_my_chart_classify.YbMyChartClassify)
+	list, e := ob.List(cond, pars)
+	if e != nil {
+		response.FailMsg("操作失败", "获取用户分类列表失败, Err: "+e.Error(), c)
+		return
+	}
+	nowTime := time.Now().Local()
+	updateCols := []string{"Sort", "ModifyTime"}
+	for i := range list {
+		list[i].Sort = sortMap[list[i].MyChartClassifyID]
+		list[i].ModifyTime = nowTime
+		if e = list[i].Update(updateCols); e != nil {
+			response.FailMsg("操作失败", "更新用户分类排序失败, Err: "+e.Error(), c)
+			return
+		}
+	}
+	response.Ok("操作成功", c)
+}

+ 2 - 0
init_serve/router.go

@@ -77,5 +77,7 @@ func InitRouter() (r *gin.Engine) {
 	routers.InitCollection(r)
 	// 弹幕路由
 	routers.InitBulletChat(r)
+	// 我的图表
+	routers.InitMyChart(r)
 	return
 }

+ 36 - 0
models/request/my_chart.go

@@ -0,0 +1,36 @@
+package request
+
+type MyChartClassifyAddReq struct {
+	ClassifyName string `json:"classify_name"`
+}
+
+type MyChartClassifyEditReq struct {
+	ClassifyId   int    `json:"classify_id"`
+	ClassifyName string `json:"classify_name"`
+}
+
+type MyChartClassifyDelReq struct {
+	ClassifyId int `json:"classify_id"`
+}
+
+type MyChartClassifySortReq struct {
+	ClassifyId int `json:"classify_id"`
+	Sort       int `json:"sort"`
+}
+
+type MyChartRelateClassifyReq struct {
+	ChartInfoId int `json:"chart_info_id"`
+	ClassifyId  int `json:"classify_id"`
+}
+
+type MyChartCollectReq struct {
+	Authorization   string `json:"authorization" form:"authorization"`
+	UniqueCode      string `json:"unique_code" form:"unique_code"`
+	ReportId        int    `json:"report_id" form:"report_id"`
+	ReportChapterId int    `json:"report_chapter_id" form:"report_chapter_id"`
+}
+
+type MyChartCollectCancelReq struct {
+	Authorization string `json:"authorization" form:"authorization"`
+	UniqueCode    string `json:"unique_code" form:"unique_code"`
+}

+ 10 - 0
models/response/my_chart.go

@@ -0,0 +1,10 @@
+package response
+
+// MyChartClassifyItem 用户图表分类
+type MyChartClassifyItem struct {
+	MyChartClassifyID   int    `json:"my_chart_classify_id"`
+	MyChartClassifyName string `json:"my_chart_classify_name"`
+	Sort                int    `json:"sort"`
+	UserID              int    `json:"user_id"`
+	CreateTime          string `json:"create_time"`
+}

+ 7 - 0
models/tables/chart_info/query.go

@@ -100,3 +100,10 @@ func GetChartInfoById(chartInfoId int) (item *ChartInfo, err error) {
 	err = global.MYSQL["data"].Model(ChartInfo{}).Where("chart_info_id = ?", chartInfoId).First(&item).Error
 	return
 }
+
+// GetChartInfoViewByUniqueCode 通过唯一编码获取图表展示信息
+func GetChartInfoViewByUniqueCode(uniqueCode string) (item *ChartInfoView, err error) {
+	sql := `SELECT * FROM chart_info WHERE unique_code = ? LIMIT 1`
+	err = global.MYSQL["data"].Raw(sql, uniqueCode).First(&item).Error
+	return
+}

+ 1 - 1
models/tables/rddp/session/session.go

@@ -4,7 +4,7 @@ import "time"
 
 // Session [...]
 type Session struct {
-	SessionID       int64     `gorm:"primaryKey;column:session_id;type:bigint(12);not null" json:"-"`
+	SessionID       int64     `gorm:"primaryKey;column:session_id;type:bigint(12);not null" json:"sessionId"`
 	UserID          int64     `gorm:"index:session_user;column:user_id;type:bigint(20);not null" json:"userId"`
 	OpenID          string    `gorm:"column:open_id;type:varchar(32);not null" json:"openId"` // openid
 	AccessToken     string    `gorm:"index:session_token;column:access_token;type:varchar(64);not null" json:"accessToken"`

+ 4 - 0
models/tables/yb_config/entity.go

@@ -15,3 +15,7 @@ type YbConfig struct {
 func (m *YbConfig) TableName() string {
 	return "yb_config"
 }
+
+const (
+	UserChartCollectMax = "user_chart_collect_max" // 用户图表收藏上限
+)

+ 53 - 0
models/tables/yb_my_chart/entity.go

@@ -0,0 +1,53 @@
+package yb_my_chart
+
+import "time"
+
+// YbMyChart 研报-我的图表
+type YbMyChart struct {
+	MyChartID         int       `gorm:"primaryKey;column:my_chart_id;type:int(10) unsigned;not null" json:"-"`
+	MyChartClassifyID int       `gorm:"index:idx_classify_id;column:my_chart_classify_id;type:int(10) unsigned;not null;default:0" json:"myChartClassifyId"` // 图表分类ID
+	ChartInfoID       int       `gorm:"column:chart_info_id;type:int(10) unsigned;not null;default:0" json:"chartInfoId"`                                    // 图表ID
+	ChartName         string    `gorm:"column:chart_name;type:varchar(255);not null;default:''" json:"chartName"`                                            // 图表名称
+	UniqueCode        string    `gorm:"column:unique_code;type:varchar(64);not null;default:''" json:"uniqueCode"`                                           // 图表唯一编码
+	ChartImage        string    `gorm:"column:chart_image;type:varchar(255);not null;default:''" json:"chartImage"`                                          // 图表图片
+	UserID            int       `gorm:"index:idx_user_id;column:user_id;type:int(10) unsigned;not null;default:0" json:"userId"`                             // 用户ID
+	ReportID          int       `gorm:"column:report_id;type:int(10) unsigned;not null;default:0" json:"reportId"`                                           // 报告ID(从哪个报告收藏的)
+	ReportChapterID   int       `gorm:"column:report_chapter_id;type:int(10) unsigned;not null;default:0" json:"reportChapterId"`                            // 报告章节ID
+	Source            int       `gorm:"column:source;type:tinyint(4) unsigned;not null;default:1" json:"source"`                                             // 1-ETA图库;2-ETA表格
+	CreateTime        time.Time `gorm:"column:create_time;type:datetime" json:"createTime"`
+	ModifyTime        time.Time `gorm:"column:modify_time;type:datetime" json:"modifyTime"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *YbMyChart) TableName() string {
+	return "yb_my_chart"
+}
+
+// YbMyChartColumns get sql column name.获取数据库列名
+var YbMyChartColumns = struct {
+	MyChartID         string
+	MyChartClassifyID string
+	ChartInfoID       string
+	ChartName         string
+	UniqueCode        string
+	ChartImage        string
+	UserID            string
+	ReportID          string
+	ReportChapterID   string
+	Source            string
+	CreateTime        string
+	ModifyTime        string
+}{
+	MyChartID:         "my_chart_id",
+	MyChartClassifyID: "my_chart_classify_id",
+	ChartInfoID:       "chart_info_id",
+	ChartName:         "chart_name",
+	UniqueCode:        "unique_code",
+	ChartImage:        "chart_image",
+	UserID:            "user_id",
+	ReportID:          "report_id",
+	ReportChapterID:   "report_chapter_id",
+	Source:            "source",
+	CreateTime:        "create_time",
+	ModifyTime:        "modify_time",
+}

+ 46 - 0
models/tables/yb_my_chart/model.go

@@ -0,0 +1,46 @@
+package yb_my_chart
+
+import "hongze/hongze_yb/global"
+
+func (m *YbMyChart) Count(condition string, pars []interface{}) (num int64, err error) {
+	err = global.DEFAULT_MYSQL.Model(m).
+		Where(condition, pars...).
+		Count(&num).Error
+	return
+}
+
+func (m *YbMyChart) Create() (err error) {
+	err = global.DEFAULT_MYSQL.Create(m).Error
+	return
+}
+
+func (m *YbMyChart) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(m).Select(updateCols).Updates(m).Error
+	return
+}
+
+func (m *YbMyChart) List(condition string, pars []interface{}) (list []*YbMyChart, err error) {
+	list = make([]*YbMyChart, 0)
+	err = global.DEFAULT_MYSQL.Model(m).
+		Where(condition, pars...).
+		Order("sort ASC, my_chart_classify_id ASC").
+		Find(&list).Error
+	return
+}
+
+func (m *YbMyChart) Fetch(id int) (item *YbMyChart, err error) {
+	err = global.DEFAULT_MYSQL.Model(m).Where("my_chart_id = ?", id).First(&item).Error
+	return
+}
+
+func (m *YbMyChart) FetchByCondition(condition string, pars []interface{}) (item *YbMyChart, err error) {
+	err = global.DEFAULT_MYSQL.Model(m).
+		Where(condition, pars...).
+		First(&item).Error
+	return
+}
+
+func (m *YbMyChart) Delete() (err error) {
+	err = global.DEFAULT_MYSQL.Delete(m).Error
+	return
+}

+ 35 - 0
models/tables/yb_my_chart_classify/entity.go

@@ -0,0 +1,35 @@
+package yb_my_chart_classify
+
+import "time"
+
+// YbMyChartClassify 研报-我的图表分类
+type YbMyChartClassify struct {
+	MyChartClassifyID   int       `gorm:"primaryKey;column:my_chart_classify_id;type:int(10) unsigned;not null" json:"my_chart_classify_id"`
+	MyChartClassifyName string    `gorm:"column:my_chart_classify_name;type:varchar(255);not null;default:''" json:"my_chart_classify_name"` // 分类名称
+	UserID              int       `gorm:"index:idx_user_id;column:user_id;type:int(10) unsigned;not null;default:0" json:"user_id"`          // 用户ID
+	Sort                int       `gorm:"column:sort;type:int(10) unsigned;not null;default:0" json:"sort"`                                  // 排序
+	CreateTime          time.Time `gorm:"column:create_time;type:datetime" json:"create_time"`
+	ModifyTime          time.Time `gorm:"column:modify_time;type:datetime" json:"modify_time"`
+}
+
+// TableName get sql table name.获取数据库表名
+func (m *YbMyChartClassify) TableName() string {
+	return "yb_my_chart_classify"
+}
+
+// YbMyChartClassifyColumns get sql column name.获取数据库列名
+var YbMyChartClassifyColumns = struct {
+	MyChartClassifyID   string
+	MyChartClassifyName string
+	UserID              string
+	Sort                string
+	CreateTime          string
+	ModifyTime          string
+}{
+	MyChartClassifyID:   "my_chart_classify_id",
+	MyChartClassifyName: "my_chart_classify_name",
+	UserID:              "user_id",
+	Sort:                "sort",
+	CreateTime:          "create_time",
+	ModifyTime:          "modify_time",
+}

+ 39 - 0
models/tables/yb_my_chart_classify/model.go

@@ -0,0 +1,39 @@
+package yb_my_chart_classify
+
+import "hongze/hongze_yb/global"
+
+func (m *YbMyChartClassify) Create() (err error) {
+	err = global.DEFAULT_MYSQL.Create(m).Error
+	return
+}
+
+func (m *YbMyChartClassify) Update(updateCols []string) (err error) {
+	err = global.DEFAULT_MYSQL.Model(m).Select(updateCols).Updates(m).Error
+	return
+}
+
+func (m *YbMyChartClassify) List(condition string, pars []interface{}) (list []*YbMyChartClassify, err error) {
+	list = make([]*YbMyChartClassify, 0)
+	err = global.DEFAULT_MYSQL.Model(m).
+		Where(condition, pars...).
+		Order("sort ASC, my_chart_classify_id ASC").
+		Find(&list).Error
+	return
+}
+
+func (m *YbMyChartClassify) Fetch(id int) (item *YbMyChartClassify, err error) {
+	err = global.DEFAULT_MYSQL.Model(m).Where("my_chart_classify_id = ?", id).First(&item).Error
+	return
+}
+
+func (m *YbMyChartClassify) FetchByCondition(condition string, pars []interface{}) (item *YbMyChartClassify, err error) {
+	err = global.DEFAULT_MYSQL.Model(m).
+		Where(condition, pars...).
+		First(&item).Error
+	return
+}
+
+func (m *YbMyChartClassify) Delete() (err error) {
+	err = global.DEFAULT_MYSQL.Delete(m).Error
+	return
+}

+ 31 - 0
routers/my_chart.go

@@ -0,0 +1,31 @@
+package routers
+
+import (
+	"github.com/gin-gonic/gin"
+	"hongze/hongze_yb/controller/my_chart"
+	"hongze/hongze_yb/middleware"
+)
+
+func InitMyChart(r *gin.Engine) {
+	rg := r.Group("api/")
+	// 图表分类
+	mcc := new(my_chart.MyChartClassifyController)
+	mccGroup := rg.Group("my_chart_classify/").Use(middleware.Token())
+	mccGroup.GET("list", mcc.List)
+	mccGroup.POST("add", mcc.Add)
+	mccGroup.POST("edit", mcc.Edit)
+	mccGroup.POST("sort", mcc.Sort)
+	mccGroup.POST("del", mcc.Del)
+
+	// 我的图表
+	mc := new(my_chart.MyChartController)
+	mcGroup := rg.Group("my_chart/").Use(middleware.Token())
+	mcGroup.GET("list", mc.List)
+	mcGroup.GET("detail", mc.Detail)
+	mcGroup.POST("relate_classify", mc.RelateClassify)
+
+	// 这两个接口因为可能是从iframe发出请求, 所以token被放在入参中处理而不是header里
+	mcGroupNo := rg.Group("my_chart/")
+	mcGroupNo.POST("collect", mc.Collect)
+	mcGroupNo.POST("collect_cancel", mc.CollectCancel)
+}

+ 30 - 0
services/user/user.go

@@ -478,3 +478,33 @@ func GetResearcherByUserInfo(userInfo UserInfo) (ok bool, adminInfo *admin2.Admi
 
 	return
 }
+
+// GetUserInfoByToken 通过token获取用户信息
+func GetUserInfoByToken(token string) (userInfo UserInfo, err error) {
+	sessionInfo, e := session.GetTokenByToken(token)
+	if e != nil {
+		err = errors.New("找不到对应session")
+		return
+	}
+	if sessionInfo.SessionID <= 0 {
+		err = errors.New("找不到对应session")
+		return
+	}
+	if sessionInfo.OpenID != "" {
+		u, e := GetWxUserItemByOpenId(sessionInfo.OpenID)
+		if e != nil {
+			err = errors.New("用户记录不存在或未绑定")
+			return
+		}
+		userInfo = u
+	} else {
+		// PC端
+		u, e := GetWxUserItemByUserId(int(sessionInfo.UserID), utils.USER_RECORD_PLATFORM_PC)
+		if e != nil {
+			err = errors.New("用户PC记录不存在或未绑定")
+			return
+		}
+		userInfo = u
+	}
+	return
+}

+ 9 - 0
utils/common.go

@@ -1024,3 +1024,12 @@ func JoinStr2IntArr(str, sep string) (arr []int) {
 	}
 	return
 }
+
+func TimeTransferString(format string, t time.Time) string {
+	str := t.Format(format)
+	var emptyT time.Time
+	if str == emptyT.Format(format) {
+		return ""
+	}
+	return str
+}