feat: 文件存储添加业务模块和业务记录id冗余
This commit is contained in:
parent
f65a4c0b99
commit
46a4132877
|
@ -10,6 +10,7 @@ const app: FastifyAdapter = new FastifyAdapter({
|
|||
export { app as fastifyApp };
|
||||
|
||||
app.register(FastifyMultipart, {
|
||||
attachFieldsToBody:true,
|
||||
limits: {
|
||||
fields: 10, // Max number of non-file fields
|
||||
fileSize: 1024 * 1024 * 6, // limit size 6M
|
||||
|
|
|
@ -33,7 +33,6 @@ async function bootstrap() {
|
|||
|
||||
// class-validator 的 DTO 类中注入 nest 容器的依赖 (用于自定义验证器)
|
||||
useContainer(app.select(AppModule), { fallbackOnErrors: true });
|
||||
|
||||
app.enableCors({ origin: '*', credentials: true });
|
||||
app.setGlobalPrefix(globalPrefix);
|
||||
app.useStaticAssets({ root: path.join(__dirname, '..', 'public') });
|
||||
|
|
|
@ -62,11 +62,12 @@ export class ContractService {
|
|||
{ fileIds, contractNumber, ...ext }: Partial<ContractUpdateDto>
|
||||
): Promise<void> {
|
||||
await this.entityManager.transaction(async manager => {
|
||||
if (await this.checkIsContractNumberExsit(contractNumber, id)) {
|
||||
if (contractNumber && (await this.checkIsContractNumberExsit(contractNumber, id))) {
|
||||
throw new BusinessException(ErrorEnum.CONTRACT_NUMBER_EXIST);
|
||||
}
|
||||
await manager.update(ContractEntity, id, {
|
||||
...ext
|
||||
...ext,
|
||||
contractNumber
|
||||
});
|
||||
|
||||
if (fileIds?.length) {
|
||||
|
|
|
@ -129,9 +129,9 @@ export class MaterialsInOutQueryDto extends PagerDto<MaterialsInOutQueryDto> {
|
|||
remark?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
@ApiProperty({ description: '项目' })
|
||||
project?: string;
|
||||
@IsNumber()
|
||||
@ApiProperty({ description: '项目Id' })
|
||||
projectId?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
|
|
|
@ -35,7 +35,7 @@ export class MaterialsInOutService {
|
|||
page,
|
||||
pageSize,
|
||||
product: productName,
|
||||
project: projectName,
|
||||
projectId,
|
||||
isCreateOut,
|
||||
...ext
|
||||
}: MaterialsInOutQueryDto): Promise<Pagination<MaterialsInOutEntity>> {
|
||||
|
@ -46,15 +46,24 @@ export class MaterialsInOutService {
|
|||
.leftJoin('materialsInOut.product', 'product')
|
||||
.leftJoin('product.unit', 'unit')
|
||||
.leftJoin('product.company', 'company')
|
||||
.addSelect(['files.id','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');
|
||||
|
||||
if (productName) {
|
||||
sqb.andWhere('product.name like :productName', { productName: `%${productName}%` });
|
||||
}
|
||||
if (projectName) {
|
||||
sqb.andWhere('project.name like :projectName', { projectName: `%${projectName}%` });
|
||||
|
||||
if (projectId) {
|
||||
sqb.andWhere('project.id = :projectId', { projectId });
|
||||
}
|
||||
|
||||
if (isCreateOut) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { Transform } from 'class-transformer';
|
||||
import { ArrayNotEmpty, IsArray, IsOptional, IsString } from 'class-validator';
|
||||
import { ArrayNotEmpty, IsArray, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
import { PagerDto } from '~/common/dto/pager.dto';
|
||||
|
||||
|
@ -34,6 +34,16 @@ export class StoragePageDto extends PagerDto {
|
|||
@IsOptional()
|
||||
username: string;
|
||||
|
||||
@ApiProperty({ description: '文件所属模块' })
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
businessModule: string;
|
||||
|
||||
@ApiProperty({ description: '文件上传的业务记录ID' })
|
||||
@IsNumber()
|
||||
@IsOptional()
|
||||
bussinessRecordId: string;
|
||||
|
||||
@ApiProperty({ description: '附件' })
|
||||
@IsOptional()
|
||||
@Transform(
|
||||
|
|
|
@ -45,6 +45,15 @@ export class Storage extends CommonEntity {
|
|||
@ApiProperty({ description: '用户ID' })
|
||||
userId: number;
|
||||
|
||||
@Column({ nullable: true, name: 'bussiness_module' })
|
||||
@ApiProperty({ description: '文件上传的业务模块' })
|
||||
bussinessModule: string;
|
||||
|
||||
@Column({ nullable: true, name: 'bussiness_record_id' })
|
||||
@ApiProperty({ description: '文件上传的业务记录ID' })
|
||||
bussinessRecordId: number;
|
||||
|
||||
|
||||
@ApiHideProperty()
|
||||
@ManyToMany(() => ContractEntity, contract => contract.files)
|
||||
contracts: Relation<ContractEntity[]>;
|
||||
|
|
|
@ -93,7 +93,9 @@ export class StorageService {
|
|||
type: e.storage_type,
|
||||
size: e.storage_size,
|
||||
createdAt: e.storage_created_at,
|
||||
username: e.user_username
|
||||
username: e.user_username,
|
||||
bussinessRecordId:e.storage_bussiness_record_id,
|
||||
bussinessModule:e.storage_bussiness_module
|
||||
};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { BadRequestException, Controller, Post, Req } from '@nestjs/common';
|
||||
import { BadRequestException, Body, Controller, Post, Req, UseInterceptors } from '@nestjs/common';
|
||||
import { ApiBody, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger';
|
||||
import { FastifyRequest } from 'fastify';
|
||||
|
||||
|
@ -27,18 +27,18 @@ export class UploadController {
|
|||
@ApiBody({
|
||||
type: FileUploadDto
|
||||
})
|
||||
async upload(@Req() req: FastifyRequest, @AuthUser() user: IAuthUser) {
|
||||
async upload(@Req() req: FastifyRequest, @AuthUser() user: IAuthUser, @Body() body: any) {
|
||||
if (!req.isMultipart()) throw new BadRequestException('Request is not multipart');
|
||||
|
||||
const file = await req.file();
|
||||
|
||||
// https://github.com/fastify/fastify-multipart
|
||||
// const parts = req.files()
|
||||
// for await (const part of parts)
|
||||
// console.log(part.file)
|
||||
|
||||
const { file } = body;
|
||||
const bussinessModule = body.bussinessModule?.value;
|
||||
const bussinessRecordId = Number(body.bussinessRecordId?.value) || null;
|
||||
try {
|
||||
const savedFile = await this.uploadService.saveFile(file, user.uid);
|
||||
const savedFile = await this.uploadService.saveFile(
|
||||
file,
|
||||
user.uid,
|
||||
bussinessModule,
|
||||
bussinessRecordId
|
||||
);
|
||||
|
||||
return {
|
||||
filename: savedFile
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { MultipartFile } from '@fastify/multipart';
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
|
||||
import { IsDefined } from 'class-validator';
|
||||
import { IsDefined, IsNumber, IsOptional, IsString } from 'class-validator';
|
||||
|
||||
import { IsFile } from './file.constraint';
|
||||
|
||||
|
|
|
@ -25,7 +25,12 @@ export class UploadService {
|
|||
/**
|
||||
* 保存文件上传记录
|
||||
*/
|
||||
async saveFile(file: MultipartFile, userId: number): Promise<{ id: number; path: string }> {
|
||||
async saveFile(
|
||||
file: MultipartFile,
|
||||
userId: number,
|
||||
bussinessModule?: string,
|
||||
bussinessRecordId?: number
|
||||
): Promise<{ id: number; path: string }> {
|
||||
if (isNil(file)) throw new NotFoundException('Have not any file to upload!');
|
||||
|
||||
const fileName = file.filename;
|
||||
|
@ -44,7 +49,9 @@ export class UploadService {
|
|||
path,
|
||||
type,
|
||||
size,
|
||||
userId
|
||||
userId,
|
||||
bussinessModule,
|
||||
bussinessRecordId
|
||||
});
|
||||
|
||||
return { path, id: storage.id };
|
||||
|
|
Loading…
Reference in New Issue