fix: 所有上传文件bug,车辆使用模块完成

This commit is contained in:
louis 2024-03-08 10:38:28 +08:00
parent 10f6f1ff37
commit f65a4c0b99
14 changed files with 109 additions and 58 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_222748.sql
docker exec -i huaxin-admin-mysql mysql -h 127.0.0.1 -u root -phuaxin123 hxoa < hxoa_2024-03-07_171919.sql
```
更多细节,请移步至[官方文档](https://typeorm.io/migrations)

View File

@ -23,3 +23,10 @@ export enum MaterialsInOrOutEnum {
export enum ParamConfigEnum {
MaterialsInOutPrefix = 'materials_in_out_prefix'
}
// 合同审核状态
export enum ContractStatusEnum {
Pending = 0, // 待审核
Approved = 1, // 已通过
Rejected = 2 // 已拒绝
}

View File

@ -52,5 +52,8 @@ export enum ErrorEnum {
STORAGE_REFRENCE_EXISTS = '1405:文件存在关联,无法删除,请先找到该文件关联的业务解除关联。',
// Product
PRODUCT_EXIST = '1406:产品已存在'
PRODUCT_EXIST = '1406:产品已存在',
// Contract
CONTRACT_NUMBER_EXIST = '1407:存在相同的合同编号'
}

View File

@ -69,12 +69,12 @@ export class CompanyService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
// 附件要批量插入
await manager
.createQueryBuilder()
.relation(CompanyEntity, 'files')
.of(id)
.addAndRemove(fileIds, company.files);
.add(fileIds);
}
});
}

View File

@ -3,6 +3,7 @@ import {
IsArray,
IsDate,
IsDateString,
IsEnum,
IsIn,
IsInt,
IsNumber,
@ -13,6 +14,7 @@ import {
} from 'class-validator';
import { PagerDto } from '~/common/dto/pager.dto';
import { Storage } from '../tools/storage/storage.entity';
import { ContractStatusEnum } from '~/constants/enum';
export class ContractDto {
@ApiProperty({ description: '合同编号' })
@ -37,15 +39,18 @@ export class ContractDto {
partyB: string;
@ApiProperty({ description: '签订日期' })
@IsOptional()
@IsDateString()
signingDate: string;
signingDate?: string;
@ApiProperty({ description: '交付期限' })
@IsOptional()
@IsDateString()
deliveryDeadline: string;
deliveryDeadline?: string;
@ApiProperty({ description: '审核状态(字典)' })
@IsIn([0, 1, 2])
@IsOptional()
@IsEnum(ContractStatusEnum)
status: number;
@ApiProperty({ description: '附件' })

View File

@ -1,7 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { ContractEntity } from './contract.entity';
import { EntityManager, Like, Repository } from 'typeorm';
import { EntityManager, Like, Not, Repository } from 'typeorm';
import { ContractDto, ContractQueryDto, ContractUpdateDto } from './contract.dto';
import { Pagination } from '~/helper/paginate/pagination';
import { isNumber } from 'lodash';
@ -45,23 +45,30 @@ export class ContractService {
/**
*
*/
async create(dto: ContractDto): Promise<void> {
await this.contractRepository.insert(dto);
async create({ contractNumber, ...ext }: ContractDto): Promise<void> {
if (await this.checkIsContractNumberExsit(contractNumber)) {
throw new BusinessException(ErrorEnum.CONTRACT_NUMBER_EXIST);
}
await this.contractRepository.insert(
this.contractRepository.create({ contractNumber, ...ext })
);
}
/**
*
*/
async update(id: number, { fileIds, ...data }: Partial<ContractUpdateDto>): Promise<void> {
async update(
id: number,
{ fileIds, contractNumber, ...ext }: Partial<ContractUpdateDto>
): Promise<void> {
await this.entityManager.transaction(async manager => {
if (await this.checkIsContractNumberExsit(contractNumber, id)) {
throw new BusinessException(ErrorEnum.CONTRACT_NUMBER_EXIST);
}
await manager.update(ContractEntity, id, {
...data
...ext
});
const contract = await this.contractRepository
.createQueryBuilder('contract')
.leftJoinAndSelect('contract.files', 'files')
.where('contract.id = :id', { id })
.getOne();
if (fileIds?.length) {
const count = await this.storageRepository
.createQueryBuilder('storage')
@ -70,16 +77,24 @@ export class ContractService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
await manager
.createQueryBuilder()
.relation(ContractEntity, 'files')
.of(id)
.addAndRemove(fileIds, contract.files);
// 附件要批量插入
await manager.createQueryBuilder().relation(ContractEntity, 'files').of(id).add(fileIds);
}
});
}
/**
*
* @param contractNumber
*/
async checkIsContractNumberExsit(contractNumber: string, id?: number): Promise<Boolean> {
return !!(await this.contractRepository.findOne({
where: {
contractNumber: contractNumber,
id: Not(id)
}
}));
}
/**
*
*/

View File

@ -120,7 +120,7 @@ export class MaterialsInOutEntity extends CommonEntity {
@JoinColumn({ name: 'product_id' })
product: ProductEntity;
@ManyToMany(() => Storage, storage => storage.materialsInOut)
@ManyToMany(() => Storage, storage => storage.materialsInOuts)
@JoinTable({
name: 'materials_in_out_storage',
joinColumn: { name: 'materials_in_out_id', referencedColumnName: 'id' },

View File

@ -46,7 +46,7 @@ export class MaterialsInOutService {
.leftJoin('materialsInOut.product', 'product')
.leftJoin('product.unit', 'unit')
.leftJoin('product.company', 'company')
.addSelect(['files.path', 'project.name', 'product.name', 'unit.label', 'company.name'])
.addSelect(['files.id','files.path', 'project.name', 'product.name', 'unit.label', 'company.name'])
.where(fieldSearch(ext))
.andWhere('materialsInOut.isDelete = 0')
.addOrderBy('materialsInOut.createdAt', 'DESC');
@ -97,11 +97,6 @@ export class MaterialsInOutService {
await manager.update(MaterialsInOutEntity, id, {
...data
});
const materialsInOut = await this.materialsInOutRepository
.createQueryBuilder('materialsInOut')
.leftJoinAndSelect('materialsInOut.files', 'files')
.where('materialsInOut.id = :id', { id })
.getOne();
if (fileIds?.length) {
const count = await this.storageRepository
.createQueryBuilder('storage')
@ -110,12 +105,12 @@ export class MaterialsInOutService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
// 附件要批量插入
await manager
.createQueryBuilder()
.relation(MaterialsInOutEntity, 'files')
.of(id)
.addAndRemove(fileIds, materialsInOut.files);
.add(fileIds);
}
});
}

View File

@ -90,12 +90,12 @@ export class ProductService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
// 附件要批量插入
await manager
.createQueryBuilder()
.relation(ProductEntity, 'files')
.of(id)
.addAndRemove(fileIds, product.files);
.add(fileIds);
}
});
}

View File

@ -69,12 +69,12 @@ export class ProjectService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
// 附件要批量插入
await manager
.createQueryBuilder()
.relation(ProjectEntity, 'files')
.of(id)
.addAndRemove(fileIds, project.files);
.add(fileIds);
}
});
}

View File

@ -55,7 +55,7 @@ export class Storage extends CommonEntity {
@ApiHideProperty()
@ManyToMany(() => MaterialsInOutEntity, materialsInOut => materialsInOut.files)
materialsInOut: Relation<MaterialsInOutEntity[]>;
materialsInOuts: Relation<MaterialsInOutEntity[]>;
@ApiHideProperty()
@ManyToMany(() => ProductEntity, product => product.files)

View File

@ -10,17 +10,22 @@ export class VehicleUsageDto {
@ApiProperty({ description: '外出使用的车辆名称(字典)' })
@IsNumber()
vechicleId: number;
vehicleId: number;
@ApiProperty({ description: '申请人' })
@IsString()
applicant: string;
@ApiProperty({ description: '出行司机', nullable: true })
@ApiProperty({ description: '出行司机' })
@IsOptional()
@IsString()
driver: string;
@ApiProperty({ description: '随行人员' })
@IsOptional()
@IsString()
partner?: string;
@ApiProperty({ description: '当前车辆里程数(KM)' })
@IsOptional()
@IsNumber()
@ -69,4 +74,8 @@ export class VehicleUsageUpdateDto extends PartialType(VehicleUsageDto) {
export class VehicleUsageQueryDto extends IntersectionType(
PagerDto<VehicleUsageDto>,
PartialType(VehicleUsageDto)
) {}
) {
@ApiProperty({ description: '车辆名称或者车牌号' })
@IsOptional()
vehicle?: string;
}

View File

@ -12,7 +12,7 @@ export class VehicleUsageEntity extends CommonEntity {
@Column({ name: 'vehicle_id', type: 'int', comment: '外出使用的车辆名称(字典)' })
@ApiProperty({ description: '外出使用的车辆名称(字典)' })
vechicleId: number;
vehicleId: number;
@Column({
name: 'applicant',
@ -27,11 +27,22 @@ export class VehicleUsageEntity extends CommonEntity {
name: 'driver',
type: 'varchar',
length: 50,
comment: '出行司机'
comment: '出行司机',
nullable: true
})
@ApiProperty({ description: '出行司机', nullable: true })
@ApiProperty({ description: '出行司机' })
driver: string;
@Column({
name: 'partner',
type: 'varchar',
length: 50,
comment: '随行人员',
nullable: true
})
@ApiProperty({ description: '随行人员' })
partner: string;
@Column({ name: 'current_mileage', type: 'int', comment: '当前车辆里程数(KM)', nullable: true })
@ApiProperty({ description: '当前车辆里程数(KM)' })
currentMileage: number;

View File

@ -1,6 +1,6 @@
import { Injectable } from '@nestjs/common';
import { InjectEntityManager, InjectRepository } from '@nestjs/typeorm';
import { EntityManager, Repository } from 'typeorm';
import { EntityManager, Repository, SelectQueryBuilder } from 'typeorm';
import { VehicleUsageEntity } from './vehicle_usage.entity';
import { Storage } from '../tools/storage/storage.entity';
import { ErrorEnum } from '~/constants/error-code.constant';
@ -27,15 +27,14 @@ export class VehicleUsageService {
async findAll({
page,
pageSize,
...fields
}: VehicleUsageQueryDto): Promise<Pagination<VehicleUsageEntity>> {
const { ...ext } = fields;
const sqb = this.vehicleUsageRepository
.createQueryBuilder('vehicle_usage')
.leftJoin('vehicle_usage.files', 'files')
.leftJoin('vehicle_usage.vehicle', 'vehicle')
.addSelect(['files.id', 'files.path', 'vehicle.id', 'vehicle.label'])
.where(fieldSearch(ext))
const { vehicle, ...ext } = fields;
const sqb = this.buildLeftJoinRelations().where(fieldSearch(ext));
if (vehicle) {
sqb.andWhere('vehicle.label like :vehicleName', { vehicleName: `%${vehicle}%` });
}
return paginate<VehicleUsageEntity>(sqb, {
page,
pageSize
@ -81,12 +80,12 @@ export class VehicleUsageService {
if (count !== fileIds?.length) {
throw new BusinessException(ErrorEnum.STORAGE_NOT_FOUND);
}
// 附件要批量更新
// 附件要批量插入
await manager
.createQueryBuilder()
.relation(VehicleUsageEntity, 'files')
.of(id)
.addAndRemove(fileIds, vehicleUsage.files);
.add(fileIds);
}
});
}
@ -102,14 +101,10 @@ export class VehicleUsageService {
*
*/
async info(id: number) {
const info = await this.vehicleUsageRepository
.createQueryBuilder('vehicle_usage')
.leftJoin('vehicle_usage.company', 'company')
.addSelect(['company.name', 'company.id'])
const info = this.buildLeftJoinRelations()
.where({
id
})
.andWhere('vehicle_usage.isDelete = 0')
.getOne();
return info;
}
@ -137,4 +132,15 @@ export class VehicleUsageService {
.addAndRemove(linkedFiles, vehicle_usage.files);
});
}
/**
*
*/
buildLeftJoinRelations() {
return this.vehicleUsageRepository
.createQueryBuilder('vehicle_usage')
.leftJoin('vehicle_usage.files', 'files')
.leftJoin('vehicle_usage.vehicle', 'vehicle')
.addSelect(['files.id', 'files.path', 'vehicle.id', 'vehicle.label']);
}
}