forked from yoone/API
1
0
Fork 0
API/src/service/dict.service.ts

206 lines
7.5 KiB
TypeScript

import { Provide } from '@midwayjs/core';
import { InjectEntityModel } from '@midwayjs/typeorm';
import { Repository, Like } from 'typeorm';
import { Dict } from '../entity/dict.entity';
import { DictItem } from '../entity/dict_item.entity';
import { CreateDictDTO, UpdateDictDTO } from '../dto/dict.dto';
import { CreateDictItemDTO, UpdateDictItemDTO } from '../dto/dict.dto';
import * as xlsx from 'xlsx';
@Provide()
export class DictService {
@InjectEntityModel(Dict)
dictModel: Repository<Dict>;
@InjectEntityModel(DictItem)
dictItemModel: Repository<DictItem>;
// 格式化名称为 kebab-case
private formatName(name: string): string {
// 只替换空格和下划线
return String(name).replace(/[_\s]+/g, '-').toLowerCase();
}
// 生成并返回字典的XLSX模板
getDictXLSXTemplate() {
// 定义表头
const headers = ['name', 'title'];
// 创建一个新的工作表
const ws = xlsx.utils.aoa_to_sheet([headers]);
// 创建一个新的工作簿
const wb = xlsx.utils.book_new();
// 将工作表添加到工作簿
xlsx.utils.book_append_sheet(wb, ws, 'Dicts');
// 将工作簿写入缓冲区
return xlsx.write(wb, { type: 'buffer', bookType: 'xlsx' });
}
// 从XLSX文件导入字典
async importDictsFromXLSX(buffer: Buffer) {
// 读取缓冲区中的工作簿
const wb = xlsx.read(buffer, { type: 'buffer' });
// 获取第一个工作表的名称
const wsname = wb.SheetNames[0];
// 获取第一个工作表
const ws = wb.Sheets[wsname];
// 将工作表转换为JSON对象数组
const data = xlsx.utils.sheet_to_json(ws, { header: ['name', 'title'] }).slice(1);
// 创建要保存的字典实体数组
const dicts = data.map((row: any) => {
const dict = new Dict();
dict.name = this.formatName(row.name);
dict.title = row.title;
return dict;
});
// 保存字典实体数组到数据库
await this.dictModel.save(dicts);
// 返回成功导入的记录数
return { success: true, count: dicts.length };
}
// 生成并返回字典项的XLSX模板
getDictItemXLSXTemplate() {
const headers = ['name', 'title', 'titleCN', 'value', 'sort', 'image', 'shortName'];
const ws = xlsx.utils.aoa_to_sheet([headers]);
const wb = xlsx.utils.book_new();
xlsx.utils.book_append_sheet(wb, ws, 'DictItems');
return xlsx.write(wb, { type: 'buffer', bookType: 'xlsx' });
}
// 从XLSX文件导入字典项
async importDictItemsFromXLSX(buffer: Buffer, dictId: number) {
const dict = await this.dictModel.findOneBy({ id: dictId });
if (!dict) {
throw new Error('指定的字典不存在');
}
const wb = xlsx.read(buffer, { type: 'buffer' });
const wsname = wb.SheetNames[0];
const ws = wb.Sheets[wsname];
// 支持titleCN字段的导入
const data = xlsx.utils.sheet_to_json(ws, { header: ['name', 'title', 'titleCN', 'value', 'sort', 'image', 'shortName'] }).slice(1);
const items = data.map((row: any) => {
const item = new DictItem();
item.name = this.formatName(row.name);
item.title = row.title;
item.titleCN = row.titleCN; // 保存中文名称
item.value = row.value;
item.image = row.image;
item.shortName = row.shortName;
item.sort = row.sort || 0;
item.dict = dict;
return item;
});
await this.dictItemModel.save(items);
return { success: true, count: items.length };
}
getDict(where: { name?: string; id?: number; }, relations: string[]) {
if (!where.name && !where.id) {
throw new Error('必须提供 name 或 id');
}
return this.dictModel.findOne({ where, relations });
}
// 获取字典列表,支持按标题搜索
async getDicts(options: { title?: string; name?: string; }) {
const where = {
title: options.title ? Like(`%${options.title}%`) : undefined,
name: options.name ? Like(`%${options.name}%`) : undefined,
}
return this.dictModel.find({ where });
}
// 创建新字典
async createDict(createDictDTO: CreateDictDTO) {
const dict = new Dict();
dict.name = this.formatName(createDictDTO.name);
dict.title = createDictDTO.title;
return this.dictModel.save(dict);
}
// 更新字典
async updateDict(id: number, updateDictDTO: UpdateDictDTO) {
if (updateDictDTO.name) {
updateDictDTO.name = this.formatName(updateDictDTO.name);
}
await this.dictModel.update(id, updateDictDTO);
return this.dictModel.findOneBy({ id });
}
// 删除字典及其所有字典项
async deleteDict(id: number) {
// 首先删除该字典下的所有字典项
await this.dictItemModel.delete({ dict: { id } });
// 然后删除字典本身
const result = await this.dictModel.delete(id);
return result.affected > 0;
}
// 获取字典项列表,支持按 dictId 过滤
async getDictItems(params: { dictId?: number; name?: string; title?: string; }) {
const { dictId, name, title } = params;
const where: any = {};
if (dictId) {
where.dict = { id: dictId };
}
if (name) {
where.name = Like(`%${name}%`);
}
if (title) {
where.title = Like(`%${title}%`);
}
// 如果提供了 dictId,则只返回该字典下的项
if (params.dictId) {
return this.dictItemModel.find({ where });
}
// 否则,返回所有字典项
return this.dictItemModel.find();
}
// 创建新字典项
async createDictItem(createDictItemDTO: CreateDictItemDTO) {
const dict = await this.dictModel.findOneBy({ id: createDictItemDTO.dictId });
if (!dict) {
throw new Error(`创建新字典项,指定的字典ID为${createDictItemDTO.dictId},但不存在`);
}
const item = new DictItem();
item.name = this.formatName(createDictItemDTO.name);
item.title = createDictItemDTO.title;
item.titleCN = createDictItemDTO.titleCN; // 保存中文名称
item.image = createDictItemDTO.image;
item.shortName = createDictItemDTO.shortName;
item.dict = dict;
return this.dictItemModel.save(item);
}
// 更新字典项
async updateDictItem(id: number, updateDictItemDTO: UpdateDictItemDTO) {
if (updateDictItemDTO.name) {
updateDictItemDTO.name = this.formatName(updateDictItemDTO.name);
}
await this.dictItemModel.update(id, updateDictItemDTO);
return this.dictItemModel.findOneBy({ id });
}
// 删除字典项
async deleteDictItem(id: number) {
const result = await this.dictItemModel.delete(id);
return result.affected > 0;
}
// 根据字典名称获取字典项列表
async getDictItemsByDictName(dictName: string) {
// 查找字典
const dict = await this.dictModel.findOne({ where: { name: dictName } });
// 如果字典不存在,则返回空数组
if (!dict) {
return [];
}
// 返回该字典下的所有字典项
return this.dictItemModel.find({ where: { dict: { id: dict.id } } });
}
}