oa_based/src/modules/product/product.service.ts

149 lines
4.3 KiB
TypeScript

import { Injectable } from '@nestjs/common';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { ProductEntity } from './product.entity';
import { EntityManager, Like, Repository } from 'typeorm';
import { ProductDto, ProductQueryDto, ProductUpdateDto } from './product.dto';
import { Pagination } from '~/helper/paginate/pagination';
import { paginate } from '~/helper/paginate';
import { Storage } from '../tools/storage/storage.entity';
import { BusinessException } from '~/common/exceptions/biz.exception';
import { ErrorEnum } from '~/constants/error-code.constant';
import { fieldSearch } from '~/shared/database/field-search';
@Injectable()
export class ProductService {
constructor(
@InjectEntityManager() private entityManager: EntityManager,
@InjectRepository(ProductEntity)
private productRepository: Repository<ProductEntity>,
@InjectRepository(Storage)
private storageRepository: Repository<Storage>
) {}
/**
* 查询所有产品
*/
async findAll({
page,
pageSize,
...fields
}: ProductQueryDto): Promise<Pagination<ProductEntity>> {
const { company: companyName, ...ext } = fields;
const sqb = this.productRepository
.createQueryBuilder('product')
.leftJoin('product.files', 'files')
.leftJoin('product.company', 'company')
.addSelect(['files.id', 'files.path', 'company.name', 'company.id'])
.where(fieldSearch(ext))
.andWhere('product.isDelete = 0')
.addOrderBy('product.namePinyin', 'ASC');
if (companyName) {
sqb.andWhere({
company: {
name: Like(`%${companyName}%`)
}
});
}
return paginate<ProductEntity>(sqb, {
page,
pageSize
});
}
/**
* 新增
*/
async create(dto: ProductDto): Promise<void> {
const { name, companyId } = dto;
const isExsit = await this.productRepository.findOne({
where: { name, company: { id: companyId } }
});
if (isExsit) {
throw new BusinessException(ErrorEnum.PRODUCT_EXIST);
}
await this.productRepository.insert(this.productRepository.create(dto));
}
/**
* 更新
*/
async update(id: number, { fileIds, ...data }: Partial<ProductUpdateDto>): Promise<void> {
await this.entityManager.transaction(async manager => {
await manager.update(
ProductEntity,
id,
this.productRepository.create({
...data
})
);
const product = await this.productRepository
.createQueryBuilder('product')
.leftJoinAndSelect('product.files', 'files')
.where('product.id = :id', { id })
.getOne();
if (fileIds?.length) {
const count = await this.storageRepository
.createQueryBuilder('storage')
.where('storage.id in(:fileIds)', { fileIds })
.getCount();
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
await manager
.createQueryBuilder()
.relation(ProductEntity, 'files')
.of(id)
.addAndRemove(fileIds, product.files);
}
});
}
/**
* 删除
*/
async delete(id: number): Promise<void> {
await this.productRepository.update(id, { isDelete: 1 });
}
/**
* 获取单个产品信息
*/
async info(id: number) {
const info = await this.productRepository
.createQueryBuilder('product')
.leftJoin('product.company', 'company')
.addSelect(['company.name', 'company.id'])
.where({
id
})
.andWhere('product.isDelete = 0')
.getOne();
return info;
}
/**
* 解除附件关联
* @param id 产品ID
* @param fileIds 附件ID
*/
async unlinkAttachments(id: number, fileIds: number[]) {
await this.entityManager.transaction(async manager => {
const product = await this.productRepository
.createQueryBuilder('product')
.leftJoinAndSelect('product.files', 'files')
.where('product.id = :id', { id })
.getOne();
const linkedFiles = product.files
.map(item => item.id)
.filter(item => !fileIds.includes(item));
// 附件要批量更新
await manager
.createQueryBuilder()
.relation(ProductEntity, 'files')
.of(id)
.addAndRemove(linkedFiles, product.files);
});
}
}