import { Controller, Get, Put, Body, Param, HttpCode, HttpStatus, Inject, Query, } from '@nestjs/common'; import { SYSTEM_CONFIG_REPOSITORY, ISystemConfigRepository, } from '../../domain/repositories/system-config.repository'; /** * 系统配置常量 - 热度展示设置 */ export const CONFIG_KEYS = { // 是否允许未认种用户查看各省认种热度 ALLOW_NON_ADOPTER_VIEW_HEAT: 'display.allowNonAdopterViewHeat', // 热度展示方式: 'count' | 'level' HEAT_DISPLAY_MODE: 'display.heatDisplayMode', } as const; /** * 获取系统配置响应 DTO */ interface SystemConfigResponseDto { key: string; value: string; description: string | null; updatedAt: Date; } /** * 前端展示设置响应 DTO */ interface DisplaySettingsResponseDto { allowNonAdopterViewHeat: boolean; heatDisplayMode: 'count' | 'level'; } /** * 前端展示设置请求 DTO */ interface UpdateDisplaySettingsDto { allowNonAdopterViewHeat?: boolean; heatDisplayMode?: 'count' | 'level'; } /** * 管理端系统配置控制器 */ @Controller('admin/system-config') export class AdminSystemConfigController { constructor( @Inject(SYSTEM_CONFIG_REPOSITORY) private readonly configRepo: ISystemConfigRepository, ) {} /** * 获取所有系统配置 */ @Get() async getAll(): Promise { const configs = await this.configRepo.findAll(); return configs.map((c) => ({ key: c.key, value: c.value, description: c.description, updatedAt: c.updatedAt, })); } /** * 获取单个配置 */ @Get(':key') async getByKey(@Param('key') key: string): Promise { const config = await this.configRepo.findByKey(key); if (!config) { return null; } return { key: config.key, value: config.value, description: config.description, updatedAt: config.updatedAt, }; } /** * 获取前端展示设置 */ @Get('display/settings') async getDisplaySettings(): Promise { const configs = await this.configRepo.findByKeys([ CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT, CONFIG_KEYS.HEAT_DISPLAY_MODE, ]); const configMap = new Map(configs.map((c) => [c.key, c.value])); return { allowNonAdopterViewHeat: configMap.get(CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT) === 'true', heatDisplayMode: (configMap.get(CONFIG_KEYS.HEAT_DISPLAY_MODE) as 'count' | 'level') || 'count', }; } /** * 更新前端展示设置 */ @Put('display/settings') @HttpCode(HttpStatus.OK) async updateDisplaySettings( @Body() dto: UpdateDisplaySettingsDto, ): Promise { const updates: Array<{ key: string; value: string; description?: string }> = []; if (dto.allowNonAdopterViewHeat !== undefined) { updates.push({ key: CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT, value: String(dto.allowNonAdopterViewHeat), description: '是否允许未认种用户查看各省认种热度', }); } if (dto.heatDisplayMode !== undefined) { updates.push({ key: CONFIG_KEYS.HEAT_DISPLAY_MODE, value: dto.heatDisplayMode, description: '热度展示方式: count=显示具体数量, level=仅显示热度等级', }); } if (updates.length > 0) { await this.configRepo.batchUpsert(updates, 'admin'); } // 返回更新后的配置 return this.getDisplaySettings(); } /** * 更新单个配置 */ @Put(':key') @HttpCode(HttpStatus.OK) async updateByKey( @Param('key') key: string, @Body() body: { value: string; description?: string }, ): Promise { const config = await this.configRepo.upsert( key, body.value, body.description, 'admin', ); return { key: config.key, value: config.value, description: config.description, updatedAt: config.updatedAt, }; } } /** * 移动端/公开系统配置控制器 * 用于 mobile-app 获取展示相关的配置 */ @Controller('system-config') export class PublicSystemConfigController { constructor( @Inject(SYSTEM_CONFIG_REPOSITORY) private readonly configRepo: ISystemConfigRepository, ) {} /** * 获取前端展示设置(公开接口) */ @Get('display/settings') async getDisplaySettings(): Promise { const configs = await this.configRepo.findByKeys([ CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT, CONFIG_KEYS.HEAT_DISPLAY_MODE, ]); const configMap = new Map(configs.map((c) => [c.key, c.value])); return { allowNonAdopterViewHeat: configMap.get(CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT) === 'true', heatDisplayMode: (configMap.get(CONFIG_KEYS.HEAT_DISPLAY_MODE) as 'count' | 'level') || 'count', }; } }