feat: 产品模块

This commit is contained in:
louis 2024-03-05 13:57:03 +08:00
parent 47b7015c16
commit df8806a5fb
9 changed files with 92 additions and 33 deletions

View File

@ -49,5 +49,8 @@ export enum ErrorEnum {
// Storage相关
STORAGE_NOT_FOUND = '1404:文件不存在,请重试',
STORAGE_REFRENCE_EXISTS = '1405:文件存在关联,无法删除,请先找到该文件关联的业务解除关联。'
STORAGE_REFRENCE_EXISTS = '1405:文件存在关联,无法删除,请先找到该文件关联的业务解除关联。',
// Product
PRODUCT_EXIST = '1406:产品已存在'
}

View File

@ -33,7 +33,19 @@ export class CompanyUpdateDto extends PartialType(CompanyDto) {
fileIds: number[];
}
export class ComapnyCreateDto extends PartialType(CompanyDto) {
@ApiProperty({ description: '附件' })
@IsOptional()
@IsArray()
fileIds: number[];
}
export class CompanyQueryDto extends IntersectionType(
PagerDto<CompanyDto>,
PartialType(CompanyDto)
) {}
) {
@ApiProperty({ description: '公司名称' })
@IsOptional()
@IsString()
name: string;
}

View File

@ -1,7 +1,8 @@
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
import { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm';
import { Column, Entity, JoinTable, ManyToMany, OneToMany, Relation } from 'typeorm';
import { CommonEntity } from '~/common/entity/common.entity';
import { Storage } from '../tools/storage/storage.entity';
import { ProductEntity } from '../product/product.entity';
@Entity({ name: 'company' })
export class CompanyEntity extends CommonEntity {
@ -19,6 +20,10 @@ export class CompanyEntity extends CommonEntity {
@ApiProperty({ description: '删除状态0未删除1已删除' })
isDelete: number;
@ApiHideProperty()
@OneToMany(() => ProductEntity, product => product.company)
products: Relation<ProductEntity[]>;
@ManyToMany(() => Storage, storage => storage.companys)
@JoinTable({
name: 'company_storage',

View File

@ -16,46 +16,46 @@ export const permissions = definePermission('materials_inventory:history_in_out'
DELETE: 'delete'
} as const);
@ApiTags('Materials In Out History - 原材料出入库管理')
@ApiTags('Materials In Out History - 原材料出入库记录')
@ApiSecurityAuth()
@Controller('materials-in-out')
export class MaterialsInOutController {
constructor(private miService: MaterialsInOutService) {}
constructor(private materialsInOutService: MaterialsInOutService) {}
@Get()
@ApiOperation({ summary: '获取原材料盘点列表' })
@ApiOperation({ summary: '获取原材料出入库记录列表' })
@ApiResult({ type: [MaterialsInOutEntity], isPage: true })
@Perm(permissions.LIST)
async list(@Query() dto: MaterialsInOutQueryDto) {
return this.miService.findAll(dto);
return this.materialsInOutService.findAll(dto);
}
@Get(':id')
@ApiOperation({ summary: '获取原材料盘点信息' })
@ApiOperation({ summary: '获取原材料出入库记录信息' })
@ApiResult({ type: MaterialsInOutDto })
@Perm(permissions.READ)
async info(@IdParam() id: number) {
return this.miService.info(id);
return this.materialsInOutService.info(id);
}
@Post()
@ApiOperation({ summary: '新增原材料盘点' })
@ApiOperation({ summary: '新增原材料出入库记录' })
@Perm(permissions.CREATE)
async create(@Body() dto: MaterialsInOutDto): Promise<void> {
await this.miService.create(dto);
await this.materialsInOutService.create(dto);
}
@Put(':id')
@ApiOperation({ summary: '更新原材料盘点' })
@ApiOperation({ summary: '更新原材料出入库记录' })
@Perm(permissions.UPDATE)
async update(@IdParam() id: number, @Body() dto: MaterialsInOutUpdateDto): Promise<void> {
await this.miService.update(id, dto);
await this.materialsInOutService.update(id, dto);
}
@Delete(':id')
@ApiOperation({ summary: '删除原材料盘点' })
@ApiOperation({ summary: '删除原材料出入库记录' })
@Perm(permissions.DELETE)
async delete(@IdParam() id: number): Promise<void> {
await this.miService.delete(id);
await this.materialsInOutService.delete(id);
}
@Put('unlink-attachments/:id')
@ -65,6 +65,6 @@ export class MaterialsInOutController {
@IdParam() id: number,
@Body() { fileIds }: MaterialsInOutUpdateDto
): Promise<void> {
await this.miService.unlinkAttachments(id, fileIds);
await this.materialsInOutService.unlinkAttachments(id, fileIds);
}
}

View File

@ -4,10 +4,16 @@ import { MaterialsInventoryService } from './materials_inventory.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MaterialsInventoryEntity } from './materials_inventory.entity';
import { StorageModule } from '../tools/storage/storage.module';
import { MaterialsInOutController } from './in_out/materials_in_out.controller';
import { MaterialsInOutService } from './in_out/materials_in_out.service';
import { MaterialsInOutEntity } from './in_out/materials_in_out.entity';
@Module({
imports: [TypeOrmModule.forFeature([MaterialsInventoryEntity]), StorageModule],
controllers: [MaterialsInventoryController],
providers: [MaterialsInventoryService]
imports: [
TypeOrmModule.forFeature([MaterialsInventoryEntity, MaterialsInOutEntity]),
StorageModule
],
controllers: [MaterialsInventoryController, MaterialsInOutController],
providers: [MaterialsInventoryService, MaterialsInOutService]
})
export class MaterialsInventoryModule {}

View File

@ -18,10 +18,14 @@ import { ProductEntity } from './product.entity';
export class ProductDto {
@ApiProperty({ description: '产品名称' })
@IsUnique(ProductEntity, { message: '已存在同名产品' })
@IsString()
name: string;
@ApiProperty({ description: '所属公司' })
@IsOptional()
@IsNumber()
companyId: number;
@ApiProperty({ description: '附件' })
files: Storage[];
}
@ -36,4 +40,9 @@ export class ProductUpdateDto extends PartialType(ProductDto) {
export class ProductQueryDto extends IntersectionType(
PagerDto<ProductDto>,
PartialType(ProductDto)
) {}
) {
@ApiProperty({ description: '所属公司名称' })
@IsOptional()
@IsString()
company: string;
}

View File

@ -1,14 +1,14 @@
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
import { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm';
import { Column, Entity, JoinColumn, JoinTable, ManyToMany, ManyToOne, Relation } from 'typeorm';
import { CommonEntity } from '~/common/entity/common.entity';
import { Storage } from '../tools/storage/storage.entity';
import { CompanyEntity } from '../company/company.entity';
@Entity({ name: 'product' })
export class ProductEntity extends CommonEntity {
@Column({
name: 'name',
type: 'varchar',
unique: true,
length: 255,
comment: '产品名称'
})
@ -19,6 +19,14 @@ export class ProductEntity extends CommonEntity {
@ApiProperty({ description: '删除状态0未删除1已删除' })
isDelete: number;
@Column({ name: 'company_id', type: 'int', comment: '所属公司', nullable: true })
@ApiProperty({ description: '所属公司' })
companyId: number;
@ManyToOne(() => CompanyEntity /* , { onDelete: 'CASCADE' } */)
@JoinColumn({ name: 'company_id' })
company: CompanyEntity;
@ManyToMany(() => Storage, storage => storage.products)
@JoinTable({
name: 'product_storage',

View File

@ -28,14 +28,22 @@ export class ProductService {
pageSize,
...fields
}: ProductQueryDto): Promise<Pagination<ProductEntity>> {
const queryBuilder = this.productRepository
const { company: companyName,...ext } = fields;
const sqb = this.productRepository
.createQueryBuilder('product')
.leftJoin('product.files', 'files')
.addSelect(['files.id', 'files.path'])
.where(fieldSearch(fields))
.andWhere('product.isDelete = 0');
return paginate<ProductEntity>(queryBuilder, {
.leftJoin('product.company', 'company')
.addSelect(['files.id', 'files.path', 'company.name', 'company.id'])
.where(fieldSearch(ext))
.where('product.isDelete = 0');
if (companyName) {
sqb.andWhere({
company: {
name: Like(`%${companyName}%`)
}
});
}
return paginate<ProductEntity>(sqb, {
page,
pageSize
});
@ -45,6 +53,13 @@ export class ProductService {
*
*/
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(dto);
}
@ -83,16 +98,17 @@ export class ProductService {
*
*/
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
})
@ -103,7 +119,7 @@ export class ProductService {
/**
*
* @param id ID
* @param id ID
* @param fileIds ID
*/
async unlinkAttachments(id: number, fileIds: number[]) {