From e76e0953a33423edb44b1808dfed62997ba02c2d Mon Sep 17 00:00:00 2001 From: jsasg <735273025@qq.com> Date: Wed, 23 Apr 2025 15:24:06 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20banner=E6=96=B0=E5=A2=9E=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=88=86=E7=B1=BB=E6=95=B0=E6=8D=AE=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/v1/BannerItem.php | 79 ++++++++++++++++--- app/admin/model/v1/SysBannerItemModel.php | 22 ++++++ .../v1/SysBannerProdCateMappingModel.php | 19 +++++ .../SysBannerProdCateMappingBaseModel.php | 22 ++++++ ...18_create_sys_banner_prod_cate_mapping.php | 37 +++++++++ 5 files changed, 167 insertions(+), 12 deletions(-) create mode 100644 app/admin/model/v1/SysBannerProdCateMappingModel.php create mode 100644 app/common/model/SysBannerProdCateMappingBaseModel.php create mode 100644 database/migrations/20250423032718_create_sys_banner_prod_cate_mapping.php diff --git a/app/admin/controller/v1/BannerItem.php b/app/admin/controller/v1/BannerItem.php index 3810c137..f3a9ab18 100644 --- a/app/admin/controller/v1/BannerItem.php +++ b/app/admin/controller/v1/BannerItem.php @@ -3,8 +3,11 @@ declare (strict_types = 1); namespace app\admin\controller\v1; +use app\admin\exception\InvalidOperateException; use app\admin\model\v1\SysBannerItemModel; +use app\admin\model\v1\SysBannerProdCateMappingModel; use app\admin\validate\v1\SysBannerItemValidate; +use think\facade\Log; /** * 横幅数据项控制器 @@ -67,7 +70,8 @@ class BannerItem { $id = request()->param('id'); - $banner_item = SysBannerItemModel::withoutField([ + $banner_item = SysBannerItemModel::with('prod_mapping.category') + ->withoutField([ 'created_at', 'updated_at', 'deleted_at' @@ -88,6 +92,7 @@ class BannerItem { $post = request()->post([ 'banner_id', + 'rel_prod_cate_id', 'title', 'title_txt_color', 'desc', @@ -106,8 +111,29 @@ class BannerItem return error($validate->getError()); } - $banner_item = SysBannerItemModel::create($post); - if ($banner_item->isEmpty()) { + SysBannerItemModel::startTrans(); + try { + $banner_item = SysBannerItemModel::create($post); + if ($banner_item->isEmpty()) { + throw new InvalidOperateException('新增横幅失败'); + } + if (!empty($post['rel_prod_cate_id'])) { + $mapping = SysBannerProdCateMappingModel::create([ + 'banner_item_id' => $banner_item->id, + 'product_category_id' => $post['rel_prod_cate_id'] + ]); + if ($mapping->isEmpty()) { + throw new InvalidOperateException('新增横幅与产品分类关联失败'); + } + } + + SysBannerItemModel::commit(); + } catch (InvalidOperateException $e) { + SysBannerItemModel::rollback(); + return error($e->getMessage()); + } catch (\Throwable $th) { + SysBannerItemModel::rollback(); + Log::error(sprintf('%s:%s %s', $th->getFile(), $th->getLine(), $th->getMessage())); return error('操作失败'); } @@ -120,6 +146,7 @@ class BannerItem $id = request()->param('id'); $put = request()->put([ 'banner_id', + 'rel_prod_cate_id', 'title', 'title_txt_color', 'desc', @@ -138,17 +165,45 @@ class BannerItem return error($validate->getError()); } - $banner_item = SysBannerItemModel::bypk($id)->find(); - if (empty($banner_item)) { - return error('请确认操作对象是否存在'); - } - if ($put['type'] == 'video') { - unset($put['link']); - unset($put['link_to']); - } - if (!$banner_item->save($put)) { + SysBannerItemModel::startTrans(); + try { + $banner_item = SysBannerItemModel::bypk($id)->find(); + if (empty($banner_item)) { + throw new InvalidOperateException('请确认操作对象是否存在'); + } + if ($put['type'] == 'video') { + unset($put['link']); + unset($put['link_to']); + } + if (!$banner_item->save($put)) { + throw new InvalidOperateException('操作失败'); + } + + // 更新关联的产品分类 + if (!empty($put['rel_prod_cate_id'])) { + $ok = SysBannerProdCateMappingModel::where('banner_item_id', '=', $id)->delete(); + if (!$ok) { + throw new InvalidOperateException('更新横幅与产品分类关联失败'); + } + $mapping = SysBannerProdCateMappingModel::create([ + 'banner_item_id' => $id, + 'product_category_id' => $put['rel_prod_cate_id'] + ]); + if ($mapping->isEmpty()) { + throw new InvalidOperateException('更新横幅与产品分类关联失败'); + } + } + + SysBannerItemModel::commit(); + } catch (InvalidOperateException $e) { + SysBannerItemModel::rollback(); + return error($e->getMessage()); + } catch (\Throwable $th) { + SysBannerItemModel::rollback(); + Log::error(sprintf('%s:%s %s', $th->getFile(), $th->getLine(), $th->getMessage())); return error('操作失败'); } + return success('操作成功'); } diff --git a/app/admin/model/v1/SysBannerItemModel.php b/app/admin/model/v1/SysBannerItemModel.php index 136a4d82..1e323de1 100644 --- a/app/admin/model/v1/SysBannerItemModel.php +++ b/app/admin/model/v1/SysBannerItemModel.php @@ -17,12 +17,34 @@ class SysBannerItemModel extends SysBannerItemBaseModel // 软删除字段 protected $deleteTime = 'deleted_at'; + // 绑定产品分类关联模型中字段到父模型 + protected $append = ['rel_prod_cate_id', 'rel_prod_cate_name']; + // 要隐藏的字段或关联模型数据字段 + protected $hidden = ['prod_mapping']; + // 关联分类 public function banner() { return $this->belongsTo(SysBannerModel::class, 'banner_id', 'id'); } + // 关联相关产品分类中间表模型 + public function prodMapping() + { + return $this->hasOne(SysBannerProdCateMappingModel::class, 'banner_item_id', 'id'); + } + + // 从产品分类关联模型中获取id字段 + public function getRelProdCateIdAttr() + { + return $this->prodMapping?->category?->id; + } + // 从产品分类关联模型中获取name字段 + public function getRelProdCateNameAttr() + { + return $this->prodMapping?->category?->name; + } + // 按横幅标题搜索 public function searchTitleAttr($query, $value, $data) { diff --git a/app/admin/model/v1/SysBannerProdCateMappingModel.php b/app/admin/model/v1/SysBannerProdCateMappingModel.php new file mode 100644 index 00000000..d78ba66f --- /dev/null +++ b/app/admin/model/v1/SysBannerProdCateMappingModel.php @@ -0,0 +1,19 @@ +belongsTo(ProductCategoryModel::class, 'product_category_id', 'id'); + } +} diff --git a/app/common/model/SysBannerProdCateMappingBaseModel.php b/app/common/model/SysBannerProdCateMappingBaseModel.php new file mode 100644 index 00000000..1b3c56c3 --- /dev/null +++ b/app/common/model/SysBannerProdCateMappingBaseModel.php @@ -0,0 +1,22 @@ + 'int', + 'product_category_id' => 'int', + ]; +} diff --git a/database/migrations/20250423032718_create_sys_banner_prod_cate_mapping.php b/database/migrations/20250423032718_create_sys_banner_prod_cate_mapping.php new file mode 100644 index 00000000..d563bae8 --- /dev/null +++ b/database/migrations/20250423032718_create_sys_banner_prod_cate_mapping.php @@ -0,0 +1,37 @@ +table('sys_banner_prod_cate_mapping', ['id' => false, 'engine' => 'InnoDB', 'comment' => 'banner与产品分类关联表']); + $table->addColumn('banner_item_id', 'integer', ['limit' => 11, 'null' => false, 'signed' => false, 'comment' => '横幅项id']) + ->addColumn('product_category_id', 'integer', ['limit' => 11, 'null' => false,'signed' => false, 'comment' => '产品分类id']) + ->addIndex(['banner_item_id'], ['unique' => false]) + ->addIndex(['product_category_id'], ['unique' => false]) + ->create(); + } +}