fix
@@ -0,0 +1,60 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
)
|
||||
|
||||
func main() {
|
||||
dir := "./uploads/items"
|
||||
files, err := os.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, f := range files {
|
||||
if f.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
if f.Name() == "background.png" {
|
||||
continue
|
||||
}
|
||||
|
||||
ext := strings.ToLower(filepath.Ext(f.Name()))
|
||||
if ext != ".jpg" && ext != ".jpeg" && ext != ".png" {
|
||||
continue
|
||||
}
|
||||
|
||||
path := filepath.Join(dir, f.Name())
|
||||
|
||||
info, _ := f.Info()
|
||||
oldSize := info.Size()
|
||||
|
||||
img, err := imaging.Open(path)
|
||||
if err != nil {
|
||||
fmt.Printf("Ошибка открытия %s: %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
resized := imaging.Resize(img, 1200, 0, imaging.Lanczos)
|
||||
|
||||
err = imaging.Save(resized, path, imaging.JPEGQuality(82))
|
||||
if err != nil {
|
||||
fmt.Printf("Ошибка записи %s: %v\n", f.Name(), err)
|
||||
continue
|
||||
}
|
||||
|
||||
newInfo, _ := os.Stat(path)
|
||||
newSize := newInfo.Size()
|
||||
|
||||
fmt.Printf("%s: %d КБ -> %d КБ\n", f.Name(), oldSize/1024, newSize/1024)
|
||||
}
|
||||
|
||||
fmt.Println("Готово")
|
||||
}
|
||||
@@ -3,9 +3,11 @@ module fishfish
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/disintegration/imaging v1.6.2
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
golang.org/x/crypto v0.48.0
|
||||
gorm.io/driver/postgres v1.5.7
|
||||
@@ -42,6 +44,7 @@ require (
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
|
||||
golang.org/x/arch v0.22.0 // indirect
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 // indirect
|
||||
golang.org/x/net v0.51.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
|
||||
@@ -9,6 +9,8 @@ github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gE
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12 h1:e9hWvmLYvtp846tLHam2o++qitpguFiYCKbn0w9jyqw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.12/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
@@ -34,6 +36,8 @@ github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArs
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
|
||||
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
|
||||
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
|
||||
@@ -91,11 +95,14 @@ golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
|
||||
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=
|
||||
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/net v0.51.0 h1:94R/GTO7mt3/4wIKpcR5gkGmRLOuE/2hNGeWq/GBIFo=
|
||||
golang.org/x/net v0.51.0/go.mod h1:aamm+2QF5ogm02fjy5Bb7CQ0WMt1/WVM7FtyaTLlA9Y=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
|
||||
@@ -3,8 +3,11 @@ package handlers
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"fishfish/database"
|
||||
"fishfish/models"
|
||||
@@ -116,3 +119,46 @@ func GetCategories(c *gin.Context) {
|
||||
|
||||
c.JSON(http.StatusOK, categories)
|
||||
}
|
||||
|
||||
func UploadItemAvatar(c *gin.Context) {
|
||||
itemID := c.Param("id")
|
||||
|
||||
var item models.Item
|
||||
|
||||
if err := database.DB.First(&item, itemID).Error; err != nil {
|
||||
c.JSON(http.StatusNotFound, gin.H{"error": "Товар не найден"})
|
||||
return
|
||||
}
|
||||
|
||||
file, err := c.FormFile("avatar")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Файл не найден в запросе"})
|
||||
return
|
||||
}
|
||||
|
||||
src, err := file.Open()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось открыть файл"})
|
||||
}
|
||||
defer src.Close()
|
||||
|
||||
img, err := imaging.Decode(src)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "Не удалось обработать фотографию"})
|
||||
return
|
||||
}
|
||||
|
||||
resized := imaging.Resize(img, 1200, 0, imaging.Lanczos)
|
||||
uniqueName := uuid.New().String() + ".jpg"
|
||||
dstPath := filepath.Join("./uploads/items", uniqueName)
|
||||
|
||||
if err := imaging.Save(resized, dstPath, imaging.JPEGQuality(82)); err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Не удалось сохранить фотографию"})
|
||||
return
|
||||
}
|
||||
|
||||
item.AvatarURL = "/uploads/items" + uniqueName
|
||||
database.DB.Save(&item)
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"avatar_url": item.AvatarURL})
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 138 KiB After Width: | Height: | Size: 334 KiB |
|
Before Width: | Height: | Size: 102 KiB After Width: | Height: | Size: 218 KiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 321 KiB |
|
Before Width: | Height: | Size: 117 KiB After Width: | Height: | Size: 369 KiB |
|
Before Width: | Height: | Size: 741 KiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 293 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 667 KiB |
|
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 225 KiB |
|
Before Width: | Height: | Size: 328 KiB After Width: | Height: | Size: 283 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 236 KiB |
|
Before Width: | Height: | Size: 279 KiB After Width: | Height: | Size: 367 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 275 KiB |
|
Before Width: | Height: | Size: 139 KiB After Width: | Height: | Size: 299 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 232 KiB |
|
After Width: | Height: | Size: 9.8 MiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 741 KiB |
|
After Width: | Height: | Size: 93 KiB |
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 328 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 279 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 139 KiB |
|
After Width: | Height: | Size: 52 KiB |