移除分类图片
This commit is contained in:
@@ -17,39 +17,11 @@ use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
#[RequestAttribute('/mini', 'mini', authGuard: 'users')]
|
||||
class ProductController extends BaseMiniController
|
||||
{
|
||||
/** 分类树(仅含上架商品的分类及其祖先,保证树结构完整) */
|
||||
/** 分类树(全部启用分类,含暂无商品的分类) */
|
||||
#[GetRoute('/product/categories', authorize: true)]
|
||||
public function categories(): JsonResponse
|
||||
{
|
||||
$activeCategoryIds = ProductModel::query()
|
||||
->where('status', ProductModel::STATUS_ON)
|
||||
->distinct()
|
||||
->pluck('category_id')
|
||||
->map(static fn ($id) => (int) $id)
|
||||
->filter(static fn (int $id) => $id > 0);
|
||||
|
||||
$categories = ProductCategoryModel::query()
|
||||
->where('status', ProductCategoryModel::STATUS_NORMAL)
|
||||
->get()
|
||||
->keyBy('id');
|
||||
|
||||
// 保留有上架商品的分类 + 其全部祖先
|
||||
$keep = [];
|
||||
foreach ($activeCategoryIds as $categoryId) {
|
||||
$cursor = $categoryId;
|
||||
$guard = 0;
|
||||
while ($cursor > 0 && $guard++ < 20 && $categories->has($cursor)) {
|
||||
$keep[$cursor] = true;
|
||||
$cursor = (int) $categories[$cursor]->parent_id;
|
||||
}
|
||||
}
|
||||
|
||||
$filtered = array_values(array_filter(
|
||||
$categories->toArray(),
|
||||
static fn (array $item) => isset($keep[$item['id']])
|
||||
));
|
||||
|
||||
return $this->success(ProductCategoryModel::buildTree($filtered));
|
||||
return $this->success(ProductCategoryModel::getTreeData(['*'], true));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +60,7 @@ class ProductController extends BaseMiniController
|
||||
if (!$user) return $this->success($data);
|
||||
// 门店
|
||||
$store = $this->boundStore($user);
|
||||
if(!$store) return $this->success('12313');
|
||||
if(!$store) return $this->success($data);
|
||||
|
||||
if ($store->level_id > 0) {
|
||||
foreach ($data['data'] as &$row) {
|
||||
|
||||
@@ -7,15 +7,12 @@ use App\Http\Requests\Product\ProductCategoryFormRequest;
|
||||
use App\Models\ProductCategoryModel;
|
||||
use App\Models\ProductModel;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Modules\AnnoRoute\Attribute\DeleteRoute;
|
||||
use Modules\AnnoRoute\Attribute\GetRoute;
|
||||
use Modules\AnnoRoute\Attribute\PostRoute;
|
||||
use Modules\AnnoRoute\Attribute\PutRoute;
|
||||
use Modules\AnnoRoute\Attribute\RequestAttribute;
|
||||
use Modules\Common\Http\Controllers\BaseController;
|
||||
use Modules\SystemTool\Services\SysFileService;
|
||||
|
||||
/**
|
||||
* 商品分类管理(多级分类:蔬菜/水果/其他)
|
||||
@@ -37,34 +34,17 @@ class ProductCategoryController extends BaseController
|
||||
return $this->success(ProductCategoryModel::getTreeData(['id', 'name', 'parent_id'], true));
|
||||
}
|
||||
|
||||
/** 上传商品分类图片文件 */
|
||||
#[PostRoute('/upload', 'create')]
|
||||
public function uploadImage(Request $request, SysFileService $service): JsonResponse
|
||||
{
|
||||
$data = $request->validate(['file' => 'required|file']);
|
||||
$result = $service->upload(
|
||||
$data['file'],
|
||||
9,
|
||||
20,
|
||||
Auth::id()
|
||||
);
|
||||
return $this->success($result);
|
||||
}
|
||||
|
||||
/** 创建分类 */
|
||||
#[PostRoute(authorize: 'create')]
|
||||
public function create(ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
$validated = $request->validated();
|
||||
$parentId = (int) $validated['parent_id'];
|
||||
if ($parentId > 0 && ! ProductCategoryModel::whereKey($parentId)->exists()) {
|
||||
throw new RepositoryException('父级分类不存在');
|
||||
}
|
||||
$this->assertParentIsTopLevel((int) $validated['parent_id']);
|
||||
ProductCategoryModel::create($validated);
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/** 编辑分类(防自引用成环) */
|
||||
/** 编辑分类(防自引用成环;分类最多二级) */
|
||||
#[PutRoute(route: '/{id}', authorize: 'update', where: ['id' => '[0-9]+'])]
|
||||
public function update(int $id, ProductCategoryFormRequest $request): JsonResponse
|
||||
{
|
||||
@@ -73,7 +53,12 @@ class ProductCategoryController extends BaseController
|
||||
throw new RepositoryException('分类不存在');
|
||||
}
|
||||
$validated = $request->validated();
|
||||
$this->assertNoCycle($id, (int) $validated['parent_id']);
|
||||
$parentId = (int) $validated['parent_id'];
|
||||
$this->assertNoCycle($id, $parentId);
|
||||
$this->assertParentIsTopLevel($parentId);
|
||||
if ($parentId > 0 && ProductCategoryModel::where('parent_id', $id)->exists()) {
|
||||
throw new RepositoryException('该分类下存在子分类,不能调整为子分类');
|
||||
}
|
||||
$model->update($validated);
|
||||
return $this->success();
|
||||
}
|
||||
@@ -96,6 +81,23 @@ class ProductCategoryController extends BaseController
|
||||
return $this->success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验父级分类:存在且必须为顶级分类(分类最多二级)
|
||||
*/
|
||||
private function assertParentIsTopLevel(int $parentId): void
|
||||
{
|
||||
if ($parentId === 0) {
|
||||
return;
|
||||
}
|
||||
$parent = ProductCategoryModel::whereKey($parentId)->first(['id', 'parent_id']);
|
||||
if ($parent === null) {
|
||||
throw new RepositoryException('父级分类不存在');
|
||||
}
|
||||
if ((int) $parent->parent_id !== 0) {
|
||||
throw new RepositoryException('最多支持二级分类,不能选择子分类作为上级');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 沿父链向上检查,防止 parent_id 指向自身或子孙分类形成环
|
||||
*/
|
||||
|
||||
@@ -2,9 +2,7 @@
|
||||
|
||||
namespace App\Http\Requests\Product;
|
||||
|
||||
use Illuminate\Validation\Rules\Exists;
|
||||
use Modules\Common\Http\Requests\BaseFormRequest;
|
||||
use Modules\SystemTool\Models\SysFileModel;
|
||||
|
||||
/**
|
||||
* 商品分类 创建/编辑 验证
|
||||
@@ -24,7 +22,6 @@ class ProductCategoryFormRequest extends BaseFormRequest
|
||||
'name' => 'required|string|max:50',
|
||||
'parent_id' => 'required|integer|min:0',
|
||||
'sort' => 'nullable|integer',
|
||||
'icon_id' => ['nullable', 'integer', new Exists(SysFileModel::class, 'id')],
|
||||
'status' => 'nullable|integer|in:0,1',
|
||||
];
|
||||
}
|
||||
@@ -36,7 +33,6 @@ class ProductCategoryFormRequest extends BaseFormRequest
|
||||
'name.max' => '分类名称最长 50 个字符',
|
||||
'parent_id.min' => '父级分类ID不正确',
|
||||
'status.in' => '状态值不正确',
|
||||
'icon_id.exists' => '请重新上传图片'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,13 +44,17 @@ class ProductFormRequest extends BaseFormRequest
|
||||
}
|
||||
|
||||
/**
|
||||
* 交叉校验:按成本百分比计价(price_type=1)时上浮百分点必填
|
||||
* 交叉校验:商品只能挂在末级分类;按成本百分比计价(price_type=1)时上浮百分点必填
|
||||
* (Laravel 12 FormRequest 的 after() 需返回单个 Closure,由容器 call 后注册到 Validator)
|
||||
*/
|
||||
public function after(): Closure
|
||||
{
|
||||
return function (Validator $validator): void {
|
||||
$data = (array) $validator->getData();
|
||||
$categoryId = (int) ($data['category_id'] ?? 0);
|
||||
if ($categoryId > 0 && ProductCategoryModel::where('parent_id', $categoryId)->exists()) {
|
||||
$validator->errors()->add('category_id', '该分类下存在子分类,请选择末级分类');
|
||||
}
|
||||
foreach ((array) ($data['prices'] ?? []) as $index => $row) {
|
||||
$priceType = (int) ($row['price_type'] ?? ProductPriceModel::PRICE_TYPE_FIXED);
|
||||
if ($priceType === ProductPriceModel::PRICE_TYPE_PERCENT
|
||||
|
||||
Reference in New Issue
Block a user