feat: 支持新的关卡数据结构
This commit is contained in:
@@ -1,5 +1,11 @@
|
||||
import { ApiProperty } from '@nestjs/swagger';
|
||||
import { IsBoolean, IsNotEmpty, IsNumber, IsString, Min } from 'class-validator';
|
||||
import {
|
||||
IsBoolean,
|
||||
IsNotEmpty,
|
||||
IsNumber,
|
||||
IsString,
|
||||
Min,
|
||||
} from 'class-validator';
|
||||
|
||||
export class ReportLevelProgressDto {
|
||||
@ApiProperty({ description: '分享码' })
|
||||
|
||||
@@ -18,12 +18,24 @@ export class ShareLevelDto {
|
||||
@ApiProperty()
|
||||
level!: number;
|
||||
|
||||
@ApiProperty()
|
||||
imageUrl!: string;
|
||||
@ApiProperty({ description: '图片1 URL' })
|
||||
image1Url!: string;
|
||||
|
||||
@ApiProperty({ description: '图片1 文本说明', nullable: true })
|
||||
image1Description!: string | null;
|
||||
|
||||
@ApiProperty({ description: '图片2 URL' })
|
||||
image2Url!: string;
|
||||
|
||||
@ApiProperty({ description: '图片2 文本说明', nullable: true })
|
||||
image2Description!: string | null;
|
||||
|
||||
@ApiProperty()
|
||||
answer!: string;
|
||||
|
||||
@ApiProperty({ description: '谐音梗说明', nullable: true })
|
||||
punchline!: string | null;
|
||||
|
||||
@ApiProperty({ nullable: true })
|
||||
hint1!: string | null;
|
||||
|
||||
|
||||
@@ -38,6 +38,11 @@ export class ShareLevelProgress {
|
||||
@Column({ type: 'int', default: 0, name: 'time_spent' })
|
||||
timeSpent!: number;
|
||||
|
||||
@Column({ type: 'timestamp', name: 'completed_at', nullable: true, default: null })
|
||||
@Column({
|
||||
type: 'timestamp',
|
||||
name: 'completed_at',
|
||||
nullable: true,
|
||||
default: null,
|
||||
})
|
||||
completedAt!: Date | null;
|
||||
}
|
||||
|
||||
@@ -21,8 +21,12 @@ describe('ShareService', () => {
|
||||
|
||||
const mockLevels: Level[] = Array.from({ length: 6 }, (_, i) => ({
|
||||
id: `level-${i + 1}`,
|
||||
imageUrl: `https://example.com/meme${i + 1}.jpg`,
|
||||
image1Url: `https://example.com/meme${i + 1}_1.jpg`,
|
||||
image1Description: null,
|
||||
image2Url: `https://example.com/meme${i + 1}_2.jpg`,
|
||||
image2Description: null,
|
||||
answer: `答案${i + 1}`,
|
||||
punchline: null,
|
||||
hint1: `提示${i + 1}`,
|
||||
hint2: null,
|
||||
hint3: null,
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ShareConfigRepository } from './repositories/share-config.repository';
|
||||
import { ShareParticipantRepository } from './repositories/share-participant.repository';
|
||||
import { ShareLevelProgressRepository } from './repositories/share-level-progress.repository';
|
||||
import { LevelRepository } from '../wechat-game/repositories/level.repository';
|
||||
import { pickLevelImageFields } from '../wechat-game/level-fields.helper';
|
||||
import { CreateShareDto } from './dto/create-share.dto';
|
||||
import { ReportLevelProgressDto } from './dto/report-level-progress.dto';
|
||||
import {
|
||||
@@ -83,7 +84,7 @@ export class ShareService {
|
||||
await this.shareParticipantRepository.addParticipant(config.id, userId);
|
||||
}
|
||||
|
||||
// 单次查询获取所有关卡,再按 levelIds 顺序排列
|
||||
// Single query, then reorder to match levelIds sequence
|
||||
const allLevels = await this.levelRepository.findByIds(config.levelIds);
|
||||
const levelMap = new Map(allLevels.map((l) => [l.id, l]));
|
||||
|
||||
@@ -95,11 +96,8 @@ export class ShareService {
|
||||
return {
|
||||
id: level.id,
|
||||
level: index + 1,
|
||||
imageUrl: level.imageUrl,
|
||||
...pickLevelImageFields(level),
|
||||
answer: level.answer,
|
||||
hint1: level.hint1,
|
||||
hint2: level.hint2,
|
||||
hint3: level.hint3,
|
||||
sortOrder: level.sortOrder,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user