field('id,pid,title,type,image,path,component_path,sort,desc') ->order('sort', 'desc') ->select() ->toArray(); // 转换为数组 // 使用 buildFrontMenuTree 构建树形结构 $treeFrontMenus = $this->buildFrontMenuTree($frontMenus); return json([ 'code' => 200, 'msg' => 'success', 'data' => $treeFrontMenus ]); } catch (DbException $e) { return json([ 'code' => 500, 'msg' => 'fail:' . $e->getMessage(), 'data' => $e->getTraceAsString() ]); } } /** * 创建新菜单 * @return \think\response\Json */ public function createFrontMenu() { try { // 获取请求参数 $data = $this->request->param(); // 验证参数 $this->validate($data, [ 'title|菜单名称' => 'require|max:50', 'pid|上级菜单ID' => 'integer', 'type|菜单类型' => 'require|in:1,2,3,4', 'sort|排序号' => 'integer', 'path|路由路径' => 'max:200', 'component_path|组件路径' => 'max:200', 'desc|描述' => 'max:500', ]); // 准备菜单数据 $menuData = [ 'pid' => $data['pid'] ?? 0, 'title' => $data['title'], 'type' => $data['type'], 'sort' => $data['sort'] ?? 0, 'path' => $data['path'] ?? '', 'component_path' => $data['component_path'] ?? '', 'image' => $data['image'] ?? '', 'desc' => $data['desc'] ?? '', 'create_time' => date('Y-m-d H:i:s') ]; // 创建菜单 $result = FrontMenu::insertGetId($menuData); if ($result === false) { return json([ 'code' => 500, 'msg' => 'fail' ]); } // 记录操作日志 $this->logSuccess('前端导航管理', '创建前端导航', ['id' => $result]); return json([ 'code' => 200, 'msg' => 'success' ]); } catch (ValidateException $e) { // 记录失败日志 $this->logFail('前端导航管理', '创建前端导航', $e->getMessage()); return json([ 'code' => 500, 'msg' => 'fail:' . $e->getMessage() ]); } } /** * 编辑前端导航 * @param int $id 前端导航ID * @return \think\response\Json */ public function editFrontMenu(int $id) { try { // 获取请求参数 $data = $this->request->param(); // 验证参数 $this->validate($data, [ 'title|菜单名称' => 'require|max:50', 'pid|上级菜单ID' => 'integer', 'type|菜单类型' => 'require|in:1,2,3,4', 'sort|排序号' => 'integer', 'path|路由路径' => 'max:200', 'component_path|组件路径' => 'max:200', 'desc|描述' => 'max:500', ]); // 准备更新数据 $updateData = [ 'title' => $data['title'], 'pid' => $data['pid'] ?? null, 'type' => $data['type'], 'path' => $data['path'] ?? null, 'component_path' => $data['component_path'] ?? null, 'image' => $data['image'] ?? null, 'desc' => $data['desc'] ?? null, 'sort' => $data['sort'] ?? 0, 'update_time' => date('Y-m-d H:i:s') ]; // 执行更新 FrontMenu::where('id', $id)->update($updateData); // 获取更新后的菜单信息 $menu = FrontMenu::where('id', $id)->find(); // 记录操作日志 $this->logSuccess('前端导航管理', '更新前端导航', ['id' => $id]); return json([ 'code' => 200, 'msg' => 'success', 'data' => $menu ? $menu->toArray() : [] ]); } catch (ValidateException $e) { // 记录失败日志 $this->logFail('前端导航管理', '更新前端导航', $e->getMessage()); return json([ 'code' => 400, 'msg' => $e->getError() ]); } catch (DbException $e) { // 记录失败日志 $this->logFail('前端导航管理', '更新前端导航', $e->getMessage()); return json([ 'code' => 500, 'msg' => 'fail:' . $e->getMessage(), 'data' => $e->getTraceAsString() ]); } } public function deleteFrontMenu(int $id) { try { // 检查是否有子前端导航 $hasChildren = FrontMenu::where('pid', $id) ->where('pid', $id) ->where('delete_time', null) ->count() > 0; if ($hasChildren) { return json([ 'code' => 400, 'msg' => '该前端导航下有子导航,无法删除' ]); } // 逻辑删除前端导航 $result = FrontMenu::where('id', $id) ->where('id', $id) ->where('delete_time', null) ->update([ 'delete_time' => date('Y-m-d H:i:s'), 'update_time' => date('Y-m-d H:i:s') ]); if ($result === false) { return json([ 'code' => 500, 'msg' => 'fail' ]); } // 记录操作日志 $this->logSuccess('前端导航管理', '删除前端导航', ['id' => $id]); return json([ 'code' => 200, 'msg' => 'success' ]); } catch (ValidateException $e) { // 记录失败日志 $this->logFail('前端导航管理', '删除前端导航', $e->getMessage()); return json([ 'code' => 500, 'msg' => 'fail:' . $e->getMessage() ]); } catch (DbException $e) { // 记录失败日志 $this->logFail('前端导航管理', '删除前端导航', $e->getMessage()); return json([ 'code' => 500, 'msg' => 'fail:' . $e->getMessage() ]); } } /** * 构建前端导航树形结构 * @param array $frontMenus 前端导航列表 * @param int $pid 父前端导航ID * @return array */ private function buildFrontMenuTree(array $frontMenus, int $pid = 0): array { $tree = []; foreach ($frontMenus as $frontMenu) { // 将null的pid视为0处理 $menuPid = is_null($frontMenu['pid']) ? 0 : $frontMenu['pid']; if ($menuPid == $pid) { $children = $this->buildFrontMenuTree($frontMenus, $frontMenu['id']); if (!empty($children)) { $frontMenu['children'] = $children; } $tree[] = $frontMenu; } } // 按 sort 字段降序排序 usort($tree, function ($a, $b) { $sortA = $a['sort'] ?? 0; $sortB = $b['sort'] ?? 0; return $sortB - $sortA; }); return $tree; } }