chore: 代码风格统一和项目文档添加

主要变更:

1. 代码风格统一
   - 统一使用双引号替代单引号
   - 保持项目代码风格一致性
   - 涵盖所有模块、配置、实体和服务文件

2. 项目文档
   - 新增 SECURITY_FIXES_SUMMARY.md - 安全修复总结文档
   - 新增 项目问题评估报告.md - 项目问题评估文档

3. 包含修改的文件类别
   - 配置文件:app, database, jwt, redis, cache, performance
   - 实体文件:所有 TypeORM 实体
   - 模块文件:所有业务模块
   - 公共模块:guards, decorators, interceptors, filters, utils
   - 测试文件:单元测试和 E2E 测试

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
UGREEN USER
2026-01-28 13:03:28 +08:00
parent d73a6e28b3
commit 575a29ac8f
103 changed files with 3651 additions and 2710 deletions

View File

@@ -6,41 +6,41 @@ import {
ManyToOne,
JoinColumn,
Unique,
} from 'typeorm';
import { ParticipantStatus } from '../common/enums';
import { Appointment } from './appointment.entity';
import { User } from './user.entity';
} from "typeorm";
import { ParticipantStatus } from "../common/enums";
import { Appointment } from "./appointment.entity";
import { User } from "./user.entity";
@Entity('appointment_participants')
@Unique(['appointmentId', 'userId'])
@Entity("appointment_participants")
@Unique(["appointmentId", "userId"])
export class AppointmentParticipant {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
appointmentId: string;
@ManyToOne(() => Appointment, (appointment) => appointment.participants, {
onDelete: 'CASCADE',
onDelete: "CASCADE",
})
@JoinColumn({ name: 'appointmentId' })
@JoinColumn({ name: "appointmentId" })
appointment: Appointment;
@Column()
userId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'userId' })
@JoinColumn({ name: "userId" })
user: User;
@Column({
type: 'enum',
type: "enum",
enum: ParticipantStatus,
default: ParticipantStatus.JOINED,
})
status: ParticipantStatus;
@Column({ type: 'text', nullable: true, comment: '备注' })
@Column({ type: "text", nullable: true, comment: "备注" })
note: string;
@CreateDateColumn()

View File

@@ -7,61 +7,61 @@ import {
ManyToOne,
JoinColumn,
OneToMany,
} from 'typeorm';
import { AppointmentStatus } from '../common/enums';
import { Group } from './group.entity';
import { Game } from './game.entity';
import { User } from './user.entity';
import { AppointmentParticipant } from './appointment-participant.entity';
} from "typeorm";
import { AppointmentStatus } from "../common/enums";
import { Group } from "./group.entity";
import { Game } from "./game.entity";
import { User } from "./user.entity";
import { AppointmentParticipant } from "./appointment-participant.entity";
@Entity('appointments')
@Entity("appointments")
export class Appointment {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
groupId: string;
@ManyToOne(() => Group, (group) => group.appointments, {
onDelete: 'CASCADE',
onDelete: "CASCADE",
})
@JoinColumn({ name: 'groupId' })
@JoinColumn({ name: "groupId" })
group: Group;
@Column()
gameId: string;
@ManyToOne(() => Game, (game) => game.appointments)
@JoinColumn({ name: 'gameId' })
@JoinColumn({ name: "gameId" })
game: Game;
@Column()
initiatorId: string;
@ManyToOne(() => User, (user) => user.appointments)
@JoinColumn({ name: 'initiatorId' })
@JoinColumn({ name: "initiatorId" })
initiator: User;
@Column({ type: 'varchar', length: 200, nullable: true })
@Column({ type: "varchar", length: 200, nullable: true })
title: string;
@Column({ type: 'text', nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Column({ type: 'datetime' })
@Column({ type: "datetime" })
startTime: Date;
@Column({ type: 'datetime', nullable: true })
@Column({ type: "datetime", nullable: true })
endTime: Date;
@Column({ comment: '最大参与人数' })
@Column({ comment: "最大参与人数" })
maxParticipants: number;
@Column({ default: 0, comment: '当前参与人数' })
@Column({ default: 0, comment: "当前参与人数" })
currentParticipants: number;
@Column({
type: 'enum',
type: "enum",
enum: AppointmentStatus,
default: AppointmentStatus.OPEN,
})

View File

@@ -5,37 +5,37 @@ import {
CreateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { AssetLogAction } from '../common/enums';
import { Asset } from './asset.entity';
import { User } from './user.entity';
} from "typeorm";
import { AssetLogAction } from "../common/enums";
import { Asset } from "./asset.entity";
import { User } from "./user.entity";
@Entity('asset_logs')
@Entity("asset_logs")
export class AssetLog {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
assetId: string;
@ManyToOne(() => Asset, (asset) => asset.logs, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'assetId' })
@ManyToOne(() => Asset, (asset) => asset.logs, { onDelete: "CASCADE" })
@JoinColumn({ name: "assetId" })
asset: Asset;
@Column()
userId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'userId' })
@JoinColumn({ name: "userId" })
user: User;
@Column({ type: 'enum', enum: AssetLogAction })
@Column({ type: "enum", enum: AssetLogAction })
action: AssetLogAction;
@Column({ default: 1, comment: '数量' })
@Column({ default: 1, comment: "数量" })
quantity: number;
@Column({ type: 'text', nullable: true, comment: '备注' })
@Column({ type: "text", nullable: true, comment: "备注" })
note: string;
@CreateDateColumn()

View File

@@ -7,46 +7,46 @@ import {
ManyToOne,
JoinColumn,
OneToMany,
} from 'typeorm';
import { AssetType, AssetStatus } from '../common/enums';
import { Group } from './group.entity';
import { AssetLog } from './asset-log.entity';
} from "typeorm";
import { AssetType, AssetStatus } from "../common/enums";
import { Group } from "./group.entity";
import { AssetLog } from "./asset-log.entity";
@Entity('assets')
@Entity("assets")
export class Asset {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
groupId: string;
@ManyToOne(() => Group, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column({ type: 'enum', enum: AssetType })
@Column({ type: "enum", enum: AssetType })
type: AssetType;
@Column({ length: 100 })
name: string;
@Column({ type: 'text', nullable: true, comment: '描述' })
@Column({ type: "text", nullable: true, comment: "描述" })
description: string;
@Column({ type: 'text', nullable: true, comment: '加密的账号凭据' })
@Column({ type: "text", nullable: true, comment: "加密的账号凭据" })
accountCredentials?: string | null;
@Column({ default: 1, comment: '数量(用于物品)' })
@Column({ default: 1, comment: "数量(用于物品)" })
quantity: number;
@Column({
type: 'enum',
type: "enum",
enum: AssetStatus,
default: AssetStatus.AVAILABLE,
})
status: AssetStatus;
@Column({ type: 'varchar', nullable: true, comment: '当前借用人ID' })
@Column({ type: "varchar", nullable: true, comment: "当前借用人ID" })
currentBorrowerId?: string | null;
@CreateDateColumn()

View File

@@ -6,40 +6,40 @@ import {
UpdateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { BetStatus } from '../common/enums';
import { Appointment } from './appointment.entity';
import { User } from './user.entity';
} from "typeorm";
import { BetStatus } from "../common/enums";
import { Appointment } from "./appointment.entity";
import { User } from "./user.entity";
@Entity('bets')
@Entity("bets")
export class Bet {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
appointmentId: string;
@ManyToOne(() => Appointment, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'appointmentId' })
@ManyToOne(() => Appointment, { onDelete: "CASCADE" })
@JoinColumn({ name: "appointmentId" })
appointment: Appointment;
@Column()
userId: string;
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
@ManyToOne(() => User, { onDelete: "CASCADE" })
@JoinColumn({ name: "userId" })
user: User;
@Column({ length: 100, comment: '下注选项' })
@Column({ length: 100, comment: "下注选项" })
betOption: string;
@Column({ type: 'int', comment: '下注积分' })
@Column({ type: "int", comment: "下注积分" })
amount: number;
@Column({ type: 'enum', enum: BetStatus, default: BetStatus.PENDING })
@Column({ type: "enum", enum: BetStatus, default: BetStatus.PENDING })
status: BetStatus;
@Column({ type: 'int', default: 0, comment: '赢得的积分' })
@Column({ type: "int", default: 0, comment: "赢得的积分" })
winAmount: number;
@CreateDateColumn()

View File

@@ -5,46 +5,46 @@ import {
CreateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { BlacklistStatus } from '../common/enums';
import { User } from './user.entity';
} from "typeorm";
import { BlacklistStatus } from "../common/enums";
import { User } from "./user.entity";
@Entity('blacklists')
@Entity("blacklists")
export class Blacklist {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ length: 100, comment: '目标游戏ID或用户名' })
@Column({ length: 100, comment: "目标游戏ID或用户名" })
targetGameId: string;
@Column({ type: 'text' })
@Column({ type: "text" })
reason: string;
@Column()
reporterId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'reporterId' })
@JoinColumn({ name: "reporterId" })
reporter: User;
@Column({ type: 'simple-json', nullable: true, comment: '证据图片' })
@Column({ type: "simple-json", nullable: true, comment: "证据图片" })
proofImages: string[];
@Column({
type: 'enum',
type: "enum",
enum: BlacklistStatus,
default: BlacklistStatus.PENDING,
})
status: BlacklistStatus;
@Column({ nullable: true, comment: '审核人ID' })
@Column({ nullable: true, comment: "审核人ID" })
reviewerId: string;
@ManyToOne(() => User, { nullable: true })
@JoinColumn({ name: 'reviewerId' })
@JoinColumn({ name: "reviewerId" })
reviewer: User;
@Column({ type: 'text', nullable: true, comment: '审核意见' })
@Column({ type: "text", nullable: true, comment: "审核意见" })
reviewNote: string;
@CreateDateColumn()

View File

@@ -5,33 +5,33 @@ import {
CreateDateColumn,
UpdateDateColumn,
OneToMany,
} from 'typeorm';
import { Appointment } from './appointment.entity';
} from "typeorm";
import { Appointment } from "./appointment.entity";
@Entity('games')
@Entity("games")
export class Game {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ length: 100 })
name: string;
@Column({ type: 'varchar', nullable: true, length: 255 })
@Column({ type: "varchar", nullable: true, length: 255 })
coverUrl: string;
@Column({ type: 'text', nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Column({ comment: '最大玩家数' })
@Column({ comment: "最大玩家数" })
maxPlayers: number;
@Column({ default: 1, comment: '最小玩家数' })
@Column({ default: 1, comment: "最小玩家数" })
minPlayers: number;
@Column({ length: 50, nullable: true, comment: '平台' })
@Column({ length: 50, nullable: true, comment: "平台" })
platform: string;
@Column({ type: 'simple-array', nullable: true, comment: '游戏标签' })
@Column({ type: "simple-array", nullable: true, comment: "游戏标签" })
tags: string[];
@Column({ default: true })

View File

@@ -6,39 +6,39 @@ import {
ManyToOne,
JoinColumn,
Unique,
} from 'typeorm';
import { GroupMemberRole } from '../common/enums';
import { User } from './user.entity';
import { Group } from './group.entity';
} from "typeorm";
import { GroupMemberRole } from "../common/enums";
import { User } from "./user.entity";
import { Group } from "./group.entity";
@Entity('group_members')
@Unique(['groupId', 'userId'])
@Entity("group_members")
@Unique(["groupId", "userId"])
export class GroupMember {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
groupId: string;
@ManyToOne(() => Group, (group) => group.members, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, (group) => group.members, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column()
userId: string;
@ManyToOne(() => User, (user) => user.groupMembers, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
@ManyToOne(() => User, (user) => user.groupMembers, { onDelete: "CASCADE" })
@JoinColumn({ name: "userId" })
user: User;
@Column({
type: 'enum',
type: "enum",
enum: GroupMemberRole,
default: GroupMemberRole.MEMBER,
})
role: GroupMemberRole;
@Column({ type: 'varchar', nullable: true, length: 50, comment: '组内昵称' })
@Column({ type: "varchar", nullable: true, length: 50, comment: "组内昵称" })
nickname: string;
@Column({ default: true })

View File

@@ -7,49 +7,49 @@ import {
ManyToOne,
JoinColumn,
OneToMany,
} from 'typeorm';
import { User } from './user.entity';
import { GroupMember } from './group-member.entity';
import { Appointment } from './appointment.entity';
} from "typeorm";
import { User } from "./user.entity";
import { GroupMember } from "./group-member.entity";
import { Appointment } from "./appointment.entity";
@Entity('groups')
@Entity("groups")
export class Group {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ length: 100 })
name: string;
@Column({ type: 'text', nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Column({ type: 'varchar', nullable: true, length: 255 })
@Column({ type: "varchar", nullable: true, length: 255 })
avatar: string;
@Column()
ownerId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'ownerId' })
@JoinColumn({ name: "ownerId" })
owner: User;
@Column({ default: 'normal', length: 20, comment: '类型: normal/guild' })
@Column({ default: "normal", length: 20, comment: "类型: normal/guild" })
type: string;
@Column({ nullable: true, comment: '父组ID用于子组' })
@Column({ nullable: true, comment: "父组ID用于子组" })
parentId: string;
@ManyToOne(() => Group, { nullable: true })
@JoinColumn({ name: 'parentId' })
@JoinColumn({ name: "parentId" })
parent: Group;
@Column({ type: 'text', nullable: true, comment: '公示信息' })
@Column({ type: "text", nullable: true, comment: "公示信息" })
announcement: string;
@Column({ default: 50, comment: '最大成员数' })
@Column({ default: 50, comment: "最大成员数" })
maxMembers: number;
@Column({ default: 1, comment: '当前成员数' })
@Column({ default: 1, comment: "当前成员数" })
currentMembers: number;
@Column({ default: true })

View File

@@ -5,42 +5,42 @@ import {
CreateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { Group } from './group.entity';
import { User } from './user.entity';
} from "typeorm";
import { Group } from "./group.entity";
import { User } from "./user.entity";
@Entity('honors')
@Entity("honors")
export class Honor {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
groupId: string;
@ManyToOne(() => Group, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column({ length: 200 })
title: string;
@Column({ type: 'text', nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Column({ type: 'simple-json', nullable: true, comment: '媒体文件URLs' })
@Column({ type: "simple-json", nullable: true, comment: "媒体文件URLs" })
mediaUrls: string[];
@Column({ type: 'date', comment: '事件日期' })
@Column({ type: "date", comment: "事件日期" })
eventDate: Date;
@Column({ type: 'simple-json', nullable: true, comment: '参与者ID列表' })
@Column({ type: "simple-json", nullable: true, comment: "参与者ID列表" })
participantIds: string[];
@Column()
creatorId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'creatorId' })
@JoinColumn({ name: "creatorId" })
creator: User;
@CreateDateColumn()

View File

@@ -5,43 +5,43 @@ import {
CreateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { LedgerType } from '../common/enums';
import { Group } from './group.entity';
import { User } from './user.entity';
} from "typeorm";
import { LedgerType } from "../common/enums";
import { Group } from "./group.entity";
import { User } from "./user.entity";
@Entity('ledgers')
@Entity("ledgers")
export class Ledger {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
groupId: string;
@ManyToOne(() => Group, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column()
creatorId: string;
@ManyToOne(() => User)
@JoinColumn({ name: 'creatorId' })
@JoinColumn({ name: "creatorId" })
creator: User;
@Column({ type: 'decimal', precision: 10, scale: 2 })
@Column({ type: "decimal", precision: 10, scale: 2 })
amount: number;
@Column({ type: 'enum', enum: LedgerType })
@Column({ type: "enum", enum: LedgerType })
type: LedgerType;
@Column({ type: 'varchar', length: 50, nullable: true, comment: '分类' })
@Column({ type: "varchar", length: 50, nullable: true, comment: "分类" })
category: string;
@Column({ type: 'text', nullable: true })
@Column({ type: "text", nullable: true })
description: string;
@Column({ type: 'simple-json', nullable: true, comment: '凭证图片' })
@Column({ type: "simple-json", nullable: true, comment: "凭证图片" })
proofImages: string[];
@CreateDateColumn()

View File

@@ -5,39 +5,43 @@ import {
CreateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { User } from './user.entity';
import { Group } from './group.entity';
} from "typeorm";
import { User } from "./user.entity";
import { Group } from "./group.entity";
@Entity('points')
@Entity("points")
export class Point {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
userId: string;
@ManyToOne(() => User, (user) => user.points, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
@ManyToOne(() => User, (user) => user.points, { onDelete: "CASCADE" })
@JoinColumn({ name: "userId" })
user: User;
@Column()
groupId: string;
@ManyToOne(() => Group, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column({ type: 'int', comment: '积分变动值,正为增加,负为减少' })
@Column({ type: "int", comment: "积分变动值,正为增加,负为减少" })
amount: number;
@Column({ length: 100, comment: '原因' })
@Column({ length: 100, comment: "原因" })
reason: string;
@Column({ type: 'text', nullable: true, comment: '详细说明' })
@Column({ type: "text", nullable: true, comment: "详细说明" })
description: string;
@Column({ type: 'varchar', nullable: true, comment: '关联ID如活动ID、预约ID' })
@Column({
type: "varchar",
nullable: true,
comment: "关联ID如活动ID、预约ID",
})
relatedId: string;
@CreateDateColumn()

View File

@@ -6,31 +6,31 @@ import {
UpdateDateColumn,
ManyToOne,
JoinColumn,
} from 'typeorm';
import { User } from './user.entity';
import { Group } from './group.entity';
} from "typeorm";
import { User } from "./user.entity";
import { Group } from "./group.entity";
@Entity('schedules')
@Entity("schedules")
export class Schedule {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column()
userId: string;
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
@ManyToOne(() => User, { onDelete: "CASCADE" })
@JoinColumn({ name: "userId" })
user: User;
@Column()
groupId: string;
@ManyToOne(() => Group, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'groupId' })
@ManyToOne(() => Group, { onDelete: "CASCADE" })
@JoinColumn({ name: "groupId" })
group: Group;
@Column({
type: 'simple-json',
type: "simple-json",
comment: '空闲时间段 JSON: { "mon": ["20:00-23:00"], ... }',
})
availableSlots: Record<string, string[]>;

View File

@@ -5,15 +5,15 @@ import {
CreateDateColumn,
UpdateDateColumn,
OneToMany,
} from 'typeorm';
import { UserRole } from '../common/enums';
import { GroupMember } from './group-member.entity';
import { Appointment } from './appointment.entity';
import { Point } from './point.entity';
} from "typeorm";
import { UserRole } from "../common/enums";
import { GroupMember } from "./group-member.entity";
import { Appointment } from "./appointment.entity";
import { Point } from "./point.entity";
@Entity('users')
@Entity("users")
export class User {
@PrimaryGeneratedColumn('uuid')
@PrimaryGeneratedColumn("uuid")
id: string;
@Column({ unique: true, length: 50 })
@@ -31,19 +31,24 @@ export class User {
@Column({ nullable: true, length: 255 })
avatar: string;
@Column({ type: 'enum', enum: UserRole, default: UserRole.USER })
@Column({ type: "enum", enum: UserRole, default: UserRole.USER })
role: UserRole;
@Column({ default: false, comment: '是否为会员' })
@Column({ default: false, comment: "是否为会员" })
isMember: boolean;
@Column({ type: 'datetime', nullable: true, comment: '会员到期时间' })
@Column({ type: "datetime", nullable: true, comment: "会员到期时间" })
memberExpireAt: Date;
@Column({ type: 'varchar', nullable: true, length: 50, comment: '最后登录IP' })
@Column({
type: "varchar",
nullable: true,
length: 50,
comment: "最后登录IP",
})
lastLoginIp: string | null;
@Column({ type: 'datetime', nullable: true, comment: '最后登录时间' })
@Column({ type: "datetime", nullable: true, comment: "最后登录时间" })
lastLoginAt: Date;
@CreateDateColumn()