test
@@ -24,11 +24,11 @@ class Controller extends ExController
|
||||
public function index()
|
||||
{
|
||||
$this->authorize('view', 'categories');
|
||||
$categories = Category::select('id', 'name->ru as category', 'position', 'parent_id')
|
||||
$categories = Category::select('id', 'name->ru as category', 'position', 'parent_id', 'image')
|
||||
->where('parent_id', null)
|
||||
->with(['children' => function ($parent) {
|
||||
return $parent->select('id', 'name->ru as category', 'parent_id', 'position')->orderBy('position', 'asc')->with(['children' => function ($parent) {
|
||||
return $parent->select('id', 'name->ru as category', 'parent_id', 'position')->orderBy('position', 'asc');
|
||||
return $parent->select('id', 'name->ru as category', 'parent_id', 'position', 'image')->orderBy('position', 'asc')->with(['children' => function ($parent) {
|
||||
return $parent->select('id', 'name->ru as category', 'parent_id', 'position', 'image')->orderBy('position', 'asc');
|
||||
}]);
|
||||
}])->orderBy('position', 'asc')->get();
|
||||
|
||||
@@ -102,11 +102,7 @@ class Controller extends ExController
|
||||
return view('dashboard.category.update', compact('parent_categories', 'category', 'brands'));
|
||||
}
|
||||
|
||||
if ($request->hasFile('image')) {
|
||||
$image = $request->file('image')->store('uploads/categories', 'local');
|
||||
} else {
|
||||
$image = $category->image;
|
||||
}
|
||||
$image = $request->getImage($category);
|
||||
|
||||
$this->dispatchSync(new UpdateJob($category, $request, $image));
|
||||
|
||||
|
||||
@@ -53,6 +53,8 @@ class Category extends Model
|
||||
'title_seo' => 'array',
|
||||
'is_filter_power' => 'boolean'
|
||||
];
|
||||
|
||||
protected $appends = ['image_url'];
|
||||
|
||||
protected $hidden = [
|
||||
'created_at',
|
||||
@@ -137,6 +139,11 @@ class Category extends Model
|
||||
return '';
|
||||
}
|
||||
|
||||
public function getImageUrlAttribute(): string
|
||||
{
|
||||
return $this->getImage();
|
||||
}
|
||||
|
||||
public function getImage(): string
|
||||
{
|
||||
if (!in_array($this->image, ['null', null])) {
|
||||
|
||||
@@ -26,7 +26,7 @@ class AppServiceProvider extends ServiceProvider
|
||||
date_default_timezone_set('Asia/Tashkent');
|
||||
// set lang to uz
|
||||
if (App::environment(['staging', 'production'])) {
|
||||
URL::forceScheme('https');
|
||||
URL::forceScheme('http');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
82
deployment_guide.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Production Deployment Guide
|
||||
|
||||
Ushbu yo'riqnoma local o'zgarishlarni (MinIO va API ulanishlari) serverga (Production) ko'chirish uchun kerakli qadamlarni o'z ichiga oladi.
|
||||
|
||||
## 1. Backend (Laravel) - `api.quyoshli.uz`
|
||||
|
||||
Serverga kirib, loyiha papkasida quyidagi ishlarni bajaring:
|
||||
|
||||
### `.env` faylini yangilash
|
||||
Production serverda local MinIO emas, balki **haqiqiy masofaviy MinIO** ma'lumotlari bo'lishi kerak:
|
||||
```env
|
||||
FILESYSTEM_DISK=s3
|
||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
||||
|
||||
MINIO_ACCESS_KEY=1121RspAhfuxdjqCrkXH
|
||||
MINIO_SECRET_KEY=97rvdUg266dIAseFKeJ3l2cHRavRmCrhEDQTvaDH
|
||||
MINIO_BUCKET=quyoshli
|
||||
MINIO_ENDPOINT=https://minio.quyoshli.uz
|
||||
```
|
||||
> [!IMPORTANT]
|
||||
> Masofaviy MinIO-da `AWS_USE_PATH_STYLE_ENDPOINT=false` bo'lishi mumkin (sozlamaga qarab), lekin odatda HTTPS endpointlar uchun `false` ishlatiladi.
|
||||
|
||||
### Buyruqlar ketma-ketligi
|
||||
```bash
|
||||
# Kodni yangilash
|
||||
git pull origin main
|
||||
|
||||
# Bog'liqliklarni o'rnatish
|
||||
composer install --no-dev --optimize-autoloader
|
||||
|
||||
# Ma'lumotlar bazasini yangilash
|
||||
php artisan migrate --force
|
||||
|
||||
# Keshni tozalash va optimizatsiya
|
||||
php artisan optimize
|
||||
php artisan config:cache
|
||||
php artisan view:cache
|
||||
|
||||
# Frontend assetlarni yig'ish (agar Laravel Vite ishlatilsa)
|
||||
npm install
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Ruxsatnomalar (Permissions)
|
||||
Serverda papkalarga to'g'ri ruxsat berish juda muhim:
|
||||
```bash
|
||||
sudo chown -R www-data:www-data storage bootstrap/cache public/uploads
|
||||
sudo chmod -R 775 storage bootstrap/cache public/uploads
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Frontend (Next.js) - `getgreen.uz`
|
||||
|
||||
Frontend loyihasida `.env` faylini quyidagicha sozlashingiz kerak:
|
||||
|
||||
### `.env` fayli
|
||||
```env
|
||||
API_URL=https://api.quyoshli.uz/api
|
||||
PORT=3000
|
||||
```
|
||||
|
||||
### Qayta qurish (Rebuild)
|
||||
Agar Docker ishlatayotgan bo'lsangiz:
|
||||
```bash
|
||||
docker-compose up -d --build
|
||||
```
|
||||
Agar Docker-siz bo'lsa:
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
pm2 restart all # yoki boshqa process manager
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. MinIO Sozlamalari (Masofaviy)
|
||||
Masofaviy MinIO serveringizda `quyoshli` bucket-i yaratilganiga va ruxsatnomalari (Policy) to'g'ri sozlanganiga ishonch hosil qiling:
|
||||
- Rasmlar hamma uchun ochiq bo'lishi uchun Bucket Policy-ni **Public** yoki **Read-only** qilib sozlash tavsiya etiladi.
|
||||
|
||||
> [!TIP]
|
||||
> Agar rasmlar production-da ko'rinmasa, `.env` faylidagi `AWS_USE_PATH_STYLE_ENDPOINT` qiymatini `true` yoki `false` qilib almashtirib ko'ring.
|
||||
0
public/uploads/calc/2026/04/15/YyqWQsuViSt04C9Wdty66GljQvCCWFkpLqLHMS8N.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
|
After Width: | Height: | Size: 151 KiB |
0
public/uploads/posters/2026/04/15/TrLZTb7KVgadw1yLaKzInuv4BecNYTwwRilUkfwy.png
Normal file → Executable file
|
Before Width: | Height: | Size: 146 KiB After Width: | Height: | Size: 146 KiB |
0
public/uploads/posters/thumbs/2026/04/15/TrLZTb7KVgadw1yLaKzInuv4BecNYTwwRilUkfwy.png
Normal file → Executable file
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
0
public/uploads/screens/2026/04/15/hi4Ts1no1D6bCvqGT6sx46zpWVNaL9NnuTCHG3bS.png
Normal file → Executable file
|
Before Width: | Height: | Size: 1.9 MiB After Width: | Height: | Size: 1.9 MiB |
0
public/uploads/screens/thumbs/2026/04/15/hi4Ts1no1D6bCvqGT6sx46zpWVNaL9NnuTCHG3bS.png
Normal file → Executable file
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
@@ -71,9 +71,10 @@
|
||||
></i>
|
||||
|
||||
</b>
|
||||
<span>
|
||||
<span class="d-flex align-items-center">
|
||||
<b>ID: {{ data.id }} </b>
|
||||
{{ data.category }}
|
||||
<img v-if="data.image_url" :src="data.image_url" style="width: 30px; height: 30px; object-fit: cover; margin-left: 10px; border-radius: 4px;" alt="">
|
||||
<span class="ml-1">{{ data.category }}</span>
|
||||
</span>
|
||||
|
||||
<div class="ml-auto">
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
width: 300px;
|
||||
height: auto;
|
||||
"
|
||||
:src="category.image"
|
||||
:src="category.image_url"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||