This commit is contained in:
qq
2026-04-21 22:34:39 +08:00
commit c28429b589
718 changed files with 48804 additions and 0 deletions
+354
View File
@@ -0,0 +1,354 @@
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.SignInService = void 0;
const common_1 = require("@nestjs/common");
const typeorm_1 = require("@nestjs/typeorm");
const typeorm_2 = require("typeorm");
const user_sign_in_model_1 = require("../../../model/user_sign_in.model");
const user_sign_in_calendar_model_1 = require("../../../model/user_sign_in_calendar.model");
const user_sign_in_task_model_1 = require("../../../model/user_sign_in_task.model");
const user_sign_in_task_reward_model_1 = require("../../../model/user_sign_in_task_reward.model");
const user_financial_product_model_1 = require("../../../model/user_financial_product.model");
const api_1 = require("../../common/api");
const signin_vo_1 = require("../vo/signin.vo");
const user_id_context_1 = require("../../common/context/user_id.context");
const data_source_context_1 = require("../../common/context/data_source.context");
const help_1 = require("../../common/util/help");
const financial_product_model_1 = require("../../../model/financial_product.model");
let SignInService = class SignInService {
userSignInModel;
userSignInCalendarModel;
userSignInTaskModel;
userSignInTaskRewardModel;
userFinancialProductModel;
dataSource;
constructor(userSignInModel, userSignInCalendarModel, userSignInTaskModel, userSignInTaskRewardModel, userFinancialProductModel, dataSource) {
this.userSignInModel = userSignInModel;
this.userSignInCalendarModel = userSignInCalendarModel;
this.userSignInTaskModel = userSignInTaskModel;
this.userSignInTaskRewardModel = userSignInTaskRewardModel;
this.userFinancialProductModel = userFinancialProductModel;
this.dataSource = dataSource;
}
async getSignInInfo(userId) {
const signInStats = await this.userSignInModel.findOne({
where: { userId },
});
const nowYYYMMDD = help_1.Help.formatDate(Date.now(), 'YYYY-MM-DD');
return api_1.Api.success({
...signInStats,
signToDay: nowYYYMMDD == signInStats?.lastSignInDate,
});
}
async getSignInCalendar(userId, year, month) {
const firstDay = `${year}-${String(month).padStart(2, '0')}-01`;
const lastDay = new Date(year, month, 0).toISOString().split('T')[0];
const signInRecords = await this.userSignInCalendarModel.find({
where: {
userId,
signInDate: (0, typeorm_2.Between)(firstDay, lastDay),
},
order: { signInDate: 'ASC' },
});
return api_1.Api.pagination(signInRecords, signInRecords.length);
}
async getProgress() {
const userId = (0, user_id_context_1.getUserIdContext)();
const userSignIn = await this.userSignInModel.findOneByOrFail({
userId,
});
const existFirst = userSignIn.firstSignInDate != null;
const nowDate = new Date();
const nowYYYMMDD = help_1.Help.formatDate(nowDate, 'YYYY-MM-DD');
const startDate = new Date();
startDate.setDate(startDate.getDate() - (existFirst ? 3 : 0));
let startYYYMMDD = help_1.Help.formatDate(startDate, 'YYYY-MM-DD');
const firstSignDate = userSignIn.firstSignInDate || nowYYYMMDD;
if (firstSignDate > startYYYMMDD) {
startYYYMMDD = firstSignDate;
}
const signInCalendars = await this.userSignInCalendarModel.find({
where: {
userId,
signInDate: (0, typeorm_2.Between)(startYYYMMDD, nowYYYMMDD),
},
});
const signedDates = new Map();
signInCalendars.forEach((it) => {
signedDates.set(it.signInDate, it);
});
const dates = [];
const current = new Date(startYYYMMDD);
const endDate = new Date(startYYYMMDD);
endDate.setDate(endDate.getDate() + 6);
while (current <= endDate) {
const dateStr = help_1.Help.formatDate(current, 'YYYY-MM-DD');
dates.push(dateStr);
current.setDate(current.getDate() + 1);
}
return api_1.Api.pagination(dates.map((date) => {
const vo = new signin_vo_1.SignInProgressDayVo();
vo.date = date;
vo.isFutureDay = date > nowYYYMMDD;
vo.signedIn = signedDates.has(date);
vo.isMakeUp = signedDates.get(date)?.isMakeUp || user_sign_in_calendar_model_1.SignInType.Normal;
vo.isDay = date == nowYYYMMDD;
vo.consecutiveDay = help_1.Help.diffDays(date, firstSignDate) + 1;
return vo;
}), 0);
}
async getTaskList(userId) {
const tasks = await this.userSignInTaskModel.find({
order: { requiredDays: 'ASC' },
});
if (tasks.length === 0) {
return api_1.Api.success([]);
}
const taskIds = tasks.map((t) => t.id);
const rewards = await this.userSignInTaskRewardModel.find({
where: {
userId,
userSignInTaskId: (0, typeorm_2.In)(taskIds),
},
});
const rewardMap = new Map();
for (const reward of rewards) {
rewardMap.set(reward.userSignInTaskId, reward);
}
const taskList = tasks.map((task) => {
const reward = rewardMap.get(task.id);
if (reward) {
const status = reward.claimStatus === user_sign_in_task_reward_model_1.ClaimStatus.Claimed
? signin_vo_1.TaskStatus.Completed
: signin_vo_1.TaskStatus.Pending;
return {
id: task.id,
title: task.title,
subtitle: task.subtitle,
requiredDays: task.requiredDays,
icon: task.icon,
status,
rewardId: reward.id,
};
}
return {
id: task.id,
title: task.title,
subtitle: task.subtitle,
requiredDays: task.requiredDays,
icon: task.icon,
status: signin_vo_1.TaskStatus.InProgress,
rewardId: undefined,
};
});
return api_1.Api.pagination(taskList, taskList.length);
}
async todaySignIn(userId) {
const nowYYYMMDD = help_1.Help.formatDate(Date.now(), 'YYYY-MM-DD');
const signInStats = await this.userSignInModel.findOneOrFail({
where: { userId },
});
if (signInStats && signInStats.lastSignInDate === nowYYYMMDD) {
return api_1.Api.error('今日已签到');
}
const yesterday = help_1.Help.formatDate(new Date(Date.now() - 86400000), 'YYYY-MM-DD');
let consecutiveDays = 1;
if (signInStats && signInStats.lastSignInDate === yesterday) {
consecutiveDays = signInStats.consecutiveDays + 1;
}
else {
consecutiveDays = 1;
}
await data_source_context_1.DataSourceContext.startTransaction(async (tx) => {
const signInRepo = tx.getRepository(user_sign_in_model_1.UserSignInModel);
const calendarRepo = tx.getRepository(user_sign_in_calendar_model_1.UserSignInCalendarModel);
const taskRepo = tx.getRepository(user_sign_in_task_model_1.UserSignInTaskModel);
const rewardRepo = tx.getRepository(user_sign_in_task_reward_model_1.UserSignInTaskRewardModel);
await signInRepo.update({ userId }, {
lastSignInDate: nowYYYMMDD,
consecutiveDays,
});
const calendarRecord = calendarRepo.create({
userId,
signInDate: nowYYYMMDD,
isMakeUp: user_sign_in_calendar_model_1.SignInType.Normal,
});
await calendarRepo.save(calendarRecord);
const tasks = await taskRepo.find({
order: { requiredDays: 'ASC' },
});
for (const task of tasks) {
if (consecutiveDays >= task.requiredDays) {
const existingReward = await rewardRepo.findOne({
where: {
userId,
userSignInTaskId: task.id,
},
});
if (!existingReward) {
const reward = rewardRepo.create({
userId,
userSignInTaskId: task.id,
title: task.title,
subtitle: task.subtitle,
requiredDays: task.requiredDays,
icon: task.icon,
financialProductId: task.financialProductId,
claimStatus: user_sign_in_task_reward_model_1.ClaimStatus.Pending,
});
await rewardRepo.save(reward);
}
}
}
});
return api_1.Api.successMsg('签到成功');
}
async makeUpSignIn(userId, date) {
const nowYYYMMDD = help_1.Help.formatDate(Date.now(), 'YYYY-MM-DD');
if (date >= nowYYYMMDD) {
return api_1.Api.error('只能补签今天之前的日期');
}
const signInStats = await this.userSignInModel.findOneOrFail({
where: { userId },
});
const existingRecord = await this.userSignInCalendarModel.findOne({
where: { userId, signInDate: date },
});
if (existingRecord) {
return api_1.Api.error('该日期已签到,无需补签');
}
const makeUpCount = signInStats.makeUpCount;
if (makeUpCount <= 0) {
return api_1.Api.error('补签次数已用完');
}
if (!signInStats.lastSignInDate) {
return api_1.Api.error('请先完成首次签到');
}
await data_source_context_1.DataSourceContext.startTransaction(async (tx) => {
const calendarRepo = tx.getRepository(user_sign_in_calendar_model_1.UserSignInCalendarModel);
const signInRepo = tx.getRepository(user_sign_in_model_1.UserSignInModel);
const taskRepo = tx.getRepository(user_sign_in_task_model_1.UserSignInTaskModel);
const rewardRepo = tx.getRepository(user_sign_in_task_reward_model_1.UserSignInTaskRewardModel);
const calendarRecord = calendarRepo.create({
userId,
signInDate: date,
isMakeUp: user_sign_in_calendar_model_1.SignInType.MakeUp,
});
await calendarRepo.save(calendarRecord);
const newConsecutiveDays = await this.calcConsecutiveDays(tx, userId, signInStats.lastSignInDate, signInStats.consecutiveDays);
await signInRepo.update({ userId }, {
consecutiveDays: newConsecutiveDays,
makeUpCount: () => `makeUpCount - 1`,
usedMakeUpCount: () => `usedMakeUpCount + 1`,
});
const tasks = await taskRepo.find({
order: { requiredDays: 'ASC' },
});
for (const task of tasks) {
if (newConsecutiveDays >= task.requiredDays) {
const existingReward = await rewardRepo.findOne({
where: {
userId,
userSignInTaskId: task.id,
},
});
if (!existingReward) {
const reward = rewardRepo.create({
userId,
userSignInTaskId: task.id,
title: task.title,
subtitle: task.subtitle,
requiredDays: task.requiredDays,
icon: task.icon,
financialProductId: task.financialProductId,
claimStatus: user_sign_in_task_reward_model_1.ClaimStatus.Pending,
});
await rewardRepo.save(reward);
}
}
}
});
return api_1.Api.successMsg('补签成功');
}
async calcConsecutiveDays(tx, userId, endDate, expectedDays) {
const startDate = help_1.Help.formatDate(new Date(endDate).getTime() - expectedDays * 86400000, 'YYYY-MM-DD');
const calendarRepo = tx.getRepository(user_sign_in_calendar_model_1.UserSignInCalendarModel);
const count = await calendarRepo.count({
where: {
userId,
signInDate: (0, typeorm_2.Between)(startDate, endDate),
},
});
return count === expectedDays + 1 ? expectedDays + 1 : expectedDays;
}
async claimReward(userId, rewardId) {
await data_source_context_1.DataSourceContext.startTransaction(async (tx) => {
const rewardRepo = tx.getRepository(user_sign_in_task_reward_model_1.UserSignInTaskRewardModel);
const financialProductRepo = tx.getRepository(financial_product_model_1.FinancialProductModel);
const financialRepo = tx.getRepository(user_financial_product_model_1.UserFinancialProductModel);
const reward = await rewardRepo.findOne({
where: { id: rewardId, userId },
});
if (!reward) {
throw new Error('奖励记录不存在');
}
if (reward.claimStatus === user_sign_in_task_reward_model_1.ClaimStatus.Claimed) {
throw new Error('该奖励已领取');
}
const financialProduct = await financialProductRepo.findOneBy({
id: reward.financialProductId,
});
if (!financialProduct) {
throw new Error('理财产品不存在');
}
const now = Date.now();
const periodDays = financialProduct.period;
const expireTime = Math.floor((now + periodDays * 86400000) / 1000);
const userFinancialProduct = financialRepo.create({
userId,
financialProductId: reward.financialProductId,
name: reward.title,
period: periodDays,
principal: financialProduct.principal,
yieldRate: financialProduct.yieldRate,
source: user_financial_product_model_1.HoldingSource.Gift,
status: user_financial_product_model_1.HoldingStatus.Earning,
expireTime,
});
await financialRepo.save(userFinancialProduct);
await rewardRepo.update({ id: rewardId }, {
userFinancialProductId: userFinancialProduct.id,
claimStatus: user_sign_in_task_reward_model_1.ClaimStatus.Claimed,
});
});
return api_1.Api.successMsg('领取成功');
}
};
exports.SignInService = SignInService;
exports.SignInService = SignInService = __decorate([
(0, common_1.Injectable)(),
__param(0, (0, typeorm_1.InjectRepository)(user_sign_in_model_1.UserSignInModel)),
__param(1, (0, typeorm_1.InjectRepository)(user_sign_in_calendar_model_1.UserSignInCalendarModel)),
__param(2, (0, typeorm_1.InjectRepository)(user_sign_in_task_model_1.UserSignInTaskModel)),
__param(3, (0, typeorm_1.InjectRepository)(user_sign_in_task_reward_model_1.UserSignInTaskRewardModel)),
__param(4, (0, typeorm_1.InjectRepository)(user_financial_product_model_1.UserFinancialProductModel)),
__metadata("design:paramtypes", [typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.Repository,
typeorm_2.DataSource])
], SignInService);
//# sourceMappingURL=signin.service.js.map