feat: 出入库相关api完善

This commit is contained in:
louis 2024-03-06 11:39:56 +08:00
parent 655adf787f
commit cf7c91eab2
9 changed files with 85 additions and 51 deletions

View File

@ -97,7 +97,7 @@ pnpm migration:revert
4.执行sql覆盖docker中的数据库 4.执行sql覆盖docker中的数据库
```bash ```bash
docker exec -i huaxin-admin-mysql mysql -h 127.0.0.1 -u root -phuaxin123 hxoa < hxoa_2024-03-05_151242.sql docker exec -i huaxin-admin-mysql mysql -h 127.0.0.1 -u root -phuaxin123 hxoa < hxoa_2024-03-05_222748.sql
``` ```
更多细节,请移步至[官方文档](https://typeorm.io/migrations) 更多细节,请移步至[官方文档](https://typeorm.io/migrations)

View File

@ -4,7 +4,7 @@ import { IPaginationMeta } from './interface';
export class Pagination<PaginationObject, T extends ObjectLiteral = IPaginationMeta> { export class Pagination<PaginationObject, T extends ObjectLiteral = IPaginationMeta> {
constructor( constructor(
public readonly items: PaginationObject[], public items: PaginationObject[],
public readonly meta: T public readonly meta: T
) {} ) {}

View File

@ -13,6 +13,7 @@ import {
Matches, Matches,
MinLength MinLength
} from 'class-validator'; } from 'class-validator';
import dayjs from 'dayjs';
import { PagerDto } from '~/common/dto/pager.dto'; import { PagerDto } from '~/common/dto/pager.dto';
import { MaterialsInOrOutEnum } from '~/constants/enum'; import { MaterialsInOrOutEnum } from '~/constants/enum';
import { Storage } from '~/modules/tools/storage/storage.entity'; import { Storage } from '~/modules/tools/storage/storage.entity';
@ -21,12 +22,12 @@ import { formatToDate } from '~/utils';
export class MaterialsInOutDto { export class MaterialsInOutDto {
@ApiProperty({ description: '产品' }) @ApiProperty({ description: '产品' })
@IsNumber() @IsNumber()
product: number; productId: number;
@ApiProperty({ description: '单位(字典)' }) @ApiProperty({ description: '单位(字典)' })
@IsNumber() @IsNumber()
@IsOptional() @IsOptional()
unit: number; unitId: number;
@ApiProperty({ description: '入库或出库 0:入库 1:出库' }) @ApiProperty({ description: '入库或出库 0:入库 1:出库' })
@IsEnum(MaterialsInOrOutEnum) @IsEnum(MaterialsInOrOutEnum)
@ -82,15 +83,24 @@ export class MaterialsInOutUpdateDto extends PartialType(MaterialsInOutDto) {
export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutDto> { export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutDto> {
@ApiProperty({ description: '出入库时间YYYY-MM-DD' }) @ApiProperty({ description: '出入库时间YYYY-MM-DD' })
@IsOptional() @IsOptional()
@IsArray() // @IsString()
@Transform(params => { @Transform(params => {
// 开始和结束时间用的是一天的开始和一天的结束的时分秒 // 开始和结束时间用的是一天的开始和一天的结束的时分秒
const [start, end] = params.value; const date = params.value;
return [ return [
start ? `${formatToDate(start)} 00:00:00` : null, date ? `${formatToDate(dayjs(date).startOf('month'))} 00:00:00` : null,
end ? `${formatToDate(end)} 23:59:59` : null date ? `${formatToDate(dayjs(date).endOf('month'))} 23:59:59` : null
]; ];
}) })
time?: string[]; time?: string[];
@ApiProperty({ description: '入库或出库 0:入库 1:出库' })
@IsOptional()
@IsEnum(MaterialsInOrOutEnum)
inOrOut: MaterialsInOrOutEnum;
@ApiProperty({ description: '产品名称' })
@IsOptional()
@IsString()
product: string;
} }

View File

@ -1,26 +1,30 @@
import { ApiProperty } from '@nestjs/swagger'; import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
import { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm'; import {
Column,
Entity,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
Relation,
VirtualColumn
} from 'typeorm';
import { CommonEntity } from '~/common/entity/common.entity'; import { CommonEntity } from '~/common/entity/common.entity';
import { MaterialsInOrOutEnum } from '~/constants/enum'; import { MaterialsInOrOutEnum } from '~/constants/enum';
import { ProductEntity } from '~/modules/product/product.entity';
import { DictItemEntity } from '~/modules/system/dict-item/dict-item.entity';
import { Storage } from '~/modules/tools/storage/storage.entity'; import { Storage } from '~/modules/tools/storage/storage.entity';
@Entity({ name: 'materials_in_out' }) @Entity({ name: 'materials_in_out' })
export class MaterialsInOutEntity extends CommonEntity { export class MaterialsInOutEntity extends CommonEntity {
@Column({ @Column({
name: 'product', name: 'product_id',
type: 'int', type: 'int',
comment: '产品名称' comment: '产品'
}) })
@ApiProperty({ description: '产品名称' }) @ApiProperty({ description: '产品' })
product: number; productId: number;
@Column({
name: 'unit',
type: 'int',
comment: '单位(字典)'
})
@ApiProperty({ description: '单位(字典)' })
unit: number;
@Column({ @Column({
name: 'inOrOut', name: 'inOrOut',
@ -78,6 +82,7 @@ export class MaterialsInOutEntity extends CommonEntity {
name: 'issuance_number', name: 'issuance_number',
type: 'varchar', type: 'varchar',
length: 100, length: 100,
nullable: true,
comment: '领料单号' comment: '领料单号'
}) })
@ApiProperty({ description: '领料单号' }) @ApiProperty({ description: '领料单号' })
@ -95,6 +100,13 @@ export class MaterialsInOutEntity extends CommonEntity {
@ApiProperty({ description: '删除状态0未删除1已删除' }) @ApiProperty({ description: '删除状态0未删除1已删除' })
isDelete: number; isDelete: number;
@ManyToOne(() => ProductEntity)
@JoinColumn({ name: 'product_id' })
product: ProductEntity;
@ApiHideProperty()
unit: DictItemEntity;
@ManyToMany(() => Storage, storage => storage.materialsInOut) @ManyToMany(() => Storage, storage => storage.materialsInOut)
@JoinTable({ @JoinTable({
name: 'materials_in_out_storage', name: 'materials_in_out_storage',

View File

@ -7,7 +7,11 @@ import { BusinessException } from '~/common/exceptions/biz.exception';
import { ErrorEnum } from '~/constants/error-code.constant'; import { ErrorEnum } from '~/constants/error-code.constant';
import { paginate } from '~/helper/paginate'; import { paginate } from '~/helper/paginate';
import { Storage } from '~/modules/tools/storage/storage.entity'; import { Storage } from '~/modules/tools/storage/storage.entity';
import { MaterialsInOutQueryDto, MaterialsInOutDto, MaterialsInOutUpdateDto } from './materials_in_out.dto'; import {
MaterialsInOutQueryDto,
MaterialsInOutDto,
MaterialsInOutUpdateDto
} from './materials_in_out.dto';
import { MaterialsInOutEntity } from './materials_in_out.entity'; import { MaterialsInOutEntity } from './materials_in_out.entity';
import { fieldSearch } from '~/shared/database/field-search'; import { fieldSearch } from '~/shared/database/field-search';
@ -26,25 +30,32 @@ export class MaterialsInOutService {
async findAll({ async findAll({
page, page,
pageSize, pageSize,
product: productName,
...ext ...ext
}: MaterialsInOutQueryDto): Promise<Pagination<MaterialsInOutEntity>> { }: MaterialsInOutQueryDto): Promise<Pagination<MaterialsInOutEntity>> {
const queryBuilder = this.materialsInOutRepository const sqb = this.materialsInOutRepository
.createQueryBuilder('materialsInOut') .createQueryBuilder('materialsInOut')
.leftJoin('materialsInOut.files', 'files') .leftJoin('materialsInOut.files', 'files')
.addSelect(['files.id', 'files.path']) .leftJoin('materialsInOut.product', 'product')
// .where({ .leftJoin('product.unit', 'unit')
// ...(materialsInOutNumber ? { materialsInOutNumber: Like(`%${materialsInOutNumber}%`) } : null), .addSelect(['files.id', 'files.path', 'product.id', 'product.name', 'unit.id', 'unit.label'])
// ...(title ? { title: Like(`%${title}%`) } : null),
// ...(isNumber(type) ? { type } : null),
// ...(isNumber(status) ? { status } : null)
// })
.where(fieldSearch(ext)) .where(fieldSearch(ext))
.andWhere('materialsInOut.isDelete = 0'); .andWhere('materialsInOut.isDelete = 0')
.addOrderBy('materialsInOut.time', 'DESC');
return paginate<MaterialsInOutEntity>(queryBuilder, { if (productName) {
sqb.andWhere('product.name like :productName', { productName: `%${productName}%` });
}
let pageData = await paginate<MaterialsInOutEntity>(sqb, {
page, page,
pageSize pageSize
}); });
// 产品表中的单位字段需要单独处理
pageData.items = pageData.items.map(materialsInOut => {
materialsInOut.unit = materialsInOut.product.unit;
delete materialsInOut.product.unit;
return materialsInOut;
});
return pageData;
} }
/** /**

View File

@ -1,26 +1,18 @@
import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger'; import { ApiProperty, IntersectionType, PartialType } from '@nestjs/swagger';
import { import { IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
IsArray,
IsDate,
IsDateString,
IsIn,
IsInt,
IsNumber,
IsOptional,
IsString,
Matches,
MinLength
} from 'class-validator';
import { PagerDto } from '~/common/dto/pager.dto'; import { PagerDto } from '~/common/dto/pager.dto';
import { Storage } from '../tools/storage/storage.entity'; import { Storage } from '../tools/storage/storage.entity';
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
import { ProductEntity } from './product.entity';
export class ProductDto { export class ProductDto {
@ApiProperty({ description: '产品名称' }) @ApiProperty({ description: '产品名称' })
@IsString() @IsString()
name: string; name: string;
@ApiProperty({ description: '单位(字典)' })
@IsOptional()
@IsNumber()
unitId: number;
@ApiProperty({ description: '所属公司' }) @ApiProperty({ description: '所属公司' })
@IsOptional() @IsOptional()
@IsNumber() @IsNumber()

View File

@ -14,6 +14,7 @@ import { CommonEntity } from '~/common/entity/common.entity';
import { Storage } from '../tools/storage/storage.entity'; import { Storage } from '../tools/storage/storage.entity';
import { CompanyEntity } from '../company/company.entity'; import { CompanyEntity } from '../company/company.entity';
import pinyin from 'pinyin'; import pinyin from 'pinyin';
import { DictItemEntity } from '../system/dict-item/dict-item.entity';
@Entity({ name: 'product' }) @Entity({ name: 'product' })
export class ProductEntity extends CommonEntity { export class ProductEntity extends CommonEntity {
@Column({ @Column({
@ -33,6 +34,14 @@ export class ProductEntity extends CommonEntity {
@ApiProperty({ description: '所属公司' }) @ApiProperty({ description: '所属公司' })
companyId: number; companyId: number;
@Column({ name: 'unit_id', type: 'int', comment: '单位(字典)', nullable: true })
@ApiProperty({ description: '单位(字典)' })
unitId: number;
@ManyToOne(() => DictItemEntity)
@JoinColumn({ name: 'unit_id' })
unit: DictItemEntity;
@ApiHideProperty() @ApiHideProperty()
@Column({ @Column({
name: 'name_pinyin', name: 'name_pinyin',
@ -46,7 +55,6 @@ export class ProductEntity extends CommonEntity {
@BeforeInsert() @BeforeInsert()
@BeforeUpdate() @BeforeUpdate()
updateNamePinyin() { updateNamePinyin() {
console.log('sssssssssssssss')
this.namePinyin = pinyin(this.name, { this.namePinyin = pinyin(this.name, {
style: pinyin.STYLE_NORMAL, style: pinyin.STYLE_NORMAL,
heteronym: false heteronym: false

View File

@ -33,7 +33,8 @@ export class ProductService {
.createQueryBuilder('product') .createQueryBuilder('product')
.leftJoin('product.files', 'files') .leftJoin('product.files', 'files')
.leftJoin('product.company', 'company') .leftJoin('product.company', 'company')
.addSelect(['files.id', 'files.path', 'company.name', 'company.id']) .leftJoin('product.unit', 'unit')
.addSelect(['files.id', 'files.path', 'company.name', 'company.id','unit.id','unit.label'])
.where(fieldSearch(ext)) .where(fieldSearch(ext))
.andWhere('product.isDelete = 0') .andWhere('product.isDelete = 0')
.addOrderBy('product.namePinyin', 'ASC'); .addOrderBy('product.namePinyin', 'ASC');

View File

@ -18,7 +18,7 @@ export const fieldSearch = <T>(entity: Partial<T>): ObjectLiteral => {
if (Array.isArray(entity[key])) { if (Array.isArray(entity[key])) {
result = { result = {
...result, ...result,
...(entity[key] && { createdAt: Between(entity[key][0], entity[key][1]) }) ...(entity[key] && { [key]: Between(entity[key][0], entity[key][1]) })
}; };
} else { } else {
// Handle other object types // Handle other object types