Bladeren bron

add:知识资源库报告库上传

zqbao 4 maanden geleden
bovenliggende
commit
274e256123

+ 52 - 2
controllers/report_open.go

@@ -400,7 +400,7 @@ func (this *ReportOpenController) ReportApprove() {
 			if req.ApproveType == 1 {
 				// 审批通过,将PPT或研报加入报告库中
 				go func() {
-					msg, err := knowledge.ReportKnowledgeResourceAdd(v.Title, v.DetailPdfUrl, v.AdminId, v.AdminRealName)
+					msg, err := knowledge.ReportKnowledgeResourceAdd(v.Title, []string{v.DetailPdfUrl}, v.AdminId, v.AdminRealName, "市场研究报告/内部报告/日常报告", "市场信息研究所", time.Now())
 					if err != nil {
 						utils.FileLog.Error(fmt.Sprintf("ReportKnowledgeResourceAdd-报告知识资源库添加失败,reportId:%d,msg:%s,err: %v", v.Id, msg, err))
 						return
@@ -516,7 +516,7 @@ func (this *ReportOpenController) ReportApprove() {
 			if req.ApproveType == 1 {
 				// 审批通过,将PPT或研报加入报告库中
 				go func() {
-					msg, err := knowledge.ReportKnowledgeResourceAdd(v.Title, v.PptxUrl, v.AdminId, v.AdminRealName)
+					msg, err := knowledge.ReportKnowledgeResourceAdd(v.Title, []string{v.PptxUrl}, v.AdminId, v.AdminRealName, "市场研究报告/内部报告/日常报告", "市场信息研究所", time.Now())
 					if err != nil {
 						utils.FileLog.Error(fmt.Sprintf("ReportKnowledgeResourceAdd-PPT知识资源报告库添加失败,pptId:%d,msg:%s,err: %v", v.PptId, msg, err))
 						return
@@ -790,3 +790,53 @@ func (this *ReportOpenController) ViewPointDelete() {
 	br.Success = true
 	br.Ret = 200
 }
+
+// @Title 知识资源报告库上传
+// @Description 知识资源报告库上传
+// @Param request body string/int true/false "Description"
+// @Success 200 string "操作成功"
+// @router /report/knowledge/upload [post]
+func (this *ReportOpenController) ReportKnowledgeUpload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		if br.ErrMsg == "" {
+			br.IsSendEmail = false
+		}
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+
+	var req models.ReportKnowledgeUploadRep
+	if e := this.BindForm(&req); e != nil {
+		br.Msg = "参数解析异常"
+		br.ErrMsg = fmt.Sprintf("参数解析失败,%v", e)
+		return
+	}
+	pushTime, err := time.Parse(utils.FormatDateTime, req.PushTime)
+	if err != nil {
+		br.Msg = "发布时间格式不正确"
+		return
+	}
+	fileUrls, msg, err := knowledge.UploadFormFile(this.Ctx.Request.MultipartForm.File)
+	if err != nil {
+		if msg == "" {
+			msg = "上传失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = fmt.Sprintf("上传失败, %v", err)
+		return
+	}
+	msg, err = knowledge.ReportKnowledgeResourceAdd(req.Title, fileUrls, 0, "", req.ClassifyPath, req.Source, pushTime)
+	if err != nil {
+		if msg == "" {
+			msg = "保存失败"
+		}
+		br.Msg = msg
+		br.ErrMsg = fmt.Sprintf("保存失败, %v", err)
+		return
+	}
+
+	br.Ret = 200
+	br.Msg = "上传成功"
+	br.Success = true
+}

+ 12 - 7
models/knowledge_resource.go

@@ -2,6 +2,7 @@ package models
 
 import (
 	"eta_gn/eta_report/global"
+	"eta_gn/eta_report/utils"
 	"time"
 )
 
@@ -67,7 +68,7 @@ func (k KnowledgeResource) TableName() string {
 	return "knowledge_resource"
 }
 
-func (k *KnowledgeResource) Create() (err error) {
+func (k *KnowledgeResource) Create(fileUrl []string) (err error) {
 	tx := global.DEFAULT_DmSQL.Begin()
 	defer func() {
 		if err != nil {
@@ -76,13 +77,17 @@ func (k *KnowledgeResource) Create() (err error) {
 			tx.Commit()
 		}
 	}()
-	fileUrl := k.FileUrl
-	k.FileUrl = ""
 	err = tx.Create(k).Error
-	file := new(KnowledgeResourceFile)
-	file.KnowledgeResourceId = k.KnowledgeResourceId
-	file.FileUrl = fileUrl
-	err = tx.Create(file).Error
+	if len(fileUrl) > 0 {
+		addFile := make([]*KnowledgeResourceFile, 0, len(fileUrl))
+		for _, url := range fileUrl {
+			file := new(KnowledgeResourceFile)
+			file.KnowledgeResourceId = k.KnowledgeResourceId
+			file.FileUrl = url
+			addFile = append(addFile, file)
+		}
+		err = tx.CreateInBatches(addFile, utils.MultiAddNum).Error
+	}
 	return
 }
 

+ 7 - 0
models/report_open.go

@@ -52,3 +52,10 @@ type ReportViewPointSaveReq struct {
 type ReportViewPointDeleteRep struct {
 	Id *int `description:"观点库外部id"`
 }
+
+type ReportKnowledgeUploadRep struct {
+	Title        string `form:"title" description:"文件标题"`
+	Source       string `form:"source" description:"文件来源"`
+	ClassifyPath string `form:"classify_path" description:"文件分类路径"`
+	PushTime     string `form:"push_time" description:"上传时间"`
+}

+ 9 - 0
routers/commentsRouter.go

@@ -70,6 +70,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta_gn/eta_report/controllers:ReportOpenController"] = append(beego.GlobalControllerRouter["eta_gn/eta_report/controllers:ReportOpenController"],
+        beego.ControllerComments{
+            Method: "ReportKnowledgeUpload",
+            Router: `/report/knowledge/upload`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta_gn/eta_report/controllers:ReportOpenController"] = append(beego.GlobalControllerRouter["eta_gn/eta_report/controllers:ReportOpenController"],
         beego.ControllerComments{
             Method: "ReportModify",

+ 110 - 14
services/knowledge/knowledge_resource.go

@@ -2,25 +2,49 @@ package knowledge
 
 import (
 	"eta_gn/eta_report/models"
+	"eta_gn/eta_report/services"
 	"eta_gn/eta_report/utils"
+	"fmt"
 	"html"
+	"io/ioutil"
+	"mime/multipart"
+	"os"
+	"path"
 	"strconv"
 	"strings"
 	"time"
 )
 
-func ReportKnowledgeResourceAdd(title string, fileUrl string, adminId int, adminRealName string) (msg string, err error) {
+func ReportKnowledgeResourceAdd(title string, fileUrl []string, adminId int, adminRealName, classifyPath, sourceFrom string, pushTime time.Time) (msg string, err error) {
 	classifyObj := new(models.KnowledgeClassify)
-	childClassifyId, err := classifyObj.GetChildClassifyIdByNamePath("市场研究报告", "内部报告", "日常报告")
-	if err != nil {
-		if utils.IsErrNoRow(err) {
-			msg = "分类不存在,请检查知识资源-报告库中是否存在-市场研究报告/内部报告/日常报告分类"
+	var childClassifyId int
+	if classifyPath != "" {
+		classifyPathArr := strings.Split(classifyPath, "/")
+		var classifyFirst, classifySecond, classifyThird string
+		switch len(classifyPathArr) {
+		case 1:
+			classifyFirst = classifyPathArr[0]
+		case 2:
+			classifyFirst = classifyPathArr[0]
+			classifySecond = classifyPathArr[1]
+		case 3:
+			classifyFirst = classifyPathArr[0]
+			classifySecond = classifyPathArr[1]
+			classifyThird = classifyPathArr[2]
+		}
+		childClassifyId, err = classifyObj.GetChildClassifyIdByNamePath(classifyFirst, classifySecond, classifyThird)
+		if err != nil {
+			if utils.IsErrNoRow(err) {
+				msg = "分类不存在,请检查知识资源-报告库中是否存在-" + classifyPath
+				return
+			}
+			msg = "报告库添加失败"
 			return
 		}
-		msg = "报告库添加失败"
+	} else {
+		msg = "分类不能为空"
 		return
 	}
-
 	obj := new(models.KnowledgeResource)
 	obj.ResourceType = models.KnowledgeResourceTypeReport
 	obj.ClassifyId = childClassifyId
@@ -32,15 +56,13 @@ func ReportKnowledgeResourceAdd(title string, fileUrl string, adminId int, admin
 	obj.ResourceCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
 	obj.AdminId = adminId
 	obj.AdminRealName = adminRealName
-	obj.SourceFrom = "市场信息研究所"
-	currentTime := time.Now()
-	obj.StartTime = &currentTime
+	obj.SourceFrom = sourceFrom
+	obj.StartTime = &pushTime
 	// 此处传入的url会在入库时存入knowledge_resource_file表中
-	obj.FileUrl = fileUrl
-	if fileUrl != "" {
+	if len(fileUrl) != 0 {
 		obj.IsFile = 1
 	}
-	err = obj.Create()
+	err = obj.Create(fileUrl)
 	if err != nil {
 		return
 	}
@@ -140,7 +162,7 @@ func ViewPointSave(outId, adminId int, adminRealName, title, content, sourceFrom
 		obj.StartTime = startTime
 		obj.IsFile = 0
 		obj.OutId = outId
-		err = obj.Create()
+		err = obj.Create([]string{})
 		if err != nil {
 			msg = "观点保存失败"
 			return
@@ -213,3 +235,77 @@ func ViewPointKnowledgeResourceClassifyCheckAndSave(classifyName string, resourc
 	}
 	return
 }
+
+func UploadFormFile(multipartFile map[string][]*multipart.FileHeader) (fileUrl []string, msg string, err error) {
+	client := services.NewOssClient()
+
+	// 定义允许的文件格式
+	allowedExtensions := map[string]bool{
+		".pdf":  true,
+		".doc":  true,
+		".docx": true,
+		".ppt":  true,
+		".pptx": true,
+	}
+	for _, file := range multipartFile {
+		for _, f := range file {
+			if f.Filename == "" {
+				continue
+			}
+			ext := path.Ext(f.Filename)
+			if !allowedExtensions[ext] {
+				msg = "文件格式不正确"
+				err = fmt.Errorf("文件格式不正确")
+				return
+			}
+			saveName := fmt.Sprint(utils.MD5(f.Filename), time.Now().Format(utils.FormatDateTimeUnSpace), time.Now().Nanosecond(), ext)
+			dataDir := time.Now().Format(utils.FormatDate)
+			filePath := utils.StaticDir + "files/" + dataDir + "/" + saveName
+			ok, _ := utils.PathExists(filePath)
+			if !ok {
+				err = os.MkdirAll(filePath, utils.DIR_MOD)
+				if err != nil {
+					msg = "目录创建失败"
+					return
+				}
+			}
+			fileContent, er := f.Open()
+			if er != nil {
+				msg = "文件打开失败"
+				err = er
+				return
+			}
+			fileContentBytes, er := ioutil.ReadAll(fileContent)
+			if er != nil {
+				msg = "文件读取失败"
+				err = er
+				return
+			}
+			// 保存到本地
+			er = utils.SaveToFile(fileContentBytes, filePath)
+			if er != nil {
+				msg = "文件保存失败"
+				err = er
+				return
+			}
+			_, er = os.Stat(filePath)
+			if er != nil {
+				msg = "文件信息获取失败"
+				err = er
+				return
+			}
+			randStr := utils.GetRandStringNoSpecialChar(28)
+			fileName := randStr + ext
+
+			savePath := fmt.Sprintf("%s%s%s", utils.UploadFileDir, time.Now().Format("200601/20060102/"), fileName)
+			resourceUrl, er := client.UploadFile(fileName, filePath, savePath)
+			if er != nil {
+				msg = "文件上传失败"
+				err = er
+				return
+			}
+			fileUrl = append(fileUrl, resourceUrl)
+		}
+	}
+	return
+}

+ 26 - 1
utils/common.go

@@ -10,7 +10,6 @@ import (
 	"encoding/json"
 	"errors"
 	"fmt"
-	"gorm.io/gorm"
 	"image"
 	"image/png"
 	"math"
@@ -22,6 +21,8 @@ import (
 	"strconv"
 	"strings"
 	"time"
+
+	"gorm.io/gorm"
 )
 
 func GetRandString(size int) string {
@@ -613,3 +614,27 @@ func InArrayByStr(idStrList []string, searchId string) (has bool) {
 	}
 	return
 }
+
+// SaveToFile
+// @Description: 将字节内容保存到本地文件
+// @author: Roc
+// @datetime 2024-09-05 18:12:55
+// @param content []byte
+// @param fileName string
+// @return error
+func SaveToFile(content []byte, fileName string) error {
+	file, err := os.Create(fileName)
+	if err != nil {
+		return err
+	}
+	defer func() {
+		_ = file.Close()
+	}()
+
+	_, err = file.Write(content)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}

+ 8 - 0
utils/config.go

@@ -60,12 +60,17 @@ var (
 	ResourceProxyUrl    string // 代理资源地址
 )
 
+var (
+	StaticDir string //静态文件目录
+)
+
 // 阿里云配置
 var (
 	Bucketname       string
 	Endpoint         string
 	Imghost          string
 	UploadDir        string
+	UploadFileDir    string
 	Upload_Audio_Dir string
 	AccessKeyId      string
 	AccessKeySecret  string
@@ -213,12 +218,15 @@ func init() {
 	ObjectStorageClient = config["object_storage_client"]
 	// 代理资源地址
 	ResourceProxyUrl = config["resource_proxy_url"]
+	// 静态资源目录
+	StaticDir = config["static_dir"]
 	// OSS相关
 	{
 		Endpoint = config["endpoint"]
 		Bucketname = config["bucket_name"]
 		Imghost = config["img_host"]
 		UploadDir = config["upload_dir"]
+		UploadFileDir = config["upload_file_dir"]
 		Upload_Audio_Dir = config["upload_audio_dir"]
 		AccessKeyId = config["access_key_id"]
 		AccessKeySecret = config["access_key_secret"]

+ 3 - 1
utils/constants.go

@@ -1,5 +1,7 @@
 package utils
 
+import "io/fs"
+
 // 常量定义
 const (
 	FormatTime            = "15:04:05"                //时间格式
@@ -20,7 +22,7 @@ const (
 const (
 	APPNAME = "ETA报告服务"
 )
-
+const DIR_MOD fs.FileMode = 0766 // Unix permission bits
 // 手机号,电子邮箱正则
 const (
 	RegularMobile = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0-9])|(17[0-9])|(16[0-9])|(19[0-9]))\\d{8}$" //手机号码