perf: 优化类型问题
This commit is contained in:
@@ -1,10 +1,5 @@
|
|||||||
import { plainToInstance } from 'class-transformer';
|
import { plainToInstance } from 'class-transformer';
|
||||||
import {
|
import { IsEnum, IsNumber, IsString, validateSync } from 'class-validator';
|
||||||
IsEnum,
|
|
||||||
IsNumber,
|
|
||||||
IsString,
|
|
||||||
validateSync,
|
|
||||||
} from 'class-validator';
|
|
||||||
|
|
||||||
enum Environment {
|
enum Environment {
|
||||||
Development = 'development',
|
Development = 'development',
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ export class AuthService {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (existing) {
|
if (existing) {
|
||||||
this.logger.warn(
|
this.logger.warn(`用户 ${userId} 已完成关卡 ${dto.levelId},不重复奖励`);
|
||||||
`用户 ${userId} 已完成关卡 ${dto.levelId},不重复奖励`,
|
|
||||||
);
|
|
||||||
return { points: user.points };
|
return { points: user.points };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { IsIn, IsNotEmpty, IsOptional, IsString } from 'class-validator';
|
|||||||
|
|
||||||
export class UserAssetsResponseDto {
|
export class UserAssetsResponseDto {
|
||||||
@ApiProperty({ description: '积分' })
|
@ApiProperty({ description: '积分' })
|
||||||
points: number;
|
points!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConsumePointRequestDto {
|
export class ConsumePointRequestDto {
|
||||||
@@ -11,7 +11,7 @@ export class ConsumePointRequestDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsIn(['hint_unlock'])
|
@IsIn(['hint_unlock'])
|
||||||
reason: 'hint_unlock';
|
reason!: 'hint_unlock';
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡 ID', required: false })
|
@ApiProperty({ description: '关卡 ID', required: false })
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -28,21 +28,21 @@ export class EarnPointRequestDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
@IsIn(['level_complete'])
|
@IsIn(['level_complete'])
|
||||||
reason: 'level_complete';
|
reason!: 'level_complete';
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡 ID' })
|
@ApiProperty({ description: '关卡 ID' })
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
levelId: string;
|
levelId!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GameDataResponseDto {
|
export class GameDataResponseDto {
|
||||||
@ApiProperty({ description: '用户信息' })
|
@ApiProperty({ description: '用户信息' })
|
||||||
user: {
|
user!: {
|
||||||
id: string;
|
id: string;
|
||||||
points: number;
|
points: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ApiProperty({ description: '已完成的关卡 ID 列表' })
|
@ApiProperty({ description: '已完成的关卡 ID 列表' })
|
||||||
completedLevelIds: string[];
|
completedLevelIds!: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,24 +5,24 @@ export class WxLoginRequestDto {
|
|||||||
@ApiProperty({ description: '微信 wx.login 返回的 code' })
|
@ApiProperty({ description: '微信 wx.login 返回的 code' })
|
||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty()
|
@IsNotEmpty()
|
||||||
code: string;
|
code!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class UserInfoDto {
|
export class UserInfoDto {
|
||||||
@ApiProperty({ description: '用户 ID' })
|
@ApiProperty({ description: '用户 ID' })
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '用户昵称', nullable: true })
|
@ApiProperty({ description: '用户昵称', nullable: true })
|
||||||
nickname: string | null;
|
nickname!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ description: '积分' })
|
@ApiProperty({ description: '积分' })
|
||||||
points: number;
|
points!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class WxLoginResponseDto {
|
export class WxLoginResponseDto {
|
||||||
@ApiProperty({ description: 'JWT 访问令牌' })
|
@ApiProperty({ description: 'JWT 访问令牌' })
|
||||||
token: string;
|
token!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '用户信息' })
|
@ApiProperty({ description: '用户信息' })
|
||||||
user: UserInfoDto;
|
user!: UserInfoDto;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,18 +13,18 @@ import { User } from './user.entity';
|
|||||||
@Index('idx_user_level', ['userId', 'levelId'], { unique: true })
|
@Index('idx_user_level', ['userId', 'levelId'], { unique: true })
|
||||||
export class UserLevelProgress {
|
export class UserLevelProgress {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, name: 'user_id' })
|
@Column({ type: 'varchar', length: 191, name: 'user_id' })
|
||||||
userId: string;
|
userId!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, name: 'level_id' })
|
@Column({ type: 'varchar', length: 191, name: 'level_id' })
|
||||||
levelId: string;
|
levelId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => User)
|
@ManyToOne(() => User)
|
||||||
@JoinColumn({ name: 'user_id' })
|
@JoinColumn({ name: 'user_id' })
|
||||||
user: User;
|
user!: User;
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'completed_at' })
|
@CreateDateColumn({ name: 'completed_at' })
|
||||||
completedAt: Date;
|
completedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,28 +10,28 @@ import {
|
|||||||
@Entity('wx_users')
|
@Entity('wx_users')
|
||||||
export class User {
|
export class User {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Index('idx_user_openid', { unique: true })
|
@Index('idx_user_openid', { unique: true })
|
||||||
@Column({ type: 'varchar', length: 128 })
|
@Column({ type: 'varchar', length: 128 })
|
||||||
openid: string;
|
openid!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 255, name: 'session_key', nullable: true })
|
@Column({ type: 'varchar', length: 255, name: 'session_key', nullable: true })
|
||||||
sessionKey: string | null;
|
sessionKey!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100, nullable: true })
|
@Column({ type: 'varchar', length: 100, nullable: true })
|
||||||
nickname: string | null;
|
nickname!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'text', name: 'avatar_url', nullable: true })
|
@Column({ type: 'text', name: 'avatar_url', nullable: true })
|
||||||
avatarUrl: string | null;
|
avatarUrl!: string | null;
|
||||||
|
|
||||||
/** 积分(默认 10) */
|
/** 积分(默认 10) */
|
||||||
@Column({ type: 'int', default: 10 })
|
@Column({ type: 'int', default: 10 })
|
||||||
points: number;
|
points!: number;
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'created_at' })
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ name: 'updated_at' })
|
@UpdateDateColumn({ name: 'updated_at' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ import { UserLevelProgress } from '../entities/user-level-progress.entity';
|
|||||||
import { IUserLevelProgressRepository } from './user-level-progress.repository.interface';
|
import { IUserLevelProgressRepository } from './user-level-progress.repository.interface';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class UserLevelProgressRepository
|
export class UserLevelProgressRepository implements IUserLevelProgressRepository {
|
||||||
implements IUserLevelProgressRepository
|
|
||||||
{
|
|
||||||
constructor(
|
constructor(
|
||||||
@InjectRepository(UserLevelProgress)
|
@InjectRepository(UserLevelProgress)
|
||||||
private readonly repository: Repository<UserLevelProgress>,
|
private readonly repository: Repository<UserLevelProgress>,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export class CreateShareDto {
|
|||||||
@IsString()
|
@IsString()
|
||||||
@IsNotEmpty({ message: '标题不能为空' })
|
@IsNotEmpty({ message: '标题不能为空' })
|
||||||
@MaxLength(100, { message: '标题不能超过100个字符' })
|
@MaxLength(100, { message: '标题不能超过100个字符' })
|
||||||
title: string;
|
title!: string;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
description: '6个关卡ID',
|
description: '6个关卡ID',
|
||||||
@@ -23,5 +23,5 @@ export class CreateShareDto {
|
|||||||
@ArrayMinSize(6, { message: '需要恰好6个关卡' })
|
@ArrayMinSize(6, { message: '需要恰好6个关卡' })
|
||||||
@ArrayMaxSize(6, { message: '需要恰好6个关卡' })
|
@ArrayMaxSize(6, { message: '需要恰好6个关卡' })
|
||||||
@IsString({ each: true })
|
@IsString({ each: true })
|
||||||
levelIds: string[];
|
levelIds!: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,48 +2,48 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
|
|
||||||
export class CreateShareResponseDto {
|
export class CreateShareResponseDto {
|
||||||
@ApiProperty({ description: '分享码' })
|
@ApiProperty({ description: '分享码' })
|
||||||
shareCode: string;
|
shareCode!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '分享标题' })
|
@ApiProperty({ description: '分享标题' })
|
||||||
title: string;
|
title!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡数量' })
|
@ApiProperty({ description: '关卡数量' })
|
||||||
levelCount: number;
|
levelCount!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ShareLevelDto {
|
export class ShareLevelDto {
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
level: number;
|
level!: number;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
imageUrl: string;
|
imageUrl!: string;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
answer: string;
|
answer!: string;
|
||||||
|
|
||||||
@ApiProperty({ nullable: true })
|
@ApiProperty({ nullable: true })
|
||||||
hint1: string | null;
|
hint1!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ nullable: true })
|
@ApiProperty({ nullable: true })
|
||||||
hint2: string | null;
|
hint2!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ nullable: true })
|
@ApiProperty({ nullable: true })
|
||||||
hint3: string | null;
|
hint3!: string | null;
|
||||||
|
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
sortOrder: number;
|
sortOrder!: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class JoinShareResponseDto {
|
export class JoinShareResponseDto {
|
||||||
@ApiProperty({ description: '分享码' })
|
@ApiProperty({ description: '分享码' })
|
||||||
shareCode: string;
|
shareCode!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '分享标题' })
|
@ApiProperty({ description: '分享标题' })
|
||||||
title: string;
|
title!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡列表', type: [ShareLevelDto] })
|
@ApiProperty({ description: '关卡列表', type: [ShareLevelDto] })
|
||||||
levels: ShareLevelDto[];
|
levels!: ShareLevelDto[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,32 +15,32 @@ import { ShareParticipant } from './share-participant.entity';
|
|||||||
@Entity('share_configs')
|
@Entity('share_configs')
|
||||||
export class ShareConfig {
|
export class ShareConfig {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Index('idx_share_code', { unique: true })
|
@Index('idx_share_code', { unique: true })
|
||||||
@Column({ type: 'varchar', length: 8, name: 'share_code' })
|
@Column({ type: 'varchar', length: 8, name: 'share_code' })
|
||||||
shareCode: string;
|
shareCode!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 100 })
|
@Column({ type: 'varchar', length: 100 })
|
||||||
title: string;
|
title!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, name: 'sharer_id' })
|
@Column({ type: 'varchar', length: 191, name: 'sharer_id' })
|
||||||
sharerId: string;
|
sharerId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => User)
|
@ManyToOne(() => User)
|
||||||
@JoinColumn({ name: 'sharer_id' })
|
@JoinColumn({ name: 'sharer_id' })
|
||||||
sharer: User;
|
sharer!: User;
|
||||||
|
|
||||||
/** 有序 JSON 数组,存储 6 个关卡 ID */
|
/** 有序 JSON 数组,存储 6 个关卡 ID */
|
||||||
@Column({ type: 'json', name: 'level_ids' })
|
@Column({ type: 'json', name: 'level_ids' })
|
||||||
levelIds: string[];
|
levelIds!: string[];
|
||||||
|
|
||||||
@OneToMany(() => ShareParticipant, (p) => p.shareConfig)
|
@OneToMany(() => ShareParticipant, (p) => p.shareConfig)
|
||||||
participants: ShareParticipant[];
|
participants!: ShareParticipant[];
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'created_at' })
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ name: 'updated_at' })
|
@UpdateDateColumn({ name: 'updated_at' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,23 +15,23 @@ import { ShareConfig } from './share-config.entity';
|
|||||||
@Unique('uq_share_participant', ['shareConfigId', 'participantId'])
|
@Unique('uq_share_participant', ['shareConfigId', 'participantId'])
|
||||||
export class ShareParticipant {
|
export class ShareParticipant {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Index('idx_share_config_id')
|
@Index('idx_share_config_id')
|
||||||
@Column({ type: 'varchar', length: 191, name: 'share_config_id' })
|
@Column({ type: 'varchar', length: 191, name: 'share_config_id' })
|
||||||
shareConfigId: string;
|
shareConfigId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => ShareConfig, (sc) => sc.participants)
|
@ManyToOne(() => ShareConfig, (sc) => sc.participants)
|
||||||
@JoinColumn({ name: 'share_config_id' })
|
@JoinColumn({ name: 'share_config_id' })
|
||||||
shareConfig: ShareConfig;
|
shareConfig!: ShareConfig;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, name: 'participant_id' })
|
@Column({ type: 'varchar', length: 191, name: 'participant_id' })
|
||||||
participantId: string;
|
participantId!: string;
|
||||||
|
|
||||||
@ManyToOne(() => User)
|
@ManyToOne(() => User)
|
||||||
@JoinColumn({ name: 'participant_id' })
|
@JoinColumn({ name: 'participant_id' })
|
||||||
participant: User;
|
participant!: User;
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'created_at' })
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ export class ShareController {
|
|||||||
@Post()
|
@Post()
|
||||||
@UseGuards(JwtAuthGuard)
|
@UseGuards(JwtAuthGuard)
|
||||||
@ApiBearerAuth()
|
@ApiBearerAuth()
|
||||||
@ApiOperation({ summary: '创建分享', description: '选择6关+标题,生成分享码' })
|
@ApiOperation({
|
||||||
|
summary: '创建分享',
|
||||||
|
description: '选择6关+标题,生成分享码',
|
||||||
|
})
|
||||||
@ApiResponse({ status: 201, description: '创建成功' })
|
@ApiResponse({ status: 201, description: '创建成功' })
|
||||||
@ApiResponse({ status: 400, description: '参数错误' })
|
@ApiResponse({ status: 400, description: '参数错误' })
|
||||||
async createShare(
|
async createShare(
|
||||||
|
|||||||
@@ -68,10 +68,7 @@ export class ShareService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async joinShare(
|
async joinShare(userId: string, code: string): Promise<JoinShareResponseDto> {
|
||||||
userId: string,
|
|
||||||
code: string,
|
|
||||||
): Promise<JoinShareResponseDto> {
|
|
||||||
const config = await this.shareConfigRepository.findByShareCode(code);
|
const config = await this.shareConfigRepository.findByShareCode(code);
|
||||||
if (!config) {
|
if (!config) {
|
||||||
throw new NotFoundException('分享不存在或已过期');
|
throw new NotFoundException('分享不存在或已过期');
|
||||||
|
|||||||
@@ -2,31 +2,31 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
|
|
||||||
export class GameConfigResponseDto {
|
export class GameConfigResponseDto {
|
||||||
@ApiProperty({ description: '配置ID' })
|
@ApiProperty({ description: '配置ID' })
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '配置键名' })
|
@ApiProperty({ description: '配置键名' })
|
||||||
configKey: string;
|
configKey!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '配置值' })
|
@ApiProperty({ description: '配置值' })
|
||||||
configValue: string;
|
configValue!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '配置描述', nullable: true })
|
@ApiProperty({ description: '配置描述', nullable: true })
|
||||||
description: string | null;
|
description!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ description: '是否激活' })
|
@ApiProperty({ description: '是否激活' })
|
||||||
isActive: boolean;
|
isActive!: boolean;
|
||||||
|
|
||||||
@ApiProperty({ description: '创建时间' })
|
@ApiProperty({ description: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@ApiProperty({ description: '更新时间' })
|
@ApiProperty({ description: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GameConfigListResponseDto {
|
export class GameConfigListResponseDto {
|
||||||
@ApiProperty({ type: [GameConfigResponseDto], description: '配置列表' })
|
@ApiProperty({ type: [GameConfigResponseDto], description: '配置列表' })
|
||||||
configs: GameConfigResponseDto[];
|
configs!: GameConfigResponseDto[];
|
||||||
|
|
||||||
@ApiProperty({ description: '配置总数' })
|
@ApiProperty({ description: '配置总数' })
|
||||||
total: number;
|
total!: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,40 +2,40 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
|
|
||||||
export class LevelResponseDto {
|
export class LevelResponseDto {
|
||||||
@ApiProperty({ description: '关卡编号' })
|
@ApiProperty({ description: '关卡编号' })
|
||||||
level: number;
|
level!: number;
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡ID' })
|
@ApiProperty({ description: '关卡ID' })
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '图片URL' })
|
@ApiProperty({ description: '图片URL' })
|
||||||
imageUrl: string;
|
imageUrl!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '答案' })
|
@ApiProperty({ description: '答案' })
|
||||||
answer: string;
|
answer!: string;
|
||||||
|
|
||||||
@ApiProperty({ description: '提示1', nullable: true })
|
@ApiProperty({ description: '提示1', nullable: true })
|
||||||
hint1: string | null;
|
hint1!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ description: '提示2', nullable: true })
|
@ApiProperty({ description: '提示2', nullable: true })
|
||||||
hint2: string | null;
|
hint2!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ description: '提示3', nullable: true })
|
@ApiProperty({ description: '提示3', nullable: true })
|
||||||
hint3: string | null;
|
hint3!: string | null;
|
||||||
|
|
||||||
@ApiProperty({ description: '排序顺序' })
|
@ApiProperty({ description: '排序顺序' })
|
||||||
sortOrder: number;
|
sortOrder!: number;
|
||||||
|
|
||||||
@ApiProperty({ description: '创建时间' })
|
@ApiProperty({ description: '创建时间' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@ApiProperty({ description: '更新时间' })
|
@ApiProperty({ description: '更新时间' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LevelListResponseDto {
|
export class LevelListResponseDto {
|
||||||
@ApiProperty({ type: [LevelResponseDto], description: '关卡列表' })
|
@ApiProperty({ type: [LevelResponseDto], description: '关卡列表' })
|
||||||
levels: LevelResponseDto[];
|
levels!: LevelResponseDto[];
|
||||||
|
|
||||||
@ApiProperty({ description: '关卡总数' })
|
@ApiProperty({ description: '关卡总数' })
|
||||||
total: number;
|
total!: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,27 +9,27 @@ import {
|
|||||||
@Entity('game_configs')
|
@Entity('game_configs')
|
||||||
export class GameConfig {
|
export class GameConfig {
|
||||||
@PrimaryGeneratedColumn('uuid')
|
@PrimaryGeneratedColumn('uuid')
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 255, name: 'config_key' })
|
@Column({ type: 'varchar', length: 255, name: 'config_key' })
|
||||||
configKey: string;
|
configKey!: string;
|
||||||
|
|
||||||
@Column({ type: 'text', name: 'config_value' })
|
@Column({ type: 'text', name: 'config_value' })
|
||||||
configValue: string;
|
configValue!: string;
|
||||||
|
|
||||||
@Column({
|
@Column({
|
||||||
type: 'varchar',
|
type: 'varchar',
|
||||||
length: 100,
|
length: 100,
|
||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
description: string | null;
|
description!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'boolean', default: true, name: 'is_active' })
|
@Column({ type: 'boolean', default: true, name: 'is_active' })
|
||||||
isActive: boolean;
|
isActive!: boolean;
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'created_at' })
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ name: 'updated_at' })
|
@UpdateDateColumn({ name: 'updated_at' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,29 +9,29 @@ import {
|
|||||||
@Entity('levels')
|
@Entity('levels')
|
||||||
export class Level {
|
export class Level {
|
||||||
@PrimaryColumn({ type: 'varchar', length: 191 })
|
@PrimaryColumn({ type: 'varchar', length: 191 })
|
||||||
id: string;
|
id!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, name: 'image_url' })
|
@Column({ type: 'varchar', length: 191, name: 'image_url' })
|
||||||
imageUrl: string;
|
imageUrl!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191 })
|
@Column({ type: 'varchar', length: 191 })
|
||||||
answer: string;
|
answer!: string;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, nullable: true })
|
@Column({ type: 'varchar', length: 191, nullable: true })
|
||||||
hint1: string | null;
|
hint1!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, nullable: true })
|
@Column({ type: 'varchar', length: 191, nullable: true })
|
||||||
hint2: string | null;
|
hint2!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'varchar', length: 191, nullable: true })
|
@Column({ type: 'varchar', length: 191, nullable: true })
|
||||||
hint3: string | null;
|
hint3!: string | null;
|
||||||
|
|
||||||
@Column({ type: 'int', name: 'sort_order', default: 0 })
|
@Column({ type: 'int', name: 'sort_order', default: 0 })
|
||||||
sortOrder: number;
|
sortOrder!: number;
|
||||||
|
|
||||||
@CreateDateColumn({ name: 'created_at' })
|
@CreateDateColumn({ name: 'created_at' })
|
||||||
createdAt: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
@UpdateDateColumn({ name: 'updated_at' })
|
@UpdateDateColumn({ name: 'updated_at' })
|
||||||
updatedAt: Date;
|
updatedAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
"target": "ES2023",
|
"target": "ES2023",
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"baseUrl": "./",
|
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user