refactor: 移除使用次数扣除逻辑,调整活动类型及记录逻辑

This commit is contained in:
richarjiang
2025-08-27 19:01:21 +08:00
parent c3961150ab
commit 04903426d1
5 changed files with 38 additions and 18 deletions

View File

@@ -65,7 +65,6 @@ export class AiCoachController {
confirmationData: body.confirmationData, confirmationData: body.confirmationData,
}); });
await this.usersService.deductUserUsageCount(userId);
// 普通流式/非流式响应 // 普通流式/非流式响应
const readable = result as any; const readable = result as any;

View File

@@ -517,6 +517,9 @@ export class AiCoachService {
messages.unshift({ role: 'system', content: NUTRITION_ANALYST_PROMPT }); messages.unshift({ role: 'system', content: NUTRITION_ANALYST_PROMPT });
} }
// 普通聊天才需要扣减次数
await this.usersService.deductUserUsageCount(params.userId);
return this.generateAIResponse(params.conversationId, params.userId, messages); return this.generateAIResponse(params.conversationId, params.userId, messages);
} }

View File

@@ -3,12 +3,14 @@ import { InjectModel } from '@nestjs/sequelize';
import { Op, WhereOptions } from 'sequelize'; import { Op, WhereOptions } from 'sequelize';
import { Goal, GoalRepeatType, GoalStatus } from '../models/goal.model'; import { Goal, GoalRepeatType, GoalStatus } from '../models/goal.model';
import { GoalTask, TaskStatus } from '../models/goal-task.model'; import { GoalTask, TaskStatus } from '../models/goal-task.model';
import { CreateGoalTaskDto, UpdateGoalTaskDto, GoalTaskQueryDto, CompleteGoalTaskDto } from '../dto/goal-task.dto'; import { UpdateGoalTaskDto, GoalTaskQueryDto, CompleteGoalTaskDto } from '../dto/goal-task.dto';
import * as dayjs from 'dayjs'; import * as dayjs from 'dayjs';
import * as weekOfYear from 'dayjs/plugin/weekOfYear'; import * as weekOfYear from 'dayjs/plugin/weekOfYear';
import * as isoWeek from 'dayjs/plugin/isoWeek'; import * as isoWeek from 'dayjs/plugin/isoWeek';
import * as isSameOrBefore from 'dayjs/plugin/isSameOrBefore'; import * as isSameOrBefore from 'dayjs/plugin/isSameOrBefore';
import * as isSameOrAfter from 'dayjs/plugin/isSameOrAfter'; import * as isSameOrAfter from 'dayjs/plugin/isSameOrAfter';
import { ActivityLevel, ActivityType } from 'src/users/models/user-activity.model';
import { UserActivityService } from 'src/users/services/user-activity.service';
dayjs.extend(weekOfYear); dayjs.extend(weekOfYear);
dayjs.extend(isoWeek); dayjs.extend(isoWeek);
@@ -24,6 +26,7 @@ export class GoalTaskService {
private readonly goalModel: typeof Goal, private readonly goalModel: typeof Goal,
@InjectModel(GoalTask) @InjectModel(GoalTask)
private readonly goalTaskModel: typeof GoalTask, private readonly goalTaskModel: typeof GoalTask,
private readonly userActivityService: UserActivityService,
) { } ) { }
/** /**
@@ -42,7 +45,7 @@ export class GoalTaskService {
} }
const goals = await this.goalModel.findAll({ where }); const goals = await this.goalModel.findAll({ where });
this.logger.log(`为用户 ${userId} 找到 ${goals.length} 个活跃目标`); this.logger.log(`为用户 ${userId} 找到 ${goals.length} 个活跃目标`);
for (const goal of goals) { for (const goal of goals) {
@@ -155,14 +158,14 @@ export class GoalTaskService {
// 检查是否有自定义重复规则指定星期几 // 检查是否有自定义重复规则指定星期几
const weekdays = goal.customRepeatRule?.weekdays; const weekdays = goal.customRepeatRule?.weekdays;
if (weekdays && weekdays.length > 0) { if (weekdays && weekdays.length > 0) {
// 如果有指定星期几,按指定星期几生成任务 // 如果有指定星期几,按指定星期几生成任务
this.logger.log(`为目标 ${goal.title} 生成每周任务,指定星期几: ${weekdays}`); this.logger.log(`为目标 ${goal.title} 生成每周任务,指定星期几: ${weekdays}`);
// 从今天开始生成,如果开始日期晚于今天则从开始日期开始 // 从今天开始生成,如果开始日期晚于今天则从开始日期开始
let current = startDate.isBefore(today) ? today : startDate; let current = startDate.isBefore(today) ? today : startDate;
let generatedCount = 0; let generatedCount = 0;
while (current.isSameOrBefore(actualEndDate)) { while (current.isSameOrBefore(actualEndDate)) {
@@ -199,9 +202,9 @@ export class GoalTaskService {
current = current.add(1, 'day'); current = current.add(1, 'day');
} }
this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个每周任务`); this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个每周任务`);
} }
} }
/** /**
@@ -233,11 +236,11 @@ export class GoalTaskService {
while (current.isSameOrBefore(actualEndDate)) { while (current.isSameOrBefore(actualEndDate)) {
// 计算该月的目标日期 // 计算该月的目标日期
const targetDate = current.date(targetDayOfMonth); const targetDate = current.date(targetDayOfMonth);
// 如果目标日期超出了该月的天数,则使用该月的最后一天 // 如果目标日期超出了该月的天数,则使用该月的最后一天
const daysInMonth = current.daysInMonth(); const daysInMonth = current.daysInMonth();
const actualTargetDate = targetDayOfMonth > daysInMonth ? current.date(daysInMonth) : targetDate; const actualTargetDate = targetDayOfMonth > daysInMonth ? current.date(daysInMonth) : targetDate;
// 检查是否已经过了该月的目标日期 // 检查是否已经过了该月的目标日期
if (actualTargetDate.isBefore(today)) { if (actualTargetDate.isBefore(today)) {
this.logger.log(`跳过 ${current.format('YYYY年MM月')},目标日期 ${actualTargetDate.format('MM-DD')} 已过期`); this.logger.log(`跳过 ${current.format('YYYY年MM月')},目标日期 ${actualTargetDate.format('MM-DD')} 已过期`);
@@ -272,7 +275,7 @@ export class GoalTaskService {
current = current.add(1, 'month'); current = current.add(1, 'month');
} }
this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个每月任务`); this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个每月任务`);
} }
@@ -291,7 +294,7 @@ export class GoalTaskService {
} }
const { weekdays } = goal.customRepeatRule; const { weekdays } = goal.customRepeatRule;
this.logger.log(`为目标 ${goal.title} 生成自定义任务,重复规则: ${JSON.stringify(goal.customRepeatRule)}`); this.logger.log(`为目标 ${goal.title} 生成自定义任务,重复规则: ${JSON.stringify(goal.customRepeatRule)}`);
if (weekdays && weekdays.length > 0) { if (weekdays && weekdays.length > 0) {
@@ -302,7 +305,7 @@ export class GoalTaskService {
// 从今天开始生成,如果开始日期晚于今天则从开始日期开始 // 从今天开始生成,如果开始日期晚于今天则从开始日期开始
let current = startDate.isBefore(today) ? today : startDate; let current = startDate.isBefore(today) ? today : startDate;
let generatedCount = 0; let generatedCount = 0;
this.logger.log(`开始生成自定义任务,日期范围: ${current.format('YYYY-MM-DD')}${actualEndDate.format('YYYY-MM-DD')}`); this.logger.log(`开始生成自定义任务,日期范围: ${current.format('YYYY-MM-DD')}${actualEndDate.format('YYYY-MM-DD')}`);
@@ -340,7 +343,7 @@ export class GoalTaskService {
current = current.add(1, 'day'); current = current.add(1, 'day');
} }
this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个自定义任务`); this.logger.log(`为目标 ${goal.title} 生成了 ${generatedCount} 个自定义任务`);
} else { } else {
this.logger.warn(`目标 ${goal.title} 的自定义重复规则中没有指定星期几`); this.logger.warn(`目标 ${goal.title} 的自定义重复规则中没有指定星期几`);
@@ -452,6 +455,21 @@ export class GoalTaskService {
await task.save(); await task.save();
try {
const today = dayjs().format('YYYY-MM-DD');
await this.userActivityService.recordActivity(userId, {
activityType: ActivityType.GOAL,
activityDate: today,
level: ActivityLevel.MEDIUM,
remark: `完成目标任务: ${task.title}`,
});
this.logger.log(`记录用户活跃 - 用户: ${userId} 完成目标任务: ${task.title}`);
} catch (activityError) {
// 记录活跃失败不影响主要业务流程
this.logger.error(`记录用户活跃失败: ${activityError.message}`);
}
this.logger.log(`用户 ${userId} 完成任务: ${task.title}, 当前进度: ${task.currentCount}/${task.targetCount}`); this.logger.log(`用户 ${userId} 完成任务: ${task.title}, 当前进度: ${task.currentCount}/${task.targetCount}`);
return this.formatTaskResponse(task); return this.formatTaskResponse(task);

View File

@@ -4,7 +4,7 @@ import { User } from './user.model';
export enum ActivityType { export enum ActivityType {
LOGIN = 1, // 登录 LOGIN = 1, // 登录
WORKOUT = 2, // 训练 GOAL = 2, // 目标任务完成
DIET_RECORD = 3, // 饮食记录 DIET_RECORD = 3, // 饮食记录
WEIGHT_RECORD = 4, // 体重记录 WEIGHT_RECORD = 4, // 体重记录
PROFILE_UPDATE = 5, // 资料更新 PROFILE_UPDATE = 5, // 资料更新
@@ -14,7 +14,7 @@ export enum ActivityType {
// 活跃类型显示名称映射 // 活跃类型显示名称映射
export const ActivityTypeNames: Record<ActivityType, string> = { export const ActivityTypeNames: Record<ActivityType, string> = {
[ActivityType.LOGIN]: '登录', [ActivityType.LOGIN]: '登录',
[ActivityType.WORKOUT]: '训练', [ActivityType.GOAL]: '目标任务完成',
[ActivityType.DIET_RECORD]: '饮食记录', [ActivityType.DIET_RECORD]: '饮食记录',
[ActivityType.WEIGHT_RECORD]: '体重记录', [ActivityType.WEIGHT_RECORD]: '体重记录',
[ActivityType.PROFILE_UPDATE]: '资料更新', [ActivityType.PROFILE_UPDATE]: '资料更新',
@@ -77,7 +77,7 @@ export class UserActivity extends SequelizeModel<UserActivityAttributes, UserAct
@Column({ @Column({
type: DataType.TINYINT, type: DataType.TINYINT,
allowNull: false, allowNull: false,
comment: '活跃类型1-登录2-训练3-饮食记录4-体重记录5-资料更新6-打卡', comment: '活跃类型1-登录2-目标任务完成3-饮食记录4-体重记录5-资料更新6-打卡',
}) })
activityType!: ActivityType; activityType!: ActivityType;

View File

@@ -40,6 +40,6 @@ import { ActivityLogsModule } from '../activity-logs/activity-logs.module';
], ],
controllers: [UsersController], controllers: [UsersController],
providers: [UsersService, ApplePurchaseService, EncryptionService, AppleAuthService, CosService, UserActivityService], providers: [UsersService, ApplePurchaseService, EncryptionService, AppleAuthService, CosService, UserActivityService],
exports: [UsersService, AppleAuthService], exports: [UsersService, AppleAuthService, UserActivityService],
}) })
export class UsersModule { } export class UsersModule { }