diff --git a/app/admin/common.php b/app/admin/common.php index 12436156..00ab387d 100644 --- a/app/admin/common.php +++ b/app/admin/common.php @@ -1,2 +1,28 @@ param([ + 'keywords' => '', + ]); + + $ret = ProductCategoryModel::field([ + 'id', + 'pid', + 'name', + 'level', + 'is_show' + ]) + ->withSearch(['name_nullable'], [ + 'name_nullable' => $params['keywords'] + ]) + ->select(); + if ($ret->isEmpty()) { + return success('获取成功!'); + } + + return success('获取成功!', array_to_tree($ret->toArray(), 0, 'pid', 1)); + } + + /** + * 获取商品分类详情 + */ + public function read() + { + $category = ProductCategoryModel::withoutField([ + 'language_id', + 'created_at', + 'updated_at', + 'deleted_at', + ]) + ->bypk(request()->param('id')) + ->find(); + if (empty($category)) { + return error('分类不存在!'); + } + + return success('获取成功!', $category); + } + + /** + * 新增商品分类 + */ + public function save() + { + $post = request()->post([ + 'unique_id', + 'pid' => 0, + 'name', + 'icon', + 'desc', + 'related_tco_category', + 'sort', + 'level' => 1, + 'is_show' => 1, + 'seo_title', + 'seo_keywords', + 'seo_desc' + ]); + if (empty($post['unique_id'])) { + $post['unique_id'] = md5(uniqid()); + } + $data = array_merge($post, ['language_id' => request()->lang_id]); + + $validate = new ProductCategoryValidate; + if (!$validate->check($data)) { + return error($validate->getError()); + } + + $category = new ProductCategoryModel; + + // 处理层级 + if ($data['pid'] > 0) { + $parent = $category->bypk($data['pid'])->find(); + if (!empty($parent)) { + $data['level'] = $parent->level + 1; + } + } + + if (!$category->save($data)) { + return error('操作失败!'); + } + return success('操作成功!'); + } + + /** + * 更新商品分类 + */ + public function update() + { + $id = request()->param('id'); + $put = request()->put([ + 'unique_id', + 'pid' => 0, + 'name', + 'icon', + 'desc', + 'related_tco_category', + 'sort', + 'level' => 1, + 'is_show' => 1, + 'seo_title', + 'seo_keywords', + 'seo_desc' + ]); + $data = array_merge($put, [ + 'id' => $id, + 'language_id' => request()->lang_id + ]); + + $validate = new ProductCategoryValidate; + if (!$validate->check($data)) { + return error($validate->getError()); + } + + $category = ProductCategoryModel::bypk($id)->find(); + if (empty($category)) { + return error('请确认操作对对象是否存在!'); + } + + // 处理层级 + $updated_level = false; + if ($data['pid'] != $category->pid) { + $parent = ProductCategoryModel::bypk($data['pid'])->find(); + if (!empty($parent)) { + $data['level'] = $parent->level + 1; + $updated_level = true; + } + } + + if (!$category->save($data)) { + return error('操作失败!'); + } + + // 处理子分类层级 + if ($updated_level) { + $this->handle_children($category->id, $data['level']); + } + + return success('操作成功!'); + } + private function handle_children($pid, $level) + { + $children = ProductCategoryModel::pid($pid)->select(); + if ($children->isEmpty()) { + return; + } + foreach ($children as $child) { + $child->level = $level + 1; + if ($child->save()) { + $this->handle_children($child->id, $child->level); + } + } + } + + /** + * 删除商品分类 + */ + public function delete() + { + $id = request()->param('id'); + $category = ProductCategoryModel::bypk($id)->find(); + if (empty($category)) { + return error('请确认操作对对象是否存在!'); + } + + if (!$category->delete()) { + return error('操作失败!'); + } + return success('操作成功!'); + } +} diff --git a/app/admin/model/v1/ProductCategoryModel.php b/app/admin/model/v1/ProductCategoryModel.php index 6c83fe51..3907cab6 100644 --- a/app/admin/model/v1/ProductCategoryModel.php +++ b/app/admin/model/v1/ProductCategoryModel.php @@ -4,6 +4,7 @@ declare (strict_types = 1); namespace app\admin\model\v1; use app\common\model\ProductCategoryBaseModel; +use think\model\concern\SoftDelete; /** * 产品分类模型 @@ -11,5 +12,25 @@ use app\common\model\ProductCategoryBaseModel; */ class ProductCategoryModel extends ProductCategoryBaseModel { - // + // 启用软件删除 + use SoftDelete; + // 软件字段 + protected $deleteTime = 'deleted_at'; + // 修改自动写入时间格式 + protected $autoWriteTimestamp = 'datetime'; + + // 根据pid查询 + public function scopePid($query, $pid) + { + $query->where('pid', $pid); + } + + // 搜索分类名称 + public function searchNameNullableAttr($query, $value, $data) + { + if (is_null($value)) { + return; + } + $query->where('name', 'like', '%' . $value . '%'); + } } diff --git a/app/admin/route/v1.php b/app/admin/route/v1.php index 68b7dd3c..1adeea0d 100644 --- a/app/admin/route/v1.php +++ b/app/admin/route/v1.php @@ -112,6 +112,24 @@ Route::group('v1', function () { // 产品模块 Route::group('product', function () { + // 产品分类 + Route::group('category', function () { + // 分类列表 + Route::get('index', 'ProductCategory/index'); + + // 分类详情 + Route::get('read/:id', 'ProductCategory/read'); + + // 分类新增 + Route::post('save', 'ProductCategory/save'); + + // 分类更新 + Route::put('update/:id', 'ProductCategory/update'); + + // 分类删除 + Route::delete('delete/:id', 'ProductCategory/delete'); + }); + // 产品分页列表 Route::get('index', 'Product/index'); diff --git a/app/admin/validate/v1/ProductCategoryValidate.php b/app/admin/validate/v1/ProductCategoryValidate.php new file mode 100644 index 00000000..93a4cf5d --- /dev/null +++ b/app/admin/validate/v1/ProductCategoryValidate.php @@ -0,0 +1,53 @@ + ['规则1','规则2'...] + * + * @var array + */ + protected $rule = [ + 'language_id' => 'require|integer', + 'unique_id' => 'require', + 'name' => 'require|max:64', + 'icon' => 'max:125', + 'desc' => 'max:255', + 'related_tco_category' => 'integer', + 'sort' => 'integer', + 'level' => 'integer', + 'is_show' => 'in:0,1', + 'seo_title' => 'max:255', + 'seo_keywords' => 'max:255', + 'seo_desc' => 'max:255', + ]; + + /** + * 定义错误信息 + * 格式:'字段名.规则名' => '错误信息' + * + * @var array + */ + protected $message = [ + 'language_id.require' => '语言ID不能为空', + 'language_id.integer' => '语言ID必须为整数', + 'unique_id.require' => '唯一标识不能为空', + 'name.require' => '名称不能为空', + 'name.max' => '名称最多不能超过64个字符', + 'icon.max' => '图标最多不能超过125个字符', + 'desc.max' => '描述最多不能超过255个字符', + 'related_tco_category.integer' => '关联TCO分类格式错误', + 'sort.integer' => '排序格式错误', + 'level.integer' => '级别格式错误', + 'is_show.in' => '是否显示格式错误', + 'seo_title.max' => 'SEO标题最多不能超过255个字符', + 'seo_keywords.max' => 'SEO关键字最多不能超过255个字符', + 'seo_desc.max' => 'SEO描述最多不能超过255个字符', + ]; +}