提几个建议
Opened this issue · 2 comments
一是没有favicon,强迫症受不了。
二是检查一下为何经常出现上传失败,而且毫无规律
三是建议加上图片压缩功能,用户可选
因为对于vercel用户最大上传5mb,所以加入上传压缩功能
package control
import (
"encoding/json"
"html/template"
"image"
"image/jpeg"
"io"
"log"
"net/http"
"path/filepath"
"strconv"
"strings"
"golang.org/x/image/bmp"
"golang.org/x/image/tiff"
"csz.net/tgstate/assets"
"csz.net/tgstate/conf"
"csz.net/tgstate/utils"
)
// UploadImageAPI 上传图片api
func UploadImageAPI(w http.ResponseWriter, r http.Request) {
w.Header().Set("Access-Control-Allow-Origin", "")
if r.Method == http.MethodPost {
// 获取上传的文件
file, header, err := r.FormFile("image")
if err != nil {
errJsonMsg("Unable to get file", w)
return
}
defer file.Close()
// 检查文件大小
fileInfo, err := file.Stat()
if err != nil {
errJsonMsg("Error getting file info", w)
return
}
if fileInfo.Size() > 5*1024*1024 {
errJsonMsg("File size exceeds 5MB limit", w)
return
}
// 检查文件类型
allowedExts := []string{".jpg", ".jpeg", ".png", ".bmp", ".tiff"}
ext := strings.ToLower(filepath.Ext(header.Filename))
valid := false
for _, allowedExt := range allowedExts {
if ext == allowedExt {
valid = true
break
}
}
if !valid {
errJsonMsg("Invalid file type. Only .jpg, .jpeg, .png, .bmp, .tiff are allowed.", w)
return
}
// 读取文件内容
imgData, err := io.ReadAll(file)
if err != nil {
errJsonMsg("Error reading file data", w)
return
}
// 压缩图像
img, _, err := image.Decode(bytes.NewReader(imgData))
if err != nil {
errJsonMsg("Error decoding image", w)
return
}
// 将图像压缩到5MB以下
buf := new(bytes.Buffer)
if ext == ".jpg" || ext == ".jpeg" {
err = jpeg.Encode(buf, img, &jpeg.Options{Quality: 75})
} else if ext == ".png" {
// PNG压缩较为复杂,这里简单示例
err = png.Encode(buf, img)
} else if ext == ".bmp" {
err = bmp.Encode(buf, img)
} else if ext == ".tiff" {
err = tiff.Encode(buf, img, nil)
}
if err != nil {
errJsonMsg("Error encoding image", w)
return
}
// 检查压缩后的文件大小
if buf.Len() > 5*1024*1024 {
errJsonMsg("Compressed file size exceeds 5MB limit", w)
return
}
// 保存压缩后的图像
imgData = buf.Bytes()
res := conf.UploadResponse{
Code: 0,
Message: "error",
}
img := conf.FileRoute + utils.UpDocument(utils.TgFileData(header.Filename, bytes.NewReader(imgData)))
if img != conf.FileRoute {
res = conf.UploadResponse{
Code: 1,
Message: img,
ImgUrl: strings.TrimSuffix(conf.BaseUrl, "/") + img,
}
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(res)
return
}
// 如果不是POST请求,返回错误响应
http.Error(w, "Invalid request method", http.StatusMethodNotAllowed)
}
func errJsonMsg(msg string, w http.ResponseWriter) {
// 这里示例直接返回JSON响应
response := conf.UploadResponse{
Code: 0,
Message: msg,
}
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(response)
}