fix(db): 统一字符集排序规则并修复时间戳类型
- 新增 SQL 脚本统一表与列字符集为 utf8mb4_unicode_ci - 移除建表语句冗余 COLLATE 子句,由全局配置控制 - 将挑战起止时间字段由 Date 改为 BIGINT 时间戳,避免时区与精度问题 - 补充 Winston 日志追踪挑战详情查询性能 - 数据库模块新增 charset 与 collate 全局配置,确保后续表一致性 BREAKING CHANGE: challenge.startAt/endAt 由 Date 变更为 number(毫秒时间戳),调用方需同步调整类型
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Injectable, NotFoundException, BadRequestException, ConflictException } from '@nestjs/common';
|
||||
import { Injectable, NotFoundException, BadRequestException, ConflictException, Inject } from '@nestjs/common';
|
||||
import { InjectModel } from '@nestjs/sequelize';
|
||||
import { Challenge, ChallengeStatus } from './models/challenge.model';
|
||||
import { ChallengeParticipant, ChallengeParticipantStatus } from './models/challenge-participant.model';
|
||||
@@ -10,10 +10,15 @@ import { ChallengeProgressDto, RankingItemDto } from './dto/challenge-progress.d
|
||||
import { fn, col, Op, UniqueConstraintError } from 'sequelize';
|
||||
import * as dayjs from 'dayjs';
|
||||
import { User } from '../users/models/user.model';
|
||||
import { WINSTON_MODULE_PROVIDER } from 'nest-winston';
|
||||
import { Logger as WinstonLogger } from 'winston';
|
||||
|
||||
@Injectable()
|
||||
export class ChallengesService {
|
||||
|
||||
constructor(
|
||||
@Inject(WINSTON_MODULE_PROVIDER) private readonly winstonLogger: WinstonLogger,
|
||||
|
||||
@InjectModel(Challenge)
|
||||
private readonly challengeModel: typeof Challenge,
|
||||
@InjectModel(ChallengeParticipant)
|
||||
@@ -100,6 +105,13 @@ export class ChallengesService {
|
||||
throw new NotFoundException('挑战不存在');
|
||||
}
|
||||
|
||||
this.winstonLogger.info('start get detail', {
|
||||
context: 'getChallengeDetail',
|
||||
userId,
|
||||
challengeId,
|
||||
});
|
||||
|
||||
|
||||
const [participantsCount, participation] = await Promise.all([
|
||||
this.participantModel.count({
|
||||
where: {
|
||||
@@ -118,6 +130,15 @@ export class ChallengesService {
|
||||
}),
|
||||
]);
|
||||
|
||||
this.winstonLogger.info('end get detail', {
|
||||
context: 'getChallengeDetail',
|
||||
userId,
|
||||
challengeId,
|
||||
participantsCount,
|
||||
participation,
|
||||
});
|
||||
|
||||
|
||||
const rankingsRaw = await this.participantModel.findAll({
|
||||
where: {
|
||||
challengeId,
|
||||
@@ -131,6 +152,15 @@ export class ChallengesService {
|
||||
limit: 10,
|
||||
});
|
||||
|
||||
this.winstonLogger.info('get rankingsRaw end', {
|
||||
context: 'getChallengeDetail',
|
||||
userId,
|
||||
challengeId,
|
||||
participantsCount,
|
||||
participation,
|
||||
rankingsRawCount: rankingsRaw.length,
|
||||
});
|
||||
|
||||
const progress = participation
|
||||
? this.buildChallengeProgress(participation.progressValue, participation.targetValue, challenge.progressUnit)
|
||||
: undefined;
|
||||
@@ -333,7 +363,7 @@ export class ChallengesService {
|
||||
};
|
||||
}
|
||||
|
||||
private computeStatus(startAt: Date, endAt: Date): ChallengeStatus {
|
||||
private computeStatus(startAt: number, endAt: number): ChallengeStatus {
|
||||
const now = dayjs();
|
||||
const start = dayjs(startAt);
|
||||
const end = dayjs(endAt);
|
||||
|
||||
Reference in New Issue
Block a user