Browse Source

feat:添加pdf版研报的新增和列表筛选

zqbao 8 tháng trước cách đây
mục cha
commit
6eddcf82ed

+ 279 - 5
controllers/report_pdf.go

@@ -2,6 +2,15 @@ package controllers
 
 import (
 	"eta/eta_mini_crm/models"
+	"eta/eta_mini_crm/models/response"
+	"eta/eta_mini_crm/services"
+	"eta/eta_mini_crm/utils"
+	"os"
+	"path"
+	"strings"
+	"time"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
 )
 
 type ReportPdfController struct {
@@ -32,16 +41,281 @@ func (this *ReportPdfController) Author() {
 	br.Data = items
 }
 
-// Author
-// @Title 获取报告作者接口
-// @Description 获取报告作者
+// Add
+// @Title 添加研报
+// @Description 添加研报
+// @Param   File   query   file  true       "文件"
+// @Param   Title   query   string  true       "标题"
+// @Param   Author   query   string  true       "作者名称"
+// @Param   Abstract   query   string  true       "摘要"
+// @Param   ClassifyIdFirst   query   int  true       "一级分类id"
+// @Param   ClassifyIdSecond   query   int  true       "二级分类id"
 // @Success 200 {object} models.ReportAuthorResp
-// @router /uploadPdf [get]
-func (this *ReportPdfController) UploadPdf() {
+// @router /add [post]
+func (this *ReportPdfController) Add() {
 	br := new(models.BaseResponse).Init()
 	defer func() {
 		this.Data["json"] = br
 		this.ServeJSON()
 	}()
 
+	f, h, err := this.GetFile("File")
+	if err != nil {
+		br.Msg = "获取资源信息失败"
+		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
+		return
+	}
+	defer f.Close()
+	author := this.GetString("Author")
+	abstract := this.GetString("Abstract")
+	classifyIdFirst, _ := this.GetInt("ClassifyIdFirst")
+	classifyIdSecond, _ := this.GetInt("ClassifyIdSecond")
+	title := this.GetString("Title")
+	if classifyIdFirst <= 0 {
+		br.Msg = "请选择研报所属的一级分类"
+		return
+	}
+	if classifyIdSecond <= 0 {
+		br.Msg = "请选择研报所属的二级分类"
+		return
+	}
+
+	ext := path.Ext(h.Filename)
+	dateDir := time.Now().Format("20060102")
+	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
+	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
+	if err != nil {
+		br.Msg = "存储目录创建失败"
+		br.ErrMsg = "存储目录创建失败,Err:" + err.Error()
+		return
+	}
+	randStr := utils.GetRandStringNoSpecialChar(28)
+	fileName := randStr + ext
+	fpath := uploadDir + "/" + fileName
+	defer f.Close() //关闭上传文件
+	err = this.SaveToFile("file", fpath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+	pdfUploadDir := "pdf/"
+	savePdfToOssPath := pdfUploadDir + time.Now().Format("200601/20060102/")
+	pptName := utils.GetRandStringNoSpecialChar(28)
+	savePdfToOssPath += pptName + ".pdf"
+
+	defer func() {
+		_ = os.Remove(fpath)
+	}()
+
+	ossClient := services.NewOssClient()
+	if ossClient == nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "初始化OSS服务失败"
+		return
+	}
+	pdfUrl, err := ossClient.UploadFile("", fpath, savePdfToOssPath)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "文件上传失败,Err:" + err.Error()
+		return
+	}
+
+	nameFirst, err := models.GetClassifyById(classifyIdFirst)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "一级类名获取失败,Err:" + err.Error()
+		return
+	}
+	nameSecond, err := models.GetClassifyById(classifyIdSecond)
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "二级类名获取失败,Err:" + err.Error()
+		return
+	}
+
+	pdf := &models.ReportPdf{
+		PdfUrl:             pdfUrl,
+		Title:              title,
+		Author:             author,
+		Abstract:           abstract,
+		ClassifyIdFirst:    classifyIdFirst,
+		ClassifyNameFirst:  nameFirst.ClassifyName,
+		ClassifyIdSecond:   classifyIdSecond,
+		ClassifyNameSecond: nameSecond.ClassifyName,
+		PublishTime:        time.Now(),
+		ModifyTime:         time.Now(),
+		SysUserId:          this.SysUser.SysUserId,
+		SysRealName:        this.SysUser.SysRealName,
+		State:              utils.ReportStatusUp,
+	}
+	err = pdf.Add()
+	if err != nil {
+		br.Msg = "文件上传失败"
+		br.ErrMsg = "pdf研报新增失败,Err:" + err.Error()
+		return
+	}
+
+	br.Msg = "上传成功"
+	br.Ret = 200
+	br.Success = true
+}
+
+// List
+// @Title pdf研报列表
+// @Description pdf研报列表
+// @Param   PageSize   query   int  true       "每页数据条数"
+// @Param   CurrentIndex   query   int  true       "当前页页码,从1开始"
+// @Param   ClassifyIds   query   string  true       "二级分类id,可多选用英文,隔开"
+// @Param   State   query   int  true       "研报状态, 1:已发布 2:未发布"
+// @Param   PublishStartDate   query   string  true       "发布开始时间"
+// @Param   PublishEndDate   query   string  true       "发布结束时间"
+// @Param   ModifyStartDate   query   string  true       "更新开始时间"
+// @Param   ModifyEndDate   query   string  true       "更新结束时间"
+// @Param   KeyWord   query   string  true       "报告标题/创建人"
+// @Param   SortParam   query   string  true       "排序字段"
+// @Param   SortType   query   string  true       "排序方式"
+// @Success 200 {object} models.ReportAuthorResp
+// @router /list [get]
+func (this *ReportPdfController) List() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	pageSize, _ := this.GetInt("PageSize")
+	currentIndex, _ := this.GetInt("CurrentIndex")
+	classifyIds := this.GetString("ClassifyIds")
+	state, _ := this.GetInt("State")
+	publishStartDate := this.GetString("PublishStartDate")
+	publishEndDate := this.GetString("PublishEndDate")
+	modifyStartDate := this.GetString("ModifyStartDate")
+	modifyEndDate := this.GetString("ModifyEndDate")
+	keyWord := this.GetString("KeyWord")
+	sortParam := this.GetString("SortParam")
+	sortType := this.GetString("SortType")
+
+	var condition string
+	var pars []interface{}
+
+	if pageSize <= 0 {
+		pageSize = utils.PageSize20
+	}
+	if currentIndex <= 0 {
+		currentIndex = 1
+	}
+	if classifyIds != "" {
+		classifyArr := strings.Split(classifyIds, ",")
+		condition += " AND classify_id_second in (" + utils.GetOrmReplaceHolder(len(classifyArr)) + ")"
+		pars = append(pars, classifyArr)
+	}
+
+	switch state {
+	case utils.ReportStatusUp:
+		condition += " AND state = ?"
+		pars = append(pars, state)
+	case utils.ReportStatusDown:
+		condition += " AND state = ?"
+		pars = append(pars, state)
+	}
+
+	if publishStartDate != "" && publishEndDate != "" {
+		condition += " AND publish_time >= ?"
+		publishStartTime, err := time.Parse(utils.FormatDate, publishStartDate)
+		if err != nil {
+			br.Msg = "日期格式有误"
+			br.ErrMsg = "日期格式有误,Err:" + err.Error()
+			return
+		}
+		publishStartDateStr := publishStartTime.Format(utils.FormatDateTime)
+		pars = append(pars, publishStartDateStr)
+
+		condition += " AND publish_time <= ?"
+		publishEndTime, err := time.Parse(utils.FormatDate, publishEndDate)
+		if err != nil {
+			br.Msg = "日期格式有误"
+			br.ErrMsg = "日期格式有误,Err:" + err.Error()
+			return
+		}
+		publishEndTime = publishEndTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
+		publishEndDateStr := publishEndTime.Format(utils.FormatDateTime)
+		pars = append(pars, publishEndDateStr)
+	}
+	if modifyStartDate != "" && modifyEndDate != "" {
+		condition += " AND modify_time >= ?"
+		modifyStartTime, err := time.Parse(utils.FormatDate, modifyStartDate)
+		if err != nil {
+			br.Msg = "日期格式有误"
+			br.ErrMsg = "日期格式有误,Err:" + err.Error()
+			return
+		}
+		modifyStartDateStr := modifyStartTime.Format(utils.FormatDateTime)
+		pars = append(pars, modifyStartDateStr)
+
+		condition += " AND modify_time <= ?"
+		modifyEndTime, err := time.Parse(utils.FormatDate, modifyEndDate)
+		if err != nil {
+			br.Msg = "日期格式有误"
+			br.ErrMsg = "日期格式有误,Err:" + err.Error()
+			return
+		}
+		modifyEndTime = modifyEndTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second)
+		modifyEndDateStr := modifyEndTime.Format(utils.FormatDateTime)
+		pars = append(pars, modifyEndDateStr)
+	}
+	if keyWord != "" {
+		condition += ` AND (title like ? OR sys_real_name like ?) `
+		pars = utils.GetLikeKeywordPars(pars, keyWord, 2)
+	}
+	var sortCondition string
+	if sortParam != "" && sortType != "" {
+		sortCondition = " ORDER BY "
+		var param, sort string
+		switch sortParam {
+		case "PublishTime":
+			param = "publish_time"
+		case "ModifyTime":
+			param = "modify_time"
+		}
+		switch sortType {
+		case "asc":
+			sort = " ASC "
+		case "desc":
+			sort = " DESC "
+		}
+		if param != "" && sort != "" {
+			sortCondition += param + " " + sort
+		} else {
+			sortCondition = ""
+		}
+	}
+	if sortCondition == "" {
+		sortCondition = ` ORDER BY modify_time DESC `
+	}
+
+	total, err := models.GetReportPdfCountByCondition(condition, pars)
+	if err != nil {
+		br.Msg = "获取研报列表失败"
+		br.ErrMsg = "获取研报列表统计失败,Err:" + err.Error()
+		return
+	}
+
+	startSize := utils.StartIndex(currentIndex, pageSize)
+	reportList, err := models.GetReportPdfByCondition(condition, sortCondition, pars, startSize, pageSize)
+	if err != nil {
+		br.Msg = "获取研报列表失败"
+		br.ErrMsg = "获取研报列表失败,Err:" + err.Error()
+		return
+	}
+
+	page := paging.GetPaging(currentIndex, pageSize, total)
+	resp := new(response.ReportPdfListResp)
+	resp.List = reportList
+	resp.Paging = page
+
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	br.Msg = "获取成功"
 }

+ 3 - 3
controllers/user_read_record.go

@@ -52,7 +52,7 @@ func (this *UserReadRecordController) List() {
 	registerEndDate := this.GetString("RegisterEndDate")
 	createStartDate := this.GetString("CreateStartDate")
 	createEndDate := this.GetString("CreateEndDate")
-	sortParma := this.GetString("SortParam")
+	sortParam := this.GetString("SortParam")
 	sortType := this.GetString("SortType")
 
 	var condition string
@@ -89,10 +89,10 @@ func (this *UserReadRecordController) List() {
 			condition += `) `
 		}
 	}
-	if sortParma != "" && sortType != "" {
+	if sortParam != "" && sortType != "" {
 		sortCondition = " ORDER BY "
 		var param, sort string
-		switch sortParma {
+		switch sortParam {
 		case "LastUpdateTime":
 			param = "last_update_time"
 		case "ReadCnt":

+ 7 - 0
models/classify.go

@@ -35,3 +35,10 @@ func GetClassifyList() (items []*ClassifyView, err error) {
 	_, err = o.Raw(sql).QueryRows(&items)
 	return
 }
+
+func GetClassifyById(classifyId int) (item *ClassifyView, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM classify WHERE enabled=1 AND classify_id=?`
+	err = o.Raw(sql, classifyId).QueryRow(&item)
+	return
+}

+ 1 - 0
models/db.go

@@ -39,5 +39,6 @@ func init() {
 		new(SysMessageReport),
 		new(CrmConfig),
 		new(UserChangeRecord),
+		new(ReportPdf),
 	)
 }

+ 63 - 0
models/report_pdf.go

@@ -0,0 +1,63 @@
+package models
+
+import (
+	"time"
+
+	"github.com/beego/beego/v2/client/orm"
+)
+
+type ReportPdf struct {
+	ReportPdfId        int       `orm:"pk" description:"id"`
+	PdfUrl             string    `description:"pdf文件URL"`
+	Title              string    `description:"pdf文件标题"`
+	Author             string    `description:"作者"`
+	Abstract           string    `description:"摘要"`
+	ClassifyIdFirst    int       `description:"一级分类id"`
+	ClassifyNameFirst  string    `description:"一级分类名称"`
+	ClassifyIdSecond   int       `description:"二级分类id"`
+	ClassifyNameSecond string    `description:"二级分类名称"`
+	Stage              int       `description:"期数"`
+	PublishTime        time.Time `description:"发布时间"`
+	ModifyTime         time.Time `description:"更新时间"`
+	Pv                 int       `description:"pv"`
+	Uv                 int       `description:"uv"`
+	SysUserId          int       `description:"创建人id"`
+	SysRealName        string    `description:"创建人姓名"`
+	State              int       `description:"状态"`
+}
+
+func (r *ReportPdf) Add() (err error) {
+	o := orm.NewOrm()
+	// 计算研报期数
+	sql := `SELECT COUNT(*) + 1 AS count FROM report_pdf WHERE classify_id_second=?`
+	err = o.Raw(sql, r.ClassifyIdSecond).QueryRow(&r.State)
+	if err != nil {
+		return
+	}
+	_, err = o.Insert(r)
+	return
+}
+
+func GetReportPdfCountByCondition(condition string, pars []interface{}) (count int, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT COUNT(*) AS count FROM report_pdf WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	err = o.Raw(sql, pars).QueryRow(&count)
+	return
+}
+
+func GetReportPdfByCondition(condition, sortCondition string, pars []interface{}, startPage, pageSize int) (items []*ReportPdf, err error) {
+	o := orm.NewOrm()
+	sql := `SELECT * FROM report_pdf WHERE 1=1 `
+	if condition != "" {
+		sql += condition
+	}
+	if sortCondition != "" {
+		sql += sortCondition // 排序
+	}
+	sql += ` LIMIT ?,?`
+	_, err = o.Raw(sql, pars, startPage, pageSize).QueryRows(&items)
+	return
+}

+ 12 - 0
models/response/report_pdf.go

@@ -0,0 +1,12 @@
+package response
+
+import (
+	"eta/eta_mini_crm/models"
+
+	"github.com/rdlucklib/rdluck_tools/paging"
+)
+
+type ReportPdfListResp struct {
+	List   []*models.ReportPdf
+	Paging *paging.PagingItem `description:"分页数据"`
+}

+ 27 - 0
utils/common.go

@@ -3,10 +3,16 @@ package utils
 import (
 	"crypto/md5"
 	"encoding/hex"
+	"math/rand"
 	"regexp"
 	"strconv"
+	"strings"
+	"time"
 )
 
+// 随机种子
+var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
+
 func MD5(data string) string {
 	m := md5.Sum([]byte(data))
 	return hex.EncodeToString(m[:])
@@ -69,3 +75,24 @@ func StringsToJSON(str string) string {
 func ErrNoRow() string {
 	return "<QuerySeter> no row found"
 }
+
+func GetRandStringNoSpecialChar(size int) string {
+	allLetterDigit := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"}
+	randomSb := ""
+	digitSize := len(allLetterDigit)
+	for i := 0; i < size; i++ {
+		randomSb += allLetterDigit[rnd.Intn(digitSize)]
+	}
+	return randomSb
+}
+
+func GetOrmReplaceHolder(num int) string {
+	var stringBuffer strings.Builder
+	for i := 0; i < num; i++ {
+		stringBuffer.WriteString("?")
+		if i != num-1 {
+			stringBuffer.WriteString(",")
+		}
+	}
+	return stringBuffer.String()
+}

+ 11 - 0
utils/config.go

@@ -39,6 +39,11 @@ var (
 	STSTokenCacheKey   string
 )
 
+// 基础配置
+var (
+	STATIC_DIR string
+)
+
 var (
 	LogPath    string //调用过程中的日志存放地址
 	LogFile    string
@@ -106,6 +111,12 @@ func init() {
 		STSTokenCacheKey = config["sts_token_cache_key"]
 	}
 
+	// 静态文件目录
+	STATIC_DIR = config["static_dir"]
+	if STATIC_DIR == "" {
+		STATIC_DIR = "./static"
+	}
+
 	// 初始化缓存
 	redisClient, err := initRedis(config["redis_type"], config["beego_cache"])
 	if err != nil {

+ 11 - 0
utils/constants.go

@@ -1,5 +1,7 @@
 package utils
 
+import "io/fs"
+
 const (
 	UserLoginSalt = "MiQM9YUdf89T2uIH"         // 用户登录盐值
 	DesKeySalt    = "MxuqSoUrTAmyRd9fb0TtlrPk" // DesKey盐值
@@ -42,6 +44,9 @@ const (
 	MaxDepartmentLevel         = 3
 )
 
+// DIR_MOD 目录创建权限
+const DIR_MOD fs.FileMode = 0766 // Unix permission bits
+
 // 用户状态定义
 const (
 	UserStatusNo        = 0 //禁用
@@ -49,6 +54,12 @@ const (
 	UserStatusFormal    = 2 //正式用户
 )
 
+// Pdf研报状态定义
+const (
+	ReportStatusUp   = 1 // 研报已发布
+	ReportStatusDown = 2 // 研报未发布
+)
+
 // 免验证接口
 var NoAuthApiMap = map[string]bool{
 	"/role/menu/buttons":      true,