Backend:
- ProductImagesController: GET list / POST multipart upload /
DELETE / POST set-main.
- Файлы лежат в $ContentRoot/uploads/products/{productId}/{guid}.{ext}
(volume /opt/food-market-data/uploads:/app/uploads в compose).
- В БД хранится относительный URL /uploads/products/{id}/{file}.
- UseStaticFiles на /uploads — публичная раздача (без auth).
- Допустимые расширения: jpg/jpeg/png/webp/gif, до 10 МБ.
- При первой загрузке картинка становится основной; Product.ImageUrl
синхронизируется с "основной".
- Удаление основной переводит "основной" флаг на следующую оставшуюся.
Web-nginx: /uploads/ проксируется на api:8080.
Web UI:
- Компонент <ProductImageGallery>: превьюшки 80×80 в грид,
при наведении — кнопки "сделать основным" и "удалить",
клик на превью → fullscreen lightbox с навигацией ←→ и счётчиком.
- В ProductEditPage убран инпут "URL изображения" (был технической
строкой для копипаста), вместо него блок "Изображения" с галереей.
Показывается только для уже сохранённого товара (есть id).
Docker compose: добавлен bind-mount /opt/food-market-data/uploads.
55 lines
1.7 KiB
Nginx Configuration File
55 lines
1.7 KiB
Nginx Configuration File
server {
|
|
listen 80 default_server;
|
|
root /usr/share/nginx/html;
|
|
index index.html;
|
|
|
|
# Long-running admin imports (MoySklad etc.) read from upstream for tens of
|
|
# minutes. Bump timeouts only on that path so normal API stays snappy.
|
|
location /api/admin/import/ {
|
|
proxy_pass http://api:8080;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_read_timeout 60m;
|
|
proxy_send_timeout 60m;
|
|
proxy_request_buffering off;
|
|
proxy_buffering off;
|
|
}
|
|
|
|
# API reverse-proxy — upstream name "api" resolves in the compose network.
|
|
location /api/ {
|
|
proxy_pass http://api:8080;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
proxy_set_header Upgrade $http_upgrade;
|
|
proxy_set_header Connection "upgrade";
|
|
}
|
|
|
|
location /connect/ {
|
|
proxy_pass http://api:8080;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
location /health {
|
|
proxy_pass http://api:8080;
|
|
}
|
|
|
|
# Статика изображений товаров — api раздаёт /uploads/... из volume.
|
|
location /uploads/ {
|
|
proxy_pass http://api:8080;
|
|
proxy_http_version 1.1;
|
|
proxy_set_header Host $host;
|
|
}
|
|
|
|
# SPA fallback — all other routes return index.html
|
|
location / {
|
|
try_files $uri $uri/ /index.html;
|
|
}
|
|
}
|