feat: 新增体重记录接口及枚举,优化AI教练选择项处理

This commit is contained in:
richarjiang
2025-08-28 09:46:03 +08:00
parent e3cd496f33
commit 17ee96638e
6 changed files with 277 additions and 13 deletions

View File

@@ -216,12 +216,13 @@ export class UsersService {
await user.save();
const [profile] = await this.userProfileModel.findOrCreate({
where: { userId },
defaults: { userId },
});
// 更新或创建扩展信息
if (dailyStepsGoal !== undefined || dailyCaloriesGoal !== undefined || pilatesPurposes !== undefined || weight !== undefined || initialWeight !== undefined || targetWeight !== undefined || height !== undefined || activityLevel !== undefined) {
const [profile] = await this.userProfileModel.findOrCreate({
where: { userId },
defaults: { userId },
});
if (dailyStepsGoal !== undefined) { profile.dailyStepsGoal = dailyStepsGoal as any; profileChanges.dailyStepsGoal = dailyStepsGoal; }
if (dailyCaloriesGoal !== undefined) { profile.dailyCaloriesGoal = dailyCaloriesGoal as any; profileChanges.dailyCaloriesGoal = dailyCaloriesGoal; }
if (pilatesPurposes !== undefined) { profile.pilatesPurposes = pilatesPurposes as any; profileChanges.pilatesPurposes = pilatesPurposes; }
@@ -278,6 +279,7 @@ export class UsersService {
message: 'success',
data: {
...user.toJSON(),
...profile.toJSON(),
isNew: false,
} as any,
};
@@ -318,7 +320,156 @@ export class UsersService {
order: [['created_at', 'DESC']],
limit,
});
return rows.map(r => ({ weight: r.weight, source: r.source, createdAt: r.createdAt }));
return rows.map(r => ({
id: r.id,
weight: r.weight,
source: r.source,
createdAt: r.createdAt
}));
}
/**
* 更新体重记录
*/
async updateWeightRecord(userId: string, recordId: number, updateData: { weight: number; source?: WeightUpdateSource }) {
const t = await this.sequelize.transaction();
try {
// 查找并验证体重记录是否存在且属于当前用户
const weightRecord = await this.userWeightHistoryModel.findOne({
where: { id: recordId, userId },
transaction: t,
});
if (!weightRecord) {
throw new NotFoundException('体重记录不存在');
}
const oldWeight = weightRecord.weight;
const oldSource = weightRecord.source;
// 更新体重记录
await weightRecord.update({
weight: updateData.weight,
source: updateData.source || weightRecord.source,
}, { transaction: t });
// 如果这是最新的体重记录,同时更新用户档案中的体重
const latestRecord = await this.userWeightHistoryModel.findOne({
where: { userId },
order: [['created_at', 'DESC']],
transaction: t,
});
if (latestRecord && latestRecord.id === recordId) {
const profile = await this.userProfileModel.findOne({
where: { userId },
transaction: t,
});
if (profile) {
profile.weight = updateData.weight;
await profile.save({ transaction: t });
}
}
await t.commit();
// 记录活动日志
await this.activityLogsService.record({
userId,
entityType: ActivityEntityType.USER_PROFILE,
action: ActivityActionType.UPDATE,
entityId: recordId.toString(),
changes: {
weight: { from: oldWeight, to: updateData.weight },
...(updateData.source && updateData.source !== oldSource ? { source: { from: oldSource, to: updateData.source } } : {}),
},
});
return {
code: ResponseCode.SUCCESS,
message: 'success',
data: {
id: weightRecord.id,
userId: weightRecord.userId,
weight: weightRecord.weight,
source: weightRecord.source,
createdAt: weightRecord.createdAt,
updatedAt: weightRecord.updatedAt,
},
};
} catch (error) {
await t.rollback();
this.logger.error(`更新体重记录失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
/**
* 删除体重记录
*/
async deleteWeightRecord(userId: string, recordId: number): Promise<boolean> {
const t = await this.sequelize.transaction();
try {
// 查找并验证体重记录是否存在且属于当前用户
const weightRecord = await this.userWeightHistoryModel.findOne({
where: { id: recordId, userId },
transaction: t,
});
if (!weightRecord) {
return false;
}
const recordData = {
id: weightRecord.id,
weight: weightRecord.weight,
source: weightRecord.source,
createdAt: weightRecord.createdAt,
};
// 删除体重记录
await weightRecord.destroy({ transaction: t });
// 如果删除的是最新记录,需要更新用户档案中的体重为倒数第二新的记录
const latestRecord = await this.userWeightHistoryModel.findOne({
where: { userId },
order: [['created_at', 'DESC']],
transaction: t,
});
const profile = await this.userProfileModel.findOne({
where: { userId },
transaction: t,
});
if (profile) {
if (latestRecord) {
// 有其他体重记录,更新为最新的体重
profile.weight = latestRecord.weight;
} else {
// 没有其他体重记录,清空体重字段
profile.weight = null;
}
await profile.save({ transaction: t });
}
await t.commit();
// 记录活动日志
await this.activityLogsService.record({
userId,
entityType: ActivityEntityType.USER_PROFILE,
action: ActivityActionType.DELETE,
entityId: recordId.toString(),
changes: recordData,
});
return true;
} catch (error) {
await t.rollback();
this.logger.error(`删除体重记录失败: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
}
/**