Skip to content

Commit

Permalink
add announcement module
Browse files Browse the repository at this point in the history
  • Loading branch information
BlueHorn07 committed Dec 9, 2023
1 parent 7cc0c1c commit 3f9a14f
Show file tree
Hide file tree
Showing 6 changed files with 232 additions and 0 deletions.
81 changes: 81 additions & 0 deletions src/popo/announcement/announcement.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import {
Body,
Controller,
Delete,
Get,
Param,
Patch,
Post,
Put,
UseGuards,
} from '@nestjs/common';
import { ApiBody, ApiTags } from '@nestjs/swagger';
import * as moment from 'moment';

import { AnnouncementService } from './announcement.service';
import { AnnouncementDto, AnnouncementImageDto } from './announcement.dto';
import { UserType } from '../user/user.meta';
import { JwtAuthGuard } from '../../auth/guards/jwt-auth.guard';
import { Roles } from '../../auth/authroization/roles.decorator';
import { RolesGuard } from '../../auth/authroization/roles.guard';
import { FileService } from '../../file/file.service';
import { FileBody } from '../../file/file-body.decorator';

@ApiTags('Announcement')
@Controller('announcement')
export class AnnouncementController {
constructor(
private readonly announcementService: AnnouncementService,
private readonly fileService: FileService,
) {}

@Post()
@Roles(UserType.admin, UserType.association)
@UseGuards(JwtAuthGuard, RolesGuard)
@ApiBody({ type: AnnouncementDto })
async create(@Body() dto: AnnouncementDto) {
return this.announcementService.save(dto);
}

@Post('image/:id')
@Roles(UserType.admin, UserType.association)
@UseGuards(JwtAuthGuard, RolesGuard)
@FileBody('image')
async uploadImage(@Param('id') id: number, @Body() dto: AnnouncementImageDto) {
const image_url = await this.fileService.uploadFile(
`announcement/${id}/${moment().format('YYYY-MM-DD/HH:mm:ss')}`,
dto.image,
);
await this.announcementService.updateImageUrl(id, image_url);
return image_url;
}

@Get()
getAll() {
return this.announcementService.find();
}

@Get(':id')
async getOne(@Param('id') id: number) {
return this.announcementService.findOneById(id);
}

@Patch('click/:id')
increaseClickCount(@Param('id') id: number) {
return this.announcementService.increaseClickCount(id);
}

@Put(':id')
@Roles(UserType.admin, UserType.association, UserType.staff)
@UseGuards(JwtAuthGuard, RolesGuard)
async put(@Param('id') id: number, @Body() updateAnnouncementDto: AnnouncementDto) {
return this.announcementService.update(id, updateAnnouncementDto);
}

@Delete(':id')
@Roles(UserType.admin, UserType.association)
@UseGuards(JwtAuthGuard, RolesGuard)
async delete(@Param('id') id: number) {
this.announcementService.remove(id);
}
}
15 changes: 15 additions & 0 deletions src/popo/announcement/announcement.dto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { IsFile, MaxFileSize, MemoryStoredFile } from 'nestjs-form-data';

export class AnnouncementDto {
readonly title: string;
readonly memo: string | null;
readonly start_datetime: string | null; // YYYY-MM-DD HH:mm:ss (KST)
readonly end_datetime: string | null; // YYYY-MM-DD HH:mm:ss (KST)
readonly link: string | null;
}

export class AnnouncementImageDto {
@IsFile()
@MaxFileSize(10 * 1024 * 1024) // 10MB
readonly image: MemoryStoredFile;
}
41 changes: 41 additions & 0 deletions src/popo/announcement/announcement.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import {
BaseEntity,
Column,
CreateDateColumn,
Entity,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';

@Entity()
export class Announcement extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;

@Column({ nullable: false })
title: string;

@Column('text', { nullable: true })
memo: string;

@Column({ nullable: true })
image_url: string;

@Column({ nullable: true })
link: string;

@Column({ nullable: true })
start_datetime: string; // YYYY-MM-DD HH:mm:ss (KST)

@Column({ nullable: true })
end_datetime: string; // YYYY-MM-DD HH:mm:ss (KST)

@Column({ default: 0})
click_count: number;

@CreateDateColumn()
createdAt: Date;

@UpdateDateColumn()
updateAt: Date;
}
20 changes: 20 additions & 0 deletions src/popo/announcement/announcement.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NestjsFormDataModule } from 'nestjs-form-data';

import { AnnouncementController } from './announcement.controller';
import { AnnouncementService } from './announcement.service';
import { Announcement } from './announcement.entity';
import { FileModule } from '../../file/file.module';

@Module({
imports: [
TypeOrmModule.forFeature([Announcement]),
NestjsFormDataModule,
FileModule,
],
controllers: [AnnouncementController],
providers: [AnnouncementService],
exports: [AnnouncementService],
})
export class AnnouncementModule {}
72 changes: 72 additions & 0 deletions src/popo/announcement/announcement.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Announcement } from './announcement.entity';
import { AnnouncementDto } from './announcement.dto';

const Message = {
NOT_EXISTING_REGION: "There's no such region.",
NOT_EXISTING_USER: "There's no such user.",
NOT_EXISTING_PLACE: "There's no such announcement.",
INVALID_OWNER: 'Only Association can have a announcement.',
INVALID_STAFF: 'Only Staff and ADMIN can be a manager.',
};

@Injectable()
export class AnnouncementService {
constructor(
@InjectRepository(Announcement)
private readonly announcementRepo: Repository<Announcement>,
) {}

save(dto: AnnouncementDto) {
return this.announcementRepo.save(dto);
}

updateImageUrl(id: number, image_url: string) {
return this.announcementRepo.update({ id: id }, { image_url: image_url });
}

find() {
return this.announcementRepo.find({ order: { updateAt: 'DESC' } });
}

findOneById(id: number) {
return this.announcementRepo.findOneBy({ id: id });
}

findOneByIdOrFail(id: number) {
const announcement = this.findOneById(id);
if (!announcement) {
throw new BadRequestException(Message.NOT_EXISTING_PLACE);
}
return announcement;
}

async update(id: number, dto: AnnouncementDto) {
const existAnnouncement = await this.findOneById(id);
if (!existAnnouncement) {
throw new BadRequestException(Message.NOT_EXISTING_PLACE);
}

return this.announcementRepo.update({ id: id }, dto);
}

async increaseClickCount(id: number) {
const announcement = await this.announcementRepo.findOneByOrFail({ id: id });
return this.announcementRepo.update(
{ id: id },
{ click_count: announcement.click_count + 1 },
);
}

async remove(id: number) {
const existAnnouncement = await this.findOneById(id);

if (!existAnnouncement) {
throw new BadRequestException(Message.NOT_EXISTING_PLACE);
}

return this.announcementRepo.delete({ id: id });
}
}
3 changes: 3 additions & 0 deletions src/popo/popo.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Module } from '@nestjs/common';

import { AnnouncementModule } from './announcement/announcement.module';
import { BenefitModule } from './benefit/benefit.module';
import { EquipModule } from './equip/equip.module';
import { IntroduceModule } from './introduce/introduce.module';
Expand All @@ -10,6 +12,7 @@ import { WhitebookModule } from './whitebook/whitebook.module';

@Module({
imports: [
AnnouncementModule,
BenefitModule,
PlaceModule,
EquipModule,
Expand Down

0 comments on commit 3f9a14f

Please sign in to comment.