新增AI教练模块,包括控制器、服务、模型及数据传输对象,更新应用模块以引入新模块,同时在打卡模块中添加按时间范围返回每日打卡状态的功能
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Injectable, NotFoundException, Logger, ForbiddenException } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/sequelize';
|
||||
import { Checkin, CheckinStatus } from './models/checkin.model';
|
||||
import { CreateCheckinDto, UpdateCheckinDto, CompleteCheckinDto, RemoveCheckinDto, CheckinResponseDto } from './dto/checkin.dto';
|
||||
import { CreateCheckinDto, UpdateCheckinDto, CompleteCheckinDto, RemoveCheckinDto, CheckinResponseDto, GetDailyStatusRangeQueryDto, DailyStatusItem } from './dto/checkin.dto';
|
||||
import { ResponseCode } from '../base.dto';
|
||||
import * as dayjs from 'dayjs';
|
||||
import { Op } from 'sequelize';
|
||||
@@ -115,6 +115,62 @@ export class CheckinsService {
|
||||
|
||||
return { code: ResponseCode.SUCCESS, message: 'success', data: rows.map(r => r.toJSON()) };
|
||||
}
|
||||
|
||||
// 按时间范围返回每天是否打卡(任一记录满足视为已打卡)
|
||||
async getDailyStatusRange(userId: string, query: GetDailyStatusRangeQueryDto): Promise<CheckinResponseDto<DailyStatusItem[]>> {
|
||||
const start = dayjs(query.startDate, 'YYYY-MM-DD');
|
||||
const end = dayjs(query.endDate, 'YYYY-MM-DD');
|
||||
if (!start.isValid() || !end.isValid() || end.isBefore(start)) {
|
||||
return { code: ResponseCode.ERROR, message: '无效日期范围', data: [] };
|
||||
}
|
||||
|
||||
// 查询范围内所有打卡(覆盖checkinDate与时间戳)
|
||||
const startTs = start.startOf('day').toDate();
|
||||
const endTs = end.endOf('day').toDate();
|
||||
|
||||
const rows = await this.checkinModel.findAll({
|
||||
where: {
|
||||
userId,
|
||||
[Op.or]: [
|
||||
{
|
||||
checkinDate: {
|
||||
[Op.between]: [start.format('YYYY-MM-DD') as any, end.format('YYYY-MM-DD') as any],
|
||||
} as any,
|
||||
},
|
||||
{
|
||||
[Op.or]: [
|
||||
{ startedAt: { [Op.between]: [startTs, endTs] } },
|
||||
{ completedAt: { [Op.between]: [startTs, endTs] } },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
attributes: ['checkinDate', 'startedAt', 'completedAt'],
|
||||
});
|
||||
|
||||
const set = new Set<string>();
|
||||
for (const r of rows) {
|
||||
if (r.checkinDate) {
|
||||
set.add(r.checkinDate);
|
||||
}
|
||||
if (r.startedAt) {
|
||||
set.add(dayjs(r.startedAt).format('YYYY-MM-DD'));
|
||||
}
|
||||
if (r.completedAt) {
|
||||
set.add(dayjs(r.completedAt).format('YYYY-MM-DD'));
|
||||
}
|
||||
}
|
||||
|
||||
const result: DailyStatusItem[] = [];
|
||||
let cur = start.clone();
|
||||
while (!cur.isAfter(end)) {
|
||||
const d = cur.format('YYYY-MM-DD');
|
||||
result.push({ date: d, checkedIn: set.has(d) });
|
||||
cur = cur.add(1, 'day');
|
||||
}
|
||||
|
||||
return { code: ResponseCode.SUCCESS, message: 'success', data: result };
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user