优化文案模块

This commit is contained in:
Jerry 2025-08-27 17:39:48 +08:00
parent aad87d4d7e
commit 1c793c3b20
3 changed files with 41 additions and 46 deletions

View File

@ -1,5 +1,5 @@
import { Inject, Injectable, Logger } from '@nestjs/common'; import { Inject, Injectable, Logger } from '@nestjs/common';
import fs from 'fs/promises'; import * as fs from 'fs/promises';
import * as path from 'path'; import * as path from 'path';
import { PathService } from '../../core/path/path.service'; import { PathService } from '../../core/path/path.service';
import { SystemService } from 'src/core/system/system.service'; import { SystemService } from 'src/core/system/system.service';

View File

@ -1,28 +1,27 @@
import { import {
Controller, Controller,
Get,
Param,
Post, Post,
HttpException, HttpException,
HttpStatus, HttpStatus,
Logger, Logger,
Inject, Inject,
UseGuards, UseGuards,
Body,
} from '@nestjs/common'; } from '@nestjs/common';
import { WordsService } from './words.service'; import { WordsService } from './words.service';
import { TokenAuthGuard } from '../../core/tools/token-auth.guard'; import { TokenAuthGuard } from '../../core/tools/token-auth.guard';
import { ApiBody, ApiOperation, ApiProperty } from '@nestjs/swagger'; import { ApiBody, ApiOperation, ApiProperty } from '@nestjs/swagger';
class WordsDto { class WordsDto {
@ApiProperty({ @ApiProperty({ description: '文案类型', example: 'poke' })
description: '文案id', type: string;
example: 'poke',
}) @ApiProperty({ description: '文案名称', example: 'poke' })
id: string; id: string;
@ApiProperty({ }
description: '密钥',
example: '1111', class WordsReloadDto extends WordsDto {
}) @ApiProperty({ description: '密钥', example: '1111' })
token: string; token: string;
} }
@ -37,16 +36,15 @@ export class WordsController {
/** /**
* *
*/ */
@Get('getText/:id') @Post('getText')
@ApiOperation({ @ApiOperation({ summary: '获取随机文案' })
summary: '获取随机文案', @ApiBody({ type: WordsDto })
}) async getText(@Body() dto: WordsDto) {
async getText(@Param('id') id: string) {
try { try {
const texts = await this.wordsService.loadWordById(id); const texts = await this.wordsService.loadWord(dto.type, dto.id);
if (!texts || texts.length === 0) { if (!texts || texts.length === 0) {
throw new HttpException( throw new HttpException(
`文案 ${id} 不存在或为空..`, `文案 ${dto.type}/${dto.id} 不存在或为空..`,
HttpStatus.NOT_FOUND, HttpStatus.NOT_FOUND,
); );
} }
@ -61,15 +59,13 @@ export class WordsController {
/** /**
* *
*/ */
@Post('reloadText/:id') @Post('reloadText')
@ApiOperation({ @ApiOperation({ summary: '重载某条文案' })
summary: '重载某条文案',
})
@UseGuards(TokenAuthGuard) @UseGuards(TokenAuthGuard)
@ApiBody({ type: WordsDto }) @ApiBody({ type: WordsReloadDto })
async reloadWord(@Param('id') id: string, @Param('token') token: string) { async reloadWord(@Body() dto: WordsReloadDto) {
try { try {
const success = await this.wordsService.reloadWord(id); const success = await this.wordsService.reloadWord(dto.type, dto.id);
if (success) { if (success) {
return '成功重载..'; return '成功重载..';
} else { } else {

View File

@ -8,7 +8,8 @@ import { AutoUpdateService } from '../../core/auto-update/auto-update.service';
export class WordsService { export class WordsService {
private readonly logger = new Logger(WordsService.name); private readonly logger = new Logger(WordsService.name);
private wordCache: Record<string, string[]> = {}; private wordCache: Record<string, string[]> = {};
private readonly clearIntervalMs = 30 * 60 * 1000; // 30min private readonly clearIntervalMs = 240 * 60 * 1000; // 240min
private readonly updateMs = 15 * 60 * 1000; // 15min
@Inject(PathService) @Inject(PathService)
private readonly paths: PathService; private readonly paths: PathService;
@ -21,9 +22,6 @@ export class WordsService {
this.startAutoUpdate(); this.startAutoUpdate();
} }
/**
*
*/
private startAutoClear() { private startAutoClear() {
setInterval(() => { setInterval(() => {
this.logger.log('清理文案缓存..'); this.logger.log('清理文案缓存..');
@ -31,9 +29,6 @@ export class WordsService {
}, this.clearIntervalMs); }, this.clearIntervalMs);
} }
/**
* words
*/
private startAutoUpdate() { private startAutoUpdate() {
setInterval(async () => { setInterval(async () => {
const wordsPath = this.paths.get('words'); const wordsPath = this.paths.get('words');
@ -42,52 +37,56 @@ export class WordsService {
wordsPath, wordsPath,
'words 仓库', 'words 仓库',
); );
if (updated) { if (updated) {
this.logger.log('文案仓库已更新,清理缓存..'); this.logger.log('文案仓库已更新,清理缓存..');
this.wordCache = {}; this.wordCache = {};
} }
}, this.clearIntervalMs); }, this.updateMs);
} }
/** /**
* *
*/ */
async loadWordById(id: string): Promise<string[] | null> { async loadWord(type: string, name: string): Promise<string[] | null> {
this.logger.log(`加载文案 ${id}..`); const cacheKey = `${type}/${name}`;
if (this.wordCache[id]) return this.wordCache[id]; this.logger.log(`加载文案 ${cacheKey}..`);
const filePath = path.join(this.paths.get('words'), `${id}.json`); if (this.wordCache[cacheKey]) return this.wordCache[cacheKey];
const filePath = path.join(this.paths.get('words'), type, `${name}.json`);
try { try {
const content = await fs.readFile(filePath, 'utf-8'); const content = await fs.readFile(filePath, 'utf-8');
const parsed = JSON.parse(content); const parsed = JSON.parse(content);
if (Array.isArray(parsed)) { if (Array.isArray(parsed)) {
const texts = parsed.filter((item) => typeof item === 'string'); const texts = parsed.filter((item) => typeof item === 'string');
this.wordCache[id] = texts; this.wordCache[cacheKey] = texts;
return texts; return texts;
} }
return null; return null;
} catch (e) { } catch (e) {
this.logger.error(`加载文案失败: ${id}..`, e); this.logger.error(`加载文案失败: ${cacheKey}`, e);
return null; return null;
} }
} }
/** /**
* json *
*/ */
async reloadWord(id: string): Promise<boolean> { async reloadWord(type: string, name: string): Promise<boolean> {
this.logger.log(`重载文案: ${id}..`); const cacheKey = `${type}/${name}`;
const filePath = path.join(this.paths.get('words'), `${id}.json`); this.logger.log(`重载文案: ${cacheKey}..`);
const filePath = path.join(this.paths.get('words'), type, `${name}.json`);
try { try {
const content = await fs.readFile(filePath, 'utf-8'); const content = await fs.readFile(filePath, 'utf-8');
const parsed = JSON.parse(content); const parsed = JSON.parse(content);
if (Array.isArray(parsed)) { if (Array.isArray(parsed)) {
this.wordCache[id] = parsed.filter((item) => typeof item === 'string'); this.wordCache[cacheKey] = parsed.filter(
(item) => typeof item === 'string',
);
return true; return true;
} }
return false; return false;
} catch (e) { } catch (e) {
this.logger.error(`重载文案失败: ${id}`, e); this.logger.error(`重载文案失败: ${cacheKey}`, e);
return false; return false;
} }
} }