feat: 新增产品分类增/删/改/查接口
This commit is contained in:
@@ -1,2 +1,28 @@
|
||||
<?php
|
||||
// 这是系统自动生成的公共文件
|
||||
|
||||
if (!function_exists('array_to_tree')) {
|
||||
/**
|
||||
* 数组转换为树状结构
|
||||
* @param array $data 数据
|
||||
* @param int $pid 父级ID
|
||||
* @param string $with 转换依据字段
|
||||
* @param int $level 层级
|
||||
* @return array
|
||||
*/
|
||||
function array_to_tree(array $data, int $pid, string $with = 'pid', int $level = 1)
|
||||
{
|
||||
$ret = [];
|
||||
foreach ($data as $item) {
|
||||
if ($item[$with] == $pid) {
|
||||
$item['level'] = $level;
|
||||
$children = array_to_tree($data, $item['id'], $with, $level + 1);
|
||||
if ($children) {
|
||||
$item['children'] = $children;
|
||||
}
|
||||
$ret[] = $item;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
189
app/admin/controller/v1/ProductCategory.php
Normal file
189
app/admin/controller/v1/ProductCategory.php
Normal file
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\admin\controller\v1;
|
||||
|
||||
use app\admin\model\v1\ProductCategoryModel;
|
||||
use app\admin\validate\v1\ProductCategoryValidate;
|
||||
|
||||
class ProductCategory
|
||||
{
|
||||
/**
|
||||
* 获取商品分类列表
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
$params = request()->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('操作成功!');
|
||||
}
|
||||
}
|
||||
@@ -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 . '%');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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');
|
||||
|
||||
|
||||
53
app/admin/validate/v1/ProductCategoryValidate.php
Normal file
53
app/admin/validate/v1/ProductCategoryValidate.php
Normal file
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
declare (strict_types = 1);
|
||||
|
||||
namespace app\admin\validate\v1;
|
||||
|
||||
use think\Validate;
|
||||
|
||||
class ProductCategoryValidate extends Validate
|
||||
{
|
||||
/**
|
||||
* 定义验证规则
|
||||
* 格式:'字段名' => ['规则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个字符',
|
||||
];
|
||||
}
|
||||
Reference in New Issue
Block a user