123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- import { Inject, Provide, Config } from '@midwayjs/core';
- import { get } from 'lodash';
- import { Context } from '@midwayjs/koa';
- import { InjectEntityModel } from '@midwayjs/typeorm';
- import { ServiceError, ErrorCode } from '../error/service.error';
- import dayjs = require('dayjs');
- import { DictDataService } from './system/dictData.service';
- import { Equal, Repository } from 'typeorm';
- import { Achievement } from '../entity/platform/achievement.entity';
- import { Company } from '../entity/users/company.entity';
- import { Supply } from '../entity/platform/supply.entity';
- import { Project } from '../entity/platform/project.entity';
- import { Demand } from '../entity/platform/demand.entity';
- import { UserService } from './system/user.service';
- import * as mappings from '../public/importMapping';
- import * as Excel from 'exceljs';
- import * as Path from 'path';
- import * as fs from 'fs';
- import { User } from '../entity/system/user.entity';
- /**
- * 工具类服务,为其他地方提供一些通用的函数
- */
- @Provide()
- export class UtilService {
- @Inject()
- ctx: Context;
- @Inject()
- userService: UserService;
- @InjectEntityModel(User)
- userModel: Repository<User>;
- @InjectEntityModel(Achievement)
- achievementModel: Repository<Achievement>;
- @InjectEntityModel(Project)
- projectModel: Repository<Project>;
- @InjectEntityModel(Demand)
- demandModel: Repository<Demand>;
- @InjectEntityModel(Supply)
- supplyModel: Repository<Supply>;
- @InjectEntityModel(Company)
- companyModel: Repository<Company>;
- @Inject()
- dictDataService: DictDataService;
- @Config('PathConfig.path')
- path;
- // 导出
- async toExport(query) {
- const { table, config, user } = query;
- const nowDate = new Date().getTime();
- const filename = `产学研用导出-${table}-${nowDate}.xlsx`;
- const path = this.path;
- if (!path) {
- throw new ServiceError('服务端没有设置存储路径');
- }
- if (!fs.existsSync(path)) {
- // 如果不存在文件夹,就创建
- this.mkdir(path);
- }
- try {
- let info = {};
- if (user) info = { where: { user: Equal(user) } };
- const targetModel = this[`${table}Model`];
- const data = await targetModel.find(info);
- const workbook = new Excel.Workbook();
- const sheet = workbook.addWorksheet('sheet1');
- // 根据前端传回来的设置和顺序,将表头先塞进去
- const meta = config.map(i => i.label);
- sheet.addRow(meta);
- let arr = [];
- for (const d of data) {
- arr = [];
- for (const c of config) {
- const { mark, model, code } = c;
- if (mark === 'tags') {
- if (d[model]) d[model] = arr.push(d[model].join(','));
- else arr.push(d[model]);
- } else if (mark === 'area') {
- if (d[model]) d[model] = arr.push(d[model].join('-'));
- else arr.push(d[model]);
- } else if (mark === 'dict') {
- const req = await this.dictDataService.query({ code, is_use: '0' }, {});
- if (req.data) {
- const selected = req.data.find(f => f.value === d[model]);
- if (selected) {
- d[model] = get(selected, 'label');
- arr.push(d[model]);
- } else arr.push(d[model]);
- } else arr.push(d[model]);
- } else if (mark === 'time') {
- if (d.start_time && d.end_time) {
- arr.push((d[model] = `${d.start_time}-${d.end_time}`));
- } else arr.push(d[model]);
- } else arr.push(d[model]);
- }
- sheet.addRow(arr);
- }
- // 生成excel
- const filepath = `${path}${filename}`;
- if (data.length <= 0) return;
- await workbook.xlsx.writeFile(filepath);
- return `/files/cxyy/export/${filename}`;
- } catch (error) {
- console.log(error);
- }
- }
- // 创建文件夹
- mkdir(dirname) {
- if (fs.existsSync(dirname)) {
- return true;
- }
- if (this.mkdir(Path.dirname(dirname))) {
- fs.mkdirSync(dirname);
- return true;
- }
- }
- randomStr(len = 6) {
- return Math.random().toString(36).slice(-len);
- }
- /**
- * 成果
- * @param {Object} rows excel数据
- */
- async achievement(rows) {
- const mappingList = mappings.achievement;
- const result = await this.dealRows(rows, mappingList);
- const errorList = [];
- // 需要查看是否有人,有人更新数据,没人添加数据
- const user_id = this.ctx.user.id;
- for (const [index, i] of result.entries()) {
- // 根据 成果名称 查重
- const { name } = i;
- const data = await this.achievementModel.findOne({ where: { user: Equal(user_id), name: Equal(name) } });
- if (data && data.id) {
- try {
- i.id = data.id;
- await this.achievementModel.update({ id: data.id }, i);
- } catch (error) {
- errorList.push(`修改第${index + 1}条${name}出现错误!!!`);
- }
- } else {
- try {
- await this.achievementModel.insert({ ...i, user: user_id, status: '0' });
- } catch (error) {
- const namek = Object.keys(error.errors)[0];
- const mapping = mappingList.find(i => i.field === namek);
- errorList.push(`第${index + 1}条${mapping.zh}列${name}字段出现错误!!!`);
- }
- }
- }
- return { result: result.length, errorList };
- }
- /**
- * 项目
- * @param {Object} rows excel数据
- */
- async project(rows) {
- const mappingList = mappings.project;
- const result = await this.dealRows(rows, mappingList);
- const errorList = [];
- // 需要查看是否有人,有人更新数据,没人添加数据
- const user_id = this.ctx.user.id;
- for (const [index, i] of result.entries()) {
- // 根据 项目名称 查重
- const { name } = i;
- const data = await this.projectModel.findOne({ where: { user: Equal(user_id), name: Equal(name) } });
- if (data && data.id) {
- try {
- i.id = data.id;
- await this.projectModel.update({ id: data.id }, i);
- } catch (error) {
- errorList.push(`修改第${index + 1}条${name}字段出现错误!!!`);
- }
- } else {
- try {
- await this.projectModel.insert({ ...i, user: user_id, status: '0' });
- } catch (error) {
- const namek = Object.keys(error.errors)[0];
- const mapping = mappingList.find(i => i.field === namek);
- errorList.push(`第${index + 1}条${mapping.zh}列${name}字段出现错误!!!`);
- }
- }
- }
- return { result: result.length, errorList };
- }
- /**
- * 需求
- * @param {Object} rows excel数据
- */
- async demand(rows) {
- const mappingList = mappings.demand;
- const result = await this.dealRows(rows, mappingList);
- const errorList = [];
- // 需要查看是否有人,有人更新数据,没人添加数据
- const user_id = this.ctx.user.id;
- for (const [index, i] of result.entries()) {
- // 根据 需求名称 查重
- const { name } = i;
- const data = await this.demandModel.findOne({ where: { user: Equal(user_id), name: Equal(name) } });
- if (data && data.id) {
- try {
- i.id = data.id;
- await this.demandModel.update({ id: data.id }, i);
- } catch (error) {
- errorList.push(`修改第${index + 1}条${name}出现错误!!!`);
- }
- } else {
- try {
- await this.demandModel.insert({ ...i, user: user_id, status: '0' });
- } catch (error) {
- const namek = Object.keys(error.errors)[0];
- const mapping = mappingList.find(i => i.field === namek);
- errorList.push(`第${index + 1}条${mapping.zh}列${name}字段出现错误!!!`);
- }
- }
- }
- return { result: result.length, errorList };
- }
- /**
- * 供给
- * @param {Object} rows excel数据
- */
- async supply(rows) {
- const mappingList = mappings.supply;
- const result = await this.dealRows(rows, mappingList);
- const errorList = [];
- // 需要查看是否有人,有人更新数据,没人添加数据
- const user_id = this.ctx.user.id;
- for (const [index, i] of result.entries()) {
- // 根据 供给名称 查重
- const { name } = i;
- const data = await this.supplyModel.findOne({ where: { user: Equal(user_id), name: Equal(name) } });
- if (data && data.id) {
- try {
- i.id = data.id;
- await this.supplyModel.update({ id: data.id }, i);
- } catch (error) {
- errorList.push(`修改第${index + 1}条${name}出现错误!!!`);
- }
- } else {
- try {
- await this.supplyModel.insert({ ...i, user: user_id, status: '0' });
- } catch (error) {
- const namek = Object.keys(error.errors)[0];
- const mapping = mappingList.find(i => i.field === namek);
- errorList.push(`第${index + 1}条${mapping.zh}列${name}字段出现错误!!!`);
- }
- }
- }
- return { result: result.length, errorList };
- }
- /**
- * 企业
- * @param {Object} rows excel数据
- */
- async company(rows) {
- const mappingList = mappings.company;
- const result = await this.dealRows(rows, mappingList);
- const errorList = [];
- // 需要查看是否有人,有人更新数据,没人添加数据
- const user_id = this.ctx.user.id;
- for (const [index, i] of result.entries()) {
- // 根据 企业名称 查重
- const { name } = i;
- const data = await this.companyModel.findOne({ where: { user: Equal(user_id), name: Equal(name) } });
- if (data && data.id) {
- try {
- i.id = data.id;
- await this.companyModel.update({ id: data.id }, i);
- } catch (error) {
- errorList.push(`修改第${index + 1}条${name}出现错误!!!`);
- }
- } else {
- try {
- const userInfo = await this.userModel.insert({ account: name, nick_name: name, password: '123456', gender: '0', role: ['User', 'Company'], status: '1' });
- const id = get(userInfo, 'identifiers.0.id');
- await this.companyModel.insert({ ...i, user: id, status: '0' });
- } catch (error) {
- const namek = Object.keys(error.errors)[0];
- const mapping = mappingList.find(i => i.field === namek);
- errorList.push(`第${index + 1}条${mapping.zh}列${name}字段出现错误!!!`);
- }
- }
- }
- return { result: result.length, errorList };
- }
- /**
- * 处理excel传来的数据
- * @param {Array} rows excel数据,二维数组
- * @param {Object} mappingList 设置的某个映射
- * @return {Array} result 数据
- */
- async dealRows(rows, mappingList) {
- const result = [];
- const user = this.ctx.user;
- if (!user) throw new ServiceError(ErrorCode.USER_NOT_FOUND);
- for (let i = 0; i < rows.length; i++) {
- const rowData = rows[i];
- const obj = { user: user.id };
- for (let k = 0; k < rowData.length; k++) {
- let val = rowData[k];
- if (val === null) continue;
- if (typeof val === 'object' && val !== null) {
- const richText = get(val, 'richText');
- if (richText) {
- let texts = '';
- // 使用map提取name字段,然后检查是否为undefined
- // eslint-disable-next-line array-callback-return
- const mappedNames = richText.map(item => {
- // 判断字段是否存在
- if ('text' in item) {
- return item.text;
- }
- });
- // 过滤掉null或undefined的值
- const filteredNames = mappedNames.filter(text => text !== null && text !== undefined);
- // 拼接字符串
- texts = filteredNames.join('');
- val = texts;
- }
- }
- const mapping = mappingList.find(f => f.index === k);
- if (mapping) {
- const { field, type } = mapping;
- if (type) val = await this.dealTypeValue(mapping, val);
- obj[field] = val;
- }
- }
- result.push(obj);
- }
- return result;
- }
- /**
- * 转换数据
- * @param {Object} mapping 当前要处理的映射
- * @param {any} val excel值
- * @return {any} result 转换后的数据
- */
- async dealTypeValue(mapping, val) {
- const { type, code } = mapping;
- let result;
- if (type === 'date') {
- // 判断日期对不对,经过moment处理下
- const mobj = dayjs(val);
- if (mobj.isValid()) {
- result = mobj.format('YYYY-MM-DD');
- }
- } else if (type === 'dict') {
- const req = await this.dictDataService.query({}, { code });
- if (req.data) {
- const selected = req.data.find(f => f.label === val);
- if (selected) result = get(selected, 'value');
- }
- } else if (type === 'area') {
- if (val) result = val.split('-');
- } else if (type === 'number') {
- if (val) result = parseInt(val) || 0;
- }
- return result;
- }
- nameToFunction(name) {
- const obj = {
- 成果: 'achievement',
- 项目: 'project',
- 需求: 'demand',
- 供给: 'supply',
- 企业: 'company',
- };
- return get(obj, name);
- }
- }
|