You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

182 lines
5.2 KiB

/*
* GodoAI - A software focused on localizing AI applications
* Copyright (C) 2024 https://godoos.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package image
import (
"encoding/json"
"io"
"log"
"math/rand"
"mime"
"net/http"
"os"
"path/filepath"
"strings"
)
// UploadHandler 处理单张图片上传的HTTP请求
func UploadHandler(w http.ResponseWriter, r *http.Request) {
// 设置允许的Content-Type
//r.Header.Set("Content-Type", "multipart/form-data")
// 解析上传的文件
err := r.ParseMultipartForm(10000 << 20) // 限制最大上传大小为1000MB
if err != nil {
http.Error(w, "上传文件过大"+err.Error(), http.StatusBadRequest)
return
}
file, header, err := r.FormFile("files") // 假设表单字段名为"files"
if err != nil {
http.Error(w, "没有找到文件", http.StatusBadRequest)
return
}
defer file.Close()
// 读取文件内容
fileBytes, err := io.ReadAll(file)
if err != nil {
log.Printf("读取文件内容出错: %v", err)
http.Error(w, "读取文件内容出错", http.StatusInternalServerError)
return
}
imagePath, err := GetImageDir()
if err != nil {
log.Printf("获取图片目录出错: %v", err)
http.Error(w, "获取图片目录出错", http.StatusInternalServerError)
return
}
// 生成随机文件名并保留原扩展名
randomName := generateRandomString(10) + filepath.Ext(header.Filename)
savePath := filepath.Join(imagePath, randomName)
out, err := os.Create(savePath)
if err != nil {
log.Printf("创建文件出错: %v", err)
http.Error(w, "保存文件出错", http.StatusInternalServerError)
return
}
defer out.Close()
// 将文件内容写入到服务器上的文件
_, err = out.Write(fileBytes)
if err != nil {
log.Printf("写入文件出错: %v", err)
http.Error(w, "写入文件出错", http.StatusInternalServerError)
return
}
type ResJson struct {
Path string `json:"path"`
}
resJson := ResJson{Path: savePath}
w.Header().Set("Content-Type", "application/json")
if err := json.NewEncoder(w).Encode(resJson); err != nil {
log.Printf("json encode error: %v", err)
}
// jsonStr := fmt.Sprintf(`{"code": 0, "message": "上传成功", "data":"%s"}`, savePath)
// w.Header().Set("Content-Type", "application/json")
// w.Write([]byte(jsonStr))
}
func ServeImage(w http.ResponseWriter, r *http.Request) {
// 从 URL 查询参数中获取图片路径
imagePath := r.URL.Query().Get("path")
//log.Printf("imagePath: %s", imagePath)
// 检查图片路径是否为空或无效
if imagePath == "" {
http.Error(w, "Invalid image path", http.StatusBadRequest)
return
}
// 确保图片路径是绝对路径
absImagePath, err := filepath.Abs(imagePath)
//log.Printf("absImagePath: %s", absImagePath)
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 获取文件的 MIME 类型
mimeType := mime.TypeByExtension(filepath.Ext(absImagePath))
if mimeType == "" {
mimeType = "application/octet-stream" // 如果无法识别,就用默认的二进制流类型
}
// 设置响应头的 MIME 类型
w.Header().Set("Content-Type", mimeType)
// 打开文件并读取内容
file, err := os.Open(absImagePath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer file.Close()
// 将文件内容写入响应体
_, err = io.Copy(w, file)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}
// DeleteImageHandler 处理删除图片的HTTP请求
func DeleteImageHandler(w http.ResponseWriter, r *http.Request) {
// 解析请求体中的JSON数据
var data map[string]string
err := json.NewDecoder(r.Body).Decode(&data)
if err != nil {
http.Error(w, "无法解析请求数据", http.StatusBadRequest)
return
}
imgPath, ok := data["path"]
if !ok || imgPath == "" {
http.Error(w, "缺少图片路径数据", http.StatusBadRequest)
return
}
// 检查图片路径是否有效
if _, err := os.Stat(imgPath); os.IsNotExist(err) {
http.Error(w, "图片不存在", http.StatusNotFound)
return
}
// 删除图片
err = os.Remove(imgPath)
if err != nil {
log.Printf("删除文件出错: %v", err)
http.Error(w, "删除文件出错", http.StatusInternalServerError)
return
}
jsonStr := `{"code": 0, "message": "图片删除成功"}`
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(jsonStr))
}
// 生成随机字符串
func generateRandomString(length int) string {
//rand.Seed(time.Now().UnixNano())
const charset = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
var result strings.Builder
for i := 0; i < length; i++ {
result.WriteByte(charset[rand.Intn(len(charset))])
}
return result.String()
}