diff --git a/app/apis/controller/BrandBannerController.php b/app/apis/controller/BrandBannerController.php new file mode 100644 index 0000000..52cf1ee --- /dev/null +++ b/app/apis/controller/BrandBannerController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/controller/BrandBannerTranslationController.php b/app/apis/controller/BrandBannerTranslationController.php new file mode 100644 index 0000000..9bb96f3 --- /dev/null +++ b/app/apis/controller/BrandBannerTranslationController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/controller/BrandController.php b/app/apis/controller/BrandController.php index 6b0c058..de01980 100644 --- a/app/apis/controller/BrandController.php +++ b/app/apis/controller/BrandController.php @@ -2,6 +2,8 @@ namespace app\apis\controller; +use app\apis\model\BrandBannerModel; +use app\apis\model\BrandTraitModel; use support\Request; use support\Response; use app\apis\model\BrandModel; @@ -39,7 +41,50 @@ class BrandController extends BaseController */ protected function postProcessItem(array $item, string $scene): array { - + if ($scene === 'default' || $scene === 'letter' || $scene === 'hot') { + $result = [ + 'id' => $item['id'], + 'status' => $item['status'], + 'sort' => $item['sort'], + 'toppic' => $item['toppic'], + 'descpic' => $item['descpic'], + 'logo' => $item['logo'], + 'is_hot' => $item['is_hot'], + 'name' => isset($item['translation']) ? $item['translation']['name'] : '', + 'desc' => isset($item['translation']) ? $item['translation']['desc'] : '', + 'toppic_alt' => isset($item['translation']) ? $item['translation']['toppic_alt'] : '', + 'descpic_alt' => isset($item['translation']) ? $item['translation']['descpic_alt'] : '', + 'logo_alt' => isset($item['translation']) ? $item['translation']['logo_alt'] : '', + 'created_at' => date('Y-m-d H:i:s', $item['created_at']), + 'updated_at' => date('Y-m-d H:i:s', $item['updated_at']), + ]; + if ($item['toppic']) { + $result['toppic_full'] = (new \app\mzl\modules\upload\service\OssService())->generatePrivateUrl($item['toppic']); + } + if ($item['descpic']) { + $result['descpic_full'] = (new \app\mzl\modules\upload\service\OssService())->generatePrivateUrl($item['descpic']); + } + if ($item['logo']) { + $result['logo_full'] = (new \app\mzl\modules\upload\service\OssService())->generatePrivateUrl($item['logo']); + } + $banners = BrandBannerModel::with('translation')->where(['brand_id' => $item['id']])->get(); + foreach ($banners as $k => $v) { + $v['alt'] = isset($v['translation']) ? $v['translation']['alt'] : ''; + unset($v['translation']); + if ($v['pic']) { + $v['pic_full'] = (new \app\mzl\modules\upload\service\OssService())->generatePrivateUrl($v['pic']); + } + $result['banner'][$k] = $v; + } + $traits = BrandTraitModel::with('translation')->where(['brand_id' => $item['id']])->get(); + foreach ($traits as $k => $v) { + $v['title'] = isset($v['translation']) ? $v['translation']['title'] : ''; + $v['content'] = isset($v['translation']) ? $v['translation']['content'] : ''; + unset($v['translation']); + $result['trait'][$k] = $v; + } + return $result; + } return $item; } @@ -53,8 +98,14 @@ class BrandController extends BaseController { $params = parent::prepareParams($request, $scene); - if ($scene === 'default') { - + if ($scene === 'default' || $scene === 'letter') { + $params['filters'][] = ['field' => 'status', 'operator' => '=', 'value' => '1']; + if(!empty($params['letter'])){ + $params['filters'][] = ['field' => 'letter', 'operator' => '=', 'value' => $params['letter']]; + } + if(isset($params['is_hot']) && $params['is_hot'] == 1){ + $params['filters'][] = ['field' => 'is_hot', 'operator' => '=', 'value' => 1]; + } } return $params; @@ -74,4 +125,20 @@ class BrandController extends BaseController return $this->errorResponse($th->getMessage()); } } + + /** + * 分页 + * + * @param Request $request 请求对象 + * @return Response 响应对象 + */ + public function letterAll(Request $request, string $scene = 'letter'): Response + { + try { + return parent::index($request, $scene); + } catch (\Throwable $th) { + return $this->errorResponse($th->getMessage()); + } + } + } \ No newline at end of file diff --git a/app/apis/controller/BrandTraitController.php b/app/apis/controller/BrandTraitController.php new file mode 100644 index 0000000..fdcc2f0 --- /dev/null +++ b/app/apis/controller/BrandTraitController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/controller/BrandTraitTranslationController.php b/app/apis/controller/BrandTraitTranslationController.php new file mode 100644 index 0000000..c135782 --- /dev/null +++ b/app/apis/controller/BrandTraitTranslationController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/model/BrandBannerModel.php b/app/apis/model/BrandBannerModel.php new file mode 100644 index 0000000..ec91ab7 --- /dev/null +++ b/app/apis/model/BrandBannerModel.php @@ -0,0 +1,83 @@ +belongsTo(BrandModel::class, 'brand_id'); + } + + /** + * 单条翻译 + */ + public function translation() + { + return $this->hasOne(BrandBannerTranslationModel::class, 'banner_id')->where('locale', locale()); + } + + /** + * 多条翻译 + */ + public function translations() + { + return $this->hasMany(VehicleDataTranslationModel::class, 'banner_id'); + } + + + const TRANS_FIELDS = [ + 'alt' + ]; +} \ No newline at end of file diff --git a/app/apis/model/BrandBannerTranslationModel.php b/app/apis/model/BrandBannerTranslationModel.php new file mode 100644 index 0000000..6fb08b7 --- /dev/null +++ b/app/apis/model/BrandBannerTranslationModel.php @@ -0,0 +1,66 @@ +belongsTo(BrandModel::class, 'brand_id'); + } + + public function banner() + { + return $this->belongsTo(BrandBannerModel::class, 'banner_id'); + } +} \ No newline at end of file diff --git a/app/apis/model/BrandModel.php b/app/apis/model/BrandModel.php index 07fc804..280c25b 100644 --- a/app/apis/model/BrandModel.php +++ b/app/apis/model/BrandModel.php @@ -58,4 +58,13 @@ class BrandModel extends Model { return $this->hasOne(BrandTranslationModel::class, 'brand_id')->where('locale', locale()); } + + public function banners() + { + return $this->hasMany(BrandBannerModel::class, 'brand_id','id'); + } + public function traits() + { + return $this->hasMany(BrandTraitModel::class, 'brand_id','id'); + } } \ No newline at end of file diff --git a/app/apis/model/BrandTraitModel.php b/app/apis/model/BrandTraitModel.php new file mode 100644 index 0000000..4e79070 --- /dev/null +++ b/app/apis/model/BrandTraitModel.php @@ -0,0 +1,84 @@ +belongsTo(BrandModel::class, 'brand_id'); + } + + /** + * 单条翻译 + */ + public function translation() + { + return $this->hasOne(BrandTraitTranslationModel::class, 'trait_id')->where('locale', locale()); + } + + /** + * 多条翻译 + */ + public function translations() + { + return $this->hasMany(BrandTraitTranslationModel::class, 'trait_id'); + } + + + const TRANS_FIELDS = [ + 'title', 'content' + ]; +} \ No newline at end of file diff --git a/app/apis/model/BrandTraitTranslationModel.php b/app/apis/model/BrandTraitTranslationModel.php new file mode 100644 index 0000000..5ed31c6 --- /dev/null +++ b/app/apis/model/BrandTraitTranslationModel.php @@ -0,0 +1,67 @@ +belongsTo(BrandModel::class, 'brand_id'); + } + + public function brandTrait() + { + return $this->belongsTo(BrandTraitModel::class, 'trait_id'); + } +} \ No newline at end of file diff --git a/app/apis/service/BrandBannerService.php b/app/apis/service/BrandBannerService.php new file mode 100644 index 0000000..bb34182 --- /dev/null +++ b/app/apis/service/BrandBannerService.php @@ -0,0 +1,59 @@ + function ($params) { + // $keyword = $params['keyword'] ?? ''; + // return [ + // 'filters' => [ + // ['field' => '***', 'operator' => '=', 'value' => '***'] + // ], + // 'fields' => ['id'], + // 'relations' => [], + // 'custom' => function(Builder $q) use ($keyword) { + // // 示例 + // if ($keyword) { + // $q->where(function($q2) use($keyword) { + // $q2->whereHas('***', function($q3) use($keyword) { + // $q3->where('***', 'like', "%{$keyword}%"); + // })->orWhereHas('***', function($q4) use($keyword) { + // $q4->where('***', 'like', "%{$keyword}%"); + // }); + // }); + // } + // }, + // 'sorts' => [ + // ['field' => 'created_at', 'direction' => 'desc'] + // ], + // 'pagination' => [ + // 'page' => $params['page'] ?? 1, + // 'per_page' => $params['per_page'] ?? 10, + // ] + // ]; + // } + ]; + } +} \ No newline at end of file diff --git a/app/apis/service/BrandBannerTranslationService.php b/app/apis/service/BrandBannerTranslationService.php new file mode 100644 index 0000000..99f948c --- /dev/null +++ b/app/apis/service/BrandBannerTranslationService.php @@ -0,0 +1,59 @@ + function ($params) { + // $keyword = $params['keyword'] ?? ''; + // return [ + // 'filters' => [ + // ['field' => '***', 'operator' => '=', 'value' => '***'] + // ], + // 'fields' => ['id'], + // 'relations' => [], + // 'custom' => function(Builder $q) use ($keyword) { + // // 示例 + // if ($keyword) { + // $q->where(function($q2) use($keyword) { + // $q2->whereHas('***', function($q3) use($keyword) { + // $q3->where('***', 'like', "%{$keyword}%"); + // })->orWhereHas('***', function($q4) use($keyword) { + // $q4->where('***', 'like', "%{$keyword}%"); + // }); + // }); + // } + // }, + // 'sorts' => [ + // ['field' => 'created_at', 'direction' => 'desc'] + // ], + // 'pagination' => [ + // 'page' => $params['page'] ?? 1, + // 'per_page' => $params['per_page'] ?? 10, + // ] + // ]; + // } + ]; + } +} \ No newline at end of file diff --git a/app/apis/service/BrandService.php b/app/apis/service/BrandService.php index 8f7aaee..dcd4933 100644 --- a/app/apis/service/BrandService.php +++ b/app/apis/service/BrandService.php @@ -27,12 +27,14 @@ class BrandService extends BaseService return [ 'default' => function ($params) { return [ - 'filters' => [ - ['field' => 'status', 'operator' => '=', 'value' => '1'] - ], - 'fields' => ['id', 'status', 'sort', 'created_at', 'updated_at'], + 'filters' => $params['filters'], + 'fields' => ['id', 'status', 'sort', 'toppic', 'descpic', 'logo', 'letter', 'is_hot', 'created_at', 'updated_at'], 'relations' => [ - 'translation' => ['brand_id', 'name'] + 'translation' => ['brand_id', 'name', 'desc','toppic_alt','descpic_alt','logo_alt'], + 'banners' => ['id', 'pic', 'sort',], + 'banners.translation' => ['id', 'alt',], + 'traits' => ['id', 'sort',], + 'traits.translation' => ['id', 'title', 'content',], ], 'sorts' => [ ['field' => 'id', 'direction' => 'desc'] @@ -43,6 +45,37 @@ class BrandService extends BaseService ] ]; }, + 'letter' => function ($params) { + return [ + 'filters' => $params['filters'], + 'fields' => ['id', 'status', 'sort', 'toppic', 'descpic', 'logo', 'letter', 'is_hot', 'created_at', 'updated_at'], + 'relations' => [ + 'translation' => ['brand_id', 'name', 'desc','toppic_alt','descpic_alt','logo_alt'], + 'banners' => ['id', 'pic', 'sort',], + 'banners.translation' => ['id', 'alt',], + 'traits' => ['id', 'sort',], + 'traits.translation' => ['id', 'title', 'content',], + ], + 'sorts' => [ + ['field' => 'id', 'direction' => 'desc'] + ], + ]; + }, + 'hot' => function ($params) { + return [ + 'filters' => [ + ['field' => 'status', 'operator' => '=', 'value' => '1'], + ['field' => 'is_hot', 'operator' => '=', 'value' => 1], + ], + 'fields' => ['id', 'status', 'sort', 'toppic', 'descpic', 'logo', 'letter', 'is_hot', 'created_at', 'updated_at'], + 'relations' => [ + 'translation' => ['brand_id', 'name'] + ], + 'sorts' => [ + ['field' => 'id', 'direction' => 'desc'] + ], + ]; + }, ]; } } \ No newline at end of file diff --git a/app/apis/service/BrandTraitService.php b/app/apis/service/BrandTraitService.php new file mode 100644 index 0000000..40483b7 --- /dev/null +++ b/app/apis/service/BrandTraitService.php @@ -0,0 +1,59 @@ + function ($params) { + // $keyword = $params['keyword'] ?? ''; + // return [ + // 'filters' => [ + // ['field' => '***', 'operator' => '=', 'value' => '***'] + // ], + // 'fields' => ['id'], + // 'relations' => [], + // 'custom' => function(Builder $q) use ($keyword) { + // // 示例 + // if ($keyword) { + // $q->where(function($q2) use($keyword) { + // $q2->whereHas('***', function($q3) use($keyword) { + // $q3->where('***', 'like', "%{$keyword}%"); + // })->orWhereHas('***', function($q4) use($keyword) { + // $q4->where('***', 'like', "%{$keyword}%"); + // }); + // }); + // } + // }, + // 'sorts' => [ + // ['field' => 'created_at', 'direction' => 'desc'] + // ], + // 'pagination' => [ + // 'page' => $params['page'] ?? 1, + // 'per_page' => $params['per_page'] ?? 10, + // ] + // ]; + // } + ]; + } +} \ No newline at end of file diff --git a/app/apis/service/BrandTraitTranslationService.php b/app/apis/service/BrandTraitTranslationService.php new file mode 100644 index 0000000..cdbb328 --- /dev/null +++ b/app/apis/service/BrandTraitTranslationService.php @@ -0,0 +1,59 @@ + function ($params) { + // $keyword = $params['keyword'] ?? ''; + // return [ + // 'filters' => [ + // ['field' => '***', 'operator' => '=', 'value' => '***'] + // ], + // 'fields' => ['id'], + // 'relations' => [], + // 'custom' => function(Builder $q) use ($keyword) { + // // 示例 + // if ($keyword) { + // $q->where(function($q2) use($keyword) { + // $q2->whereHas('***', function($q3) use($keyword) { + // $q3->where('***', 'like', "%{$keyword}%"); + // })->orWhereHas('***', function($q4) use($keyword) { + // $q4->where('***', 'like', "%{$keyword}%"); + // }); + // }); + // } + // }, + // 'sorts' => [ + // ['field' => 'created_at', 'direction' => 'desc'] + // ], + // 'pagination' => [ + // 'page' => $params['page'] ?? 1, + // 'per_page' => $params['per_page'] ?? 10, + // ] + // ]; + // } + ]; + } +} \ No newline at end of file diff --git a/app/apis/validate/BrandBannerTranslationValidator.php b/app/apis/validate/BrandBannerTranslationValidator.php new file mode 100644 index 0000000..aba6d95 --- /dev/null +++ b/app/apis/validate/BrandBannerTranslationValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/apis/validate/BrandBannerValidator.php b/app/apis/validate/BrandBannerValidator.php new file mode 100644 index 0000000..7a9d1bd --- /dev/null +++ b/app/apis/validate/BrandBannerValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/apis/validate/BrandTraitTranslationValidator.php b/app/apis/validate/BrandTraitTranslationValidator.php new file mode 100644 index 0000000..9a44e20 --- /dev/null +++ b/app/apis/validate/BrandTraitTranslationValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/apis/validate/BrandTraitValidator.php b/app/apis/validate/BrandTraitValidator.php new file mode 100644 index 0000000..437f633 --- /dev/null +++ b/app/apis/validate/BrandTraitValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/console/controller/BrandController.php b/app/console/controller/BrandController.php index 97d6bcb..d246cff 100644 --- a/app/console/controller/BrandController.php +++ b/app/console/controller/BrandController.php @@ -41,7 +41,6 @@ class BrandController extends BaseController */ protected function postProcessItem(array $item, string $scene): array { - if ($scene === 'default') { $result = [ 'id' => $item['id'], @@ -50,6 +49,7 @@ class BrandController extends BaseController 'toppic' => $item['toppic'], 'descpic' => $item['descpic'], 'logo' => $item['logo'], + 'is_hot' => $item['is_hot'], 'name' => isset($item['translation']) ? $item['translation']['name'] : '', 'desc' => isset($item['translation']) ? $item['translation']['desc'] : '', 'toppic_alt' => isset($item['translation']) ? $item['translation']['toppic_alt'] : '', diff --git a/config/route.php b/config/route.php index 1e2adba..abd0e5a 100644 --- a/config/route.php +++ b/config/route.php @@ -41,10 +41,14 @@ Route::group('/apis', function() { // 隐私协议 Route::any('/agt/privacy', [\app\apis\controller\AgreementController::class, 'one']); // 品牌按字母查询 -// Route::any('/brand/letterAll', [\app\apis\controller\BrandController::class, 'letterAll']); + Route::any('/brand/letterAll', [\app\apis\controller\BrandController::class, 'letterAll']); + // 品牌按字母查询 + Route::any('/brand/detail', [\app\apis\controller\BrandController::class, 'detail']); // 新车管理 Route::any('/vehicle/new/list', [\app\console\controller\VehicleNewController::class, 'index']); Route::any('/vehicle/new/{id}/detail', [\app\console\controller\VehicleNewController::class, 'detail']); + // 能源列表 + Route::any('/energy/preset', [\app\console\controller\EnergyController::class, 'presets']); }); // ====== ====== ====== 网站 ====== ====== ======