import { Injectable } from '@nestjs/common' ; import { InjectRepository } from '@nestjs/typeorm' ; import { Repository , DeleteResult , SelectQueryBuilder , Brackets , ObjectLiteral , } from 'typeorm' ; import { Article } from '../../../entities/article.entity' ; import { CreateArticleDto } from './dto/create-article.dto' ; @ Injectable ( ) export class ArticleService { private readonly perPage : number = 16 ; constructor ( @ InjectRepository ( Article ) private readonly repository ) { } private async getQueryBuilder ( ) { return this . repository . createQueryBuilder ( 'article' ) . leftJoinAndSelect ( 'article.views' , 'view' ) . where ( 'article.publishedAt IS NOT NULL' ) . andWhere ( 'article.publishedAt < NOW()' ) . orderBy ( 'article.publishedAt' , 'DESC' ) ; } public async find ( skip ? , take ? ) { const builder = await this . getQueryBuilder ( ) ; return builder . skip ( skip ) . take ( take ) . getMany ( ) ; } public async findAll ( ) { return this . find ( ) ; } public async findByPage ( page ) { const skip = this . perPage * ( page - 1 ) ; const take = this . perPage ; return this . find ( skip , take ) ; } public async findAndCount ( ) { const builder = await this . getQueryBuilder ( ) ; return builder . getCount ( ) ; } public async findByIdsAndPage ( ids , page ) { if ( ids . length === 0 ) { return [ ] ; } const skip = this . perPage * ( page - 1 ) ; const take = this . perPage ; const builder = await this . getQueryBuilder ( ) ; return builder . andWhereInIds ( ids ) . skip ( skip ) . take ( take ) . getMany ( ) ; } public async findByIdsAndCount ( ids ) { if ( ids . length === 0 ) { return 0 ; } const builder = await this . getQueryBuilder ( ) ; return builder . andWhereInIds ( ids ) . getCount ( ) ; } public async findHotArticles ( ) { const skip = 0 ; const take = this . perPage ; const articles = await this . find ( skip , take ) ; articles . sort ( ( a , b ) => b . views . length - a . views . length ) ; return articles ; } public async search ( values , page ) { const where = new Brackets ( qb => { const SQL = 'article.title ILIKE :title' ; const getParameters = ( value ) : ObjectLiteral => ( { title : `%${ value }%` , } ) ; for ( let i = 0 ; i < values . length ; i ++ ) { const value = values [ i ] ; if ( i === 0 ) { qb . where ( SQL , getParameters ( value ) ) ; } else { qb . orWhere ( SQL , getParameters ( value ) ) ; } } } ) ; const skip = this . perPage * ( page - 1 ) ; const take = this . perPage ; let builder = await this . getQueryBuilder ( ) ; return builder . andWhere ( where ) . skip ( skip ) . take ( take ) . getMany ( ) ; } public async searchAndCount ( values ) { const where = new Brackets ( qb => { const SQL = 'article.title ILIKE :title' ; const getParameters = ( value ) : ObjectLiteral => ( { title : `%${ value }%` , } ) ; for ( let i = 0 ; i < values . length ; i ++ ) { const value = values [ i ] ; if ( i === 0 ) { qb . where ( SQL , getParameters ( value ) ) ; } else { qb . orWhere ( SQL , getParameters ( value ) ) ; } } } ) ; let builder = await this . getQueryBuilder ( ) ; return builder . andWhere ( where ) . getCount ( ) ; } public async findOne ( id ) { const builder = await this . getQueryBuilder ( ) ; return builder . andWhere ( 'article.id = :id' , { id } ) . getOne ( ) ; } public async create ( createArticleDto ) { return this . repository . create ( createArticleDto ) ; } public async save ( article ) { return this . repository . save ( article ) ; } public async delete ( id ) { return this . repository . delete ( id ) ; } }