From f747ad5442e314f41d9319b61941da5f7af69096 Mon Sep 17 00:00:00 2001 From: liuyun Date: Sun, 11 Oct 2026 22:32:14 +0800 Subject: [PATCH] =?UTF-8?q?feat(tenant):=20=E7=A7=9F=E6=88=B7=E5=93=81?= =?UTF-8?q?=E7=89=8C=E5=AE=9A=E5=88=B6=EF=BC=88brand=5Fname/logo=5Furl/the?= =?UTF-8?q?me=5Fcolor/copyright=20+=20GET=20/auth/brand=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 --- .../20261011142924_tenant_brand/migration.sql | 5 +++ prisma/schema.prisma | 20 ++++++---- src/auth/auth.controller.ts | 8 ++++ src/auth/auth.service.ts | 19 +++++++++ src/tenants/dto.ts | 40 +++++++++++++++++++ src/tenants/tenants.service.ts | 4 ++ 6 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 prisma/migrations/20261011142924_tenant_brand/migration.sql diff --git a/prisma/migrations/20261011142924_tenant_brand/migration.sql b/prisma/migrations/20261011142924_tenant_brand/migration.sql new file mode 100644 index 0000000..b381ff9 --- /dev/null +++ b/prisma/migrations/20261011142924_tenant_brand/migration.sql @@ -0,0 +1,5 @@ +-- AlterTable +ALTER TABLE `sys_tenant` ADD COLUMN `brand_name` VARCHAR(64) NULL, + ADD COLUMN `copyright` VARCHAR(255) NULL, + ADD COLUMN `logo_url` VARCHAR(255) NULL, + ADD COLUMN `theme_color` VARCHAR(16) NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 35b0d42..ee5c4bb 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -12,14 +12,18 @@ datasource db { /// 租户 model Tenant { - id String @id @default(uuid(7)) @db.VarChar(36) - code String @unique @db.VarChar(64) - name String @db.VarChar(128) - status String @default("enabled") @db.VarChar(16) - remark String? @db.VarChar(255) - createdAt DateTime @default(now()) @map("created_at") - createdBy String? @map("created_by") @db.VarChar(36) - updatedAt DateTime @updatedAt @map("updated_at") + id String @id @default(uuid(7)) @db.VarChar(36) + code String @unique @db.VarChar(64) + name String @db.VarChar(128) + status String @default("enabled") @db.VarChar(16) + remark String? @db.VarChar(255) + brandName String? @map("brand_name") @db.VarChar(64) + logoUrl String? @map("logo_url") @db.VarChar(255) + themeColor String? @map("theme_color") @db.VarChar(16) + copyright String? @db.VarChar(255) + createdAt DateTime @default(now()) @map("created_at") + createdBy String? @map("created_by") @db.VarChar(36) + updatedAt DateTime @updatedAt @map("updated_at") @@map("sys_tenant") } diff --git a/src/auth/auth.controller.ts b/src/auth/auth.controller.ts index dfdc2e4..ed0eed3 100644 --- a/src/auth/auth.controller.ts +++ b/src/auth/auth.controller.ts @@ -49,6 +49,14 @@ export class AuthController { return this.auth.getPermissionSet(ctx.tenantCode, ctx.userId); } + /** 当前租户品牌(仅需登录)。 */ + @Get('brand') + brand() { + const ctx = getRequestContext(); + if (!ctx) throw new UnauthorizedException('未登录'); + return this.auth.getBrand(ctx.tenantCode); + } + /** 修改本人密码(仅需登录)。 */ @Patch('me/password') changePassword(@Body() dto: ChangePasswordDto) { diff --git a/src/auth/auth.service.ts b/src/auth/auth.service.ts index c588da7..d0812be 100644 --- a/src/auth/auth.service.ts +++ b/src/auth/auth.service.ts @@ -439,6 +439,25 @@ export class AuthService { return (await this.redis.getJson(sessionRevokedKey(sid))) != null; } + /** 当前租户品牌(登录后前端拉取应用)。 */ + async getBrand(tenantCode: string): Promise<{ + name: string; + brandName: string | null; + logoUrl: string | null; + themeColor: string | null; + copyright: string | null; + }> { + const tenant = await this.prisma.client.tenant.findUnique({ where: { code: tenantCode } }); + if (!tenant) throw new UnauthorizedException('租户不存在'); + return { + name: tenant.name, + brandName: tenant.brandName, + logoUrl: tenant.logoUrl, + themeColor: tenant.themeColor, + copyright: tenant.copyright, + }; + } + /** 聚合权限码与超管标志。 */ private async resolveAuth(tenantCode: string, userId: string): Promise { const roleRows = await this.prisma.client.userRole.findMany({ diff --git a/src/tenants/dto.ts b/src/tenants/dto.ts index 9a3e9bc..5fa559f 100644 --- a/src/tenants/dto.ts +++ b/src/tenants/dto.ts @@ -33,6 +33,26 @@ export class CreateTenantDto { @IsOptional() @IsString() remark?: string; + + @ApiPropertyOptional({ description: '品牌名' }) + @IsOptional() + @IsString() + brandName?: string; + + @ApiPropertyOptional({ description: 'Logo 地址' }) + @IsOptional() + @IsString() + logoUrl?: string; + + @ApiPropertyOptional({ description: '主色(如 #2E7FA3)' }) + @IsOptional() + @IsString() + themeColor?: string; + + @ApiPropertyOptional({ description: '版权文案' }) + @IsOptional() + @IsString() + copyright?: string; } export class UpdateTenantDto { @@ -50,6 +70,26 @@ export class UpdateTenantDto { @IsOptional() @IsString() remark?: string; + + @ApiPropertyOptional({ description: '品牌名' }) + @IsOptional() + @IsString() + brandName?: string; + + @ApiPropertyOptional({ description: 'Logo 地址' }) + @IsOptional() + @IsString() + logoUrl?: string; + + @ApiPropertyOptional({ description: '主色(如 #2E7FA3)' }) + @IsOptional() + @IsString() + themeColor?: string; + + @ApiPropertyOptional({ description: '版权文案' }) + @IsOptional() + @IsString() + copyright?: string; } export class ListTenantQuery extends PageQuery { diff --git a/src/tenants/tenants.service.ts b/src/tenants/tenants.service.ts index eef6411..91d312b 100644 --- a/src/tenants/tenants.service.ts +++ b/src/tenants/tenants.service.ts @@ -30,6 +30,10 @@ export class TenantsService extends BaseCrudService { name: dto.name, status: dto.status ?? 'enabled', remark: dto.remark, + brandName: dto.brandName, + logoUrl: dto.logoUrl, + themeColor: dto.themeColor, + copyright: dto.copyright, createdBy: ctx?.userId ?? null, }, });