Skip to content

Commit

Permalink
FEAT: Profile img system
Browse files Browse the repository at this point in the history
  • Loading branch information
손보석 authored and 손보석 committed Aug 31, 2023
1 parent 18c933c commit 75192ac
Show file tree
Hide file tree
Showing 25 changed files with 197 additions and 46 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@nestjs/swagger": "^7.1.8",
"@nestjs/terminus": "^10.0.1",
"@types/jsonwebtoken": "^9.0.2",
"@types/multer": "^1.4.7",
"axios": "^1.5.0",
"bcryptjs": "^2.4.3",
"class-validator": "^0.14.0",
Expand Down
4 changes: 3 additions & 1 deletion src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import { LoggerMiddleware } from './middlewares/logger.middlware'
import { JwtAuthGuard } from './guard/AuthGuard'
import { CommentsModule } from './comments/comments.module'
import { QuestionModule } from './question/question.module'
import { FileController } from './file/file.controller'
import { FileModule } from './file/file.module'

@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/sclife'), UserModule, SignModule, HealthModule, CommentsModule, QuestionModule],
imports: [MongooseModule.forRoot('mongodb://localhost/sclife'), UserModule, SignModule, HealthModule, CommentsModule, QuestionModule, FileModule],
controllers: [AppController],
providers: [AppService, LoggerMiddleware, JwtAuthGuard],
})
Expand Down
16 changes: 4 additions & 12 deletions src/dto/comment.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,19 @@ import { IsDateString, IsString } from 'class-validator'
export class CommentDto {
@ApiProperty({
required: true,
example: '안녕하세요',
example: '',
description: '내용'
})
@IsString()
readonly content: string

@ApiProperty({
required: true,
example: '안녕하세요',
description: '제목'
})
@IsString()
readonly postTitle: string
readonly post_id: string

@ApiProperty({
required: true,
example: '안녕하세요',
description: '게시물 내용'
description: '내용'
})
@IsString()
readonly postContent: string
readonly content: string

@IsDateString()
readonly createdAt: Date
Expand Down
7 changes: 7 additions & 0 deletions src/dto/question.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import { ApiProperty } from '@nestjs/swagger'
import { IsDateString, IsString } from 'class-validator'

export class QuestionDto {
@ApiProperty({
example: 'asdf.png',
description: '이미지'
})
@IsString()
readonly img: string

@ApiProperty({
required: true,
example: '안녕하세요',
Expand Down
25 changes: 23 additions & 2 deletions src/dto/user.dto.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import { ApiProperty } from '@nestjs/swagger'
import { IsArray, IsString } from 'class-validator'
import { IsArray, IsNumber, IsString } from 'class-validator'

export class UserDto {
@ApiProperty({
example: 'default.jpg',
description: '프로필 이미지'
})
@IsString()
readonly img: string

@ApiProperty({
required: true,
example: 'gildong',
Expand All @@ -10,6 +17,14 @@ export class UserDto {
@IsString()
readonly name: string

@ApiProperty({
required: true,
example: '[email protected]',
description: '이메일'
})
@IsString()
readonly email: string

@ApiProperty({
required: true,
example: 'qwer1234!',
Expand All @@ -19,10 +34,16 @@ export class UserDto {
readonly password: string

@ApiProperty({
required: true,
example: '그룹이름',
description: '그룹',
})
@IsArray()
readonly group: string[]

@ApiProperty({
example: '97',
description: '상담, 진담 점수'
})
@IsNumber()
readonly score: number
}
24 changes: 24 additions & 0 deletions src/file/file.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { Controller, Get, Req, Res } from '@nestjs/common'
import { Request, Response } from 'express'
import { FileService } from './file.service'

@Controller('upload')
export class FileController {
constructor(private readonly fileService: FileService) {}

@Get('post/:name')
getPostImgByName(
@Req() req: Request,
@Res() res: Response
) {
return this.fileService.post(req, res)
}

@Get('profile/:name')
getProfileImgByName(
@Req() req: Request,
@Res() res: Response
) {
return this.fileService.profile(req, res)
}
}
9 changes: 9 additions & 0 deletions src/file/file.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Module } from '@nestjs/common'
import { FileService } from './file.service'
import { FileController } from './file.controller'

@Module({
controllers: [FileController],
providers: [FileService]
})
export class FileModule {}
16 changes: 16 additions & 0 deletions src/file/file.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { Injectable } from '@nestjs/common'
import { Request, Response } from 'express'
import { join } from 'path'

@Injectable()
export class FileService {
async post(req: Request, res: Response) {
const name = req.params.name
return res.sendFile(join(process.cwd(), `uploads/post/${name}`))
}

async profile(req: Request, res: Response) {
const name = req.params.name
return res.sendFile(join(process.cwd(), `uploads/profile/${name}`))
}
}
2 changes: 1 addition & 1 deletion src/guard/AuthGuard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ import { Injectable } from '@nestjs/common'
import { AuthGuard } from '@nestjs/passport'

@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}
export class JwtAuthGuard extends AuthGuard('jwt') {}
18 changes: 12 additions & 6 deletions src/question/question.controller.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Body, Controller, Get, Post } from '@nestjs/common'
import { Body, Controller, Get, Post, UploadedFile, UseInterceptors } from '@nestjs/common'
import { QuestionService } from './question.service'
import { Question } from '../schema/question.schema'
import { ApiBearerAuth, ApiOperation, ApiSecurity, ApiTags } from '@nestjs/swagger'
import { FileInterceptor } from '@nestjs/platform-express'
import { QuestionDto } from 'src/dto/question.dto'

@ApiBearerAuth()
@ApiSecurity('basic')
Expand All @@ -11,14 +13,18 @@ export class QuestionController {
constructor(private readonly questionService: QuestionService) {}

@ApiOperation({ summary: '질문 등록' })
@UseInterceptors(FileInterceptor('file'))
@Post()
async createQuestion(@Body('content2') content2: string): Promise<Question> {
return await this.questionService.createQuestion(content2)
createQuestion(
@UploadedFile() file: Array<Express.Multer.File>,
@Body() body: QuestionDto
): Promise<Question> {
return this.questionService.create({ ...body, img: JSON.parse(JSON.stringify(file)).filename })
}

@ApiOperation({ summary: '질문 보기' })
@Get()
async getAllQuestion(): Promise<Question[]> {
return await this.questionService.getAllQuestion()
getAllQuestion(): Promise<Question[]> {
return this.questionService.getAll()
}
}
}
14 changes: 13 additions & 1 deletion src/question/question.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,21 @@ import { MongooseModule } from '@nestjs/mongoose'
import { QuestionSchema } from 'src/schema/question.schema'
import { QuestionService } from './question.service'
import { QuestionController } from './question.controller'
import { MulterModule } from '@nestjs/platform-express'
import { diskStorage } from 'multer'

@Module({
imports: [MongooseModule.forFeature([{ name: 'Question', schema: QuestionSchema }])],
imports: [
MongooseModule.forFeature([{ name: 'Question', schema: QuestionSchema }]),
MulterModule.register({
storage: diskStorage({
destination: './uploads/post',
filename: (_, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`)
}
})
})
],
controllers: [QuestionController],
providers: [QuestionService],
})
Expand Down
7 changes: 4 additions & 3 deletions src/question/question.service.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { Injectable } from '@nestjs/common'
import { InjectModel } from '@nestjs/mongoose'
import { Model } from 'mongoose'
import { QuestionDto } from 'src/dto/question.dto'
import { Question } from 'src/schema/question.schema'

@Injectable()
export class QuestionService {
constructor(@InjectModel('Question') private readonly questionModel: Model<Question>) {}

async createQuestion(content2: string): Promise<Question> {
const newQuestion = new this.questionModel({ content2 })
async create(body: QuestionDto): Promise<Question> {
const newQuestion = new this.questionModel(body)
return await newQuestion.save()
}

async getAllQuestion(): Promise<Question[]> {
async getAll(): Promise<Question[]> {
return await this.questionModel.find().exec()
}
}
7 changes: 2 additions & 5 deletions src/schema/comment.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ export type CommentDocument = HydratedDocument<Comment>
@Schema()
export class Comment {
@Prop({ required: true })
content: string

@Prop({ required: true })
postTitle: string
post_id: string

@Prop({ required: true })
postContent: string
content: string

@Prop({ default: Date.now })
createdAt: Date
Expand Down
3 changes: 3 additions & 0 deletions src/schema/question.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export type QuestionDocument = HydratedDocument<Question>

@Schema()
export class Question {
@Prop()
img: string

@Prop({ required: true })
content2: string

Expand Down
8 changes: 7 additions & 1 deletion src/schema/user.schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ export type UserDocument = HydratedDocument<User>

@Schema()
export class User {
@Prop()
img: string

@Prop({ required: true })
name: string

Expand All @@ -14,8 +17,11 @@ export class User {
@Prop({ required: true })
password: string

@Prop({ required: true })
@Prop()
group: string[]

@Prop()
score: number
}

export const UserSchema = SchemaFactory.createForClass(User)
2 changes: 1 addition & 1 deletion src/sign/sign.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class SignController {
@ApiOperation({ summary: '회원가입' })
@Post('up')
signUp(@Body() body: UserDto) {
return this.signService.sign_up(body)
return this.signService.sign_up({ ...body, img: 'default.jpg', score: 100 })
}

@ApiResponse({
Expand Down
10 changes: 10 additions & 0 deletions src/sign/sign.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { MongooseModule } from '@nestjs/mongoose'
import { User, UserSchema } from '../schema/user.schema'
import { JwtModule } from '@nestjs/jwt'
import { jwtConstants } from '../../util/secret.contants'
import { MulterModule } from '@nestjs/platform-express'
import { diskStorage } from 'multer'

@Module({
imports: [
Expand All @@ -15,6 +17,14 @@ import { jwtConstants } from '../../util/secret.contants'
}),
}),
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
MulterModule.register({
storage: diskStorage({
destination: './uploads/profile',
filename: (_, file, cb) => {
cb(null, `${Date.now()}-${file.originalname}`)
}
})
})
],
controllers: [SignController],
providers: [SignService],
Expand Down
15 changes: 7 additions & 8 deletions src/sign/sign.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,18 @@ export class SignService {
constructor(@InjectModel(User.name) private userModel: Model<User>, private jwtService: JwtService) {}

async sign_up(user: UserDto) {
const findUser = await this.userModel.findOne({ name: user.name })
if (findUser) return { status: 401, message: `user '${user.name}' already exists` }

const createUser = new this.userModel(user).save()
const findUser = await this.userModel.findOne({ email: user.email })
if (findUser) return { status: 401, message: `user '${user.email}' already exists` }
new this.userModel(user).save()
return { status: 200, data: new this.userModel(user) }
}

async sign_in(user: UserDto) {
const findUser = await this.userModel.findOne({ name: user.name })
const findUser = await this.userModel.findOne({ email: user.email })
if (!findUser) return { status: 401 }

const accessToken = this.jwtService.sign({ name: findUser.name })

const accessToken = this.jwtService.sign({ id: findUser._id, email: findUser.email, name: findUser.name })
return { status: 200, accessToken }
}

Expand All @@ -32,7 +31,7 @@ export class SignService {
return { status: 401, message: 'User not found' }
}

const invalidatedToken = this.jwtService.sign({ invalidated: true })
this.jwtService.sign({ invalidated: true })
return { status: 200, message: 'Logged out successfully' }
}
}
Loading

0 comments on commit 75192ac

Please sign in to comment.