diff --git a/app/apis/controller/AdController.php b/app/apis/controller/AdController.php new file mode 100644 index 0000000..72bf6ee --- /dev/null +++ b/app/apis/controller/AdController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/controller/AdTranslationController.php b/app/apis/controller/AdTranslationController.php new file mode 100644 index 0000000..81c7343 --- /dev/null +++ b/app/apis/controller/AdTranslationController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/apis/model/AdModel.php b/app/apis/model/AdModel.php new file mode 100644 index 0000000..1b7530b --- /dev/null +++ b/app/apis/model/AdModel.php @@ -0,0 +1,72 @@ +hasOne(AdTranslationModel::class, 'ad_id')->where('locale', locale()); + } + + /** + * 多条翻译 + */ + public function translations() + { + return $this->hasMany(AdTranslationModel::class, 'ad_id'); + } +} \ No newline at end of file diff --git a/app/apis/model/AdTranslationModel.php b/app/apis/model/AdTranslationModel.php new file mode 100644 index 0000000..a9587cd --- /dev/null +++ b/app/apis/model/AdTranslationModel.php @@ -0,0 +1,56 @@ + function ($params) { + return [ + 'filters' => $params['filters'], + 'fields' => ['id', 'image', 'status', 'sort', 'creater', 'created_at', 'updated_at'], + 'relations' => [ + 'translation' => ['ad_id', 'alt', 'title'], + ], + 'sorts' => [ + ['field' => 'sort', 'direction' => 'desc'], + ['field' => 'created_at', 'direction' => 'desc'], + ], + 'pagination' => [ + 'page' => $params['page'] ?? 1, + 'per_page' => $params['per_page'] ?? 8, + ] + ]; + }, + ]; + } +} \ No newline at end of file diff --git a/app/apis/service/AdTranslationService.php b/app/apis/service/AdTranslationService.php new file mode 100644 index 0000000..f785776 --- /dev/null +++ b/app/apis/service/AdTranslationService.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/AdTranslationValidator.php b/app/apis/validate/AdTranslationValidator.php new file mode 100644 index 0000000..a2a551d --- /dev/null +++ b/app/apis/validate/AdTranslationValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/apis/validate/AdValidator.php b/app/apis/validate/AdValidator.php new file mode 100644 index 0000000..9d887dd --- /dev/null +++ b/app/apis/validate/AdValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/console/controller/AdController.php b/app/console/controller/AdController.php new file mode 100644 index 0000000..7e34f6a --- /dev/null +++ b/app/console/controller/AdController.php @@ -0,0 +1,106 @@ +errorResponse($th->getMessage()); + } + } + + public function add(Request $request): Response + { + try { + $request->setPost('creater', $request->user['id']); + $id = $this->getService()->add($request->all()); + return $id ? $this->successResponse(['id' => $id]) + : $this->errorResponse(); + } catch (\Throwable $th) { + return $this->errorResponse($th->getMessage()); + } + } + + public function edit(Request $request, int $id): Response + { + try { + $request->setPost('id',$id); + $request->setPost('creater', $request->user['id']); + return $this->getService()->edit($request->all(), $id) + ? $this->successResponse() + : $this->errorResponse(); + } catch (\Throwable $th) { + return $this->errorResponse($th->getMessage().$th->getFile().$th->getLine()); + } + } +} \ No newline at end of file diff --git a/app/console/controller/AdTranslationController.php b/app/console/controller/AdTranslationController.php new file mode 100644 index 0000000..d467d61 --- /dev/null +++ b/app/console/controller/AdTranslationController.php @@ -0,0 +1,81 @@ +errorResponse($th->getMessage()); + } + } +} \ No newline at end of file diff --git a/app/console/model/AdModel.php b/app/console/model/AdModel.php new file mode 100644 index 0000000..fb6c9c8 --- /dev/null +++ b/app/console/model/AdModel.php @@ -0,0 +1,72 @@ +hasOne(AdTranslationModel::class, 'ad_id')->where('locale', locale()); + } + + /** + * 多条翻译 + */ + public function translations() + { + return $this->hasMany(AdTranslationModel::class, 'ad_id'); + } +} \ No newline at end of file diff --git a/app/console/model/AdTranslationModel.php b/app/console/model/AdTranslationModel.php new file mode 100644 index 0000000..dd17706 --- /dev/null +++ b/app/console/model/AdTranslationModel.php @@ -0,0 +1,56 @@ + function ($params) { + return [ + 'filters' => $params['filters'], + 'fields' => ['id', 'image', 'status', 'sort', 'creater', 'created_at', 'updated_at'], + 'relations' => [ + 'translation' => ['ad_id', 'alt', 'title'], + ], + 'sorts' => [ + ['field' => 'sort', 'direction' => 'desc'], + ['field' => 'created_at', 'direction' => 'desc'], + ], + 'pagination' => [ + 'page' => $params['page'] ?? 1, + 'per_page' => $params['per_page'] ?? 8, + ] + ]; + }, + ]; + } + + + protected array $translatable = [ + 'alt', 'title' + ]; + + public function add(array $params) + { + $sourceLocale = locale(); + $sourceFields = $this->extractSourceFields($params); + if (empty($sourceFields)) { + throw new \InvalidArgumentException("请传递至少一条 {$sourceLocale} 语言的翻译字段"); + }; + + Db::beginTransaction(); + try { + $info = $this->create($params); + if (!$info) { + throw new BusinessException('提交失败'); + } + + // 异步翻译并写入 hs_ad_translation 表 + (new TranslationService())->queueTranslations( + 'ad', + $info->id, + $sourceLocale, + $sourceFields + ); + + Db::commit(); + return $info->id; + } catch (\Throwable $th) { + Db::rollBack(); + throw $th; + } + } + + public function edit(array $params, int $id) + { + $sourceLocale = locale(); + $sourceFields = $this->extractSourceFields($params); + if (empty($sourceFields)) { + throw new \InvalidArgumentException("请传递至少一条 {$sourceLocale} 语言的翻译字段"); + }; + + Db::beginTransaction(); + try { + $info = $this->update($id, $params); + if (!$info) { + throw new BusinessException('提交失败'); + } + + // 异步翻译并写入 hs_ad_translation 表 + AdTranslationModel::updateOrCreate( + [ + 'ad_id' => $id, + 'locale' => $sourceLocale, + ], + $sourceFields + ); + + Db::commit(); + return true; + } catch (\Throwable $th) { + Db::rollBack(); + throw $th; + } + } +} \ No newline at end of file diff --git a/app/console/service/AdTranslationService.php b/app/console/service/AdTranslationService.php new file mode 100644 index 0000000..4682077 --- /dev/null +++ b/app/console/service/AdTranslationService.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/console/validate/AdTranslationValidator.php b/app/console/validate/AdTranslationValidator.php new file mode 100644 index 0000000..5b15cea --- /dev/null +++ b/app/console/validate/AdTranslationValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/console/validate/AdValidator.php b/app/console/validate/AdValidator.php new file mode 100644 index 0000000..cf65f16 --- /dev/null +++ b/app/console/validate/AdValidator.php @@ -0,0 +1,29 @@ + [ + + ], + + 'update' => [ + + ] + ]; +} \ No newline at end of file diff --git a/app/mzl/modules/translation/config/trans.php b/app/mzl/modules/translation/config/trans.php index b191d15..155b836 100644 --- a/app/mzl/modules/translation/config/trans.php +++ b/app/mzl/modules/translation/config/trans.php @@ -63,9 +63,9 @@ return [ 'translation_model' => \app\console\model\VehicleNewAlbumTranslationModel::class, 'foreign_key' => 'album_id', ], - 'vehicleNewContent' => [ - 'translation_model' => \app\console\model\VehicleNewContentTranslationModel::class, - 'foreign_key' => 'content_id', + 'ad' => [ + 'translation_model' => \app\console\model\AdTranslationModel::class, + 'foreign_key' => 'ad_id', ], 'vehicleNewAttributes' => [ 'translation_model' => \app\console\model\VehicleNewAttributesTranslationModel::class, diff --git a/config/route.php b/config/route.php index 670e50d..43bb957 100644 --- a/config/route.php +++ b/config/route.php @@ -60,6 +60,9 @@ Route::group('/apis', function() { Route::any('/article/{id}/detail', [\app\apis\controller\ArticleController::class, 'detail']); Route::any('/article/home', [\app\apis\controller\ArticleController::class, 'home']); + //广告管理 + Route::any('/ad/list', [\app\apis\controller\AdController::class, 'index']); + //图片代理 Route::any('/upload/image/proxy', [\app\mzl\modules\upload\controller\UploadController::class, 'proxy']); }); @@ -266,6 +269,12 @@ Route::group('/console', function() { Route::any('/comment/{id}/update', [\app\console\controller\CommentController::class, 'edit']); Route::any('/comment/{id}/delete', [\app\console\controller\CommentController::class, 'destroy']); Route::any('/comment/{id}/detail', [\app\console\controller\CommentController::class, 'detail']); + + //广告管理 + Route::any('/ad/list', [\app\console\controller\AdController::class, 'index']); + Route::any('/ad/add', [\app\console\controller\AdController::class, 'add']); + Route::any('/ad/{id}/update', [\app\console\controller\AdController::class, 'edit']); + Route::any('/ad/{id}/delete', [\app\console\controller\AdController::class, 'destroy']); }); // ====== ====== ====== 后台管理 ====== ====== ======