chore: src/modules/knowledge/service/film.ts
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import { KnowledgeFilmEntity } from './../entity/film';
|
||||
import { Inject, Provide } from '@midwayjs/core';
|
||||
import { BaseService } from '@cool-midway/core';
|
||||
import { InjectEntityModel } from '@midwayjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { escapeObject } from '../utils/xss';
|
||||
|
||||
/**
|
||||
* 知识库模块-电影信息
|
||||
*/
|
||||
@Provide()
|
||||
export class KnowledgeFilmService extends BaseService {
|
||||
@InjectEntityModel(KnowledgeFilmEntity)
|
||||
knowledgeFilmEntity: Repository<KnowledgeFilmEntity>;
|
||||
|
||||
@Inject()
|
||||
ctx;
|
||||
|
||||
/**
|
||||
* 新增电影
|
||||
* - 业务层查重:检查同名电影是否已存在
|
||||
* - 对用户输入进行 XSS 过滤,防止存储型 XSS 攻击
|
||||
* - 排除 posters 字段(JSON数组,不需要转义)
|
||||
* @param params 电影数据
|
||||
*/
|
||||
async add(params: any) {
|
||||
// 业务层查重:检查同名电影是否已存在
|
||||
if (params.name) {
|
||||
const exist = await this.knowledgeFilmEntity.findOne({
|
||||
where: { name: params.name }
|
||||
});
|
||||
if (exist) {
|
||||
throw new Error(`电影"${params.name}"已存在,请勿重复添加`);
|
||||
}
|
||||
}
|
||||
// XSS 过滤 - 排除 posters 字段(JSON 数组)
|
||||
const safeParams = escapeObject(params, ['posters']);
|
||||
return super.add(safeParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新电影
|
||||
* - 对用户输入进行 XSS 过滤,防止存储型 XSS 攻击
|
||||
* - 排除 posters 字段(JSON数组,不需要转义)
|
||||
* @param params 电影数据
|
||||
*/
|
||||
async update(params: any) {
|
||||
// XSS 过滤 - 排除 posters 字段(JSON 数组)
|
||||
const safeParams = escapeObject(params, ['posters']);
|
||||
return super.update(safeParams);
|
||||
}
|
||||
|
||||
/**
|
||||
* API: importFilms - 批量导入电影数据
|
||||
* - 业务层查重:检查同名电影是否已存在,已存在则跳过
|
||||
* - 将 Excel 导入的数据逐条插入数据库
|
||||
* - 跳过名称为空的记录
|
||||
* - 对文本字段进行 XSS 过滤
|
||||
* @param films 电影数据数组(来自 Excel 解析)
|
||||
* @returns 导入结果统计
|
||||
*/
|
||||
async importFilms(films: any[]) {
|
||||
const successList: string[] = [];
|
||||
const failList: { name: string; error: string }[] = [];
|
||||
const skipList: string[] = [];
|
||||
|
||||
for (const film of films) {
|
||||
// 跳过名称为空的记录
|
||||
if (!film.name) {
|
||||
failList.push({ name: film.name || '(空)', error: '名称不能为空' });
|
||||
continue;
|
||||
}
|
||||
|
||||
// 业务层查重:检查同名电影是否已存在
|
||||
const exist = await this.knowledgeFilmEntity.findOne({
|
||||
where: { name: film.name }
|
||||
});
|
||||
if (exist) {
|
||||
skipList.push(film.name);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
// 映射 Excel 列名到数据库字段
|
||||
const filmData = {
|
||||
name: film.name || '',
|
||||
director: film.director || film['导演'] || film['导演/作者'] || '',
|
||||
year: film.year || film['年份'] || null,
|
||||
country: film.country || film['国家'] || '',
|
||||
language: film.language || film['语言'] || '',
|
||||
mainCharacters: film.mainCharacters || film['主要人物'] || '',
|
||||
synopsis: film.synopsis || film['内容简介'] || '',
|
||||
backgroundStory: film.backgroundStory || film['背景故事'] || '',
|
||||
posters: film.posters || film['海报链接']
|
||||
? [film.posters || film['海报链接']]
|
||||
: [],
|
||||
categoryId: film.categoryId ?? film['分类ID'] ?? film['分类'] ?? 45,
|
||||
quality: film.quality || film['质量'] || film['质量评级'] || 'C',
|
||||
watched: film.watched || film['是否已看'] || false,
|
||||
doubanRating: film.doubanRating || film['豆瓣评分'] || null,
|
||||
tmdbRating: film.tmdbRating || film['TMDB评分'] || null,
|
||||
link: film.link || film['链接'] || '',
|
||||
honors: film.honors || film['荣誉'] || '',
|
||||
highlights: film.highlights || film['亮点所在'] || '',
|
||||
whyWorthWatching: film.whyWorthWatching || film['为什么值得一看'] || ''
|
||||
};
|
||||
|
||||
// XSS 过滤
|
||||
const safeData = escapeObject(filmData, ['posters']);
|
||||
await this.knowledgeFilmEntity.insert(safeData);
|
||||
successList.push(filmData.name);
|
||||
} catch (e: any) {
|
||||
failList.push({ name: film.name, error: e.message || '导入失败' });
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
total: films.length,
|
||||
success: successList.length,
|
||||
fail: failList.length,
|
||||
skip: skipList.length,
|
||||
successList,
|
||||
failList,
|
||||
skipList
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user