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; @InjectEntityModel(DictItem) dictItemModel: Repository; // 格式化名称为 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 } } }); } }