diff --git a/app/admin/controller/v1/SysMallStoreEntrance.php b/app/admin/controller/v1/SysMallStoreEntrance.php new file mode 100644 index 00000000..94f38910 --- /dev/null +++ b/app/admin/controller/v1/SysMallStoreEntrance.php @@ -0,0 +1,201 @@ +get([ + 'name', + 'page/d' => 1, + 'size/d' => 10 + ]); + + // 查询数据 + $data = SysMallStoreEntranceModel::withoutField([ + 'language_id', + 'hover_image', + 'updated_at', + 'deleted_at' + ]) + ->withSearch(['name'], ['name' => $param['name']??null]) + ->language(request()->lang_id) + ->order(['sort' => 'asc', 'id' => 'desc']) + ->paginate([ + 'list_rows' => $param['size'], + 'page' => $param['page'], + ]) + ?->each(function($item) { + // 列表页面图片输出缩略图 + if (!empty($item['image'])) { + $item['image'] = thumb($item['image']); + } + }); + + return success('获取成功', $data); + } + + /** + * 获取详情 + */ + public function read() + { + $id = request()->param('id/d'); + $record = SysMallStoreEntranceModel::bypk($id) + ->withoutField(['language_id', 'created_at', 'updated_at', 'deleted_at']) + ->find(); + if (empty($record)) { + return error('商城店铺入口数据不存在'); + } + + return success('success', $record); + } + + /** + * 新增数据 + */ + public function save() + { + $post = request()->post([ + 'name', + 'image', + 'hover_image', + 'link', + 'sort', + 'disabled' + ]); + $data = array_merge($post, ['language_id' => request()->lang_id]); + + // 参数校验 + $validate = new SysMallStoreEntranceValidate(); + if (!$validate->scene('create')->check($data)) { + return error($validate->getError()); + } + + // 保存数据 + $entrance = SysMallStoreEntranceModel::create($data); + if ($entrance->isEmpty()) { + return error('保存失败'); + } + return success('保存成功'); + } + + /** + * 更新数据 + */ + public function update() + { + $id = request()->param('id/d'); + $post = request()->post([ + 'name', + 'image', + 'hover_image', + 'link', + 'sort', + 'disabled' + ]); + $data = array_merge($post, ['language_id' => request()->lang_id]); + + // 参数校验 + $validate = new SysMallStoreEntranceValidate(); + $check_data = array_merge($data, ['id' => $id]); + if (!$validate->scene('update')->check($check_data)) { + return error($validate->getError()); + } + + // 更新数据 + $entrance = SysMallStoreEntranceModel::bypk($id)->find(); + if (empty($entrance)) { + return error('请确认操作对象是否存在'); + } + if (!$entrance->save($data)) { + return error('操作失败'); + } + + return success('操作成功'); + } + + /** + * 删除 + */ + public function delete() + { + $id = request()->param('id/d'); + + // 删除数据 + $record = SysMallStoreEntranceModel::bypk($id)->find(); + if (empty($record)) { + return error('请确认操作对象是否正确'); + } + if (!$record->delete()) { + return error('操作失败'); + } + + return success('操作成功'); + } + + /** + * 导出Excel + */ + public function export() + { + $schema = [ + 'id' => 'ID', + 'image' => '图片', + 'hover_image' => '悬浮图', + 'name' => '名称', + 'link' => '链接地址', + 'sort' => '排序', + 'disabled' => '状态', + 'created_at' => '添加时间' + ]; + + // 获取导出数据 + $data = $this->getExportData(); + + // 导出 + return xlsx_writer($data, $schema, '系统商城店铺入口列表' . date('YmdHis')); + } + + // 获取要导出的数据 + private function getExportData() + { + $server = request()->server(); + $image_host = $server['REQUEST_SCHEME'] . "://" . $server['SERVER_NAME'] . '/'; + $param = request()->get(['name']); + + // 查询数据 + return SysMallStoreEntranceModel::withoutField([ + 'language_id', + 'updated_at', + 'deleted_at' + ]) + ->withSearch(['name'], ['name' => $param['name']??null]) + ->language(request()->lang_id) + ->order(['sort' => 'asc', 'id' => 'desc']) + ->select() + ?->each(function($item) use($image_host) { + // 拼接完整图片URL + if (!empty($item['image'])) { + $item['image'] = url_join($image_host, $item['image']); + } + if (!empty($item['hover_image'])) { + $item['hover_image'] = url_join($image_host, $item['hover_image']); + } + // 状态转换 + $item['disabled'] = $item['disabled'] == 1 ? '禁用' : '启用'; + }) + ->toArray(); + } +} diff --git a/app/admin/model/v1/SysMallStoreEntranceModel.php b/app/admin/model/v1/SysMallStoreEntranceModel.php new file mode 100644 index 00000000..f1cd1a81 --- /dev/null +++ b/app/admin/model/v1/SysMallStoreEntranceModel.php @@ -0,0 +1,61 @@ +belongsTo(\app\index\model\LanguageModel::class, 'language_id', 'id'); + } + + // 所属语言范围查询 + public function scopeLanguage($query, $language) + { + $query->where($this->getTable() . '.language_id', '=', $language); + } + + // 查询启用状态 + public function scopeEnabled($query) + { + $query->where('disabled', '=', 0); + } + + // 查询禁用状态 + public function scopeDisabled($query) + { + $query->where('disabled', '=', 1); + } + + // 按名称搜索 + public function searchNameAttr($query, $value, $data) + { + if (is_null($value)) { + return; + } + $query->where('name', 'like', "%{$value}%"); + } + + // 按链接地址搜索 + public function searchLinkAttr($query, $value, $data) + { + if (is_null($value)) { + return; + } + $query->where('link_url', 'like', "%{$value}%"); + } +} diff --git a/app/admin/route/v1.php b/app/admin/route/v1.php index bae867d5..b8e56853 100644 --- a/app/admin/route/v1.php +++ b/app/admin/route/v1.php @@ -595,6 +595,29 @@ Route::group('v1', function () { // 反馈管理 - 产品询盘列表 Route::get('product/inquiry/index', 'ProductInquiry/index'); + // 系统商城店铺入口 + Route::group('mall', function() { + Route::group('store', function() { + // 店铺入口列表分页 + Route::get('index', 'SysMallStoreEntrance/index'); + + // 店铺入口导出 + Route::get('export', 'SysMallStoreEntrance/export'); + + // 店铺入口详情 + Route::get('read/:id', 'SysMallStoreEntrance/read'); + + // 店铺入口新增 + Route::post('save', 'SysMallStoreEntrance/save'); + + // 店铺入口更新 + Route::put('update/:id', 'SysMallStoreEntrance/update'); + + // 店铺入口删除 + Route::delete('delete/:id', 'SysMallStoreEntrance/delete'); + }); + }); + // 配置项列表 Route::group('config', function() { // 配置分组 diff --git a/app/admin/validate/v1/SysMallStoreEntranceValidate.php b/app/admin/validate/v1/SysMallStoreEntranceValidate.php new file mode 100644 index 00000000..31d8b33d --- /dev/null +++ b/app/admin/validate/v1/SysMallStoreEntranceValidate.php @@ -0,0 +1,60 @@ + ['规则1','规则2'...] + * + * @var array + */ + protected $rule = [ + 'id' => 'require|integer', + 'language_id' => 'require|integer', + 'name' => 'require|max:255', + 'image' => 'require|max:255', + 'hover_image' => 'max:255', + 'link' => 'max:500', + 'sort' => 'require|integer', + 'disabled' => 'in:0,1', + ]; + + /** + * 定义错误信息 + * 格式:'字段名.规则名' => '错误信息' + * + * @var array + */ + protected $message = [ + 'id.require' => 'ID不能为空', + 'id.integer' => 'ID必须是整数', + 'language_id.require' => '语言ID不能为空', + 'language_id.integer' => '语言ID必须是整数', + 'name.require' => '商城名称不能为空', + 'name.max' => '商城名称长度不能超过:rule个字符', + 'image.require' => '图片不能为空', + 'image.max' => '图片长度不能超过:rule个字符', + 'hover_image.max' => '悬浮图长度不能超过:rule个字符', + 'link.max' => '链接地址长度不能超过:rule个字符', + 'sort.require' => '排序不能为空', + 'sort.integer' => '排序必须是整数', + 'disabled.in' => '禁用状态只能是0或1', + ]; + + // 新增场景 + protected function sceneCreate() + { + return $this->remove('id', 'require|integer'); + } + + // 更新场景 + protected function sceneUpdate() + { + return $this->append('id', 'require|integer'); + } +} diff --git a/app/common/model/SysMallStoreEntranceBaseModel.php b/app/common/model/SysMallStoreEntranceBaseModel.php new file mode 100644 index 00000000..7e4115c2 --- /dev/null +++ b/app/common/model/SysMallStoreEntranceBaseModel.php @@ -0,0 +1,32 @@ + 'int', + 'language_id' => 'int', + 'name' => 'string', + 'image' => 'string', + 'hover_image' => 'string', + 'link' => 'string', + 'sort' => 'int', + 'disabled' => 'int', + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'deleted_at' => 'datetime', + ]; +} diff --git a/database/migrations/20260328021117_sys_mall_store_entrance.php b/database/migrations/20260328021117_sys_mall_store_entrance.php new file mode 100644 index 00000000..4180738c --- /dev/null +++ b/database/migrations/20260328021117_sys_mall_store_entrance.php @@ -0,0 +1,50 @@ +table('sys_mall_store_entrance', [ + 'engine' => 'MyISAM', + 'collation' => 'utf8mb4_general_ci', + 'comment' => '系统商城店铺入口表' + ]); + + $table->addColumn('language_id', 'integer', ['signed' => false, 'null' => false, 'comment' => '语言ID']) + ->addColumn('name', 'string', ['limit' => 255, 'null' => false, 'comment' => '商城名称']) + ->addColumn('image', 'string', ['limit' => 255, 'default' => '', 'comment' => '图片']) + ->addColumn('hover_image', 'string', ['limit' => 255, 'default' => '', 'comment' => '悬浮图']) + ->addColumn('link', 'string', ['limit' => 500, 'default' => '', 'comment' => '链接地址']) + ->addColumn('sort', 'integer', ['default' => 0, 'comment' => '排序']) + ->addColumn('disabled', 'boolean', ['default' => 0, 'comment' => '是否禁用 0:启用 1:禁用']) + ->addColumn('created_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间']) + ->addColumn('updated_at', 'timestamp', ['null' => false, 'default' => 'CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP', 'comment' => '更新时间']) + ->addColumn('deleted_at', 'timestamp', ['null' => true, 'comment' => '删除时间']) + ->addIndex(['language_id'], ['name' => 'idx_language_id']) + ->create(); + } +}