fix: 所有上传文件bug,车辆使用模块完成
This commit is contained in:
parent
10f6f1ff37
commit
f65a4c0b99
|
@ -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)
|
||||
|
|
|
@ -23,3 +23,10 @@ export enum MaterialsInOrOutEnum {
|
|||
export enum ParamConfigEnum {
|
||||
MaterialsInOutPrefix = 'materials_in_out_prefix'
|
||||
}
|
||||
|
||||
// 合同审核状态
|
||||
export enum ContractStatusEnum {
|
||||
Pending = 0, // 待审核
|
||||
Approved = 1, // 已通过
|
||||
Rejected = 2 // 已拒绝
|
||||
}
|
||||
|
|
|
@ -52,5 +52,8 @@ export enum ErrorEnum {
|
|||
STORAGE_REFRENCE_EXISTS = '1405:文件存在关联,无法删除,请先找到该文件关联的业务解除关联。',
|
||||
|
||||
// Product
|
||||
PRODUCT_EXIST = '1406:产品已存在'
|
||||
PRODUCT_EXIST = '1406:产品已存在',
|
||||
|
||||
// Contract
|
||||
CONTRACT_NUMBER_EXIST = '1407:存在相同的合同编号'
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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: '附件' })
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}));
|
||||
}
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
|
|
|
@ -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' },
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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']);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue