Skip to content

Commit

Permalink
feat: location 업데이트 api 완성
Browse files Browse the repository at this point in the history
  • Loading branch information
yunuo46 committed Dec 6, 2023
1 parent f0bfe1b commit 5954116
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 67 deletions.
5 changes: 5 additions & 0 deletions back/src/modules/message/dto/update-message-location.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import { IsNotEmpty, IsNumber, Min, Max } from '@nestjs/class-validator';
import { ApiProperty } from '@nestjs/swagger';

export class UpdateMessageLocationDto {
@IsNumber()
@IsNotEmpty()
@ApiProperty({ type: Number, description: '메세지 ID' })
readonly message_id: number;

@IsNumber()
@Min(1)
@Max(72)
Expand Down
15 changes: 15 additions & 0 deletions back/src/modules/message/dto/update-message-locations.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ValidateNested } from '@nestjs/class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { UpdateMessageLocationDto } from './update-message-location.dto';
import { Expose, Type } from 'class-transformer';

export class UpdateMessageLocationsDto {
@Expose()
@Type(() => UpdateMessageLocationDto)
@ValidateNested({ each: true })
@ApiProperty({
type: [UpdateMessageLocationDto],
description: '업데이트 할 메세지 위치 리스트'
})
readonly location_list: UpdateMessageLocationDto[];
}
6 changes: 3 additions & 3 deletions back/src/modules/message/entity/message.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ export class MessageEntity {
@Column({ length: 16 })
sender: string;

@CreateDateColumn({ default: null })
is_deleted: Date | null;
@CreateDateColumn({ default: `${process.env.DATE_DEFAULT}` })
is_deleted: Date;

@Column()
location: number;
Expand All @@ -50,7 +50,7 @@ export class MessageEntity {
@Column()
confidence: number;

@CreateDateColumn({ default: null })
@CreateDateColumn({ nullable: true, default: null })
opened: Date | null;

@CreateDateColumn()
Expand Down
16 changes: 6 additions & 10 deletions back/src/modules/message/message.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ import {
import { ResCreateMessageDto } from './dto/response/res-create-message.dto';
import { MessageDto } from './dto/message.dto';
import { JWTGuard } from 'src/common/guards/jwt.guard';
import { UpdateMessageLocationDto } from './dto/update-message-location.dto';
import { JWTRequest } from 'src/common/interface/request.interface';
import { ClovaService } from './clova.service';
import { UpdateMessageLocationsDto } from './dto/update-message-locations.dto';
@ApiTags('Message API')
@Controller('message')
export class MessageController {
Expand Down Expand Up @@ -149,14 +149,14 @@ export class MessageController {

@UseGuards(JWTGuard)
@ApiCookieAuth('access_token')
@Put('/:message_id/location')
@Put('/location')
@ApiOperation({
summary: '메세지 위치 변경',
description: '메시지의 위치를 변경합니다.'
})
@ApiResponse({
status: 200,
type: MessageDto
type: UpdateMessageLocationsDto
})
@ApiBadRequestResponse({
description: '잘못된 요청입니다.'
Expand All @@ -171,12 +171,8 @@ export class MessageController {
description: '목표 위치가 비어있지 않습니다.'
})
async updateMessageLocation(
@Param('message_id') message_id: number,
@Body() updateMessageLocationDto: UpdateMessageLocationDto
): Promise<UpdateMessageLocationDto> {
return await this.messageService.updateMessageLocation(
message_id,
updateMessageLocationDto
);
@Body() updateDtos: UpdateMessageLocationsDto
): Promise<UpdateMessageLocationsDto> {
return await this.messageService.updateMessageLocations(updateDtos);
}
}
147 changes: 93 additions & 54 deletions back/src/modules/message/message.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
NotFoundException
} from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { DataSource, Repository } from 'typeorm';
import { ReqCreateMessageDto } from './dto/request/req-create-message.dto';
import { MessageEntity } from './entity/message.entity';
import { ResCreateMessageDto } from './dto/response/res-create-message.dto';
Expand All @@ -18,6 +18,7 @@ import { LetterEntity } from './entity/letter.entity';
import { ResClovaSentiment } from './clova.service';
import { SnowballEntity } from '../snowball/entity/snowball.entity';
import { DecorationPrefixEntity } from '../snowball/entity/decoration-prefix.entity';
import { UpdateMessageLocationsDto } from './dto/update-message-locations.dto';

@Injectable()
export class MessageService {
Expand All @@ -29,7 +30,8 @@ export class MessageService {
@InjectRepository(LetterEntity)
private readonly letterRepository: Repository<LetterEntity>,
@InjectRepository(DecorationPrefixEntity)
private readonly decorationPrefixRepository: Repository<DecorationPrefixEntity>
private readonly decorationPrefixRepository: Repository<DecorationPrefixEntity>,
private readonly dataSource: DataSource
) {}
async createMessage(
createMessageDto: ReqCreateMessageDto,
Expand All @@ -46,10 +48,8 @@ export class MessageService {
user_id: user_id,
snowball_id: snowball_id,
location: location,
opened: null,
...resClovaSentiment,
...createMessageDto
// is_deleted랑 created는 자동으로 설정
});
try {
await this.messageRepository.save(messageEntity, {
Expand All @@ -73,7 +73,10 @@ export class MessageService {

async isInsertAllowed(snowball_id: number): Promise<void> {
const messageCount = await this.messageRepository.count({
where: { snowball_id: snowball_id, is_deleted: null }
where: {
snowball_id: snowball_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
}
});
if (messageCount >= 30) {
throw new ConflictException('메세지 갯수가 30개를 초과했습니다');
Expand All @@ -99,36 +102,35 @@ export class MessageService {
}

async deleteMessage(user_id: number, message_id: number): Promise<void> {
try {
const message = await this.messageRepository.findOne({
where: { id: message_id },
select: ['user_id', 'is_deleted']
});
if (message.user_id !== user_id) {
throw new ForbiddenException(
`${message_id} 메시지는 해당 유저의 메시지가 아닙니다.`
);
}
if (!message) {
throw new NotFoundException(
`${message_id} 메시지를 찾을 수 없었습니다.`
);
}
if (message.is_deleted) {
throw new GoneException(`${message_id}는 이미 삭제된 메시지입니다.`);
}
await this.messageRepository.save(
{ id: message_id, is_deleted: Date() },
{ reload: false }
const message = await this.messageRepository.findOne({
where: { id: message_id },
select: ['user_id', 'is_deleted']
});
if (message.user_id !== user_id) {
throw new ForbiddenException(
`${message_id} 메시지는 해당 유저의 메시지가 아닙니다.`
);
} catch (err) {
throw new BadRequestException('서버 오류');
}
if (!message) {
throw new NotFoundException(`${message_id} 메시지를 찾을 수 없었습니다.`);
}
console.log(message.is_deleted.getTime());

if (message.is_deleted.getTime() !== Number(process.env.TIME_DEFAULT)) {
throw new GoneException(`${message_id}는 이미 삭제된 메시지입니다.`);
}
await this.messageRepository.save(
{ id: message_id, is_deleted: new Date() },
{ reload: false }
);
}

async getAllMessages(user_id: number): Promise<MessageDto[]> {
const messageEntities = await this.messageRepository.find({
where: { user_id: user_id, is_deleted: null }
where: {
user_id: user_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
}
});
if (!messageEntities) {
throw new NotFoundException(`User with id ${user_id} not found`);
Expand All @@ -143,7 +145,10 @@ export class MessageService {

async openMessage(message_id: number): Promise<MessageDto> {
const messageEntity = await this.messageRepository.findOne({
where: { id: message_id, is_deleted: null }
where: {
id: message_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
}
});
if (!messageEntity) {
throw new NotFoundException(
Expand All @@ -156,7 +161,7 @@ export class MessageService {
);
}
await this.messageRepository.save(
{ id: message_id, opened: Date() },
{ id: message_id, opened: new Date() },
{ reload: false }
);
const messageDto = plainToInstance(
Expand All @@ -167,30 +172,59 @@ export class MessageService {
return messageDto;
}

async updateMessageLocations(
updateDtos: UpdateMessageLocationsDto
): Promise<UpdateMessageLocationsDto> {
const result: UpdateMessageLocationDto[] = [];
console.log(updateDtos.location_list);
for (const updateDto of updateDtos.location_list) {
const success = await this.updateMessageLocation(updateDto);
if (success) result.push(updateDto);
}
const instance = { location_list: result };
return plainToInstance(UpdateMessageLocationsDto, {
instance
});
}

async updateMessageLocation(
message_id: number,
updateMessageLocationDto: UpdateMessageLocationDto
): Promise<UpdateMessageLocationDto> {
const { location } = updateMessageLocationDto;
const updateResult = await this.messageRepository
.createQueryBuilder()
.update(MessageEntity)
.set({
location
})
.where('id = :id', { id: message_id, is_deleted: false })
.execute();
if (!updateResult.affected) {
throw new NotFoundException('업데이트를 실패했습니다');
} else if (updateResult.affected > 1) {
throw new BadRequestException('데이터 중복 오류');
updateDto: UpdateMessageLocationDto
): Promise<boolean> {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.connect();
await queryRunner.startTransaction('READ COMMITTED');

const { message_id, location } = updateDto;

try {
await queryRunner.manager
.createQueryBuilder()
.update(MessageEntity)
.set({
location
})
.where('id = :id', {
id: message_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
})
.execute();
await queryRunner.commitTransaction();
} catch (err) {
await queryRunner.rollbackTransaction();
console.log(err.sqlMessage);
return false;
} finally {
await queryRunner.release();
}
return updateMessageLocationDto;
return true;
}

async getMessageCount(user_id: number): Promise<number> {
return this.messageRepository.count({
where: { user_id: user_id, is_deleted: null }
where: {
user_id: user_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
}
});
}

Expand All @@ -199,7 +233,10 @@ export class MessageService {
groups: string
): Promise<MessageDto[]> {
const messageEntities = await this.messageRepository.find({
where: { snowball_id: snowball_id, is_deleted: null }
where: {
snowball_id: snowball_id,
is_deleted: new Date(`${process.env.DATE_DEFAULT}`)
}
});

const messageDtos = messageEntities.map(entity =>
Expand All @@ -225,12 +262,14 @@ export class MessageService {
}

async findLocation(snowball_id: number): Promise<number> {
const findLocations = this.messageRepository
.createQueryBuilder('message')
const locations = await this.messageRepository
.createQueryBuilder()
.select('location')
.where('snowball_id = :snowball_id', { snowball_id })
.andWhere('is_deleted = false');
const locations = await findLocations.getRawMany();
.andWhere('is_deleted =:is_deleted', {
is_deleted: `${process.env.DATE_DEFAULT}`
})
.getRawMany();

let firstEmptyLocation: number | null = null;
for (let i = 1; i <= 30; i++) {
Expand Down

0 comments on commit 5954116

Please sign in to comment.