request->get('name'))) { $name = $this->request->get('name'); $where[] = ['name', 'like', '%' . $name . '%']; } // 状态筛选 if (!empty($this->request->get('status'))) { $status = $this->request->get('status'); $where['status'] = $status; } // 排序 $order = []; if (!empty($this->request->get('order'))) { $order_a = $this->request->get('order'); $order_a = explode(',', $order_a); $order[$order_a[0]] = $order_a[1]; } else { $order['sort'] = 'asc'; $order['id'] = 'asc'; } // 查询所有分类 $categoryList = Db::name('product_category') ->where($where) ->order($order) ->select() ->toArray(); // 构建树形结构 $tree = $this->buildTree($categoryList); $this->success('查询成功', $tree); } /** * 构建树形结构 * @param array $items * @param int $parentId * @return array */ private function buildTree(array $items, $parentId = 0) { $tree = []; foreach ($items as $item) { if ($item['parent_id'] == $parentId) { $children = $this->buildTree($items, $item['id']); if ($children) { $item['children'] = $children; } $tree[] = $item; } } return $tree; } /** * 新增/编辑分类 * @return void */ public function edit() { $id = $this->request->post('id'); $name = $this->request->post('name'); $parentId = $this->request->post('parent_id', 0); $icon = $this->request->post('icon', ''); $sort = $this->request->post('sort', 0); $status = $this->request->post('status', 1); if (empty($name)) { $this->error(__('分类名称不能为空')); } // 验证分类名称是否已存在(同一父级下不能重复) $checkName = Db::name('product_category') ->where('name', $name) ->where('parent_id', $parentId); if (!empty($id)) { $checkName->where('id', '<>', $id); } if ($checkName->find()) { $this->error(__('同级分类下已存在相同名称')); } // 检查父级分类是否存在 if ($parentId > 0) { $parentCategory = Db::name('product_category') ->where('id', $parentId) ->find(); if (!$parentCategory) { $this->error(__('父级分类不存在')); } // 防止循环引用(不能将分类设置为自己的子分类) if (!empty($id) && $parentId == $id) { $this->error(__('不能将分类设置为自己的父级')); } } $data = [ 'name' => $name, 'parent_id' => $parentId, 'icon' => $icon, 'sort' => $sort, 'status' => $status ]; try { if (!empty($id)) { // 编辑 $categoryInfo = Db::name('product_category') ->where('id', $id) ->find(); if (!$categoryInfo) { $this->error(__('分类不存在')); } $result = Db::name('product_category') ->where('id', $id) ->update($data); $message = '编辑成功'; } else { // 新增 $data['create_time'] = date('Y-m-d H:i:s'); $result = Db::name('product_category') ->insert($data); $id = Db::name('product_category')->getLastInsID(); $message = '新增成功'; } if ($result) { $this->success($message, ['id' => $id]); } else { $this->error(__('操作失败')); } } catch (\Exception $e) { $this->error('操作失败: ' . $e->getMessage()); } } /** * 删除分类 * @return void */ public function delete() { $id = $this->request->post('id'); if (empty($id)) { $this->error(__('参数错误')); } // 检查是否有子分类 $hasChildren = Db::name('product_category') ->where('parent_id', $id) ->count(); if ($hasChildren > 0) { $this->error(__('该分类下有子分类,请先删除子分类')); } // 检查是否有产品关联 $hasProduct = Db::name('product') ->where('category_id', $id) ->count(); if ($hasProduct > 0) { $this->error(__('该分类下有关联的产品,请先删除或转移产品')); } try { $result = Db::name('product_category') ->where('id', $id) ->delete(); if ($result) { $this->success('删除成功'); } else { $this->error(__('删除失败')); } } catch (\Exception $e) { $this->error('删除失败: ' . $e->getMessage()); } } /** * 分类详情 * @return void */ public function detail() { $id = $this->request->get('id'); if (empty($id)) { $this->error(__('参数错误')); } $categoryInfo = Db::name('product_category') ->where('id', $id) ->find(); if (!$categoryInfo) { $this->error(__('分类不存在')); } // 获取父级分类信息 if ($categoryInfo['parent_id'] > 0) { $parentInfo = Db::name('product_category') ->where('id', $categoryInfo['parent_id']) ->field('id, name') ->find(); $categoryInfo['parent_info'] = $parentInfo; } else { $categoryInfo['parent_info'] = null; } // 统计子分类数量 $childrenCount = Db::name('product_category') ->where('parent_id', $id) ->count(); $categoryInfo['children_count'] = $childrenCount; // 统计产品数量 $productCount = Db::name('product') ->where('category_id', $id) ->count(); $categoryInfo['product_count'] = $productCount; $this->success('查询成功', $categoryInfo); } /** * 批量更新分类状态 * @return void */ public function batchStatus() { $ids = $this->request->post('ids'); $status = $this->request->post('status'); if (empty($ids) || empty($status)) { $this->error(__('参数错误')); } if (!is_array($ids)) { $ids = explode(',', $ids); } try { $result = Db::name('product_category') ->whereIn('id', $ids) ->update([ 'status' => $status ]); if ($result) { $statusText = $status == 1 ? '启用' : '禁用'; $this->success("成功{$statusText}{$result}个分类"); } else { $this->error(__('操作失败')); } } catch (\Exception $e) { $this->error('操作失败: ' . $e->getMessage()); } } /** * 获取分类下拉选项(用于选择父级分类) * @return void */ public function selectOptions() { // 获取所有启用的分类 $categoryList = Db::name('product_category') ->where('status', 1) ->order('sort', 'asc') ->order('id', 'asc') ->select() ->toArray(); // 构建树形结构用于前端展示 $tree = $this->buildTreeForSelect($categoryList); $this->success('查询成功', $tree); } /** * 构建用于下拉选择的树形结构 * @param array $items * @param int $parentId * @param int $level * @return array */ private function buildTreeForSelect(array $items, $parentId = 0, $level = 0) { $tree = []; $prefix = str_repeat(' ', $level * 2); foreach ($items as $item) { if ($item['parent_id'] == $parentId) { $item['label'] = ($level > 0 ? $prefix . '├─ ' : '') . $item['name']; $item['value'] = $item['id']; $children = $this->buildTreeForSelect($items, $item['id'], $level + 1); if ($children) { $item['children'] = $children; } $tree[] = $item; } } return $tree; } /** * 获取分类状态选项 * @return void */ public function statusOptions() { $options = [ ['value' => 1, 'label' => '启用'], ['value' => 2, 'label' => '禁用'] ]; $this->success('获取成功', $options); } /** * 移动分类排序 * @return void */ public function moveSort() { $id = $this->request->post('id'); $direction = $this->request->post('direction'); // up:上移, down:下移 if (empty($id) || empty($direction)) { $this->error(__('参数错误')); } $categoryInfo = Db::name('product_category') ->where('id', $id) ->find(); if (!$categoryInfo) { $this->error(__('分类不存在')); } try { Db::startTrans(); // 获取同级分类 $siblings = Db::name('product_category') ->where('parent_id', $categoryInfo['parent_id']) ->order('sort', 'asc') ->order('id', 'asc') ->select() ->toArray(); // 找到当前分类在列表中的位置 $currentIndex = -1; foreach ($siblings as $index => $sibling) { if ($sibling['id'] == $id) { $currentIndex = $index; break; } } if ($currentIndex === -1) { throw new \Exception('分类在同级中不存在'); } if ($direction == 'up' && $currentIndex > 0) { // 上移:与上一个交换排序值 $prevSibling = $siblings[$currentIndex - 1]; Db::name('product_category') ->where('id', $id) ->update(['sort' => $prevSibling['sort']]); Db::name('product_category') ->where('id', $prevSibling['id']) ->update(['sort' => $categoryInfo['sort']]); } elseif ($direction == 'down' && $currentIndex < count($siblings) - 1) { // 下移:与下一个交换排序值 $nextSibling = $siblings[$currentIndex + 1]; Db::name('product_category') ->where('id', $id) ->update(['sort' => $nextSibling['sort']]); Db::name('product_category') ->where('id', $nextSibling['id']) ->update(['sort' => $categoryInfo['sort']]); } else { // 已经在最前或最后,无需移动 Db::rollback(); $this->success('无需移动'); } Db::commit(); $this->success('移动成功'); } catch (\Exception $e) { Db::rollback(); $this->error('移动失败: ' . $e->getMessage()); } } }