Skip to content

Commit

Permalink
FES-67 change customer profile image (1st commit) (#10)
Browse files Browse the repository at this point in the history
* FES-67 change customer profile image (1st commit)

* adjust logic

---------

Co-authored-by: NHT <[email protected]>
  • Loading branch information
manhtran150394 and hoangtuan910 authored Mar 11, 2024
1 parent afb3815 commit 9929df8
Show file tree
Hide file tree
Showing 12 changed files with 1,942 additions and 783 deletions.
13 changes: 13 additions & 0 deletions .env.example.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# DATABASE
DB_HOST=
DB_PORT=
DB_USERNAME=
DB_PASSWORD=
DB_NAME=

#AWS S3
AWS_S3_REGION=
AWS_ACCESS_KEY=
AWS_SECRET_ACCESS_KEY=
AWS_S3_BUCKET=
CLOUDFRONT_DISTRIBUTION_DOMAIN=
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# compiled output
# compiled output and dependency
/dist
/node_modules
/.yarn

# Logs
logs
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.529.1",
"@aws-sdk/lib-storage": "^3.529.1",
"@nestjs/axios": "^3.0.1",
"@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.2.0",
Expand Down
72 changes: 72 additions & 0 deletions src/feature/customer/customer.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,19 @@ import { Customer } from 'src/entity/customer.entity';
import { NutiExpertService } from 'src/dependency/nuti-expert/nuti-expert.service';
import { UpdateCustomerProfileRequest } from './dto/update-customer-profile-request.dto';
import { UpdateCustomerProfileResponse } from './dto/update-customer-profile-response.dto';
import { UploadImageRequest } from './dto/upload-image-request.dto';
import { UploadImageResponse } from './dto/upload-image-response.dto';
import { UpdateProfileImageRequest } from './dto/update-profile-image-request.dto';
import { UpdateProfileImageResponse } from './dto/update-profile-image-response.dto';
import { FileType } from 'src/type';
import { ConfigService } from '@nestjs/config';

@Controller()
export class CustomerController {
constructor(
private readonly customerService: CustomerService,
private readonly nutiExperService: NutiExpertService,
private config: ConfigService,
) {}

@MessagePattern({ cmd: 'create_customer_profile' })
Expand Down Expand Up @@ -136,4 +143,69 @@ export class CustomerController {
}
return response;
}

@MessagePattern({ cmd: 'upload_image' })
async uploadImage(reqData: UploadImageRequest): Promise<UploadImageResponse> {
const res = new UploadImageResponse(200, '');
const { fileName, file, fileType } = reqData;
const cloudFrontDistribtionDomain = this.config.get<string>(
'CLOUDFRONT_DISTRIBUTION_DOMAIN',
);

try {
const resData = await this.customerService.uploadImage(
fileName,
file,
fileType,
);
res.message = 'Upload image successfully';
res.data = cloudFrontDistribtionDomain + resData.Key;
} catch (error) {
if (error instanceof HttpException) {
res.statusCode = error.getStatus();
res.message = error.getResponse();
res.data = null;
} else {
res.statusCode = 500;
res.message = error.toString();
res.data = null;
}
}

return res;
}

@MessagePattern({ cmd: 'update_profile_image' })
async updateProfileImage(
data: UpdateProfileImageRequest,
): Promise<UpdateProfileImageResponse> {
const res = new UpdateProfileImageResponse(200, '');
const { customer_id, url } = data.requestData;
try {
const type: FileType = 'image';
const name: string = 'customer profile image';
const description: string = 'customer profile image';
const resData = await this.customerService.updateProfileImage(
customer_id,
type,
name,
description,
url,
);
res.message = 'Update profile image successfully';
res.data = resData;
} catch (error) {
if (error instanceof HttpException) {
res.statusCode = error.getStatus();
res.message = error.getResponse();
res.data = null;
} else {
res.statusCode = 500;
res.message = error.toString();
res.data = null;
}
}

return res;
}
}
2 changes: 2 additions & 0 deletions src/feature/customer/customer.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import { Customer } from 'src/entity/customer.entity';
import { HealthInfo } from 'src/entity/health-info.entity';
import { Media } from 'src/entity/media.entity';
import { NutiExpertModule } from 'src/dependency/nuti-expert/nuti-expert.module';
import { ConfigModule } from '@nestjs/config';

@Module({
imports: [
TypeOrmModule.forFeature([Customer, HealthInfo, Media]),
NutiExpertModule,
ConfigModule.forRoot(),
],
controllers: [CustomerController],
providers: [CustomerService],
Expand Down
78 changes: 78 additions & 0 deletions src/feature/customer/customer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ import { Media } from 'src/entity/media.entity';
import { GeneralResponse } from 'src/dto/general-response.dto';
import { PhysicalActivityLevel } from 'src/enum';
import { NutiExpertService } from 'src/dependency/nuti-expert/nuti-expert.service';
import { S3Client } from '@aws-sdk/client-s3';
import { Upload } from '@aws-sdk/lib-storage';
import { ConfigService } from '@nestjs/config';

@Injectable()
export class CustomerService {
Expand All @@ -17,6 +20,7 @@ export class CustomerService {
private healthInfoRepo: Repository<HealthInfo>,
@InjectRepository(Media) private mediaRepo: Repository<Media>,
private readonly nutiExperService: NutiExpertService,
private config: ConfigService,
) {}
async createProfile(
height_m: number,
Expand Down Expand Up @@ -238,4 +242,78 @@ export class CustomerService {
return updatedCustomer;
}
}
async uploadImage(fileName: string, file: Buffer, file_type: string) {
const _file = Buffer.from(file);

const upload = new Upload({
client: new S3Client({
region: this.config.get('AWS_S3_REGION'),
credentials: {
accessKeyId: this.config.get('AWS_ACCESS_KEY'),
secretAccessKey: this.config.get('AWS_SECRET_ACCESS_KEY'),
},
}),
params: {
Bucket: this.config.get('AWS_S3_BUCKET'),
Key: 'customer/' + fileName,
Body: _file,
ContentType: file_type,
// ACL: 'public-read',
},
});

upload.on('httpUploadProgress', (p) => {
console.log(p);
});

const data = await upload.done();
console.log('respose upload data', data);
if (data) {
return data;
} else {
throw new HttpException(`Can not upload image`, 500);
}
}
async updateProfileImage(
customer_id: number,
type: string,
name: string,
description: string,
url: string,
): Promise<Customer> {
/*
Check whether this profile existed
*/
const customer = await this.customerRepo.findOne({
relations: {
profile_image: true,
health_info: true,
},
where: {
customer_id: customer_id,
},
});
if (!customer) {
throw new HttpException(`Profile doesn't exist`, 400);
}
/*
//Update or create profile image
*/
customer.profile_image = customer.profile_image
? await this.mediaRepo.save({
media_id: customer.profile_image.media_id,
type: type,
name: name,
description: description,
url: url,
})
: await this.mediaRepo.save({
type: type,
name: name,
description: description,
url: url,
});
const updatedCustomer = await this.customerRepo.save(customer);
return updatedCustomer;
}
}
11 changes: 11 additions & 0 deletions src/feature/customer/dto/update-profile-image-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class UpdateProfileImageRequest {
requestData: RequestData;
}

interface RequestData {
customer_id: number;
// type: string;
// name: string;
// description: string;
url: string;
}
3 changes: 3 additions & 0 deletions src/feature/customer/dto/update-profile-image-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { GeneralResponse } from 'src/dto/general-response.dto';

export class UpdateProfileImageResponse extends GeneralResponse {}
5 changes: 5 additions & 0 deletions src/feature/customer/dto/upload-image-request.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class UploadImageRequest {
fileName: string;
file: Buffer;
fileType: string;
}
3 changes: 3 additions & 0 deletions src/feature/customer/dto/upload-image-response.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { GeneralResponse } from 'src/dto/general-response.dto';

export class UploadImageResponse extends GeneralResponse {}
2 changes: 2 additions & 0 deletions src/type/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export interface GenericUser {
userName: string;
permissions: string;
}

export type FileType = 'image' | 'video';
Loading

0 comments on commit 9929df8

Please sign in to comment.