Skip to content

Commit

Permalink
Merge pull request #49 from depromeet/feature/reward-issue47
Browse files Browse the repository at this point in the history
리워드 시스템 추가
  • Loading branch information
ImNM authored May 10, 2022
2 parents 507b41f + f62b8f7 commit 3ac5b35
Show file tree
Hide file tree
Showing 10 changed files with 219 additions and 5 deletions.
15 changes: 15 additions & 0 deletions src/apis/users/dto/sendLigningSuccessDto.res.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose } from 'class-transformer';

export class SendLightningSuccessDtoResDto {
constructor(sendLightningSuccess: boolean) {
this.sendLightningSuccess = sendLightningSuccess;
}
@ApiProperty({
type: Boolean,
default: false,
description: '번개보낸 성공여부',
})
@Expose()
sendLightningSuccess: boolean;
}
19 changes: 19 additions & 0 deletions src/apis/users/user.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { UserProfileDto } from 'src/common/dtos/UserProfile.dto';
import { ReportResultDtoResDto } from './dto/reportResultDto.res.dto';
import { CanChangeNicknameResDto } from './dto/canChangeNickname.res.dto';
import { NewAlarmStateResDto } from './dto/newAlarmState.res.dto';
import { SendLightningSuccessDtoResDto } from './dto/sendLigningSuccessDto.res.dto';

@ApiTags('user')
@Controller('user')
Expand Down Expand Up @@ -153,4 +154,22 @@ export class UserController {
toggleAppAlarm(@ReqUser() user: User) {
return this.userService.toggleAlarmAlarm(user.userIdDto);
}

@ApiOperation({
summary: '상대방에게 번개를 보낸다',
})
@Post(':userId/lightning')
@ApiResponse({
status: 201,
description: '요청 성공시',
type: SendLightningSuccessDtoResDto,
})
@ApiResponse({
status: 201,
description: '이미 요청되었으면하루에 한번 ',
type: SendLightningSuccessDtoResDto,
})
sendLightningToUser(@ReqUser() user: User, @Param() userIdDto: UserIdDto) {
return this.userService.sendLightningToUser(user.userIdDto, userIdDto);
}
}
10 changes: 9 additions & 1 deletion src/apis/users/user.module.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { forwardRef, Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AuthModule } from 'src/auth/auth.module';
import { Lightning, LightningSchema } from 'src/models/lightning.model';
import { Report, ReportSchema } from 'src/models/report.model';
import { User, UserSchema } from 'src/models/user.model';
import { LightningRepository } from 'src/repositories/lightning.repository';
import { ReportRepository } from 'src/repositories/report.repository';
import { UserRepository } from 'src/repositories/user.repository';
import { UserController } from './user.controller';
Expand All @@ -13,11 +15,17 @@ import { UserService } from './user.service';
MongooseModule.forFeature([
{ name: User.name, schema: UserSchema },
{ name: Report.name, schema: ReportSchema },
{ name: Lightning.name, schema: LightningSchema },
]),
forwardRef(() => AuthModule),
],
controllers: [UserController],
providers: [UserRepository, UserService, ReportRepository],
providers: [
UserRepository,
UserService,
ReportRepository,
LightningRepository,
],
exports: [UserService, ReportRepository, UserRepository],
})
export class UserModule {}
47 changes: 47 additions & 0 deletions src/apis/users/user.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ import { NewAlarmStateResDto } from './dto/newAlarmState.res.dto';
import { UserProfileDto } from 'src/common/dtos/UserProfile.dto';
import { BlockedUserDto } from 'src/common/dtos/BlockedUserList.dto';
import { AuthService } from 'src/auth/auth.service';
import { LightningRepository } from 'src/repositories/lightning.repository';
import { SendLightningSuccessDtoResDto } from './dto/sendLigningSuccessDto.res.dto';
import {
USER_LEVELUP_COUNT_TYPE,
USER_LEVEL_TYPE,
} from 'src/common/consts/enum';

@Injectable()
export class UserService {
Expand All @@ -26,6 +32,7 @@ export class UserService {
private reportRepository: ReportRepository,
@Inject(forwardRef(() => AuthService))
private authService: AuthService,
private lightnignRepository: LightningRepository,
) {}

private checkBlocked(userIdDto: UserIdDto, blockedUserDto: BlockedUserDto) {
Expand Down Expand Up @@ -57,6 +64,8 @@ export class UserService {
updateProfileReqDto: UpdateProfileReqDto,
): Promise<User> {
// auto 시리얼 라이징

//TODO : 닉네임 변경시에 한번더 밸리데이션? 내프로필 정보랑 닉네임 일치하면 변경하고..
return await this.userRepository.updateProfile(
userIdDto,
updateProfileReqDto,
Expand Down Expand Up @@ -172,4 +181,42 @@ export class UserService {
const appAlarm = await this.userRepository.toggleApptAlarm(myUserIdDto);
return { appAlarm: appAlarm };
}

@returnValueToDto(SendLightningSuccessDtoResDto)
async sendLightningToUser(
sender: UserIdDto,
receive: UserIdDto,
): Promise<SendLightningSuccessDtoResDto> {
const checkReportExist = this.lightnignRepository.findOneLightningByUserId(
sender,
receive,
);
if (checkReportExist) {
return { sendLightningSuccess: false };
}

const expireAt = new Date();
// utc 한국시간 기준으로 자정으로 설정
expireAt.setUTCHours(15, 0, 0, 0);
// expireAt.setHours()
await this.lightnignRepository.saveLighting(sender, receive, expireAt);
const addUserScore = await this.userRepository.addUserLigthningScore(
receive,
);

switch (addUserScore.lightningScore) {
case USER_LEVELUP_COUNT_TYPE.LEVEL1:
await this.userRepository.levelUpUser(receive, USER_LEVEL_TYPE.LEVEL1);
break;
case USER_LEVELUP_COUNT_TYPE.LEVEL2:
await this.userRepository.levelUpUser(receive, USER_LEVEL_TYPE.LEVEL2);
break;
case USER_LEVELUP_COUNT_TYPE.LEVEL3:
await this.userRepository.levelUpUser(receive, USER_LEVEL_TYPE.LEVEL3);
break;
default:
break;
}
return { sendLightningSuccess: true };
}
}
16 changes: 16 additions & 0 deletions src/common/consts/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,23 @@ enum QUESTION_FIND_FILTER_TYPE {
NEWORDER = 'NEWORDER', //한강공원
}

enum USER_LEVEL_TYPE {
LEVEL0 = 0, //대학교
LEVEL1 = 1, //공연장
LEVEL2 = 2, //한강공원
LEVEL3 = 2, //한강공원
}

enum USER_LEVELUP_COUNT_TYPE {
LEVEL0 = 0, //대학교
LEVEL1 = 5, //공연장
LEVEL2 = 25, //한강공원
LEVEL3 = 100, //한강공원
}

export {
USER_LEVELUP_COUNT_TYPE,
USER_LEVEL_TYPE,
QUESTION_FIND_FILTER_TYPE,
getEnumToArray,
getEnumTypeValues,
Expand Down
14 changes: 11 additions & 3 deletions src/common/dtos/UserProfile.dto.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { ApiProperty } from '@nestjs/swagger';
import { Expose, Transform, Type } from 'class-transformer';
import { Profile } from 'src/models/user.model';
import { Profile, User } from 'src/models/user.model';
import { Types } from 'mongoose';
import { TransformObjectIdToString } from '../decorators/Expose.decorator';

export class UserProfileDto {
constructor(user) {
constructor(user: User) {
if (user) {
this._id = user._id;
this.nickname = user.nickname;
this.profile = user.profile;
this.level = user.level;
}
}
@ApiProperty({ type: String, example: '626cf238b51596721c21289b' })
Expand All @@ -26,6 +27,13 @@ export class UserProfileDto {
@Type(() => Profile)
@Expose()
profile: Profile;

@ApiProperty({
type: Number,
description: '유저의 확성기 레벨',
})
@Expose()
level: number;
}

export const UserProfileSelect = { _id: 1, nickname: 1, profile: 1 };
export const UserProfileSelect = { _id: 1, nickname: 1, profile: 1, level: 1 };
27 changes: 27 additions & 0 deletions src/models/lightning.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Prop, Schema, SchemaFactory, SchemaOptions } from '@nestjs/mongoose';

import { Exclude, Expose, Transform, Type } from 'class-transformer';
import { Types } from 'mongoose';

const options: SchemaOptions = {
collection: 'lightning',
timestamps: true,
};

@Schema(options)
export class Lightning {
@Prop({ type: Types.ObjectId })
sendUser: Types.ObjectId;

@Prop({ type: Types.ObjectId })
receiveUser: Types.ObjectId;

@Prop({
type: Date,
expires: 0,
})
@Expose()
expireAt: Date;
}

export const LightningSchema = SchemaFactory.createForClass(Lightning);
22 changes: 22 additions & 0 deletions src/models/user.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,28 @@ export class User {
@Transform(({ value }) => toKRTimeZone(value), { toClassOnly: true })
@Expose()
createdAt: Date;

@ApiProperty({
type: Number,
description: '유저의 번개 점수',
})
@Prop({
type: Number,
default: 0,
})
@Expose()
lightningScore: number;

@ApiProperty({
type: Number,
description: '유저의 확성기 레벨',
})
@Prop({
type: Number,
default: 0,
})
@Expose()
level: number;
}

export const _UserSchema = SchemaFactory.createForClass(User);
Expand Down
36 changes: 36 additions & 0 deletions src/repositories/lightning.repository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { InjectModel } from '@nestjs/mongoose';
import { Injectable } from '@nestjs/common';
import { Model } from 'mongoose';
import { UserIdDto } from 'src/common/dtos/UserId.dto';
import { Lightning } from 'src/models/lightning.model';

@Injectable()
export class LightningRepository {
constructor(
@InjectModel(Lightning.name)
private readonly LightningModel: Model<Lightning>,
) {}

async saveLighting(
senderIdDto: UserIdDto,
receiveIdDto: UserIdDto,
expireAtDate: Date,
): Promise<Lightning> {
const lightning = new this.LightningModel({
sendUser: senderIdDto.userId,
receiveUser: receiveIdDto.userId,
expireAt: expireAtDate,
});
return await lightning.save();
}

async findOneLightningByUserId(
senderIdDto: UserIdDto,
receiveIdDto: UserIdDto,
): Promise<Lightning | null> {
return await this.LightningModel.findOne({
sendUser: senderIdDto.userId,
receiveUser: receiveIdDto.userId,
});
}
}
18 changes: 17 additions & 1 deletion src/repositories/user.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { Room } from 'src/models/room.model';
import { UpdateProfileReqDto } from 'src/apis/users/dto/updateUserDto.req.dto';
import { UserProfileSelect } from 'src/common/dtos/UserProfile.dto';
import { ResShortCutRoomDto } from 'src/common/dtos/shortCutRoomInfo.res.dto';
import { STATUS_TYPE } from 'src/common/consts/enum';
import { STATUS_TYPE, USER_LEVEL_TYPE } from 'src/common/consts/enum';

@Injectable()
export class UserRepository {
Expand Down Expand Up @@ -383,4 +383,20 @@ export class UserRepository {

return roomInfo.length ? roomInfo[0] : null;
}

async addUserLigthningScore(userIdDto: UserIdDto): Promise<User> {
return await this.userModel.findOneAndUpdate(
{ _id: userIdDto.userId },
{ $inc: { lightningScore: 1 } },
{ new: true },
);
}

async levelUpUser(userIdDto: UserIdDto, userlevel: number): Promise<User> {
return await this.userModel.findOneAndUpdate(
{ _id: userIdDto.userId },
{ level: userlevel },
{ new: true },
);
}
}

0 comments on commit 3ac5b35

Please sign in to comment.