diff --git a/global.d.ts b/global.d.ts index 4fd70e5..5f69474 100644 --- a/global.d.ts +++ b/global.d.ts @@ -37,6 +37,7 @@ declare global { LINEPAY_CHANNEL_SECRET_KEY: string; LINEPAY_SITE: string; SHARE_CODE_SECRET_KEY: string; + MOVIE_GO_URL: string; } } } diff --git a/src/controller/baseController.ts b/src/controller/baseController.ts index e209c3c..f3250d0 100644 --- a/src/controller/baseController.ts +++ b/src/controller/baseController.ts @@ -2,6 +2,9 @@ import { CustomResponseType } from '../types/customResponseType'; import { ResponseObject } from '../utils/responseObject'; export abstract class BaseController { + /** + * @description 如果 data 裡面有 specific_redirect_url 則要轉址 + */ public formatResponse( message: string, status = CustomResponseType.SYSTEM_ERROR, diff --git a/src/controller/orderController.ts b/src/controller/orderController.ts index a55b908..cb73c15 100644 --- a/src/controller/orderController.ts +++ b/src/controller/orderController.ts @@ -63,6 +63,9 @@ class OrderController extends BaseController { ); }; + /** + * @description 使用者付款後 line 會到這個 url + */ public linePayConfirmNotify: TMethod = async (req) => { const linePayConfirmDto = new LinePayConfirmDTO(req); const order = @@ -79,13 +82,22 @@ class OrderController extends BaseController { return this.formatResponse( CustomResponseType.OK_MESSAGE, CustomResponseType.OK, - order, + { + specific_redirect_url: process.env.MOVIE_GO_URL, + }, ); }; - // 取消付款 - - // 退款 + // TODO: 取消交易 + public linePayCancelNotify: TMethod = async () => { + return this.formatResponse( + CustomResponseType.OK_MESSAGE, + CustomResponseType.OK, + { + specific_redirect_url: process.env.MOVIE_GO_URL, + }, + ); + }; public getOrders: TMethod = async (req) => { const orderFilterDto = new OrderFilterDto(req); diff --git a/src/dto/ticket/getTicketsDto.ts b/src/dto/ticket/getTicketsDto.ts index 327c3b7..c0e8075 100644 --- a/src/dto/ticket/getTicketsDto.ts +++ b/src/dto/ticket/getTicketsDto.ts @@ -73,9 +73,9 @@ export class GetTicketsDto { ...(this._userId && { userId: { $eq: this._userId } }), ...(this._ids && { _id: { $in: this._ids } }), ...((this._expiredAtFrom || this._expiredAtTo) && { - startAt: { - ...(this._expiredAtFrom && { $lte: this._expiredAtFrom }), - ...(this._expiredAtTo && { $gte: this._expiredAtTo }), + expiredAt: { + ...(this._expiredAtFrom && { $gte: this._expiredAtFrom }), + ...(this._expiredAtTo && { $lte: this._expiredAtTo }), }, }), ...(this._isPublished && { isPublished: { $eq: this._isPublished } }), diff --git a/src/routes/baseRoute.ts b/src/routes/baseRoute.ts index e0e0cf7..2f5e2d2 100644 --- a/src/routes/baseRoute.ts +++ b/src/routes/baseRoute.ts @@ -40,7 +40,21 @@ export abstract class BaseRoute { (req, res, next) => { method .call(this.controller, req, res, next) - .then((obj) => res.status(HttpStatus.OK).json(obj)) + .then((obj) => { + const isRedirect = !!( + obj.data && + (obj.data as { specific_redirect_url?: string }) + .specific_redirect_url + ); + if (isRedirect) { + const { specific_redirect_url } = obj.data as { + specific_redirect_url: string; + }; + res.redirect(HttpStatus.OK, specific_redirect_url); + } else { + res.status(HttpStatus.OK).json(obj); + } + }) .catch((err) => { logger.error(err); next(controller.formatResponse(err.message, err.status)); diff --git a/src/routes/orderRoute.ts b/src/routes/orderRoute.ts index dea002f..453fb30 100644 --- a/src/routes/orderRoute.ts +++ b/src/routes/orderRoute.ts @@ -64,6 +64,15 @@ export class OrderRoute extends BaseRoute { this.responseHandler(this.controller.linePayConfirmNotify), ); + this.router.get( + '/v1/order/linePay/cancel', + /** + * #swagger.tags = ['Order'] + * #swagger.summary = 'LinePay 取消交易回傳交易結果' + */ + this.responseHandler(this.controller.linePayCancelNotify), + ); + // 使用者取消付款 // 使用者退款 diff --git a/src/service/ticketService.ts b/src/service/ticketService.ts index cfdc9a9..6a67287 100644 --- a/src/service/ticketService.ts +++ b/src/service/ticketService.ts @@ -2,11 +2,9 @@ import log4js from '../config/log4js'; import { IOrder, IOrderProduct } from '../models/order'; import { throwError } from '../utils/errorHandler'; import { CustomResponseType } from '../types/customResponseType'; -import { areTimesInOrder } from '../utils/common'; import { TicketRepository } from '../repository/ticketRepository'; import { CreateTicketDto } from '../dto/ticket/createTicketDto'; import { GetTicketsDto } from '../dto/ticket/getTicketsDto'; -import { SortOrder } from '../types/common.type'; import { VerifyTicketsDTO } from '../dto/ticket/verifyTicketsDto'; import { EditTicketsDTO } from '../dto/ticket/editTicketsDto'; import { CreateShareCodeDTO } from '../dto/ticket/createShareCodeDto'; @@ -32,20 +30,9 @@ export class TicketService { private readonly productRepository: ProductRepository = new ProductRepository(); - public findTickets = async (ticketFilterDto: GetTicketsDto) => { - const { expiredAtFrom, expiredAtTo } = ticketFilterDto; + public findTickets = async (ticketFilterDto: GetTicketsDto) => + await this.ticketRepository.findTickets(ticketFilterDto); - // 確認時間順序 - areTimesInOrder( - [ - { name: 'expiredAtFrom', value: expiredAtFrom }, - { name: 'expiredAtTo', value: expiredAtTo }, - ], - SortOrder.asc, - ); - - return await this.ticketRepository.findTickets(ticketFilterDto); - }; public findSharedTickets = async ( getSharedTicketsDto: GetSharedTicketsDto, ) => { diff --git a/src/validator/ticket/getTicket.pipe.ts b/src/validator/ticket/getTicket.pipe.ts index 5419860..a42ab08 100644 --- a/src/validator/ticket/getTicket.pipe.ts +++ b/src/validator/ticket/getTicket.pipe.ts @@ -13,12 +13,12 @@ import { booleanStrings } from '../../utils/constants'; export class GetTicketPipe extends PipeBase { private validateExpiredAtFrom: TCustomValidator = (value, { req }) => { const { expiredAtTo } = (req as IGetTicketsReq).query; - return this.validatePeriod(value, expiredAtTo, (a, b) => b.isAfter(a)); + return this.validatePeriod(value, expiredAtTo, (a, b) => a.isBefore(b)); }; private validateExpiredAtTo: TCustomValidator = (value, { req }) => { const { expiredAtFrom } = (req as IGetTicketsReq).query; - return this.validatePeriod(value, expiredAtFrom, (a, b) => a.isBefore(b)); + return this.validatePeriod(expiredAtFrom, value, (a, b) => a.isBefore(b)); }; public transform = () => [