forked from yoone/API
163 lines
5.4 KiB
TypeScript
163 lines
5.4 KiB
TypeScript
import { Provide } from '@midwayjs/core';
|
|
import { InjectEntityModel } from '@midwayjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import { Template } from '../entity/template.entity';
|
|
import { CreateTemplateDTO, UpdateTemplateDTO } from '../dto/template.dto';
|
|
import { Eta } from 'eta';
|
|
import { generateTestDataFromEta } from '../utils/testdata.util';
|
|
|
|
/**
|
|
* @service TemplateService 模板服务
|
|
*/
|
|
@Provide()
|
|
export class TemplateService {
|
|
private eta = new Eta();
|
|
|
|
// 注入 Template 实体模型
|
|
@InjectEntityModel(Template)
|
|
templateModel: Repository<Template>;
|
|
|
|
/**
|
|
* 获取所有模板的列表
|
|
* @returns {Promise<Template[]>} 模板实体数组
|
|
*/
|
|
async getTemplateList(params: { currentPage?: number, pageSize?: number } = {}): Promise<{ items: Template[], total: number }> {
|
|
const { currentPage = 1, pageSize = 10 } = params;
|
|
// 使用 findAndCount 方法查询所有模板
|
|
const [items, total] = await this.templateModel.findAndCount({
|
|
skip: (currentPage - 1) * pageSize,
|
|
take: pageSize,
|
|
});
|
|
return { items, total };
|
|
}
|
|
|
|
/**
|
|
* 根据唯一名称获取模板
|
|
* @param {string} name - 模板名称
|
|
* @returns {Promise<Template>} 模板实体
|
|
*/
|
|
async getTemplateByName(name: string): Promise<Template> {
|
|
// 使用 findOne 方法按名称查询模板
|
|
return this.templateModel.findOne({ where: { name } });
|
|
}
|
|
|
|
/**
|
|
* 创建一个新模板
|
|
* @param {CreateTemplateDTO} templateData - 创建模板所需的数据
|
|
* @returns {Promise<Template>} 创建后的模板实体
|
|
*/
|
|
async createTemplate(templateData: CreateTemplateDTO): Promise<Template> {
|
|
// 创建一个新的模板实例
|
|
const template = new Template();
|
|
// 设置模板的名称和值
|
|
template.name = templateData.name;
|
|
template.value = templateData.value;
|
|
if (templateData.testData && templateData.testData.trim().length > 0) {
|
|
template.testData = templateData.testData;
|
|
} else {
|
|
const obj = generateTestDataFromEta(template.value);
|
|
template.testData = JSON.stringify(obj);
|
|
}
|
|
// 保存新模板到数据库
|
|
return this.templateModel.save(template);
|
|
}
|
|
|
|
/**
|
|
* 根据 ID 更新一个现有模板
|
|
* @param {number} id - 模板 ID
|
|
* @param {UpdateTemplateDTO} templateData - 更新模板所需的数据
|
|
* @returns {Promise<Template>} 更新后的模板实体
|
|
*/
|
|
async updateTemplate(
|
|
id: number,
|
|
templateData: UpdateTemplateDTO
|
|
): Promise<Template> {
|
|
// 首先根据 ID 查找模板
|
|
const template = await this.templateModel.findOneBy({ id });
|
|
// 如果模板不存在,则抛出错误
|
|
if (!template) {
|
|
throw new Error(`模板 ID ${id} 不存在`);
|
|
}
|
|
// 更新模板的名称和值
|
|
template.name = templateData.name;
|
|
template.value = templateData.value;
|
|
if (templateData.testData && templateData.testData.trim().length > 0) {
|
|
template.testData = templateData.testData;
|
|
} else {
|
|
const obj = generateTestDataFromEta(template.value);
|
|
template.testData = JSON.stringify(obj);
|
|
}
|
|
// 保存更新后的模板到数据库
|
|
return this.templateModel.save(template);
|
|
}
|
|
|
|
/**
|
|
* 根据 ID 删除一个模板
|
|
* @param {number} id - 模板 ID
|
|
* @returns {Promise<boolean>} 如果删除成功则返回 true,否则返回 false
|
|
*/
|
|
async deleteTemplate(id: number): Promise<boolean> {
|
|
// 首先根据 ID 查找模板
|
|
const template = await this.templateModel.findOneBy({ id });
|
|
// 如果模板不存在,则抛出错误
|
|
if (!template) {
|
|
throw new Error(`模板 ID ${id} 不存在`);
|
|
}
|
|
// 如果模板不可删除,则抛出错误
|
|
if (!template.deletable) {
|
|
throw new Error(`模板 ${template.name} 不可删除`);
|
|
}
|
|
// 执行删除操作
|
|
const result = await this.templateModel.delete(id);
|
|
// 如果影响的行数大于 0,则表示删除成功
|
|
return result.affected > 0;
|
|
}
|
|
|
|
/**
|
|
* 根据模板名称和数据对象渲染最终字符串
|
|
* @param {string} name - 模板名称
|
|
* @param {Record<string, any>} data - 用于替换占位符的数据对象
|
|
* @returns {Promise<string>} 渲染后的字符串
|
|
*/
|
|
async render(name: string, data: Record<string, any>): Promise<string> {
|
|
// 根据名称获取模板
|
|
const template = await this.getTemplateByName(name);
|
|
// 如果模板不存在,则抛出错误
|
|
if (!template) {
|
|
throw new Error(`模板 '${name}' 不存在`);
|
|
}
|
|
|
|
// 使用 Eta 渲染
|
|
return this.eta.renderString(template.value, data);
|
|
}
|
|
|
|
/**
|
|
* 根据模板内容和数据对象渲染最终字符串
|
|
* @param {string} template - 模板内容
|
|
* @param {Record<string, any>} data - 用于替换占位符的数据对象
|
|
* @returns {Promise<string>} 渲染后的字符串
|
|
*/
|
|
async renderWithTemplate(template: string, data: Record<string, any>): Promise<string> {
|
|
// 直接使用 Eta 渲染传入的模板内容
|
|
return this.eta.renderString(template, data);
|
|
}
|
|
|
|
/**
|
|
* 回填所有缺失 testData 的模板
|
|
* @returns 更新的模板数量
|
|
*/
|
|
async backfillMissingTestData(): Promise<number> {
|
|
const items = await this.templateModel.find({ where: { } });
|
|
let updated = 0;
|
|
for (const t of items) {
|
|
if (!t.testData || t.testData.trim().length === 0) {
|
|
const obj = generateTestDataFromEta(t.value);
|
|
t.testData = JSON.stringify(obj);
|
|
await this.templateModel.save(t);
|
|
updated++;
|
|
}
|
|
}
|
|
return updated;
|
|
}
|
|
}
|