Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BE] 즐겨찾기, 마이페이지 API 수정 #201

Merged
merged 6 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion BE/src/asset/asset.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export class Asset {
@Column({ nullable: false, default: 0 })
total_profit: number;

@Column('decimal', { nullable: false, default: 0, precision: 10, scale: 5 })
@Column('decimal', { nullable: false, default: 0, precision: 10, scale: 2 })
total_profit_rate: number;

@Column({ nullable: true })
Expand Down
26 changes: 19 additions & 7 deletions BE/src/asset/asset.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,24 @@ export class AssetRepository extends Repository<Asset> {

async findAllPendingOrders(userId: number, tradeType: TradeType) {
const queryRunner = this.dataSource.createQueryRunner();
return queryRunner.manager.find<Order>(Order, {
where: {
user_id: userId,
status: StatusType.PENDING,
trade_type: tradeType,
},
});
await queryRunner.startTransaction();

try {
const orders = await queryRunner.manager.find<Order>(Order, {
where: {
user_id: userId,
status: StatusType.PENDING,
trade_type: tradeType,
},
});

await queryRunner.commitTransaction();
return orders;
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}
5 changes: 3 additions & 2 deletions BE/src/asset/asset.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Injectable } from '@nestjs/common';
import { MoreThan } from 'typeorm';
import { UserStockRepository } from './user-stock.repository';
import { AssetRepository } from './asset.repository';
import { MypageResponseDto } from './dto/mypage-response.dto';
Expand Down Expand Up @@ -81,7 +82,7 @@ export class AssetService {
newAsset.stock_balance,
newAsset.total_asset,
newAsset.total_profit,
newAsset.total_profit_rate,
newAsset.total_profit_rate.toFixed(2),
newAsset.total_profit_rate >= 0,
);

Expand All @@ -106,7 +107,7 @@ export class AssetService {
private async updateMyAsset(asset: Asset, currPrices) {
const userId = asset.user_id;
const userStocks = await this.userStockRepository.find({
where: { user_id: userId },
where: { user_id: userId, quantity: MoreThan(0) },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 여기 근데 보유량이 0인 경우는 뭔가요??
예를 들어 삼성전자 20주 구매했는데 20주 전부 매도하면 보유량이 0이 되는건가요?
만약에 그런거라면, 하루에 한번씩 장 마감 됐을 때 저런 거 delete 하는 로직도 추가되면 좋을 거 같아요!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

맞습니당! 그 로직도 추가하면 좋을 것 같네요ㅎㅎ

});

const totalPrice = userStocks.reduce(
Expand Down
2 changes: 1 addition & 1 deletion BE/src/asset/user-stock.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class UserStock {
@Column({ nullable: false })
quantity: number;

@Column('float', { nullable: false, scale: 5 })
@Column('float', { nullable: false, scale: 2 })
avg_price: number;

@UpdateDateColumn()
Expand Down
4 changes: 3 additions & 1 deletion BE/src/asset/user-stock.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ export class UserStockRepository extends Repository<UserStock> {
'stocks',
'stocks.code = user_stocks.stock_code',
)
.where('user_stocks.user_id = :userId', { userId })
.where('user_stocks.user_id = :userId AND user_stocks.quantity > 0', {
userId,
})
.getRawMany<UserStockInterface>();
}

Expand Down
4 changes: 2 additions & 2 deletions BE/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ async function bootstrap() {
'http://localhost:5173',
'http://juga.kro.kr:5173',
'http://juga.kro.kr:3000',
//개발 서버
// 개발 서버
'http://223.130.151.42:5173',
'http://223.130.151.42:3000',
//배포 서버
// 배포 서버
'http://175.45.204.158',
'http://175.45.204.158:3000',
'http://juga.kro.kr',
Expand Down
2 changes: 1 addition & 1 deletion BE/src/ranking/ranking.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ export class RankingService {

return {
topRank: parsedTopRank,
userRank: userRank,
userRank,
};
}

Expand Down
19 changes: 0 additions & 19 deletions BE/src/stock/bookmark/stock-bookmark.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,23 +73,4 @@ export class StockBookmarkController {
parseInt(request.user.userId, 10),
);
}

@Get('/:stockCode')
@ApiBearerAuth()
@UseGuards(JwtAuthGuard)
@ApiOperation({ summary: '특정 종목에 대한 즐겨찾기 등록 여부 조회 API' })
@ApiResponse({
status: 200,
description: '즐겨찾기 등록 여부 조회 성공',
example: { is_bookmarked: true },
})
async getBookmarkActive(
@Req() request: Request,
@Param('stockCode') stockCode: string,
) {
return this.stockBookmarkService.getBookmarkActive(
parseInt(request.user.userId, 10),
stockCode,
);
}
}
9 changes: 0 additions & 9 deletions BE/src/stock/bookmark/stock-bookmark.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,4 @@ export class StockBookmarkService {
}),
);
}

async getBookmarkActive(userId, stockCode) {
return {
is_bookmarked: await this.stockBookmarkRepository.existsBy({
user_id: userId,
stock_code: stockCode,
}),
};
}
}
3 changes: 3 additions & 0 deletions BE/src/stock/detail/dto/stock-detail-response.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,7 @@ export class InquirePriceResponseDto {

@ApiProperty({ description: '주식 하한가' })
stck_llam: string;

@ApiProperty({ description: '즐겨찾기 여부 (미인증시 false)' })
is_bookmarked: boolean;
}
29 changes: 26 additions & 3 deletions BE/src/stock/detail/stock-detail.controller.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,35 @@
import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import {
Body,
Controller,
Get,
Param,
Post,
Req,
UseGuards,
} from '@nestjs/common';
import {
ApiBearerAuth,
ApiBody,
ApiOperation,
ApiParam,
ApiResponse,
ApiTags,
} from '@nestjs/swagger';
import { Request } from 'express';
import { StockDetailService } from './stock-detail.service';
import { InquirePriceResponseDto } from './dto/stock-detail-response.dto';
import { StockDetailChartRequestDto } from './dto/stock-detail-chart-request.dto';
import { InquirePriceChartResponseDto } from './dto/stock-detail-chart-response.dto';
import { OptionalAuthGuard } from '../../auth/optional-auth-guard';

@ApiTags('특정 주식 종목에 대한 detail 페이지 조회 API')
@Controller('/api/stocks/detail')
export class StockDetailController {
constructor(private readonly stockDetailService: StockDetailService) {}

@Get(':stockCode')
@ApiBearerAuth()
@UseGuards(OptionalAuthGuard)
@ApiOperation({ summary: '단일 주식 종목 detail 페이지 상단부 조회 API' })
@ApiParam({
name: 'stockCode',
Expand All @@ -30,8 +43,18 @@ export class StockDetailController {
description: '단일 주식 종목 기본값 조회 성공',
type: InquirePriceResponseDto,
})
getStockDetail(@Param('stockCode') stockCode: string) {
return this.stockDetailService.getInquirePrice(stockCode);
async getStockDetail(
@Req() request: Request,
@Param('stockCode') stockCode: string,
) {
const stockData = await this.stockDetailService.getInquirePrice(stockCode);
if (!request.user) return stockData;

stockData.is_bookmarked = await this.stockDetailService.getBookmarkActive(
parseInt(request.user.userId, 10),
stockCode,
);
return stockData;
}

@Post(':stockCode')
Expand Down
23 changes: 22 additions & 1 deletion BE/src/stock/detail/stock-detail.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,35 @@ import { InjectDataSource } from '@nestjs/typeorm';
import { Injectable } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { Stocks } from './stock-detail.entity';
import { Bookmark } from '../bookmark/stock-bookmark.entity';

@Injectable()
export class StockDetailRepository extends Repository<Stocks> {
constructor(@InjectDataSource() dataSource: DataSource) {
constructor(@InjectDataSource() private readonly dataSource: DataSource) {
super(Stocks, dataSource.createEntityManager());
}

async findOneByCode(code: string) {
return this.findOne({ where: { code } });
}

async existsBookmarkByUserIdAndStockCode(userId: number, stockCode: string) {
const queryRunner = this.dataSource.createQueryRunner();
await queryRunner.startTransaction();

try {
const isExist = queryRunner.manager.existsBy(Bookmark, {
user_id: userId,
stock_code: stockCode,
});

await queryRunner.commitTransaction();
return await isExist;
} catch (error) {
await queryRunner.rollbackTransaction();
throw error;
} finally {
await queryRunner.release();
}
}
}
8 changes: 8 additions & 0 deletions BE/src/stock/detail/stock-detail.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export class StockDetailService {
per: stock.per,
stck_mxpr: stock.stck_mxpr,
stck_llam: stock.stck_llam,
is_bookmarked: false,
};
}

Expand Down Expand Up @@ -101,6 +102,13 @@ export class StockDetailService {
return this.formatStockInquirePriceData(response).slice().reverse();
}

getBookmarkActive(userId: number, stockCode: string) {
return this.stockDetailRepository.existsBookmarkByUserIdAndStockCode(
userId,
stockCode,
);
}

/**
* @private API에서 받은 국내주식기간별시세(일/주/월/년) 데이터를 필요한 정보로 정제하는 함수
* @param {InquirePriceApiResponse} response - API 응답에서 받은 원시 데이터
Expand Down
Loading