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中的数据库
```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)

View File

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

View File

@ -13,6 +13,7 @@ import {
Matches,
MinLength
} from 'class-validator';
import dayjs from 'dayjs';
import { PagerDto } from '~/common/dto/pager.dto';
import { MaterialsInOrOutEnum } from '~/constants/enum';
import { Storage } from '~/modules/tools/storage/storage.entity';
@ -21,12 +22,12 @@ import { formatToDate } from '~/utils';
export class MaterialsInOutDto {
@ApiProperty({ description: '产品' })
@IsNumber()
product: number;
productId: number;
@ApiProperty({ description: '单位(字典)' })
@IsNumber()
@IsOptional()
unit: number;
unitId: number;
@ApiProperty({ description: '入库或出库 0:入库 1:出库' })
@IsEnum(MaterialsInOrOutEnum)
@ -82,15 +83,24 @@ export class MaterialsInOutUpdateDto extends PartialType(MaterialsInOutDto) {
export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutDto> {
@ApiProperty({ description: '出入库时间YYYY-MM-DD' })
@IsOptional()
@IsArray()
// @IsString()
@Transform(params => {
// 开始和结束时间用的是一天的开始和一天的结束的时分秒
const [start, end] = params.value;
const date = params.value;
return [
start ? `${formatToDate(start)} 00:00:00` : null,
end ? `${formatToDate(end)} 23:59:59` : null
date ? `${formatToDate(dayjs(date).startOf('month'))} 00:00:00` : null,
date ? `${formatToDate(dayjs(date).endOf('month'))} 23:59:59` : null
];
})
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 { Column, Entity, JoinTable, ManyToMany, Relation } from 'typeorm';
import { ApiHideProperty, ApiProperty } from '@nestjs/swagger';
import {
Column,
Entity,
JoinColumn,
JoinTable,
ManyToMany,
ManyToOne,
OneToMany,
Relation,
VirtualColumn
} from 'typeorm';
import { CommonEntity } from '~/common/entity/common.entity';
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';
@Entity({ name: 'materials_in_out' })
export class MaterialsInOutEntity extends CommonEntity {
@Column({
name: 'product',
name: 'product_id',
type: 'int',
comment: '产品名称'
comment: '产品'
})
@ApiProperty({ description: '产品名称' })
product: number;
@Column({
name: 'unit',
type: 'int',
comment: '单位(字典)'
})
@ApiProperty({ description: '单位(字典)' })
unit: number;
@ApiProperty({ description: '产品' })
productId: number;
@Column({
name: 'inOrOut',
@ -78,6 +82,7 @@ export class MaterialsInOutEntity extends CommonEntity {
name: 'issuance_number',
type: 'varchar',
length: 100,
nullable: true,
comment: '领料单号'
})
@ApiProperty({ description: '领料单号' })
@ -95,6 +100,13 @@ export class MaterialsInOutEntity extends CommonEntity {
@ApiProperty({ description: '删除状态0未删除1已删除' })
isDelete: number;
@ManyToOne(() => ProductEntity)
@JoinColumn({ name: 'product_id' })
product: ProductEntity;
@ApiHideProperty()
unit: DictItemEntity;
@ManyToMany(() => Storage, storage => storage.materialsInOut)
@JoinTable({
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 { paginate } from '~/helper/paginate';
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 { fieldSearch } from '~/shared/database/field-search';
@ -26,25 +30,32 @@ export class MaterialsInOutService {
async findAll({
page,
pageSize,
product: productName,
...ext
}: MaterialsInOutQueryDto): Promise<Pagination<MaterialsInOutEntity>> {
const queryBuilder = this.materialsInOutRepository
const sqb = this.materialsInOutRepository
.createQueryBuilder('materialsInOut')
.leftJoin('materialsInOut.files', 'files')
.addSelect(['files.id', 'files.path'])
// .where({
// ...(materialsInOutNumber ? { materialsInOutNumber: Like(`%${materialsInOutNumber}%`) } : null),
// ...(title ? { title: Like(`%${title}%`) } : null),
// ...(isNumber(type) ? { type } : null),
// ...(isNumber(status) ? { status } : null)
// })
.leftJoin('materialsInOut.product', 'product')
.leftJoin('product.unit', 'unit')
.addSelect(['files.id', 'files.path', 'product.id', 'product.name', 'unit.id', 'unit.label'])
.where(fieldSearch(ext))
.andWhere('materialsInOut.isDelete = 0');
return paginate<MaterialsInOutEntity>(queryBuilder, {
.andWhere('materialsInOut.isDelete = 0')
.addOrderBy('materialsInOut.time', 'DESC');
if (productName) {
sqb.andWhere('product.name like :productName', { productName: `%${productName}%` });
}
let pageData = await paginate<MaterialsInOutEntity>(sqb, {
page,
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 {
IsArray,
IsDate,
IsDateString,
IsIn,
IsInt,
IsNumber,
IsOptional,
IsString,
Matches,
MinLength
} from 'class-validator';
import { IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
import { PagerDto } from '~/common/dto/pager.dto';
import { Storage } from '../tools/storage/storage.entity';
import { IsUnique } from '~/shared/database/constraints/unique.constraint';
import { ProductEntity } from './product.entity';
export class ProductDto {
@ApiProperty({ description: '产品名称' })
@IsString()
name: string;
@ApiProperty({ description: '单位(字典)' })
@IsOptional()
@IsNumber()
unitId: number;
@ApiProperty({ description: '所属公司' })
@IsOptional()
@IsNumber()

View File

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

View File

@ -33,7 +33,8 @@ export class ProductService {
.createQueryBuilder('product')
.leftJoin('product.files', 'files')
.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))
.andWhere('product.isDelete = 0')
.addOrderBy('product.namePinyin', 'ASC');

View File

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