|  | @@ -1,15 +1,20 @@
 | 
	
		
			
				|  |  |  package upload
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  import (
 | 
	
		
			
				|  |  | +	"bytes"
 | 
	
		
			
				|  |  |  	"fmt"
 | 
	
		
			
				|  |  | +	"io"
 | 
	
		
			
				|  |  |  	"kpt-pasture/config"
 | 
	
		
			
				|  |  |  	"kpt-pasture/http/middleware"
 | 
	
		
			
				|  |  |  	"net/http"
 | 
	
		
			
				|  |  |  	"os"
 | 
	
		
			
				|  |  | +	"path/filepath"
 | 
	
		
			
				|  |  | +	"time"
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	"gitee.com/xuyiping_admin/pkg/apierr"
 | 
	
		
			
				|  |  |  	"gitee.com/xuyiping_admin/pkg/xerr"
 | 
	
		
			
				|  |  |  	"github.com/gin-gonic/gin"
 | 
	
		
			
				|  |  | +	"github.com/xuri/excelize/v2"
 | 
	
		
			
				|  |  |  )
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func Photos(c *gin.Context) {
 | 
	
	
		
			
				|  | @@ -36,7 +41,145 @@ func Photos(c *gin.Context) {
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func Files(c *gin.Context) {
 | 
	
		
			
				|  |  | +	// 获取上传的文件
 | 
	
		
			
				|  |  | +	file, err := c.FormFile("file")
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Customf("获取文件失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 检查文件类型
 | 
	
		
			
				|  |  | +	ext := filepath.Ext(file.Filename)
 | 
	
		
			
				|  |  | +	if ext != ".xlsx" && ext != ".xls" {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Custom("只支持Excel文件(.xlsx, .xls)"))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 检查文件大小
 | 
	
		
			
				|  |  | +	if file.Size == 0 {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Custom("文件为空"))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 创建保存目录
 | 
	
		
			
				|  |  | +	uploadDir := fmt.Sprintf("%s/files/excel", config.WorkDir)
 | 
	
		
			
				|  |  | +	if err := os.MkdirAll(uploadDir, 0755); err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("创建目录失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 生成唯一文件名
 | 
	
		
			
				|  |  | +	filename := fmt.Sprintf("%d%s", time.Now().UnixNano(), ext)
 | 
	
		
			
				|  |  | +	filePath := filepath.Join(uploadDir, filename)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 保存文件
 | 
	
		
			
				|  |  | +	if err := c.SaveUploadedFile(file, filePath); err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("保存文件失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 打开上传的文件
 | 
	
		
			
				|  |  | +	src, err := file.Open()
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("打开文件失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	defer src.Close()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 读取文件内容
 | 
	
		
			
				|  |  | +	fileBytes, err := io.ReadAll(src)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("读取文件内容失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 检查文件头部签名
 | 
	
		
			
				|  |  | +	if len(fileBytes) < 8 {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Custom("文件格式不正确"))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 检查Excel文件签名
 | 
	
		
			
				|  |  | +	isExcel := false
 | 
	
		
			
				|  |  | +	if ext == ".xlsx" {
 | 
	
		
			
				|  |  | +		// XLSX文件签名
 | 
	
		
			
				|  |  | +		if bytes.Equal(fileBytes[:4], []byte{0x50, 0x4B, 0x03, 0x04}) {
 | 
	
		
			
				|  |  | +			isExcel = true
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	} else if ext == ".xls" {
 | 
	
		
			
				|  |  | +		// XLS文件签名
 | 
	
		
			
				|  |  | +		if bytes.Equal(fileBytes[:8], []byte{0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1}) {
 | 
	
		
			
				|  |  | +			isExcel = true
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	if !isExcel {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Custom("文件格式不正确,请确保上传的是有效的Excel文件"))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 读取Excel文件
 | 
	
		
			
				|  |  | +	options := excelize.Options{
 | 
	
		
			
				|  |  | +		RawCellValue: true,
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	f, err := excelize.OpenReader(bytes.NewReader(fileBytes), options)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		// 如果直接读取失败,尝试从保存的文件读取
 | 
	
		
			
				|  |  | +		f, err = excelize.OpenFile(filePath)
 | 
	
		
			
				|  |  | +		if err != nil {
 | 
	
		
			
				|  |  | +			apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("读取Excel文件失败,请确保文件格式正确: %s", err.Error()))
 | 
	
		
			
				|  |  | +			return
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +	defer f.Close()
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 获取第一个工作表
 | 
	
		
			
				|  |  | +	sheetName := f.GetSheetName(0)
 | 
	
		
			
				|  |  | +	rows, err := f.GetRows(sheetName)
 | 
	
		
			
				|  |  | +	if err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusInternalServerError, xerr.Customf("读取工作表失败: %s", err.Error()))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 处理Excel数据
 | 
	
		
			
				|  |  | +	if len(rows) < 2 {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Custom("Excel文件数据为空"))
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 获取表头并转换为中文
 | 
	
		
			
				|  |  | +	headers := rows[0]
 | 
	
		
			
				|  |  | +	headerMap := make(map[string]string)
 | 
	
		
			
				|  |  | +	for _, header := range headers {
 | 
	
		
			
				|  |  | +		headerMap[header] = header
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 处理数据行
 | 
	
		
			
				|  |  | +	var data []map[string]string
 | 
	
		
			
				|  |  | +	for i, row := range rows[1:] {
 | 
	
		
			
				|  |  | +		if len(row) != len(headers) {
 | 
	
		
			
				|  |  | +			apierr.AbortBadRequest(c, http.StatusBadRequest, xerr.Customf("第%d行数据列数与表头不匹配", i+2))
 | 
	
		
			
				|  |  | +			return
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +		rowData := make(map[string]string)
 | 
	
		
			
				|  |  | +		for j, cell := range row {
 | 
	
		
			
				|  |  | +			rowData[headers[j]] = cell
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +		data = append(data, rowData)
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	// 调用后端服务处理数据
 | 
	
		
			
				|  |  | +	if err := middleware.BackendOperation(c).OpsService.ImportExcel(c, data); err != nil {
 | 
	
		
			
				|  |  | +		apierr.AbortBadRequest(c, http.StatusBadRequest, err)
 | 
	
		
			
				|  |  | +		return
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +	c.JSON(http.StatusOK, gin.H{
 | 
	
		
			
				|  |  | +		"code": http.StatusOK,
 | 
	
		
			
				|  |  | +		"msg":  "导入成功",
 | 
	
		
			
				|  |  | +		"data": nil,
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func OssVideo(c *gin.Context) {
 |