Browse Source

智能研报额外内容

hsun 1 year ago
parent
commit
78fc013900

+ 179 - 11
controllers/smart_report/smart_report.go

@@ -10,8 +10,12 @@ import (
 	smartReportService "eta/eta_api/services/smart_report"
 	"eta/eta_api/utils"
 	"fmt"
+	"github.com/kgiannakakis/mp3duration/src/mp3duration"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"html"
+	"io/ioutil"
+	"os"
+	"path"
 	"strings"
 	"time"
 )
@@ -86,6 +90,8 @@ func (this *SmartReportController) Add() {
 	item.Stage = stageMax
 	item.AdminId = sysUser.AdminId
 	item.AdminRealName = sysUser.RealName
+	item.LastModifyAdminId = sysUser.AdminId
+	item.LastModifyAdminName = sysUser.AdminName
 	item.CreateTime = time.Now().Local()
 	item.ModifyTime = time.Now().Local()
 	if e = item.Create(); e != nil {
@@ -176,7 +182,23 @@ func (this *SmartReportController) Edit() {
 		br.ErrMsg = "获取研报失败, Err: " + e.Error()
 		return
 	}
+	if item.State == 2 {
+		br.Msg = "报告已发布, 请取消发布后编辑"
+		return
+	}
 
+	// 内容是否变更, 只有内容产生变更时, 才更新最后更新人和内容更新时间字段
+	contentModify := false
+	if item.ClassifyIdFirst != req.ClassifyIdFirst ||
+		item.ClassifyIdSecond != req.ClassifyIdSecond ||
+		item.Title != req.Title ||
+		item.Abstract != req.Abstract ||
+		item.Frequency != req.Frequency ||
+		utils.MD5(item.Content) != utils.MD5(req.Content) {
+		contentModify = true
+	}
+	cols := []string{"ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond", "Title", "Abstract", "Author",
+		"Frequency", "Content", "ContentSub", "ContentStruct", "ModifyTime"}
 	item.ClassifyIdFirst = req.ClassifyIdFirst
 	item.ClassifyNameFirst = req.ClassifyNameFirst
 	item.ClassifyIdSecond = req.ClassifyIdSecond
@@ -189,8 +211,13 @@ func (this *SmartReportController) Edit() {
 	item.ContentSub = subContent
 	item.ContentStruct = req.ContentStruct
 	item.ModifyTime = time.Now().Local()
-	cols := []string{"ClassifyIdFirst", "ClassifyNameFirst", "ClassifyIdSecond", "ClassifyNameSecond", "Title", "Abstract", "Author",
-		"Frequency", "Content", "ContentSub", "ContentStruct", "ModifyTime"}
+	if contentModify {
+		fmt.Println(contentModify)
+		item.LastModifyAdminId = sysUser.AdminId
+		item.LastModifyAdminName = sysUser.AdminName
+		item.ContentModifyTime = time.Now().Local()
+		cols = append(cols, "LastModifyAdminId", "LastModifyAdminName", "ContentModifyTime")
+	}
 	if e := item.Update(cols); e != nil {
 		br.Msg = "操作失败"
 		br.ErrMsg = "更新报告失败, Err: " + e.Error()
@@ -373,6 +400,12 @@ func (this *SmartReportController) Publish() {
 	if req.PublishState == 2 {
 		cols = append(cols, "PublishTime")
 		item.PublishTime = time.Now().Local()
+
+		// 写入队列
+		var queue smart_report.Report2ImgQueueReq
+		queue.ReportType = 2
+		queue.ReportCode = item.ReportCode
+		_ = utils.Rc.LPush(utils.CACHE_CREATE_REPORT_IMGPDF_QUEUE, queue)
 	}
 	// 取消发布时同时清除掉Img和PDF的文件地址
 	if req.PublishState == 1 {
@@ -665,8 +698,11 @@ func (this *SmartReportController) SaveContent() {
 		item.Content = req.Content
 		item.ContentSub = subContent
 		item.ContentStruct = req.ContentStruct
+		item.ContentModifyTime = time.Now().Local()
+		item.LastModifyAdminId = sysUser.AdminId
+		item.LastModifyAdminName = sysUser.AdminName
 		item.ModifyTime = time.Now().Local()
-		cols := []string{"Content", "ContentSub", "ContentStruct", "ModifyTime"}
+		cols := []string{"Content", "ContentSub", "ContentStruct", "ContentModifyTime", "LastModifyAdminId", "LastModifyAdminName", "ModifyTime"}
 		if e = item.Update(cols); e != nil {
 			br.Msg = "操作失败"
 			br.ErrMsg = "更新报告内容失败"
@@ -819,8 +855,8 @@ func (this *SmartReportController) List() {
 		keyword := strings.TrimSpace(params.Keyword)
 		if keyword != "" {
 			kw := fmt.Sprint("%", keyword, "%")
-			condition += fmt.Sprintf(` AND (title LIKE ? OR admin_real_name LIKE ?)`)
-			pars = append(pars, kw, kw)
+			condition += fmt.Sprintf(` AND (title LIKE ? OR admin_real_name LIKE ? OR last_modify_admin_name LIKE ?)`)
+			pars = append(pars, kw, kw, kw)
 		}
 		if params.StartDate != "" && params.EndDate != "" {
 			condition += fmt.Sprintf(` AND %s >= ? AND %s <= ?`, params.TimeType, params.TimeType)
@@ -877,6 +913,7 @@ func (this *SmartReportController) List() {
 		"smart_report_id", "report_code", "classify_id_first", "classify_name_first", "classify_id_second", "classify_name_second", "add_type",
 		"title", "author", "frequency", "stage", "video_url", "video_name", "video_play_seconds", "video_size", "detail_img_url", "detail_pdf_url",
 		"admin_id", "admin_real_name", "state", "publish_time", "pre_publish_time", "pre_msg_send", "msg_is_send", "msg_send_time", "create_time", "modify_time",
+		"last_modify_admin_id", "last_modify_admin_name", "content_modify_time",
 	}
 	list, e := reportOB.GetPageItemsByCondition(condition, pars, fields, "", startSize, params.PageSize)
 	if e != nil {
@@ -969,12 +1006,11 @@ func (this *SmartReportController) DetailImg() {
 		return
 	}
 
-	// TODO:生成一个长图或者PDF需要个2min左右, 加个锁避免重复请求生成服务
-
-	// TODO:未生成, 则调用eta_report的详情转换接口去生成一次
-	go func() {
-
-	}()
+	// 写入队列
+	var queue smart_report.Report2ImgQueueReq
+	queue.ReportType = 2
+	queue.ReportCode = item.ReportCode
+	_ = utils.Rc.LPush(utils.CACHE_CREATE_REPORT_IMGPDF_QUEUE, queue)
 
 	br.Msg = "图片正在生成中, 请稍后下载"
 	return
@@ -1023,3 +1059,135 @@ func (this *SmartReportController) LastPublishedReport() {
 	br.Msg = "获取成功"
 	br.Data = resp
 }
+
+// VoiceUpload
+// @Title 音频上传
+// @Description 音频上传接口
+// @Param   file   query   file  true       "文件"
+// @Param   SmartReportId	query   int  true       "报告ID"
+// @Success Ret=200 上传成功
+// @router /voice_upload [post]
+func (this *SmartReportController) VoiceUpload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	f, h, err := this.GetFile("file")
+	if err != nil {
+		br.Msg = "获取资源信息失败"
+		br.ErrMsg = "获取资源信息失败,Err:" + err.Error()
+		return
+	}
+	reportId, _ := this.GetInt("SmartReportId")
+	if reportId <= 0 {
+		br.Msg = "参数有误"
+		br.ErrMsg = fmt.Sprintf("参数有误, SmartReportId: %d", reportId)
+		return
+	}
+
+	reportOb := new(smart_report.SmartReport)
+	item, e := reportOb.GetItemById(reportId)
+	if e != nil {
+		if e.Error() == utils.ErrNoRow() {
+			br.Msg = "报告不存在, 请刷新页面"
+			return
+		}
+		br.Msg = "操作失败"
+		br.ErrMsg = "获取报告信息失败, Err:" + err.Error()
+		return
+	}
+
+	ext := path.Ext(h.Filename)
+	dateDir := time.Now().Format("20060102")
+	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
+	err = os.MkdirAll(uploadDir, 0777)
+	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
+	}
+
+	resourceUrl := ``
+	//上传到阿里云 和 minio
+	if utils.ObjectStorageClient == "minio" {
+		resourceUrl, err = services.UploadAudioToMinIo(fileName, fpath)
+		if err != nil {
+			br.Msg = "文件上传失败"
+			br.ErrMsg = "文件上传失败,Err:" + err.Error()
+			return
+		}
+	} else {
+		resourceUrl, err = services.UploadAudioAliyun(fileName, fpath)
+		if err != nil {
+			br.Msg = "文件上传失败"
+			br.ErrMsg = "文件上传失败,Err:" + err.Error()
+			return
+		}
+	}
+
+	defer func() {
+		_ = os.Remove(fpath)
+	}()
+
+	resource := new(models.Resource)
+	resource.ResourceUrl = resourceUrl
+	resource.ResourceType = 2
+	resource.CreateTime = time.Now()
+	newId, err := models.AddResource(resource)
+	if err != nil {
+		br.Msg = "资源上传失败"
+		br.ErrMsg = "资源上传失败,Err:" + err.Error()
+		return
+	}
+	fmt.Println(fpath)
+	playSeconds, err := mp3duration.Calculate(fpath)
+	if playSeconds <= 0 {
+		playSeconds, err = utils.GetVideoPlaySeconds(fpath)
+		if err != nil {
+			br.Msg = "获取音频时间失败"
+			br.ErrMsg = "获取音频时间失败,Err:" + err.Error()
+			return
+		}
+	}
+	createTime := item.CreateTime.Format("0102")
+	videoName := item.Title + "(" + createTime + ")"
+	fileBody, err := ioutil.ReadFile(fpath)
+	videoSize := len(fileBody)
+	sizeFloat := (float64(videoSize) / float64(1024)) / float64(1024)
+	sizeStr := utils.SubFloatToFloatStr(sizeFloat, 2)
+
+	item.VideoUrl = resourceUrl
+	item.VideoName = videoName
+	item.VideoPlaySeconds = playSeconds
+	item.VideoSize = sizeStr
+	item.ModifyTime = time.Now().Local()
+	updateCols := []string{"VideoUrl", "VideoName", "VideoPlaySeconds", "VideoSize", "ModifyTime"}
+	if e = item.Update(updateCols); e != nil {
+		br.Msg = "上传失败"
+		br.ErrMsg = "上传失败,Err:" + e.Error()
+		return
+	}
+
+	resp := new(models.ResourceResp)
+	resp.Id = newId
+	resp.ResourceUrl = resourceUrl
+	br.Msg = "上传成功"
+	br.Ret = 200
+	br.Success = true
+	br.Data = resp
+	return
+}

+ 84 - 61
models/smart_report/smart_report.go

@@ -17,37 +17,42 @@ const (
 
 // SmartReport 智能研报
 type SmartReport struct {
-	SmartReportId      int       `orm:"column(smart_report_id);pk" description:"智能研报ID"`
-	ReportCode         string    `description:"报告唯一编码"`
-	ClassifyIdFirst    int       `description:"一级分类ID"`
-	ClassifyNameFirst  string    `description:"一级分类名称"`
-	ClassifyIdSecond   int       `description:"二级分类ID"`
-	ClassifyNameSecond string    `description:"二级分类名称"`
-	AddType            int       `description:"新增方式:1-新增报告;2-继承报告"`
-	Title              string    `description:"标题"`
-	Abstract           string    `description:"摘要"`
-	Author             string    `description:"作者"`
-	Frequency          string    `description:"频度"`
-	Stage              int       `description:"期数"`
-	Content            string    `description:"内容"`
-	ContentSub         string    `description:"内容前两个章节"`
-	ContentStruct      string    `description:"内容组件"`
-	VideoUrl           string    `description:"音频文件URL"`
-	VideoName          string    `description:"音频文件名称"`
-	VideoPlaySeconds   string    `description:"音频播放时长"`
-	VideoSize          string    `description:"音频文件大小,单位M"`
-	AdminId            int       `description:"创建者ID"`
-	AdminRealName      string    `description:"创建者姓名"`
-	State              int       `description:"发布状态:1-待发布;2-已发布"`
-	PublishTime        time.Time `description:"发布时间"`
-	PrePublishTime     time.Time `description:"预发布时间"`
-	PreMsgSend         int       `description:"定时发布后是否推送模版消息:0-否;1-是"`
-	MsgIsSend          int       `description:"消息是否已发送:0-否;1-是"`
-	MsgSendTime        time.Time `description:"模版消息发送时间"`
-	DetailImgUrl       string    `description:"报告详情长图地址"`
-	DetailPdfUrl       string    `description:"报告详情PDF地址"`
-	CreateTime         time.Time `description:"创建时间"`
-	ModifyTime         time.Time `description:"修改时间"`
+	SmartReportId       int       `orm:"column(smart_report_id);pk" description:"智能研报ID"`
+	ReportCode          string    `description:"报告唯一编码"`
+	ClassifyIdFirst     int       `description:"一级分类ID"`
+	ClassifyNameFirst   string    `description:"一级分类名称"`
+	ClassifyIdSecond    int       `description:"二级分类ID"`
+	ClassifyNameSecond  string    `description:"二级分类名称"`
+	AddType             int       `description:"新增方式:1-新增报告;2-继承报告"`
+	Title               string    `description:"标题"`
+	Abstract            string    `description:"摘要"`
+	Author              string    `description:"作者"`
+	Frequency           string    `description:"频度"`
+	Stage               int       `description:"期数"`
+	Content             string    `description:"内容"`
+	ContentSub          string    `description:"内容前两个章节"`
+	ContentStruct       string    `description:"内容组件"`
+	VideoUrl            string    `description:"音频文件URL"`
+	VideoName           string    `description:"音频文件名称"`
+	VideoPlaySeconds    float64   `description:"音频播放时长"`
+	VideoSize           string    `description:"音频文件大小,单位M"`
+	AdminId             int       `description:"创建者ID"`
+	AdminRealName       string    `description:"创建者姓名"`
+	State               int       `description:"发布状态:1-待发布;2-已发布"`
+	LastModifyAdminId   int       `description:"最后更新人ID"`
+	LastModifyAdminName string    `description:"最后更新人姓名"`
+	ContentModifyTime   time.Time `description:"内容更新时间"`
+	Pv                  int       `description:"pv"`
+	Uv                  int       `description:"uv"`
+	PublishTime         time.Time `description:"发布时间"`
+	PrePublishTime      time.Time `description:"预发布时间"`
+	PreMsgSend          int       `description:"定时发布后是否推送模版消息:0-否;1-是"`
+	MsgIsSend           int       `description:"消息是否已发送:0-否;1-是"`
+	MsgSendTime         time.Time `description:"模版消息发送时间"`
+	DetailImgUrl        string    `description:"报告详情长图地址"`
+	DetailPdfUrl        string    `description:"报告详情PDF地址"`
+	CreateTime          time.Time `description:"创建时间"`
+	ModifyTime          time.Time `description:"修改时间"`
 }
 
 func (m *SmartReport) TableName() string {
@@ -160,36 +165,42 @@ func (m *SmartReport) GetMaxStageByClassifyId(classifyId int) (stage int, err er
 
 // SmartReportItem 智能研报信息
 type SmartReportItem struct {
-	SmartReportId      int    `description:"智能研报ID"`
-	ReportCode         string `description:"报告唯一编码"`
-	ClassifyIdFirst    int    `description:"一级分类ID"`
-	ClassifyNameFirst  string `description:"一级分类名称"`
-	ClassifyIdSecond   int    `description:"二级分类ID"`
-	ClassifyNameSecond string `description:"二级分类名称"`
-	AddType            int    `description:"新增方式:1-新增报告;2-继承报告"`
-	Title              string `description:"标题"`
-	Abstract           string `description:"摘要"`
-	Author             string `description:"作者"`
-	Frequency          string `description:"频度"`
-	Stage              int    `description:"期数"`
-	Content            string `description:"内容"`
-	ContentSub         string `description:"内容前两个章节"`
-	ContentStruct      string `description:"内容组件"`
-	VideoUrl           string `description:"音频文件URL"`
-	VideoName          string `description:"音频文件名称"`
-	VideoPlaySeconds   string `description:"音频播放时长"`
-	VideoSize          string `description:"音频文件大小,单位M"`
-	AdminId            int    `description:"创建者姓名"`
-	AdminRealName      string `description:"创建者姓名"`
-	State              int    `description:"发布状态:1-待发布;2-已发布"`
-	PublishTime        string `description:"发布时间"`
-	MsgIsSend          int    `description:"消息是否已发送:0-否;1-是"`
-	DetailImgUrl       string `description:"报告详情长图地址"`
-	DetailPdfUrl       string `description:"报告详情PDF地址"`
-	CreateTime         string `description:"创建时间"`
-	ModifyTime         string `description:"修改时间"`
-	CanEdit            bool   `description:"是否可编辑"`
-	Editor             string `description:"当前编辑人"`
+	SmartReportId       int     `description:"智能研报ID"`
+	ReportCode          string  `description:"报告唯一编码"`
+	ClassifyIdFirst     int     `description:"一级分类ID"`
+	ClassifyNameFirst   string  `description:"一级分类名称"`
+	ClassifyIdSecond    int     `description:"二级分类ID"`
+	ClassifyNameSecond  string  `description:"二级分类名称"`
+	AddType             int     `description:"新增方式:1-新增报告;2-继承报告"`
+	Title               string  `description:"标题"`
+	Abstract            string  `description:"摘要"`
+	Author              string  `description:"作者"`
+	Frequency           string  `description:"频度"`
+	Stage               int     `description:"期数"`
+	Content             string  `description:"内容"`
+	ContentSub          string  `description:"内容前两个章节"`
+	ContentStruct       string  `description:"内容组件"`
+	VideoUrl            string  `description:"音频文件URL"`
+	VideoName           string  `description:"音频文件名称"`
+	VideoPlaySeconds    float64 `description:"音频播放时长"`
+	VideoSize           string  `description:"音频文件大小,单位M"`
+	AdminId             int     `description:"创建者姓名"`
+	AdminRealName       string  `description:"创建者姓名"`
+	LastModifyAdminId   int     `description:"最后更新人ID"`
+	LastModifyAdminName string  `description:"最后更新人姓名"`
+	ContentModifyTime   string  `description:"内容更新时间"`
+	Pv                  int     `description:"pv"`
+	Uv                  int     `description:"uv"`
+	State               int     `description:"发布状态:1-待发布;2-已发布"`
+	PublishTime         string  `description:"发布时间"`
+	PrePublishTime      string  `description:"预发布时间"`
+	MsgIsSend           int     `description:"消息是否已发送:0-否;1-是"`
+	DetailImgUrl        string  `description:"报告详情长图地址"`
+	DetailPdfUrl        string  `description:"报告详情PDF地址"`
+	CreateTime          string  `description:"创建时间"`
+	ModifyTime          string  `description:"修改时间"`
+	CanEdit             bool    `description:"是否可编辑"`
+	Editor              string  `description:"当前编辑人"`
 }
 
 // FormatSmartReport2Item 格式化智能研报数据格式
@@ -219,8 +230,14 @@ func FormatSmartReport2Item(origin *SmartReport) (item *SmartReportItem) {
 	item.VideoSize = origin.VideoSize
 	item.AdminId = origin.AdminId
 	item.AdminRealName = origin.AdminRealName
+	item.LastModifyAdminId = origin.LastModifyAdminId
+	item.LastModifyAdminName = origin.LastModifyAdminName
+	item.ContentModifyTime = utils.TimeTransferString(utils.FormatDateTime, origin.ContentModifyTime)
+	item.Pv = origin.Pv
+	item.Uv = origin.Uv
 	item.State = origin.State
 	item.PublishTime = utils.TimeTransferString(utils.FormatDateTime, origin.PublishTime)
+	item.PrePublishTime = utils.TimeTransferString(utils.FormatDateTime, origin.PrePublishTime)
 	item.MsgIsSend = origin.MsgIsSend
 	item.DetailImgUrl = origin.DetailImgUrl
 	item.DetailPdfUrl = origin.DetailPdfUrl
@@ -314,3 +331,9 @@ type ElasticSmartReport struct {
 	StageStr           string `description:"报告期数"`
 	Frequency          string `description:"频度"`
 }
+
+// Report2ImgQueueReq 报告详情生成长图队列请求体
+type Report2ImgQueueReq struct {
+	ReportType int    `description:"报告类型: 1-研报; 2-智能研报"`
+	ReportCode string `description:"报告唯一编码"`
+}

+ 9 - 0
routers/commentsRouter.go

@@ -4543,6 +4543,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/smart_report:SmartReportController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/smart_report:SmartReportController"],
+        beego.ControllerComments{
+            Method: "VoiceUpload",
+            Router: `/voice_upload`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/trade_analysis:TradeAnalysisController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/trade_analysis:TradeAnalysisController"],
         beego.ControllerComments{
             Method: "GetClassifyName",

+ 1 - 1
services/smart_report/smart_report.go

@@ -34,7 +34,7 @@ func SmartReportBuildVideoAndUpdate(item *smart_report.SmartReport) {
 	item.VideoUrl = videoUrl
 	item.VideoName = videoName
 	item.VideoSize = videoSize
-	item.VideoPlaySeconds = fmt.Sprintf("%.2f", videoPlaySeconds)
+	item.VideoPlaySeconds = videoPlaySeconds
 	item.ModifyTime = time.Now().Local()
 	cols := []string{"VideoUrl", "VideoName", "VideoSize", "VideoPlaySeconds", "ModifyTime"}
 	if e = item.Update(cols); e != nil {

+ 2 - 0
utils/constants.go

@@ -216,6 +216,8 @@ const (
 
 	CACHE_SMART_REPORT_EDITING  = "eta:smart_report:editing:" // 智能研报用户编辑中
 	CACHE_SMART_REPORT_SEND_MSG = "eta:smart_report:sending:" // 智能研报用户报告推送
+
+	CACHE_CREATE_REPORT_IMGPDF_QUEUE = "eta_report:report_img_pdf_queue" // 生成报告长图PDF队列
 )
 
 // 模板消息推送类型