Browse Source

Merge branch 'feature/eta2.2.6_material' into debug

xyxie 4 months ago
parent
commit
8d4c296ce8

+ 323 - 117
controllers/material/material.go

@@ -1,6 +1,7 @@
 package material
 
 import (
+	"archive/zip"
 	"encoding/json"
 	"eta/eta_api/controllers"
 	"eta/eta_api/models"
@@ -10,8 +11,10 @@ import (
 	"eta/eta_api/utils"
 	"fmt"
 	"github.com/h2non/filetype"
+	"github.com/rdlucklib/rdluck_tools/http"
 	"github.com/rdlucklib/rdluck_tools/paging"
 	"io/ioutil"
+	"os"
 	"path"
 	"strconv"
 	"strings"
@@ -130,11 +133,17 @@ func (this *MaterialController) AddMaterialClassify() {
 		level = parentClassify.Level + 1
 		levelPath = parentClassify.LevelPath
 	}
+	var count int
+	switch this.Lang {
+	case utils.LANG_EN:
+		count, err = material.GetMaterialClassifyNameEnCount(req.ClassifyName, req.ParentId)
+	default:
+		count, err = material.GetMaterialClassifyNameCount(req.ClassifyName, req.ParentId)
+	}
 
-	count, e := material.GetMaterialClassifyNameCount(req.ClassifyName, req.ParentId)
-	if e != nil {
+	if err != nil {
 		br.Msg = "判断名称是否已存在失败"
-		br.ErrMsg = "判断名称是否已存在失败,Err:" + e.Error()
+		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
 		return
 	}
 	if count > 0 {
@@ -148,6 +157,7 @@ func (this *MaterialController) AddMaterialClassify() {
 	maxSort, _ := material.GetMaterialClassifyMaxSort(req.ParentId)
 	classify.ParentId = req.ParentId
 	classify.ClassifyName = req.ClassifyName
+	classify.ClassifyNameEn = req.ClassifyName
 	classify.CreateTime = time.Now()
 	classify.ModifyTime = time.Now()
 	classify.SysUserId = this.SysUser.AdminId
@@ -221,7 +231,19 @@ func (this *MaterialController) EditMaterialClassify() {
 		br.Msg = "获取分类信息失败,Err:" + err.Error()
 		return
 	}
-	count, err := material.GetMaterialClassifyNameNotSelfCount(req.ClassifyId, req.ClassifyName, item.ParentId)
+	var count int
+	updateStr := make([]string, 0)
+	switch this.Lang {
+	case utils.LANG_EN:
+		count, err = material.GetMaterialClassifyNameEnNotSelfCount(req.ClassifyId, req.ClassifyName, item.ParentId)
+		item.ClassifyNameEn = req.ClassifyName
+		updateStr = append(updateStr, "ClassifyNameEn")
+	default:
+		count, err = material.GetMaterialClassifyNameNotSelfCount(req.ClassifyId, req.ClassifyName, item.ParentId)
+		item.ClassifyName = req.ClassifyName
+		updateStr = append(updateStr, "ClassifyName")
+	}
+
 	if err != nil {
 		br.Msg = "判断名称是否已存在失败"
 		br.ErrMsg = "判断名称是否已存在失败,Err:" + err.Error()
@@ -232,13 +254,10 @@ func (this *MaterialController) EditMaterialClassify() {
 		br.IsSendEmail = false
 		return
 	}
-	//levelPath = fmt.Sprintf("%s,%d", levelPath, req.ClassifyId)
-	//item.LevelPath = levelPath
-	//item.ParentId = req.ParentId
-	item.ClassifyName = req.ClassifyName
+
 	item.ModifyTime = time.Now()
-	//e = item.Update([]string{"LevelPath", "ParentId", "ClassifyName", "ModifyTime"})
-	err = item.Update([]string{"ClassifyName", "ModifyTime"})
+	updateStr = append(updateStr, "ModifyTime")
+	err = item.Update(updateStr)
 	if err != nil {
 		br.Msg = "保存分类失败"
 		br.ErrMsg = "保存分类失败,Err:" + err.Error()
@@ -1176,108 +1195,40 @@ func (this *MaterialController) BatchAdd() {
 		br.Msg = "请填写图片名称"
 		return
 	}
-
-	// 判断文件名是否已存在
-	exist, e := material.GetMaterialByNames(materialNames)
-	if e != nil && e.Error() != utils.ErrNoRow() {
-		br.Msg = "获取失败"
-		br.ErrMsg = "获取数据失败,Err:" + err.Error()
-		return
-	}
-	if e == nil && exist.MaterialId > 0 {
-		br.Msg = fmt.Sprintf("图片名称:%s 已存在", exist.MaterialName)
-		return
-	}
-	// 获取表单中的所有文件
-	/*files, err := this.GetFiles("Files")
-	if err != nil {
-		br.Msg = "文件上传失败"
-		br.ErrMsg = "文件上传失败,Err:" + err.Error()
-		return
-	}
-	if len(files) == 0 {
-		br.Msg = "请选择文件"
-		return
-	}
-	if len(materialNames) != len(files) {
-		br.Msg = "图片数量与名称数量不一致"
-		return
-	}
-	// 创建目标目录(如果不存在)
-	uploadDir := utils.STATIC_DIR + "hongze/" + time.Now().Format("20060102")
-	if err = os.MkdirAll(uploadDir, utils.DIR_MOD); err != nil {
-		br.Msg = "存储目录创建失败"
-		br.ErrMsg = "存储目录创建失败, Err:" + err.Error()
-		return
-	}
-
-	// 处理单个文件(这里假设files是一个多文件字段)
-	// 实际上,当使用<input type="file" name="files" multiple>时,
-	// 它会作为多个文件字段发送到服务器,名字相同但后缀不同,例如:files, files[1], files[2]等。
-	// 所以我们需要遍历这些字段。
-
-	// 创建一个map来存储所有文件
-	fileUrlMap := make(map[string]string)
-
-	// 获取上传文件的头部信息
-	//fileHeaders := this.Ctx.Request.Header["Content-Disposition"]
-	for k, fileHeader := range files {
-		// 解析Content-Disposition头以获取文件名
-		// 获取文件名(避免路径遍历攻击,只使用文件名部分)
-		fileName := filepath.Base(fileHeader.Filename)
-		fileName = strings.TrimSpace(strings.Replace(fileName, "\\", "/", -1)) // 替换可能存在的反斜杠
-		fileName = strings.Trim(fileName, " \"\n\r\t")                         // 去除文件名两侧的空白字符和引号
-
-		ext := path.Ext(fileName)
-		ossFileName := utils.GetRandStringNoSpecialChar(28) + ext
-		filePath := filepath.Join(uploadDir, ossFileName)
-
-		// 创建目标文件
-		dst, e := os.Create(filePath)
-		if e != nil {
-			br.Msg = "文件创建失败"
-			br.ErrMsg = "文件创建失败, Err:" + e.Error()
-			//http.Error(w, e.Error(), http.StatusInternalServerError)
-			return
-		}
-		defer dst.Close()
-		src, e := fileHeader.Open()
-		if e != nil {
-			br.Msg = "文件打开失败"
-			br.ErrMsg = "文件打开失败, Err:" + e.Error()
+	existList := make([]*material.Material, 0)
+	switch this.Lang {
+	case utils.LANG_EN:
+		existList, err = material.GetMaterialByNameEns(materialNames)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
-		// 将上传的文件内容复制到目标文件
-		if _, err = io.Copy(dst, src); err != nil {
-			br.Msg = "文件保存失败"
-			br.ErrMsg = "文件保存失败, Err:" + err.Error()
+		if len(existList) > 0 {
+			msg := "图片名称:"
+			for _, v := range existList {
+				msg += v.MaterialNameEn + " "
+			}
+			br.Msg = fmt.Sprintf("%s 已存在", msg)
 			return
 		}
-
-		defer func() {
-			_ = os.Remove(filePath)
-		}()
-		// 上传到阿里云
-		ossDir := utils.RESOURCE_DIR + "cloud_disk/"
-
-		savePath := ossDir + time.Now().Format("200601/20060102/") + ossFileName
-		ossClient := services.NewOssClient()
-		if ossClient == nil {
-			br.Msg = "上传失败"
-			br.ErrMsg = "初始化OSS服务失败"
+	default:
+		// 判断文件名是否已存在
+		existList, err = material.GetMaterialByNames(materialNames)
+		if err != nil {
+			br.Msg = "获取失败"
+			br.ErrMsg = "获取数据失败,Err:" + err.Error()
 			return
 		}
-		resourceUrl, e := ossClient.UploadFile(ossFileName, filePath, savePath)
-		if e != nil {
-			br.Msg = "文件上传失败"
-			br.ErrMsg = "文件上传失败,Err:" + e.Error()
+		if len(existList) > 0 {
+			msg := "图片名称:"
+			for _, v := range existList {
+				msg += v.MaterialName + " "
+			}
+			br.Msg = fmt.Sprintf("%s 已存在", msg)
 			return
 		}
-
-		// 将文件保存到map中(这里主要是为了演示,实际使用中可能不需要)
-		fileUrlMap[materialNames[k]] = resourceUrl
-	}*/
-
+	}
 	err = materialService.BatchAddMaterial(req.MaterialList, classifyId, sysUser.AdminId, sysUser.AdminName)
 	if err != nil {
 		br.Msg = "文件上传失败"
@@ -1339,7 +1290,7 @@ func (this *MaterialController) Upload() {
 	ossDir := utils.RESOURCE_DIR + "material_dir/"
 	savePath := ossDir + time.Now().Format("200601/20060102/") + fileName
 	// 上传文件
-	resourceUrl, err := services.CommonUploadToOssAndFileName(f, fileName, savePath)
+	resourceUrl, err := services.CommonUploadToOssAndFileName(h, fileName, savePath)
 	if err != nil {
 		br.Msg = "文件上传失败"
 		br.ErrMsg = "文件上传失败,Err:" + err.Error()
@@ -1568,28 +1519,41 @@ func (this *MaterialController) Rename() {
 		br.ErrMsg = "获取素材库信息失败,Err:" + err.Error()
 		return
 	}
-	// 判断名称是否重复
-	if info.MaterialName == req.MaterialName {
-		br.Msg = "名称未修改"
-		return
+	var exist *material.Material
+	updateStr := make([]string, 0)
+	switch this.Lang {
+	case utils.LANG_EN:
+		// 判断名称是否重复
+		if info.MaterialNameEn == req.MaterialName {
+			br.Msg = "名称未修改"
+			return
+		}
+		exist, err = material.GetMaterialByNameEn(req.MaterialName)
+		info.MaterialNameEn = req.MaterialName
+		updateStr = append(updateStr, "MaterialNameEn")
+	default:
+		// 判断名称是否重复
+		if info.MaterialName == req.MaterialName {
+			br.Msg = "名称未修改"
+			return
+		}
+		exist, err = material.GetMaterialByName(req.MaterialName)
+		info.MaterialName = req.MaterialName
+		updateStr = append(updateStr, "MaterialName")
 	}
-
-	// 查询名称是否已存在
-	exist, e := material.GetMaterialByNames([]string{req.MaterialName})
-	if e != nil && e.Error() != utils.ErrNoRow() {
+	if err != nil && err.Error() != utils.ErrNoRow() {
 		br.Msg = "获取失败"
 		br.ErrMsg = "获取数据失败,Err:" + err.Error()
 		return
 	}
-	if e == nil && exist.MaterialId > 0 {
+	if err == nil && exist.MaterialId > 0 {
 		br.Msg = "图片名称已存在"
 		return
 	}
-	info.MaterialName = req.MaterialName
 	info.ModifyTime = time.Now()
-
+	updateStr = append(updateStr, "ModifyTime")
 	//更换分类素材库
-	err = info.Update([]string{"MaterialName", "ModifyTime"})
+	err = info.Update(updateStr)
 	if err != nil {
 		br.Msg = err.Error()
 		return
@@ -1600,3 +1564,245 @@ func (this *MaterialController) Rename() {
 	br.Success = true
 	br.Msg = msg
 }
+
+// BatchDownload
+// @Title 批量下载素材
+// @Description 批量下载素材
+// @Param	request	body material.DeleteSandbox true "type json string"
+// @Success 200 标记成功
+// @router /batch/download [post]
+func (this *MaterialController) BatchDownload() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req material.BatchDeleteMaterialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	downMaterialList := make([]*material.MaterialListItems, 0)
+	if req.IsSelectAll {
+		classifyId := req.ClassifyId
+		keyword := req.Keyword
+		isShowMe := req.IsShowMe
+		//获取图表信息
+		list, e, msg := materialService.GetBatchSelectedMaterialList(classifyId, keyword, isShowMe, sysUser)
+		if e != nil {
+			br.Msg = "获取素材库信息失败"
+			if msg != "" {
+				br.Msg = msg
+			}
+			br.ErrMsg = "获取素材库信息失败,Err:" + e.Error()
+			return
+		}
+		notSelectIds := make(map[int]struct{})
+		if len(req.MaterialIds) >= 0 {
+			for _, v := range req.MaterialIds {
+				notSelectIds[v] = struct{}{}
+			}
+		}
+		for _, v := range list {
+			if _, ok := notSelectIds[v.MaterialId]; !ok {
+				downMaterialList = append(downMaterialList, v)
+			}
+		}
+	} else {
+		if len(req.MaterialIds) > 0 {
+			// 批量查询指标数据
+			downMaterialList, err = material.GetMaterialByIds(req.MaterialIds)
+			if err != nil {
+				br.Msg = "获取素材库信息失败"
+				br.ErrMsg = "获取素材库信息失败,Err:" + err.Error()
+				return
+			}
+		}
+	}
+
+	if len(downMaterialList) <= 0 {
+		br.Msg = "请选择要下载的素材"
+		return
+	}
+	// 创建zip
+	zipName := time.Now().Format(utils.FormatDateTimeUnSpace) + utils.GetRandString(5) + ".zip"
+	savePath := zipName
+	zipFile, err := os.Create(zipName)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "生成压缩文件失败, Err: " + err.Error()
+		return
+	}
+	zipWriter := zip.NewWriter(zipFile)
+	// 生成zip过程中报错关闭
+	defer func() {
+		if err != nil {
+			_ = zipWriter.Close()
+			_ = zipFile.Close()
+		}
+		_ = os.Remove(savePath)
+	}()
+
+	// 获取资源, 写入zip
+	zipFileName := ""
+	for i := range downMaterialList {
+		if downMaterialList[i].MaterialName == "" || downMaterialList[i].ImgUrl == "" {
+			continue
+		}
+		fmt.Printf("开始压缩第%d个文件\n", i+1)
+		dotIndex := strings.LastIndex(downMaterialList[i].ImgUrl, ".")
+
+		// 如果找不到点,或者点是文件名的第一个字符(不合法情况),则返回空字符串
+		if dotIndex == -1 || dotIndex == 0 {
+			continue
+		}
+
+		fileExt := downMaterialList[i].ImgUrl[dotIndex+1:]
+		ioWriter, err := zipWriter.Create(fmt.Sprintf("%s.%s", downMaterialList[i].MaterialName, fileExt))
+		if err != nil {
+			if os.IsPermission(err) {
+				br.Msg = "操作失败"
+				br.ErrMsg = "打包权限不足, Err: " + err.Error()
+				return
+			}
+			br.Msg = "操作失败"
+			br.ErrMsg = "压缩出错, Err: " + err.Error()
+			return
+		}
+
+		var content []byte
+		content, err = http.Get(downMaterialList[i].ImgUrl)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "资源获取失败, Err: " + err.Error()
+			return
+		}
+		_, err = ioWriter.Write(content)
+		if err != nil {
+			br.Msg = "操作失败"
+			br.ErrMsg = "压缩文件写入失败, Err: " + err.Error()
+			return
+		}
+		if zipFileName == "" {
+			zipFileName = downMaterialList[i].MaterialName
+		}
+		fmt.Printf("第%d个文件写入成功\n", i+1)
+	}
+	// 生成zip后关闭,否则下载文件会损坏
+	_ = zipWriter.Close()
+	_ = zipFile.Close()
+
+	this.Ctx.Output.Download(savePath, fmt.Sprintf("%s.zip", zipFileName))
+
+	msg := "操作成功"
+	br.Ret = 200
+	br.Success = true
+	br.Msg = msg
+}
+
+// Download
+// @Title 下载素材
+// @Description 下载素材
+// @Param	request	body material.DeleteSandbox true "type json string"
+// @Success 200 标记成功
+// @router /download [post]
+func (this *MaterialController) Download() {
+	br := new(models.BaseResponse).Init()
+	defer func() {
+		this.Data["json"] = br
+		this.ServeJSON()
+	}()
+	sysUser := this.SysUser
+	if sysUser == nil {
+		br.Msg = "请登录"
+		br.ErrMsg = "请登录,SysUser Is Empty"
+		br.Ret = 408
+		return
+	}
+	var req material.RenameMaterialReq
+	err := json.Unmarshal(this.Ctx.Input.RequestBody, &req)
+	if err != nil {
+		br.Msg = "参数解析异常!"
+		br.ErrMsg = "参数解析失败,Err:" + err.Error()
+		return
+	}
+
+	if req.MaterialId <= 0 {
+		br.Msg = "缺少素材库编号"
+		return
+	}
+	// 判断素材是否存在
+	info, err := material.GetMaterialById(req.MaterialId)
+	if err != nil {
+		if err.Error() == utils.ErrNoRow() {
+			br.Msg = "素材不存在"
+			return
+		}
+		br.Msg = "获取素材库信息失败"
+		br.ErrMsg = "获取素材库信息失败,Err:" + err.Error()
+		return
+	}
+	if info.ImgUrl == "" {
+		br.Msg = "素材地址为空"
+		return
+	}
+
+	fileName := info.MaterialName
+	// 查找文件名中最后一个点的位置
+	dotIndex := strings.LastIndex(info.ImgUrl, ".")
+
+	// 如果找不到点,或者点是文件名的第一个字符(不合法情况),则返回空字符串
+	if dotIndex == -1 || dotIndex == 0 {
+		br.Msg = "素材地址错误"
+		return
+	}
+
+	fileName += "." + info.ImgUrl[dotIndex+1:] // 添加扩展名到文件名
+	// 获取路径中的文件名
+	urlFileName := path.Base(info.ImgUrl)
+	uploadDir := utils.STATIC_DIR + "hongze/" + time.Now().Format("20060102")
+	if e := os.MkdirAll(uploadDir, utils.DIR_MOD); e != nil {
+		br.Msg = "存储目录创建失败"
+		br.ErrMsg = "存储目录创建失败, Err:" + e.Error()
+		return
+	}
+	var content []byte
+	content, err = http.Get(info.ImgUrl)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "资源获取失败, Err: " + err.Error()
+		return
+	}
+	filePath := uploadDir + "/" + urlFileName
+	ioWriter, err := os.Create(filePath)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "文件创建失败, Err: " + err.Error()
+		return
+	}
+	n, err := ioWriter.Write(content)
+	fmt.Println("n", n)
+	if err != nil {
+		br.Msg = "操作失败"
+		br.ErrMsg = "压缩文件写入失败, Err: " + err.Error()
+		return
+	}
+	this.Ctx.Output.Download(filePath, fileName)
+
+	defer func() {
+		_ = os.Remove(filePath)
+	}()
+	br.Ret = 200
+	br.Success = true
+	br.Msg = "success"
+}

+ 35 - 20
models/material/material.go

@@ -12,6 +12,7 @@ import (
 type Material struct {
 	MaterialId      int       `orm:"column(material_id);pk" description:"素材id"`
 	MaterialName    string    `description:"素材名称"`
+	MaterialNameEn  string    `description:"英文素材名称"`
 	ImgUrl          string    `description:"素材图片地址"`
 	SysUserId       int       `description:"作者id"`
 	SysUserRealName string    `description:"作者名称"`
@@ -85,6 +86,7 @@ func UpdateMaterial(materialInfo *Material, updateMaterialColumn []string) (err
 type MaterialListItem struct {
 	MaterialId      int    `description:"素材id"`
 	MaterialName    string `description:"素材名称"`
+	MaterialNameEn  string `description:"英文素材名称"`
 	ImgUrl          string `description:"素材图片地址"`
 	ModifyTime      string `description:"修改时间"`
 	CreateTime      string `description:"创建时间"`
@@ -114,10 +116,6 @@ func CheckOpMaterialPermission(sysUser *system.Admin, createUserId int) (ok bool
 	if ok == false && createUserId == sysUser.AdminId {
 		ok = true
 	}
-	// 如果图表权限id 是 1 ,那么允许编辑
-	if ok == false && sysUser.ChartPermission == 1 {
-		ok = true
-	}
 	return
 }
 
@@ -222,24 +220,14 @@ func GetMaterialByClassifyIdAndName(classifyId int, name string) (item *Material
 	return
 }
 
-// GetMaterialNameByIds 根据素材名称
-func GetMaterialNameByIds(ids []int) (items []*Material, err error) {
+// GetMaterialByIds 根据素材id获取素材信息
+func GetMaterialByIds(ids []int) (items []*MaterialListItems, err error) {
 	o := orm.NewOrmUsingDB("rddp")
-	sql := ` SELECT material_id, material_name FROM material WHERE material_id in (` + utils.GetOrmInReplace(len(ids)) + `) `
+	sql := ` SELECT * FROM material WHERE material_id in (` + utils.GetOrmInReplace(len(ids)) + `) `
 	_, err = o.Raw(sql, ids).QueryRows(&items)
 	return
 }
 
-func MoveMaterial(MaterialId, classifyId int) (err error) {
-	o := orm.NewOrmUsingDB("rddp")
-	sql := ` UPDATE  material
-			SET
-			  classify_id = ?
-			WHERE material_id = ?`
-	_, err = o.Raw(sql, classifyId, MaterialId).Exec()
-	return
-}
-
 // UpdateMaterialSortByClassifyId 根据素材id更新排序
 func UpdateMaterialSortByClassifyId(classifyId, nowSort, prevMaterialId int, updateSort string) (err error) {
 	o := orm.NewOrmUsingDB("rddp")
@@ -295,7 +283,7 @@ type BatchDeleteMaterialReq struct {
 	ClassifyId  int    `description:"分类id"`
 	IsShowMe    bool   `description:"操作人id,支持多选,用英文,隔开"`
 	Keyword     string `description:"关键字"`
-	IsSelectAll bool   `description:"是否选择所有指标"`
+	IsSelectAll bool   `description:"是否选择所有素材"`
 }
 
 type BatchChangeClassifyMaterialReq struct {
@@ -321,10 +309,30 @@ func GetMaterialInfoCountByClassifyIds(classifyIds []string) (count int, err err
 	return
 }
 
-func GetMaterialByNames(materialNames []string) (item *Material, err error) {
+func GetMaterialByNames(materialNames []string) (items []*Material, err error) {
 	o := orm.NewOrmUsingDB("rddp")
 	sql := `SELECT * FROM material WHERE material_name in (` + utils.GetOrmInReplace(len(materialNames)) + `) limit 1`
-	err = o.Raw(sql, materialNames).QueryRow(&item)
+	_, err = o.Raw(sql, materialNames).QueryRows(&items)
+	return
+}
+
+func GetMaterialByNameEns(materialNames []string) (items []*Material, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM material WHERE material_name_en in (` + utils.GetOrmInReplace(len(materialNames)) + `) limit 1`
+	_, err = o.Raw(sql, materialNames).QueryRows(&items)
+	return
+}
+
+func GetMaterialByName(materialName string) (item *Material, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM material WHERE material_name = ?`
+	err = o.Raw(sql, materialName).QueryRow(&item)
+	return
+}
+func GetMaterialByNameEn(materialName string) (item *Material, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT * FROM material WHERE material_name_en = ?`
+	err = o.Raw(sql, materialName).QueryRow(&item)
 	return
 }
 
@@ -335,6 +343,13 @@ func GetMaterialCountByName(materialName string) (count int, err error) {
 	return
 }
 
+func GetMaterialCountByNameEn(materialName string) (count int, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT COUNT(1) AS count FROM material WHERE material_name_en=? `
+	err = o.Raw(sql, materialName).QueryRow(&count)
+	return
+}
+
 // GetMaterialMaxSort 获取最大的排序数
 func GetMaterialMaxSort() (sort int, err error) {
 	o := orm.NewOrmUsingDB("rddp")

+ 26 - 33
models/material/material_classify.go

@@ -10,6 +10,7 @@ import (
 type MaterialClassify struct {
 	ClassifyId      int       `orm:"column(classify_id);pk"`
 	ClassifyName    string    `description:"分类名称"`
+	ClassifyNameEn  string    `description:"英文分类名称"`
 	ParentId        int       `description:"父级id"`
 	CreateTime      time.Time `description:"创建时间"`
 	ModifyTime      time.Time `description:"修改时间"`
@@ -43,16 +44,17 @@ func GetMaterialClassifyAll() (items []*MaterialClassifyItems, err error) {
 }
 
 type MaterialClassifyItems struct {
-	ClassifyId   int       `orm:"column(classify_id);pk"`
-	ClassifyName string    `description:"分类名称"`
-	ParentId     int       `description:"父级id"`
-	CreateTime   time.Time `description:"创建时间"`
-	ModifyTime   time.Time `description:"修改时间"`
-	SysUserId    int       `description:"创建人id"`
-	SysUserName  string    `description:"创建人姓名"`
-	Level        int       `description:"层级"`
-	Sort         int       `description:"排序字段,越小越靠前,默认值:10"`
-	Children     []*MaterialClassifyItems
+	ClassifyId     int       `orm:"column(classify_id);pk"`
+	ClassifyName   string    `description:"分类名称"`
+	ClassifyNameEn string    `description:"英文分类名称"`
+	ParentId       int       `description:"父级id"`
+	CreateTime     time.Time `description:"创建时间"`
+	ModifyTime     time.Time `description:"修改时间"`
+	SysUserId      int       `description:"创建人id"`
+	SysUserName    string    `description:"创建人姓名"`
+	Level          int       `description:"层级"`
+	Sort           int       `description:"排序字段,越小越靠前,默认值:10"`
+	Children       []*MaterialClassifyItems
 }
 
 type MaterialClassifyListResp struct {
@@ -72,6 +74,13 @@ func GetMaterialClassifyNameCount(classifyName string, parentId int) (count int,
 	return
 }
 
+func GetMaterialClassifyNameEnCount(classifyName string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT COUNT(1) AS count FROM material_classify WHERE parent_id=? AND classify_name_en=? `
+	err = o.Raw(sql, parentId, classifyName).QueryRow(&count)
+	return
+}
+
 func GetMaterialClassifyNameNotSelfCount(id int, classifyName string, parentId int) (count int, err error) {
 	o := orm.NewOrmUsingDB("rddp")
 	sql := `SELECT COUNT(1) AS count FROM material_classify WHERE classify_id !=? AND parent_id=? AND classify_name=? `
@@ -79,6 +88,13 @@ func GetMaterialClassifyNameNotSelfCount(id int, classifyName string, parentId i
 	return
 }
 
+func GetMaterialClassifyNameEnNotSelfCount(id int, classifyName string, parentId int) (count int, err error) {
+	o := orm.NewOrmUsingDB("rddp")
+	sql := `SELECT COUNT(1) AS count FROM material_classify WHERE classify_id !=? AND parent_id=? AND classify_name_en=? `
+	err = o.Raw(sql, id, parentId, classifyName).QueryRow(&count)
+	return
+}
+
 // GetMaterialClassifyMaxSort 获取沙盘分类下最大的排序数
 func GetMaterialClassifyMaxSort(parentId int) (sort int, err error) {
 	o := orm.NewOrmUsingDB("rddp")
@@ -99,13 +115,6 @@ func GetMaterialClassifyById(classifyId int) (item *MaterialClassify, err error)
 	return
 }
 
-func EditMaterialClassify(classifyId, ChartPermissionId int, ClassifyName, ChartPermissionName string) (err error) {
-	o := orm.NewOrmUsingDB("rddp")
-	sql := `UPDATE material_classify SET classify_name=?,chart_permission_id = ?, chart_permission_name = ?, modify_time=NOW() WHERE classify_id=? `
-	_, err = o.Raw(sql, ClassifyName, ChartPermissionId, ChartPermissionName, classifyId).Exec()
-	return
-}
-
 type MaterialClassifyDeleteCheckReq struct {
 	ClassifyId int `description:"分类id"`
 }
@@ -198,22 +207,6 @@ type SandboxLinkCheckResp struct {
 	ReportIdList    []*SandboxLinkCheckItem `description:"报告id列表"`
 }
 
-// 获取所有子级分类id
-func GetMaterialClassifySubcategories(classifyId int) (Ids string, err error) {
-	o := orm.NewOrmUsingDB("rddp")
-	sql := `SELECT GROUP_CONCAT(classify_id) AS ids
-FROM (
-SELECT @pv := ? AS classify_id
-UNION ALL
-SELECT sc.classify_id
-FROM material_classify sc
-JOIN (SELECT @pv := ?) initial
-WHERE sc.parent_id = @pv
-) subcategories; `
-	err = o.Raw(sql, classifyId, classifyId).QueryRow(&Ids)
-	return
-}
-
 func GetMaterialClassifyByLevelPath(levelPath string) (items []*MaterialClassify, err error) {
 	o := orm.NewOrmUsingDB("rddp")
 	sql := `SELECT * FROM material_classify where level_path like "` + levelPath + `%"`

+ 18 - 0
routers/commentsRouter.go

@@ -7864,6 +7864,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"],
+        beego.ControllerComments{
+            Method: "BatchDownload",
+            Router: `/batch/download`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"],
         beego.ControllerComments{
             Method: "ChangeClassify",
@@ -7954,6 +7963,15 @@ func init() {
             Filters: nil,
             Params: nil})
 
+    beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"],
+        beego.ControllerComments{
+            Method: "Download",
+            Router: `/download`,
+            AllowHTTPMethods: []string{"post"},
+            MethodParams: param.Make(),
+            Filters: nil,
+            Params: nil})
+
     beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"] = append(beego.GlobalControllerRouter["eta/eta_api/controllers/material:MaterialController"],
         beego.ControllerComments{
             Method: "List",

+ 13 - 2
services/file.go

@@ -89,6 +89,17 @@ func saveToFile(fileMulti multipart.File, tofile string) error {
 	return nil
 }
 
+func saveToFileByHeader(fileHeader *multipart.FileHeader, tofile string) error {
+	src, err := fileHeader.Open()
+	f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
+	if err != nil {
+		return err
+	}
+	defer f.Close()
+	io.Copy(f, src)
+	return nil
+}
+
 // GetResourceUrlBySvgImg
 // @Description: 通过svg图片生成图片资源地址(传到OSS后的地址)
 // @author: Roc
@@ -269,7 +280,7 @@ func AddWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, wmList
 }
 
 // CommonUploadToOssAndFileName 通用上传文件
-func CommonUploadToOssAndFileName(fileMulti multipart.File, newFileName, savePath string) (resourceUrl string, err error) {
+func CommonUploadToOssAndFileName(fileHeader *multipart.FileHeader, newFileName, savePath string) (resourceUrl string, err error) {
 	dateDir := time.Now().Format("20060102")
 	uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
 	err = os.MkdirAll(uploadDir, utils.DIR_MOD)
@@ -280,7 +291,7 @@ func CommonUploadToOssAndFileName(fileMulti multipart.File, newFileName, savePat
 
 	//本地地址
 	fpath := uploadDir + "/" + newFileName
-	err = saveToFile(fileMulti, fpath)
+	err = saveToFileByHeader(fileHeader, fpath)
 	if err != nil {
 		err = errors.New("文件上传失败,Err:" + err.Error())
 		return

+ 5 - 3
services/material/material.go

@@ -73,6 +73,7 @@ func BatchAddMaterial(materialList []material.BatchAddMaterialItem, classifyId,
 		sort = sort + 1
 		addList = append(addList, &material.Material{
 			MaterialName:    v.MaterialName,
+			MaterialNameEn:  v.MaterialName,
 			ImgUrl:          v.ImgUrl,
 			SysUserId:       opUserId,
 			SysUserRealName: opUserName,
@@ -94,6 +95,7 @@ func AddMaterial(req material.AddAndEditMaterial, opUserId int, opUserName strin
 	//素材主表信息
 	materialInfo := &material.Material{
 		MaterialName:    utils.TrimStr(req.MaterialName),
+		MaterialNameEn:  utils.TrimStr(req.MaterialName),
 		ImgUrl:          utils.TrimStr(req.ImgUrl),
 		SysUserId:       opUserId,
 		SysUserRealName: opUserName,
@@ -188,7 +190,7 @@ func MoveMaterialClassify(classifyInfo *material.MaterialClassify, req *material
 		classifyInfo.ModifyTime = nodeInfo.ModifyTime
 		classifyInfo.ParentId = nodeInfo.ParentId
 
-		levelPath := ""
+		levelPath := classifyInfo.LevelPath
 		if classifyInfo.ParentId != oldParentId {
 			//查找父级分类
 			parentClassify, e := material.GetMaterialClassifyById(classifyInfo.ParentId)
@@ -198,9 +200,9 @@ func MoveMaterialClassify(classifyInfo *material.MaterialClassify, req *material
 				return
 			}
 			levelPath = fmt.Sprintf("%s,%d", parentClassify.LevelPath, classifyInfo.ClassifyId)
+			classifyInfo.LevelPath = levelPath
+			updateCol = append(updateCol, "LevelPath")
 		}
-		classifyInfo.LevelPath = levelPath
-		updateCol = append(updateCol, "LevelPath")
 		err = classifyInfo.Update(updateCol)
 		if err != nil {
 			err = fmt.Errorf("修改失败,Err:" + err.Error())