This commit is contained in:
@@ -19,10 +19,14 @@ model LauncherNotice {
|
|||||||
startsAt DateTime? @map("starts_at") @db.Timestamptz(3)
|
startsAt DateTime? @map("starts_at") @db.Timestamptz(3)
|
||||||
endsAt DateTime? @map("ends_at") @db.Timestamptz(3)
|
endsAt DateTime? @map("ends_at") @db.Timestamptz(3)
|
||||||
priority Int @default(0)
|
priority Int @default(0)
|
||||||
|
createdById String? @map("created_by_id") @db.Uuid
|
||||||
|
createdByName String? @map("created_by_name")
|
||||||
|
createdByEmail String? @map("created_by_email")
|
||||||
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(3)
|
||||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||||
|
|
||||||
@@index([appKey, isActive, priority])
|
@@index([appKey, isActive, priority])
|
||||||
|
@@index([createdByEmail])
|
||||||
@@map("launcher_notices")
|
@@map("launcher_notices")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF to_regclass('public.launcher_notices') IS NOT NULL THEN
|
||||||
|
ALTER TABLE "launcher_notices"
|
||||||
|
ADD COLUMN IF NOT EXISTS "created_by_id" UUID,
|
||||||
|
ADD COLUMN IF NOT EXISTS "created_by_name" TEXT,
|
||||||
|
ADD COLUMN IF NOT EXISTS "created_by_email" TEXT;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF to_regclass('public.launcher_notices') IS NOT NULL THEN
|
||||||
|
CREATE INDEX IF NOT EXISTS "launcher_notices_created_by_email_idx" ON "launcher_notices"("created_by_email");
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
@@ -7,6 +7,7 @@ import {
|
|||||||
Patch,
|
Patch,
|
||||||
Post,
|
Post,
|
||||||
Query,
|
Query,
|
||||||
|
Req,
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -31,8 +32,11 @@ export class NoticesController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Post()
|
@Post()
|
||||||
create(@Body() body: CreateLauncherNoticeDto) {
|
create(
|
||||||
return this.noticesService.create(body);
|
@Body() body: CreateLauncherNoticeDto,
|
||||||
|
@Req() request: { admin?: { id: string; name: string; email: string } },
|
||||||
|
) {
|
||||||
|
return this.noticesService.create(body, request.admin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id')
|
@Patch(':id')
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
import { Module } from '@nestjs/common';
|
import { Module } from '@nestjs/common';
|
||||||
|
|
||||||
|
import { AuthPrismaModule } from '../auth-prisma/auth-prisma.module';
|
||||||
import { LauncherPrismaModule } from '../launcher-prisma/launcher-prisma.module';
|
import { LauncherPrismaModule } from '../launcher-prisma/launcher-prisma.module';
|
||||||
import { NoticesController } from './notices.controller';
|
import { NoticesController } from './notices.controller';
|
||||||
import { NoticesService } from './notices.service';
|
import { NoticesService } from './notices.service';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [LauncherPrismaModule],
|
imports: [AuthPrismaModule, LauncherPrismaModule],
|
||||||
controllers: [NoticesController],
|
controllers: [NoticesController],
|
||||||
providers: [NoticesService],
|
providers: [NoticesService],
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,16 +1,66 @@
|
|||||||
import { Injectable, NotFoundException } from '@nestjs/common';
|
import { Injectable, NotFoundException } from '@nestjs/common';
|
||||||
|
import { ConfigService } from '@nestjs/config';
|
||||||
|
|
||||||
import { Prisma } from '@prisma/launcher-client';
|
import { Prisma } from '@prisma/launcher-client';
|
||||||
|
import { AuthPrismaService } from '../auth-prisma/auth-prisma.service';
|
||||||
import { LauncherPrismaService } from '../launcher-prisma/launcher-prisma.service';
|
import { LauncherPrismaService } from '../launcher-prisma/launcher-prisma.service';
|
||||||
|
import { getUserAvatarUrl } from '../users/users.service';
|
||||||
import {
|
import {
|
||||||
CreateLauncherNoticeDto,
|
CreateLauncherNoticeDto,
|
||||||
ListLauncherNoticesQuery,
|
ListLauncherNoticesQuery,
|
||||||
UpdateLauncherNoticeDto,
|
UpdateLauncherNoticeDto,
|
||||||
} from './dto';
|
} from './dto';
|
||||||
|
|
||||||
|
type AdminRequester = {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
};
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class NoticesService {
|
export class NoticesService {
|
||||||
constructor(private readonly launcherPrisma: LauncherPrismaService) {}
|
constructor(
|
||||||
|
private readonly authPrisma: AuthPrismaService,
|
||||||
|
private readonly configService: ConfigService,
|
||||||
|
private readonly launcherPrisma: LauncherPrismaService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
private creatorData(requester?: AdminRequester) {
|
||||||
|
return requester
|
||||||
|
? {
|
||||||
|
createdById: requester.id,
|
||||||
|
createdByName: requester.name,
|
||||||
|
createdByEmail: requester.email,
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
}
|
||||||
|
|
||||||
|
private async withCreatorAvatars<T extends { createdByEmail?: string | null }>(items: T[]) {
|
||||||
|
const emails = [...new Set(items.map((item) => item.createdByEmail).filter((email): email is string => Boolean(email)))];
|
||||||
|
if (emails.length === 0) return items.map((item) => ({ ...item, createdByAvatarUrl: null }));
|
||||||
|
|
||||||
|
const users = await this.authPrisma.user.findMany({
|
||||||
|
where: { email: { in: emails } },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
email: true,
|
||||||
|
profileImageMime: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const userByEmail = new Map(users.map((user) => [user.email, user]));
|
||||||
|
const authBaseUrl = this.configService.get<string>('AUTH_PUBLIC_URL')
|
||||||
|
?? this.configService.get<string>('ATNMY_AUTH_URL')
|
||||||
|
?? this.configService.get<string>('AUTH_EXTERNAL_URL')
|
||||||
|
?? 'https://auth.autonomystudio.net';
|
||||||
|
|
||||||
|
return items.map((item) => {
|
||||||
|
const user = item.createdByEmail ? userByEmail.get(item.createdByEmail) : null;
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
createdByAvatarUrl: getUserAvatarUrl(user?.id ?? '', user?.profileImageMime, authBaseUrl),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async list(query: ListLauncherNoticesQuery) {
|
async list(query: ListLauncherNoticesQuery) {
|
||||||
const keyword = query.keyword?.trim();
|
const keyword = query.keyword?.trim();
|
||||||
@@ -37,11 +87,11 @@ export class NoticesService {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notices: notices.map((notice, index) => ({
|
notices: await this.withCreatorAvatars(notices.map((notice, index) => ({
|
||||||
...notice,
|
...notice,
|
||||||
no: notices.length - index,
|
no: notices.length - index,
|
||||||
status: getNoticeStatus(notice, now),
|
status: getNoticeStatus(notice, now),
|
||||||
})),
|
}))),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,9 +107,12 @@ export class NoticesService {
|
|||||||
return { notice };
|
return { notice };
|
||||||
}
|
}
|
||||||
|
|
||||||
async create(body: CreateLauncherNoticeDto) {
|
async create(body: CreateLauncherNoticeDto, requester?: AdminRequester) {
|
||||||
const notice = await this.launcherPrisma.launcherNotice.create({
|
const notice = await this.launcherPrisma.launcherNotice.create({
|
||||||
data: toCreateNoticeData(body),
|
data: {
|
||||||
|
...toCreateNoticeData(body),
|
||||||
|
...this.creatorData(requester),
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
return { notice };
|
return { notice };
|
||||||
|
|||||||
Reference in New Issue
Block a user