findOrEmpty()->toArray(); } /** * 根据上级ID和语言获取下级栏目 * * @param $parentId * @param bool $onlyChild 仅获取下级 默认true false=获取所有后代 * @return array */ public static function getChildrenByParentId($parentId, bool $onlyChild = true) { if ($parentId <= 0) { return []; } $category = self::getById($parentId); if (empty($category)) { return []; } if ($onlyChild) { $where[] = ['c.parent_id', '=', $parentId]; } else { $where[] = ['c.path', 'like', $category['path'].$parentId.',%']; } return self::alias('c') ->leftJoin('model m', 'c.model_id=m.id') ->field('c.*, m.manager, m.template, m.name as modelName') // ->where('c.parent_id', $parentId) ->where($where) ->order('c.sort', 'asc') ->order('c.id', 'asc') ->select() ->toArray(); } //重写方法 public static function getById($categoryId) { return self::alias('c') ->leftJoin('model m', 'c.model_id = m.id') ->where('c.id', $categoryId) ->field('c.*, m.template') ->findOrEmpty() ->toArray(); } //查看是否有下级栏目 public static function hasChildren($categoryId) { if (is_array($categoryId)) { $count = self::where('parent_id', 'in', $categoryId)->count(); } else { $count = self::where(['parent_id' => $categoryId])->count(); } return $count ? true : false; } //获取前台菜单 public static function getListForFrontMenu() { $items = self::alias('c') ->leftJoin('model m', 'c.model_id=m.id') ->field('c.*, m.manager, m.template') ->where('c.state', 1) ->where('c.frontend_show', 1) ->order('is_index desc, sort asc') ->select() ->toArray(); return self::getCates($items); } /** * 获取栏目 * @param bool $limit 是否限制查询 * @param array $cates 需要限制查询的栏目IDs */ public static function getList($limit = false, $cates = []) { if ($limit && empty($cates)) { return []; } return self::alias('c') ->leftJoin('model m', 'c.model_id=m.id') ->field('c.*, m.manager, m.name as modelName') ->when($limit, function ($query) use ($cates) { // $query->whereIn('c.id', $cates); }) ->order('sort', 'asc') ->select() ->toArray(); } //获取栏目分级列表 public static function getListTree($isMenu = false) { if ($isMenu) { $items = self::where('c.state', 1)->order('sort', 'asc')->select()->toArray(); } else { $items = self::order('sort', 'asc')->select()->toArray(); } return self::getCates($items); } //获取递归栏目 public static function getCates($cates, $parentId = 0) { $menus = []; foreach ($cates as $cate) { if ($cate['parent_id'] == $parentId) { $children = self::getCates($cates, $cate['id']); if (!empty($children)) { $cate['children'] = $children; } $menus[] = $cate; } } return $menus; } public static function onAfterInsert($category) { $category->sort = $category->id; $category->save(); } //递归获取栏目名称面包屑 public static function getCatesCrumbs($currentId = 0) { $crumbs = []; $category = self::getById($currentId); if ($category) { if ($category['parent_id'] != 0) { $categoryIds = explode(',', trim($category['path'], ',')); $categories = self::where('id', 'in', $categoryIds)->column('*', 'id'); foreach ($categoryIds as $id) { if (isset($categories[$id])) { $crumbs[] = $categories[$id]['title']; } } } $crumbs[] = $category['title']; } return $crumbs; } //获取栏目中涉及到的文件 public static function getFilesInUse() { $items = self::select()->toArray(); $data = []; foreach ($items as $item) { $src = trim($item['src']); if (!empty($src)) { $key = getKeyByPath($src); $data[$key] = $src; } } return $data; } // 根据栏目路径获取所属的一级栏目ID 0则表示当前栏目是就是一级 public static function firstGradeId($categoryPath, $categoryId) { $categoryPath = explode(',', $categoryPath); $firstCategoryId = $categoryId; if (isset($categoryPath[2]) && !empty($categoryPath[2])) { $firstCategoryId = $categoryPath[2]; } return $firstCategoryId; } //当前分类的最高级分类Id public static function firstGradeById($id) { $res = 0; $item = self::getById($id); if ($item) { $res = $id; if ($item['parent_id'] > 0) { $items = self::select()->toArray(); $first = self::getFirstGrade($items, $item['parent_id']); if (!empty($first)) { $res = $first['id']; } } } return $res; } public static function getFirstGrade($items, $parentId) { $data = []; foreach ($items as $key => $item) { if ($item['id'] == $parentId) { if ($item['parent_id'] > 0) { unset($items[$key]); $parent = self::getFirstGrade($items, $item['parent_id']); if (!empty($parent)) { $data = $parent; } else { $data = $item; } } else { $data = $item; } } } return $data; } /** * 当前分类和子分类 * * @param int $parentId * @return array */ public static function getCategoryWithChildren(int $parentId) { $item = self::getById($parentId); if ($item) { $childList = self::getChildrenByParentId($parentId); $childIds = []; foreach ($childList as $child) { $childIds[] = $child['id']; } $item['children'] = $childList; $item['children_ids'] = $childIds; } return $item; } /** * 当前分类和子分类的ID集 * @param int $parentId * @return array|int[] */ public static function getCategoryWithChildrenIds(int $parentId) { $categoryIds = [$parentId]; $item = self::getCategoryWithChildren($parentId); if ($item) { $categoryIds = array_merge($categoryIds, $item['children_ids']); } return $categoryIds; } public static function getByRuleAlias($alias) { return self::where('route', $alias)->findOrEmpty()->toArray(); } /* * 设置了路由别名的栏目 * 路由别名长度大的优先排序,路由匹配优先规则 */ public static function getRouteList() { return self::whereRaw('char_length(route) > 0') ->field('id,route,model_id, char_length(route) as alias_len') ->order('alias_len', 'desc') ->select() ->toArray(); } /** * 获取所有下级分类 * * @param int $parentId * @return Collection * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function findAllChildren(int $parentId) { return self::whereFindInSet('path', $parentId)->select(); } /** * 根据栏目分组ID获取该分组所有的栏目ID集 * * @param int $groupId * @return array|int[] * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function getGroupCategoryIds(int $groupId) { $list = [$groupId]; $items = self::findAllChildren($groupId); $childrenIds = $items->column('id'); return array_merge($list, $childrenIds); } /** * 判断当前分类是否为文章类 * * @param int $cateId */ public static function isArticle(int $cateId) { $item = self::getById($cateId); $res = false; if (!empty($item) && $item['model_id'] == Model::MODEL_ARTICLE) { $res = true; } return $res; } /** * 根据栏目标识获取栏目信息 * * @param string $categoryKey * @return array|\think\Model|null * @throws DataNotFoundException * @throws DbException * @throws ModelNotFoundException */ public static function findByCategoryKey(string $categoryKey) { if (strlen($categoryKey) == 0) { return null; } return self::where('category_key', $categoryKey)->find(); } public static function navList($categoryId = 0) { $menus = self::getListForFrontMenu(); $allCategories = Category::getList(false); foreach ($menus as &$menu) { $menu['children_ids'] = []; // $menusGroup = []; if (isset($menu['children'])) { $menu['children_ids'] = array_column($menu['children'], 'id'); // foreach ($menu['children'] as $child) { // $menusGroup[$child['group_name']][] = $child; // } } // $menu['menus_group'] = $menusGroup; $menu['all_subordinate_ids'] = self::getAllSubordinateIds($allCategories, $menu['id'], true); $menu['isActive'] = 0; if ($categoryId == $menu['id'] || in_array($categoryId, $menu['all_subordinate_ids'])) { $menu['isActive'] = 1; } } $data = [ // 'categoryId' => $categoryId, 'menus' => $menus, ]; // dd($menus); // exit; return $data; } // 所有下级栏目ID 包含当前栏目ID private static function getAllSubordinateIds($items, $curId = 0, $containCurrent = false) { $list = []; foreach ($items as $k => $item) { if ($item['parent_id'] == $curId) { $list[] = $item['id']; unset($items[$k]); $childrenIds = self::getAllSubordinateIds($items, $item['id']); if ($childrenIds) { $list = array_merge($list, $childrenIds); } } } if ($containCurrent) { $list = array_merge([$curId], $list); } return $list; } //当前分类的最高级分类Id public static function getPosition($id) { $position = ""; $item = self::getById($id); if ($item) { $position = "{$item['title']}"; if ($item['parent_id'] > 0) { $items = self::select()->toArray(); $first = self::getPositionGrade($items, $item['parent_id']); if (!empty($first)) { $position = $first.$position; } } } return $position; } public static function getPositionGrade($items, $parentId) { $data = ""; foreach ($items as $key => $item) { if ($item['id'] == $parentId) { $data = "{$item['title']}"; if ($item['parent_id'] > 0) { unset($items[$key]); $parent = self::getFirstGrade($items, $item['parent_id']); if (!empty($parent)) { $data = "{$parent['title']}".$data; } } } } return $data; } // 根据栏目路径获取所有上级 public static function categoryPath($categoryPath): array { $ids = explode(',', $categoryPath); $arr = []; foreach ($ids as $id) { if ($id > 0) { $arr[] = $id; } } return Category::whereIn('id', $arr)->field('id,title,src,src_mobile,path,route,url')->select()->toArray(); } }