From 994cd2a65855c8086288525c25b372fc8829d192 Mon Sep 17 00:00:00 2001 From: jsasg <735273025@qq.com> Date: Mon, 10 Mar 2025 18:02:19 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=A8=AA=E5=B9=85?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/controller/v1/Banner.php | 221 ++++++++++++++++++ app/admin/model/v1/SysBannerItemModel.php | 56 +++++ app/admin/model/v1/SysBannerModel.php | 19 ++ app/admin/route/v1.php | 24 ++ .../validate/v1/SysBannerItemValidate.php | 63 +++++ app/common/model/SysBannerBaseModel.php | 34 +++ app/common/model/SysBannerItemBaseModel.php | 37 +++ .../20241231020620_create_sys_banner_item.php | 2 +- 8 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 app/admin/controller/v1/Banner.php create mode 100644 app/admin/model/v1/SysBannerItemModel.php create mode 100644 app/admin/model/v1/SysBannerModel.php create mode 100644 app/admin/validate/v1/SysBannerItemValidate.php create mode 100644 app/common/model/SysBannerBaseModel.php create mode 100644 app/common/model/SysBannerItemBaseModel.php diff --git a/app/admin/controller/v1/Banner.php b/app/admin/controller/v1/Banner.php new file mode 100644 index 00000000..a31c39b4 --- /dev/null +++ b/app/admin/controller/v1/Banner.php @@ -0,0 +1,221 @@ +param([ + 'title', + 'banner_id', + 'created_at', + 'page/d' => 1, + 'size/d' => 10 + ]); + + $banners = SysBannerItemModel::field([ + 'id', + 'banner_id', + 'title', + 'sort', + 'created_at' + ]) + ->with(['banner' => function ($query) { + $query->field(['id', 'name' => 'banner_name']); + }]) + ->withSearch(['title', 'created_at'], [ + 'title' => $param['title'] ?? null, + 'created_at' => !empty($param['created_at']) ? explode(',', $param['created_at']) : null + ]) + ->bannerId($param['banner_id'] ?? null) + ->paginate([ + 'list_rows' => $param['size'] ?? 10, + 'page' => $param['page'] ?? 1 + ]) + ->bindAttr('banner', ['banner_name']) + ->hidden(['banner_id', 'banner']); + + return success('获取成功', $banners); + } + + // 详情 + public function read() + { + $id = request()->param('id'); + + $banner = SysBannerItemModel::withoutField([ + 'created_at', + 'updated_at', + 'deleted_at' + ]) + ->find($id); + if (empty($banner)) { + return error('横幅不存在'); + } + + return success('获取成功', $banner); + } + + // 新增 + public function save() + { + $post = request()->post([ + 'banner_id', + 'title', + 'title_txt_color', + 'desc', + 'desc_txt_color', + 'type', + 'image', + 'video', + 'link_to', + 'link', + 'sort', + 'status' + ]); + + $validate = new SysBannerItemValidate; + if (!$validate->scene('add')->check($post)) { + return error($validate->getError()); + } + + $banner = SysBannerItemModel::create($post); + if ($banner->isEmpty()) { + return error('操作失败'); + } + + return success('操作成功'); + } + + // 修改 + public function update() + { + $id = request()->param('id'); + $put = request()->put([ + 'banner_id', + 'title', + 'title_txt_color', + 'desc', + 'desc_txt_color', + 'type', + 'image', + 'video', + 'link_to', + 'link', + 'sort', + 'status' + ]); + + $validate = new SysBannerItemValidate; + if (!$validate->check(array_merge($put, ['id' => $id]))) { + return error($validate->getError()); + } + + $banner = SysBannerItemModel::bypk($id)->find(); + if (empty($banner)) { + return error('请确认操作对象是否存在'); + } + + if (!$banner->save($put)) { + return error('操作失败'); + } + return success('操作成功'); + } + + // 设置排序值 + public function sort() + { + $id = request()->param('id'); + $sort = request()->param('sort'); + + $banner = SysBannerItemModel::bypk($id)->find(); + if (empty($banner)) { + return error('请确认操作对象是否存在'); + } + + if ($banner->sort != $sort) { + $banner->sort = $sort; + if (!$banner->save()) { + return error('操作失败'); + } + } + return success('操作成功'); + } + + // 导出 + public function export() + { + $schema = [ + 'id' => 'ID', + 'banner_name' => '分类名称', + 'title' => '横幅名称', + 'title_txt_color' => '横幅名称字体颜色', + 'desc' => '描述', + 'desc_txt_color' => '描述字体颜色', + 'type' => '前台显示类型', + 'image' => '图片地址', + 'video' => '视频地址', + 'link_to' => '链接类型', + 'link' => '链接地址', + 'sort' => '排序值', + 'status' => '状态', + 'created_at' => '添加时间' + ]; + + // 获取要导出的横幅项数据 + $banners = $this->getBannerExportData(); + + // 导出 + return xlsx_writer($banners, $schema); + } + // 获取导出数据 + private function getBannerExportData() + { + $param = request()->param([ + 'title', + 'banner_id', + 'created_at' + ]); + return SysBannerItemModel::withoutField([ + 'updated_at', + 'deleted_at' + ]) + ->with(['banner' => function ($query) { + $query->field(['id', 'name' => 'banner_name']); + }]) + ->withSearch(['title', 'created_at'], [ + 'title' => $param['title'] ?? null, + 'created_at' => !empty($param['created_att']) ? explode(',', $param['created_att']) : null, + ]) + ->bannerId($param['banner_id'] ?? null) + ->order(['sort' => 'asc', 'id' => 'desc']) + ->select() + ->bindAtt('banner', ['banner_name']) + ->hidden(['banner_id', 'banner']); + } + + // 删除 + public function delete() + { + $id = request()->param('id'); + + $banner = SysBannerItemModel::bypk($id)->find(); + if (empty($banner)) { + return error('请确认操作对象是否存在'); + } + + if (!$banner->delete()) { + return error('操作失败'); + } + return success('操作成功'); + } +} diff --git a/app/admin/model/v1/SysBannerItemModel.php b/app/admin/model/v1/SysBannerItemModel.php new file mode 100644 index 00000000..136a4d82 --- /dev/null +++ b/app/admin/model/v1/SysBannerItemModel.php @@ -0,0 +1,56 @@ +belongsTo(SysBannerModel::class, 'banner_id', 'id'); + } + + // 按横幅标题搜索 + public function searchTitleAttr($query, $value, $data) + { + if (empty($value)) { + return; + } + $query->where('title', 'like', "%{$value}%"); + } + + // 按添加时间搜索 + public function searchCreatedAtAttr($query, $value, $data) + { + if (empty($value)) { + return; + } + if (is_array($value)) { + if (count($value) > 1) { + $query->whereBetweenTime ('created_at', $value[0], $value[1]); + } else { + $query->whereTime('created_at', '>=', $value[0]); + } + } + } + + // 根据横幅id查询 + public function scopeBannerId($query, $value) + { + if (is_null($value)) return; + $query->where('banner_id', '=', $value); + } +} diff --git a/app/admin/model/v1/SysBannerModel.php b/app/admin/model/v1/SysBannerModel.php new file mode 100644 index 00000000..db1b8e6a --- /dev/null +++ b/app/admin/model/v1/SysBannerModel.php @@ -0,0 +1,19 @@ + ['规则1','规则2'...] + * + * @var array + */ + protected $rule = [ + 'id' => 'require|integer', + 'banner_id' => 'require|integer', + 'title' => 'require|max:128', + 'title_txt_color' => 'max:7', + 'desc' => 'max:255', + 'desc_txt_color' => 'max:7', + 'type' => 'in:image,video', + 'image' => 'max:255', + 'video' => 'max:255', + 'link_to' => 'max:64|in:article,goods_category,goods,custom', + 'link' => 'max:255', + 'sort' => 'integer', + 'status' => 'in:-1,1' + ]; + + /** + * 定义错误信息 + * 格式:'字段名.规则名' => '错误信息' + * + * @var array + */ + protected $message = [ + 'id.require' => 'ID不能为空', + 'id.integer' => 'ID必须是整数', + 'banner_id.require' => '横幅项分类不能为空', + 'banner_id.integer' => '横幅项分类必须是整数', + 'title.require' => '名称不能为空', + 'title.max' => '名称最多不能超过128个字符', + 'title_txt_color.max' => '名称字体颜色最多不能超过7个字符', + 'desc.max' => '描述最多不能超过255个字符', + 'desc_txt_color.max' => '描述字体颜色最多不能超过7个字符', + 'type.in' => '显示类型必须是image或video', + 'image.max' => '图片地址最多不能超过255个字符', + 'video.max' => '视频地址最多不能超过255个字符', + 'link_to.max' => '连接类型最多不能超过64个字符', + 'link_to.in' => '连接类型必须是article,goods_category,goods,custom中之一', + 'link.max' => '连接最多不能超过255个字符', + 'sort.integer' => '排序值必须是整数', + 'status.in' => '状态必须是-1或1' + ]; + + // 新增场景 + public function sceneAdd() + { + return $this->remove('id', 'require|integer'); + } +} diff --git a/app/common/model/SysBannerBaseModel.php b/app/common/model/SysBannerBaseModel.php new file mode 100644 index 00000000..157c59a9 --- /dev/null +++ b/app/common/model/SysBannerBaseModel.php @@ -0,0 +1,34 @@ + 'int', + 'language_id' => 'int', + 'at_platform' => 'string', + 'at_page' => 'string', + 'at_position' => 'int', + 'unique_label' => 'string', + 'name' => 'string', + 'desc' => 'string', + 'sort' => 'sort', + 'status' => 'int', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime', + ]; +} diff --git a/app/common/model/SysBannerItemBaseModel.php b/app/common/model/SysBannerItemBaseModel.php new file mode 100644 index 00000000..a3961a29 --- /dev/null +++ b/app/common/model/SysBannerItemBaseModel.php @@ -0,0 +1,37 @@ + 'int', + 'banner_id' => 'int', + 'title' => 'string', + 'title_txt_color' => 'string', + 'desc' => 'string', + 'desc_txt_color' => 'string', + 'type' => 'int', + 'image' => 'string', + 'video' => 'string', + 'link_to' => 'string', + 'link' => 'string', + 'sort' => 'int', + 'status' => 'int', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime' + ]; +} diff --git a/database/migrations/20241231020620_create_sys_banner_item.php b/database/migrations/20241231020620_create_sys_banner_item.php index 3a74fd27..856c80eb 100644 --- a/database/migrations/20241231020620_create_sys_banner_item.php +++ b/database/migrations/20241231020620_create_sys_banner_item.php @@ -36,7 +36,7 @@ class CreateSysBannerItem extends Migrator ->addColumn('type', 'string', ['limit' => 16, 'null' => false, 'comment' => '类型: image为图片, video为视频']) ->addColumn('image', 'string', ['limit' => 255, 'null' => false, 'comment' => '图片']) ->addColumn('video', 'string', ['limit' => 255, 'null' => false, 'comment' => '视频']) - ->addColumn('link_to', 'string', ['limit' => 64, 'null' => false, 'comment' => '链接到(类型): article:文章, goods_category:商品分类, goods:商品, link:自定义链接']) + ->addColumn('link_to', 'string', ['limit' => 64, 'null' => false, 'comment' => '链接到(类型): article:文章, goods_category:商品分类, goods:商品, custom:自定义链接']) ->addColumn('link', 'string', ['limit' => 255, 'null' => false, 'comment' => '链接']) ->addColumn('sort', 'integer', ['limit' => 11, 'null' => false, 'default' => 0, 'comment' => '排序']) ->addColumn('status', 'boolean', ['limit' => 1, 'null' => false, 'default' => 1, 'comment' => '-1为禁用, 1为启用'])