import { BadRequestException, Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { In, LessThan, Like, MoreThan, Repository } from 'typeorm'; import { Menu } from '@/modules/menu/menu.entity'; import { SharedService } from '@/shared/shared.service'; import { Article } from '@/modules/article/article.entity'; import { Category } from '@/modules/category/category.entity'; import { getTopMenuFragment } from '@/common/utils'; import { CustomException, ErrorCode } from '@/common/exceptions/custom.exception'; @Injectable() export class WebService { constructor( @InjectRepository(Menu) private menuRepo: Repository, @InjectRepository(Article) private articleRepo: Repository
, @InjectRepository(Category) private categoryRepo: Repository, private readonly sharedService: SharedService, ) {} async findMenuTree(locale?: string): Promise { const lang = this.sharedService.handleValidLang(locale); const menus = await this.menuRepo.find({ where: { enable: true, // isPublish: true, }, order: { order: 'ASC', children: { order: 'ASC', }, }, relations: { children: true, category: true, translations: true, }, select: { category: { id: true, title: true, }, }, }); const allMenus = menus.map((menu) => (menu.translations?.length ? menu.translate(lang) : menu)); // console.log('menus', lang, allMenus); return this.sharedService.handleTree(allMenus); } async findArticleDetail(id: number, locale?: string) { const lang = this.sharedService.handleValidLang(locale); const article = await this.articleRepo.findOne({ where: { id, enable: true }, relations: { user: true, translations: true, category: true }, select: { user: { id: true, username: true, }, category: { id: true, title: true, }, }, }); return article ? article.translate(lang) : false; } async setArticleCount(id: number) { const article = await this.articleRepo.findOne({ where: { id, enable: true }, }); if (!article) { return false; } article.readCount = article.readCount + 1; // console.log('article', article); await this.articleRepo.save(article); return true; } async getTopCategory1(id: number) { let currentCategory = await this.categoryRepo.findOne({ where: { id, enable: true }, relations: { parent: true }, }); if (!currentCategory) { return null; // 如果分类不存在,返回 null } // 递归查找顶层父分类 while (currentCategory.parent) { currentCategory = await this.categoryRepo.findOne({ where: { id: currentCategory.parent.id, enable: true }, relations: { parent: true }, }); } console.log('currentCategory', currentCategory); return currentCategory.id ? this.categoryRepo.findOne({ where: { id: currentCategory.id, enable: true }, relations: { children: true }, }) : null; } async getCategoryTreeAndPath(id: number, locale: string) { const lang = this.sharedService.handleValidLang(locale); const categories = await this.categoryRepo.find({ where: { enable: true }, relations: { children: true, translations: true }, }); const data = this.sharedService.handleTree(categories.map((cate) => cate.translate(lang))); return getTopMenuFragment(data, id); } async searchArticles(key: string, locale?: string) { const lang = this.sharedService.handleValidLang(locale); const articles = await this.articleRepo.find({ where: [ { enable: true, }, { translations: { locale: lang, title: Like(`%${key || ''}%`), }, }, { translations: { locale: lang, content: Like(`%${key || ''}%`), }, }, ], relations: { translations: true }, }); return articles.map((article) => article.translate(lang)); } async findCateAllChildIds(parentId: number) { const childIds: number[] = []; // 递归查找所有子菜单的 id const findChildren = async (id: number) => { const children = await this.categoryRepo.find({ where: { parentId: id, enable: true } }); for (const child of children) { childIds.push(child.id); await findChildren(child.id); // 递归查找子菜单的子菜单 } }; await findChildren(parentId); return childIds; } async getArticlesByCate(id: number, locale?: string) { const lang = this.sharedService.handleValidLang(locale); // 保留 const category = await this.categoryRepo.findOne({ where: { id: id, enable: true }, relations: { children: true }, }); const ids = await this.findCateAllChildIds(category.id); // ids.push(category.id); // console.log('ids', ids); const articles = await this.articleRepo.find({ where: { categoryId: id, enable: true, }, relations: { translations: true }, order: { order: 'DESC', createTime: 'DESC', }, }); const childArticles = await this.articleRepo.find({ where: { categoryId: In(ids), enable: true, }, relations: { translations: true }, order: { order: 'DESC', createTime: 'DESC', }, }); // console.log('childArticles', childArticles); return articles.length > 0 ? articles.map((article) => article.translate(lang)) : childArticles.map((article) => article.translate(lang)); } async getNearArticle(currentId: number, locale?: string) { const lang = this.sharedService.handleValidLang(locale); const currentEntity = await this.articleRepo.findOne({ where: { id: currentId, enable: true }, }); if (!currentEntity) { // throw new CustomException(ErrorCode.ERR_4000, '当前数据不存在'); return []; } const prevEntity = await this.articleRepo.findOne({ where: { id: LessThan(currentId), categoryId: currentEntity.categoryId, enable: true }, order: { id: 'DESC' }, relations: { translations: true }, }); const nextEntity = await this.articleRepo.findOne({ where: { id: MoreThan(currentId), categoryId: currentEntity.categoryId, enable: true }, order: { id: 'ASC' }, relations: { translations: true }, }); return [ prevEntity ? prevEntity.translate(lang) : null, nextEntity ? nextEntity.translate(lang) : null, ]; } }