处理冲突
commit
ce8ee04df9
|
|
@ -51,12 +51,13 @@ class Components extends BaseRenderer {
|
|||
->options([
|
||||
"menubar" => false,
|
||||
"min_height" => 500,
|
||||
"toolbar" => "undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | image link | outdent indent | numlist bullist | forecolor backcolor removeformat | charmap emoticons",
|
||||
"plugins" => 'image link table lists charmap emoticons code table fullscreen',
|
||||
"toolbar" => "undo redo | bold italic underline strikethrough | fontfamily fontsize blocks | alignleft aligncenter alignright alignjustify | image link | outdent indent | numlist bullist table | forecolor backcolor removeformat | charmap emoticons | code fullscreen",
|
||||
"toolbar_mode" => "wrap",
|
||||
"help_tabs" => [],
|
||||
"convert_urls" => false,
|
||||
"quickbars_selection_toolbar" => "fontsize forecolor backcolor",
|
||||
"toolbar_mode" => "wrap",
|
||||
"quickbars_insert_toolbar" => false,
|
||||
// "quickbars_selection_toolbar" => "fontsize forecolor backcolor",
|
||||
// "quickbars_insert_toolbar" => false,
|
||||
])
|
||||
->receiver(admin_url('upload_rich'))
|
||||
->name($name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace App\Casts;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Illuminate\Support\Facades\Storage as StorageFacades;
|
||||
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
|
||||
|
||||
/**
|
||||
* 转换文件存储路径
|
||||
*
|
||||
* get: 返回全路径
|
||||
* set: 原样保存
|
||||
*/
|
||||
class Storage implements CastsAttributes
|
||||
{
|
||||
protected $disk;
|
||||
|
||||
function __construct($disk = 'public')
|
||||
{
|
||||
$this->disk = $disk;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cast the given value.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param mixed $value
|
||||
* @param array $attributes
|
||||
* @return array
|
||||
*/
|
||||
public function get($model, $key, $value, $attributes)
|
||||
{
|
||||
return $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : StorageFacades::disk($this->disk)->url($value)) : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the given value for storage.
|
||||
*
|
||||
* @param \Illuminate\Database\Eloquent\Model $model
|
||||
* @param string $key
|
||||
* @param array $value
|
||||
* @param array $attributes
|
||||
* @return string
|
||||
*/
|
||||
public function set($model, $key, $value, $attributes)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
|
@ -44,6 +44,7 @@ class Handler extends ExceptionHandler
|
|||
*/
|
||||
public function register()
|
||||
{
|
||||
// Laravel9.x 无法捕获 ModelNotFoundException, 在父类 prepareException 方法中被转换为 Symfony\Component\HttpKernel\Exception\NotFoundHttpException
|
||||
$this->renderable(function (\Illuminate\Database\Eloquent\ModelNotFoundException $e, Request $request) {
|
||||
if ($request->acceptsJson()) {
|
||||
return response()->json(['status' => 404, 'msg' => '资源不存在', 'data' => null], 200);
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ class ArticleController extends Controller
|
|||
|
||||
$list = $query->paginate($request->input('per_page'));
|
||||
|
||||
|
||||
|
||||
return $this->json(ArticleResource::collection($list));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Api;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\{Region, RegionCategory};
|
||||
use App\Http\Resources\{RegionResource, RegionCategoryResource, RegionPlantResource, PlantHarvestResource};
|
||||
use App\Filters\Admin\RegionFilter;
|
||||
|
||||
class RegionController extends Controller
|
||||
{
|
||||
public function category(Request $request)
|
||||
{
|
||||
$list = RegionCategory::query()->show()->sort()->get();
|
||||
|
||||
return $this->json(RegionCategoryResource::collection($list));
|
||||
}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
$query = Region::with(['currentPlant'])->filter($request->all(), RegionFilter::class)->sort()->show();
|
||||
|
||||
$list = $query->paginate($request->input('per_page'));
|
||||
|
||||
return $this->json(RegionResource::collection($list));
|
||||
}
|
||||
|
||||
public function show($id)
|
||||
{
|
||||
$info = Region::with(['currentPlant'])->show()->findOrFail($id);
|
||||
|
||||
return $this->json(RegionResource::make($info));
|
||||
}
|
||||
|
||||
public function plants($id, Request $request)
|
||||
{
|
||||
$info = Region::show()->findOrFail($id);
|
||||
|
||||
$query = $info->plants();
|
||||
$per = $request->input('per_page');
|
||||
if ($per == -1) {
|
||||
$list = $query->get();
|
||||
} else {
|
||||
$list = $query->paginate($per);
|
||||
}
|
||||
|
||||
return $this->json(RegionPlantResource::collection($list));
|
||||
}
|
||||
|
||||
public function harvests($id, Request $request)
|
||||
{
|
||||
$info = Region::show()->findOrFail($id);
|
||||
$query = $info->harvests();
|
||||
$per = $request->input('per_page');
|
||||
if ($per == -1) {
|
||||
$list = $query->get();
|
||||
} else {
|
||||
$list = $query->paginate($per);
|
||||
}
|
||||
|
||||
return $this->json(PlantHarvestResource::collection($list));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class PlantHarvestResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'plant_id' => $this->plant_id,
|
||||
'region_id' => $this->region_id,
|
||||
'director' => $this->director,
|
||||
'area' => $this->area,
|
||||
'output' => $this->output,
|
||||
'harvest_at' => $this->harvest_at ? $this->harvest_at->timestamp : null,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class RegionCategoryResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'icon' => $this->icon,
|
||||
'description' => $this->description,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class RegionPlantResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'plant_name' => $this->plant_name,
|
||||
'director' => $this->director,
|
||||
'area' => $this->area,
|
||||
'start_at' => $this->start_at ? $this->start_at->timestamp : null,
|
||||
'end_at' => $this->end_at ? $this->end_at->timestamp : null,
|
||||
'plant_state' => $this->plant_state,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Resources;
|
||||
|
||||
use Illuminate\Http\Resources\Json\JsonResource;
|
||||
|
||||
class RegionResource extends JsonResource
|
||||
{
|
||||
/**
|
||||
* Transform the resource into an array.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return array|\Illuminate\Contracts\Support\Arrayable|\JsonSerializable
|
||||
*/
|
||||
public function toArray($request)
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'cover' => $this->cover,
|
||||
'director' => $this->director,
|
||||
'area' => $this->area,
|
||||
'description' => $this->description,
|
||||
'category_id' => $this->category_id,
|
||||
'category' => RegionCategoryResource::make($this->whenLoaded('category')),
|
||||
'current_plant' => RegionPlantResource::make($this->whenLoaded('currentPlant')),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
@ -2,12 +2,10 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use App\Casts\Storage;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* 文章
|
||||
*/
|
||||
|
|
@ -23,15 +21,9 @@ class Article extends Model
|
|||
'published_at' => 'datetime:Y-m-d H:i:s',
|
||||
'is_enable' => 'boolean',
|
||||
'is_recommend' => 'boolean',
|
||||
'cover' => Storage::class,
|
||||
];
|
||||
|
||||
protected function cover(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn($value) => $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : Storage::url($value)) : '',
|
||||
);
|
||||
}
|
||||
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(ArticleCategory::class, 'category_id');
|
||||
|
|
|
|||
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use App\Casts\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Filters\BannerFilter;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* 广告图
|
||||
|
|
@ -25,15 +23,9 @@ class Banner extends Model
|
|||
'published_at' => 'datetime:Y-m-d H:i:s',
|
||||
'is_enable' => 'boolean',
|
||||
'link_config' => 'json',
|
||||
'picture' => Storage::class,
|
||||
];
|
||||
|
||||
protected function picture(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
get: fn($value) => $value ? (Str::startsWith($value, ['http://', 'https://']) ? $value : Storage::url($value)) : '',
|
||||
);
|
||||
}
|
||||
|
||||
public function place()
|
||||
{
|
||||
return $this->belongsTo(BannerPlace::class, 'place_id');
|
||||
|
|
|
|||
|
|
@ -2,9 +2,14 @@
|
|||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use App\Casts\Storage;
|
||||
use EloquentFilter\Filterable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* 实验田
|
||||
*/
|
||||
class Region extends Model
|
||||
{
|
||||
use Filterable;
|
||||
|
|
@ -14,11 +19,27 @@ class Region extends Model
|
|||
'sort', 'is_recommend','is_enable'
|
||||
];
|
||||
|
||||
protected $casts = [
|
||||
'cover' => Storage::class,
|
||||
];
|
||||
|
||||
protected function serializeDate(\DateTimeInterface $date){
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
public function category(){
|
||||
public function scopeShow($q)
|
||||
{
|
||||
return $q->where('is_enable', 1);
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->orderBy('sort', 'desc')->latest('id');
|
||||
}
|
||||
|
||||
// 试验田分类
|
||||
public function category()
|
||||
{
|
||||
return $this->belongsTo(RegionCategory::class, 'category_id');
|
||||
}
|
||||
|
||||
|
|
@ -26,6 +47,23 @@ class Region extends Model
|
|||
return $this->belongsToMany(MonitorMode::class, RegionMonitor::class, 'region_id', 'monitor_id')->withTimestamps();
|
||||
}
|
||||
|
||||
// 种植记录
|
||||
public function plants()
|
||||
{
|
||||
return $this->hasMany(RegionPlantLog::class, 'region_id')->orderBy('start_at', 'desc');
|
||||
}
|
||||
|
||||
// 当前种植
|
||||
public function currentPlant()
|
||||
{
|
||||
return $this->hasOne(RegionPlantLog::class, 'region_id')->orderBy('start_at', 'desc');
|
||||
}
|
||||
|
||||
// 收货记录
|
||||
public function harvests()
|
||||
{
|
||||
return $this->hasMany(PlantHarvestLog::class, 'region_id')->orderBy('harvest_at', 'desc');
|
||||
}
|
||||
|
||||
public static function regionTabConfig($region = null){
|
||||
$tabs = [
|
||||
|
|
|
|||
|
|
@ -5,13 +5,21 @@ namespace App\Models;
|
|||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use EloquentFilter\Filterable;
|
||||
use App\Casts\Storage;
|
||||
|
||||
/**
|
||||
* 区域分类
|
||||
*/
|
||||
class RegionCategory extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Filterable;
|
||||
|
||||
protected $fillable = ['name', 'icon', 'description', 'parent_id', 'level', 'sort', 'path', 'is_enable'];
|
||||
|
||||
protected $casts = [
|
||||
'icon' => Storage::class,
|
||||
];
|
||||
|
||||
protected function serializeDate(\DateTimeInterface $date){
|
||||
return $date->format('Y-m-d H:i:s');
|
||||
|
|
@ -41,4 +49,14 @@ class RegionCategory extends Model
|
|||
{
|
||||
return $this->belongsTo(self::class, 'parent_id');
|
||||
}
|
||||
|
||||
public function scopeShow($q)
|
||||
{
|
||||
return $q->where('is_enable', 1);
|
||||
}
|
||||
|
||||
public function scopeSort($q)
|
||||
{
|
||||
return $q->orderBy('sort', 'desc')->latest('id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ use EloquentFilter\Filterable;
|
|||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
/**
|
||||
* 种植记录
|
||||
*/
|
||||
class RegionPlantLog extends Model
|
||||
{
|
||||
use Filterable;
|
||||
|
|
@ -19,13 +22,15 @@ class RegionPlantLog extends Model
|
|||
|
||||
//1进行中,2已结束
|
||||
protected function plantState():Attribute
|
||||
{
|
||||
{
|
||||
return Attribute::make(
|
||||
get:fn($value, $attributes) => $attributes['end_at'] ? 2:1,
|
||||
get: fn($value) => $this->end_at ? 2 : 1,
|
||||
);
|
||||
}
|
||||
|
||||
public function harvestes(){
|
||||
// 收获记录
|
||||
public function harvestes()
|
||||
{
|
||||
return $this->hasMany(PlantHarvestLog::class, 'plant_id');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
namespace App\Services\Admin;
|
||||
|
||||
use App\Models\PlantHarvestLog;
|
||||
use App\Models\{PlantHarvestLog, RegionPlantLog};
|
||||
use App\Filters\Admin\PlantHarvestLogFilter;
|
||||
use Illuminate\Support\Arr;
|
||||
use Throwable;
|
||||
|
|
@ -21,7 +21,7 @@ class CropHarvestService extends BaseService
|
|||
public function store($data): bool
|
||||
{
|
||||
$columns = $this->getTableColumns();
|
||||
$model = $this->getModel();
|
||||
$model = $this->getModel();
|
||||
|
||||
foreach ($data as $k => $v) {
|
||||
if (!in_array($k, $columns)) {
|
||||
|
|
@ -29,6 +29,9 @@ class CropHarvestService extends BaseService
|
|||
}
|
||||
$model->setAttribute($k, $v);
|
||||
}
|
||||
if ($model->plant_id) {
|
||||
$model->region_id = RegionPlantLog::where('id', $model->plant_id)->value('region_id');
|
||||
}
|
||||
|
||||
try{
|
||||
DB::beginTransaction();
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ return new class extends Migration
|
|||
{
|
||||
Schema::create('plant_harvest_logs', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('region_id');
|
||||
$table->unsignedBigInteger('plant_id');
|
||||
$table->string('director')->nullable()->comment('负责人');
|
||||
$table->decimal('area')->default(0.00)->comment('面积/平米');
|
||||
|
|
|
|||
|
|
@ -20,5 +20,6 @@ class DatabaseSeeder extends Seeder
|
|||
$this->call(KeywordSeeder::class);
|
||||
$this->call(BannerSeeder::class);
|
||||
$this->call(SettingSeeder::class);
|
||||
$this->call(RegionCategorySeeder::class);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use App\Http\Controllers\Api\{BannerController, AdminNoticeController, ArticleController, RegionController};
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
@ -14,12 +15,18 @@ use Illuminate\Support\Facades\Route;
|
|||
|
|
||||
*/
|
||||
|
||||
Route::get('banner', [\App\Http\Controllers\Api\BannerController::class, 'index']);
|
||||
Route::get('banner', [BannerController::class, 'index']);
|
||||
|
||||
Route::get('notice', [\App\Http\Controllers\Api\AdminNoticeController::class, 'index']);
|
||||
Route::get('notice/{id}', [\App\Http\Controllers\Api\AdminNoticeController::class, 'show']);
|
||||
Route::get('notice', [AdminNoticeController::class, 'index']);
|
||||
Route::get('notice/{id}', [AdminNoticeController::class, 'show']);
|
||||
|
||||
Route::get('article/category', [\App\Http\Controllers\Api\ArticleController::class, 'category']);
|
||||
Route::get('article/tree', [\App\Http\Controllers\Api\ArticleController::class, 'tree']);
|
||||
Route::get('article', [\App\Http\Controllers\Api\ArticleController::class, 'index']);
|
||||
Route::get('article/{id}', [\App\Http\Controllers\Api\ArticleController::class, 'show']);
|
||||
Route::get('article/category', [ArticleController::class, 'category']);
|
||||
Route::get('article/tree', [ArticleController::class, 'tree']);
|
||||
Route::get('article', [ArticleController::class, 'index']);
|
||||
Route::get('article/{id}', [ArticleController::class, 'show']);
|
||||
|
||||
Route::get('region/category', [RegionController::class, 'category']);
|
||||
Route::get('region', [RegionController::class, 'index']);
|
||||
Route::get('region/{id}', [RegionController::class, 'show']);
|
||||
Route::get('region/{id}/plants', [RegionController::class, 'plants']);
|
||||
Route::get('region/{id}/harvests', [RegionController::class, 'harvests']);
|
||||
|
|
|
|||
Loading…
Reference in New Issue