Skip to content

Commit

Permalink
Merge pull request #251 from Roger13579/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
y0000ga authored Jun 20, 2024
2 parents 4ea7917 + 7ce4d11 commit a38b8f1
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 65 deletions.
76 changes: 38 additions & 38 deletions src/dto/group/groupFilterDto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
} from '../../types/group.type';
import { SortOrder } from '../../types/common.type';

type TDateRange = {
type TTimeRange = {
$and: {
time: {
$gte?: Date;
Expand All @@ -25,7 +25,7 @@ export class GroupFilterDto {
private readonly _page: number;
private readonly _limit: number;
private readonly _sort: Record<string, 1 | -1>;
private readonly _dateRanges: TDateRange[] = [];
private readonly _timeRanges: TTimeRange[] = [];

get filter() {
const titleRegex = this._title ? new RegExp(this._title) : undefined;
Expand All @@ -38,7 +38,7 @@ export class GroupFilterDto {
amount: { $eq: this._participantCount },
}),
...(this._haveTicket && { haveTicket: this._haveTicket }),
$or: this._dateRanges,
...(this._timeRanges.length > 0 && { $or: this._timeRanges }),
};
}

Expand All @@ -61,10 +61,6 @@ export class GroupFilterDto {
};
}

get dateRanges() {
return this._dateRanges;
}

constructor(req: IGetGroupsReq) {
const {
title,
Expand Down Expand Up @@ -99,40 +95,44 @@ export class GroupFilterDto {

// date range

const dateFrom = moment(startDate, 'YYYY/MM/DD').startOf('day');
const dateTo = moment(endDate, 'YYYY/MM/DD').endOf('day');
const timeFrom = moment(startTime, 'HH:mm');
const timeTo = moment(endTime, 'HH:mm');
const hasTimeRange = !!startDate && !!endDate && !!startTime && !!endTime;

const dateRanges: TDateRange[] = [];
for (
let date = dateFrom.clone();
date.isSameOrBefore(dateTo);
date.add(1, 'days')
) {
const start = {
hour: timeFrom.hours(),
minute: timeFrom.minutes(),
second: 0,
millisecond: 0,
};
const end = {
hour: timeTo.hours(),
minute: timeTo.minutes(),
second: 0,
millisecond: 0,
};
if (hasTimeRange) {
const dateFrom = moment(startDate, 'YYYY/MM/DD').startOf('day');
const dateTo = moment(endDate, 'YYYY/MM/DD').endOf('day');
const timeFrom = moment(startTime, 'HH:mm');
const timeTo = moment(endTime, 'HH:mm');

const dateRange = {
$and: [
{ time: { $gte: new Date(date.clone().set(start).toISOString()) } },
{ time: { $lte: new Date(date.clone().set(end).toISOString()) } },
],
};
const dateRanges: TTimeRange[] = [];
for (
let date = dateFrom.clone();
date.isSameOrBefore(dateTo);
date.add(1, 'days')
) {
const start = {
hour: timeFrom.hours(),
minute: timeFrom.minutes(),
second: 0,
millisecond: 0,
};
const end = {
hour: timeTo.hours(),
minute: timeTo.minutes(),
second: 0,
millisecond: 0,
};

dateRanges.push(dateRange);
}
const dateRange = {
$and: [
{ time: { $gte: new Date(date.clone().set(start).toISOString()) } },
{ time: { $lte: new Date(date.clone().set(end).toISOString()) } },
],
};

this._dateRanges = dateRanges;
dateRanges.push(dateRange);
}

this._timeRanges = dateRanges;
}
}
}
16 changes: 8 additions & 8 deletions src/routes/groupRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,29 +260,29 @@ export class GroupRoute extends BaseRoute {
}
#swagger.parameters['startDate'] = {
in: 'query',
required: true,
description: '開始活動日期-起 (一定要遵循以下格式)',
required: false,
description: '開始活動日期-起一定要遵循以下格式,若要以時段搜尋則 startDate、endDate、startTime、endTime 皆為必填。',
type: 'string',
example: '2024/01/12'
}
#swagger.parameters['endDate'] = {
in: 'query',
required: true,
description: '開始活動日期-迄 (一定要遵循以下格式)',
required: false,
description: '開始活動日期-迄一定要遵循以下格式,若要以時段搜尋則 startDate、endDate、startTime、endTime 皆為必填。',
type: 'string',
example:'2024/07/12'
}
#swagger.parameters['startTime'] = {
in: 'query',
required: true,
description: '開始活動時間-起 (一定要遵循以下格式)',
required: false,
description: '開始活動時間-起一定要遵循以下格式,若要以時段搜尋則 startDate、endDate、startTime、endTime 皆為必填。',
type: 'string',
example: '01:00'
}
#swagger.parameters['endTime'] = {
in: 'query',
required: true,
description: '開始活動時間-迄 (一定要遵循以下格式)',
required: false,
description: '開始活動時間-迄一定要遵循以下格式,若要以時段搜尋則 startDate、endDate、startTime、endTime 皆為必填。',
type: 'string',
example: '23:00'
}
Expand Down
9 changes: 0 additions & 9 deletions src/service/groupService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,15 +145,6 @@ export class GroupService {
}
}
public async findGroups(groupFilterDto: GroupFilterDto) {
const { dateRanges } = groupFilterDto;

if (dateRanges.length === 0) {
throwError(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + '時間區間有誤',
CustomResponseType.INVALID_GROUP_FILTER,
);
}

return await this.groupRepository.findGroups(groupFilterDto);
}

Expand Down
71 changes: 61 additions & 10 deletions src/validator/group/getGroup.pipe.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,35 @@
import { PipeBase } from '../pipe.base';
import { query } from 'express-validator';
import { CustomResponseType } from '../../types/customResponseType';
import { GroupSortField, GroupStatus } from '../../types/group.type';
import { OptionType } from '../index.type';
import {
GroupSortField,
GroupStatus,
IGetGroupsReq,
} from '../../types/group.type';
import { OptionType, TCustomValidator } from '../index.type';
import { SortOrder } from '../../types/common.type';
import { booleanStrings, nullableOption } from '../../utils/constants';

const timeFormat = /^([01]\d|2[0-3]):([0-5]\d)$/; // HH:mm 格式
const dateFormat = /^\d{4}\/\d{2}\/\d{2}$/; // YYYY/MM/DD 格式

export class GetGroupsPipe extends PipeBase {
private validateTimeRange: TCustomValidator = (value, { req }) => {
const { startTime, endTime, startDate, endDate } = (req as IGetGroupsReq)
.query;

const hasTimeRange = !!startTime && !!endTime && !!startDate && !!endDate;
const hasNoTimeRange = !startTime && !endTime && !startDate && !endDate;

return hasTimeRange || hasNoTimeRange;
};

private validateTimeFormat: TCustomValidator<string> = (value) =>
timeFormat.test(value) || !value;

private validateDateFormat: TCustomValidator<string> = (value) =>
dateFormat.test(value) || !value;

public transform = () => [
this.limitValidation(
query('limit'),
Expand All @@ -33,21 +56,49 @@ export class GetGroupsPipe extends PipeBase {
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'participantCount',
),
query('startTime')
.exists()
.optional()
.custom(this.validateTimeFormat)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'startTime 格式錯誤',
)
.custom(this.validateTimeRange)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'startTime',
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE +
'使用時間區段搜尋時,startTime、endTime、startDate、endDate 皆為必填',
),
query('endTime')
.exists()
.withMessage(CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'endTime'),
.optional()
.custom(this.validateTimeFormat)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'endTime 格式錯誤',
)
.custom(this.validateTimeRange)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE +
'使用時間區段搜尋時,startTime、endTime、startDate、endDate 皆為必填',
),
query('startDate')
.exists()
.optional()
.custom(this.validateDateFormat)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'startDate 格式錯誤',
)
.custom(this.validateTimeRange)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'startDate',
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE +
'使用時間區段搜尋時,startTime、endTime、startDate、endDate 皆為必填',
),
query('endDate')
.exists()
.withMessage(CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'endDate'),
.optional()
.custom(this.validateDateFormat)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE + 'endDate 格式錯誤',
)
.custom(this.validateTimeRange)
.withMessage(
CustomResponseType.INVALID_GROUP_FILTER_MESSAGE +
'使用時間區段搜尋時,startTime、endTime、startDate、endDate 皆為必填',
),
query('sortField')
.optional(nullableOption)
.custom(this.validateOption(OptionType.item, GroupSortField))
Expand Down

0 comments on commit a38b8f1

Please sign in to comment.