123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- 'use strict';
- const { CrudService } = require('naf-framework-mongoose/lib/service');
- const { BusinessError, ErrorCode } = require('naf-core').Error;
- const { ObjectId } = require('mongoose').Types;
- const _ = require('lodash');
- const compressing = require('compressing');
- const { sep } = require('path');
- const path = require('path');
- const fs = require('fs');
- const encoding = require('encoding'); // 编码转换
- const fxp = require('fast-xml-parser'); // xml转换
- // 专利运营专利申请预警表
- class PatentwarningService extends CrudService {
- constructor(ctx) {
- super(ctx, 'patentwarning');
- this.model = this.ctx.model.Patent.Patentwarning;
- this.import_root_path = _.get(this.ctx.app.config.import, 'root_path');
- this.patentInfo = this.ctx.model.Patent.Patentinfo;
- this.patentApply = this.ctx.model.Patent.Patentapply;
- this.personalModel = this.ctx.model.Personal;
- }
- async import({ uri }) {
- uri = uri.replace('/files', this.import_root_path);
- const fileFullName = path.basename(uri);
- const arr = fileFullName.split('.');
- const ext = _.last(arr);
- const fileName = _.head(arr);
- const uncompressFilePath = `${this.import_root_path}${sep}temp`;
- if (ext !== 'zip') {
- throw new BusinessError(ErrorCode.FILE_FAULT, '只接收压缩格式为zip的压缩包');
- }
- // 解压
- try {
- await compressing.zip.uncompress(uri, `${uncompressFilePath}`);
- } catch (error) {
- throw new BusinessError(ErrorCode.FILE_FAULT, '解压失败');
- }
- // 修改,多个专利:需要扫描下解压后的文件夹,然后循环处理下面所有的内容
- const tempDirRootPath = `${uncompressFilePath}${sep}${fileName}`;
- const tempDir = await fs.readdirSync(tempDirRootPath);
- const errorList = [];
- for (const tempDirPath of tempDir) {
- const thisDirPath = `${tempDirRootPath}${sep}${tempDirPath}`;
- const patentNumber = tempDirPath;
- // 找到
- let filePaths = [];
- try {
- filePaths = await this.findFileNameLoop(thisDirPath);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '解析文件具体位置失败' });
- continue;
- }
- if (filePaths.length <= 0) {
- errorList.push({ key: patentNumber, word: '未找到文件' });
- continue;
- }
- const xmlPath = filePaths.find(f => f.includes('.xml'));
- if (!xmlPath) {
- errorList.push({ key: patentNumber, word: '未找到xml文件' });
- continue;
- // throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到xml文件');
- }
- let create_number;
- try {
- create_number = await this.dealXml(xmlPath);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '解析申请号失败' });
- continue;
- // throw new BusinessError(ErrorCode.SERVICE_FAULT, '解析申请号失败');
- }
- if (!create_number) {
- errorList.push({ key: patentNumber, word: '未找到申请号' });
- continue;
- // throw new BusinessError(ErrorCode.FILE_FAULT, '未找到申请号');
- }
- let result;
- try {
- result = await this.getPatentFromInfo(create_number);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '查询专利信息失败' });
- continue;
- // throw new BusinessError(ErrorCode.SERVICE_FAULT, '查询专利信息失败');
- }
- // 再找
- if (!result) {
- try {
- result = await this.getPatentFromApply(create_number);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '查询申请信息失败' });
- continue;
- }
- }
- // 找不到就算了,弹回去了
- if (!result) {
- errorList.push({ key: patentNumber, word: '未通过申请号找到指定专利' });
- continue;
- // throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未通过申请号找到指定专利');
- }
- let warningData;
- try {
- warningData = await this.getWarningData(result);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '组织专利信息警告数据失败' });
- continue;
- // throw new BusinessError(ErrorCode.SERVICE_FAULT, '组织专利信息警告数据失败');
- }
- const tifPaths = filePaths.filter(f => f.includes('.tif'));
- let lastResult;
- if (tifPaths && tifPaths.length > 0) {
- try {
- lastResult = await this.toUploadTif(warningData, tifPaths);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '存储数据失败' });
- continue;
- }
- }
- if (lastResult) {
- try {
- await this.dirDelete(`${uncompressFilePath}`);
- } catch (error) {
- errorList.push({ key: patentNumber, word: '清除缓存失败' });
- continue;
- }
- }
- }
- if (errorList.length > 0) return errorList;
- return 'ok';
- }
- /**
- * 上传图片,保存
- * @param {Array} data 警告数据,未保存
- * @param {Array} files tif图片文件路径数组
- */
- async toUploadTif(data, files) {
- const filePaths = [];
- const savePath = ObjectId();
- for (const file of files) {
- let arr = file.split(sep);
- const fullFileName = _.last(arr);
- arr = fullFileName.split('.');
- // 文件后缀
- const ext = _.last(arr);
- // 图片文件
- const buffer = await fs.readFileSync(file);
- // 新文件名
- const randomStr = ObjectId();
- // 新文件名带后缀
- const newFileName = `${randomStr}.${ext}`;
- // 上传后部分路径
- const shortPath = `platform${sep}patent${sep}${savePath}${sep}`;
- // 上传全路径
- const path = `${this.import_root_path}${sep}${shortPath}`;
- // 检查上传全路径是否存在,不存在就创建文件夹
- await this.checkPathAndCreate(path);
- // 另存文件
- await fs.writeFileSync(`${path}${newFileName}`, buffer);
- // 替换为files开头
- let dataPath = path.replace(this.import_root_path, '/files');
- while (dataPath.indexOf('\\') >= 0) {
- dataPath = dataPath.replace('\\', '/');
- }
- // 补全请求用路径的所有路径
- dataPath += newFileName;
- filePaths.push(dataPath);
- }
- for (const i of data) {
- i.file_url = filePaths;
- }
- const res = await this.model.insertMany(data);
- return res;
- }
- /**
- * 检查路径,没有创建
- * @param {Array} filePath 图片路径数组
- */
- async checkPathAndCreate(filePath) {
- const arr = filePath.split(sep);
- // w:第一个是盘符,直接和第二个合并
- // l:前几个应该都是存在的.也可以合并
- let head = _.head(arr);
- if (arr[1]) head = `${head}${sep}${arr[1]}`;
- arr.shift();
- arr[0] = head;
- let curPath;
- for (const p of arr) {
- curPath = `${curPath ? curPath + sep : ''}${p}`;
- if (!fs.existsSync(curPath)) {
- await fs.mkdirSync(curPath);
- }
- }
- }
- /**
- * 组织专利预警数据
- * @param {Object} patent 专利
- */
- async getWarningData(patent) {
- const object = {};
- if (_.get(patent, 'create_number'))object.create_number = _.get(patent, 'create_number');
- if (_.get(patent, 'id'))object.patent_id = _.get(patent, 'id');
- if (_.get(patent, 'name'))object.patent_name = _.get(patent, 'name');
- // 找人的信息
- let userIds = _.get(patent, 'user_id', _.get(patent, 'inventor'));
- if (!userIds) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到专利的发明人');
- if (!_.isArray(userIds)) userIds = [ userIds ];
- userIds = userIds.map(i => ObjectId(i));
- const users = await this.personalModel.find({ _id: userIds });
- const arr = [];
- for (const user of users) {
- if (!_.get(user, '_id') || !_.get(user, 'name')) continue;
- const { _id, name } = user;
- const obj = _.cloneDeep(object);
- obj.to_id = _id;
- obj.to_name = name;
- arr.push(obj);
- }
- return arr;
- }
- /**
- * 在patentApply表中找指定的专利
- * @param {String} create_number 专利的申请号
- */
- async getPatentFromApply(create_number) {
- const res = await this.patentApply.findOne({ create_number });
- return res;
- }
- /**
- * 在patentInfo表中找指定的专利
- * @param {String} create_number 专利的申请号
- */
- async getPatentFromInfo(create_number) {
- const res = await this.patentInfo.findOne({ create_number });
- return res;
- }
- /**
- * 根据路径找到xml,再找到该xml的申请号
- * @param {String} filePath xml的文件路径
- */
- async dealXml(filePath) {
- const buffer = await fs.readFileSync(filePath);
- let str = encoding.convert(buffer, 'UTF8', 'GBK');
- if (!str) throw new BusinessError(ErrorCode.FILE_FAULT, '读取xml文件失败');
- str = str.toString();
- const json = fxp.parse(str);
- const create_number = _.get(json, 'data-bus.TONGZHISXJ.SHUXINGXX.SHENQINGH');
- return create_number;
- }
- /**
- * 找到深层的tif和xml
- * 因为命名方式都是以文件名,之后tif的文件夹也在深层fileName.套娃且文件名都是fileName
- * @param {String} uri temp路径
- */
- async findFileNameLoop(uri) {
- const filePath = `${_.trimEnd(uri, sep)}${sep}`;
- if (!fs.existsSync(filePath)) {
- return [];
- }
- const files = fs.readdirSync(filePath);
- let result = [];
- for (const file of files) {
- const curPath = `${filePath}${file}`;
- if (fs.statSync(curPath).isDirectory()) {
- const arr = await this.findFileNameLoop(curPath);
- result.push(...arr);
- } else {
- result.push(curPath);
- }
- }
- result = result.filter(f => f.includes('.tif') || f.includes('.xml'));
- return result;
- }
- /**
- * 删除路径下的所有内容
- * @param {String} filePath 路径
- */
- async dirDelete(filePath) {
- if (fs.existsSync(filePath)) {
- const files = fs.readdirSync(filePath);
- for (const file of files) {
- const curPath = `${filePath}${sep}${file}`;
- if (fs.statSync(curPath).isDirectory()) { // recurse
- this.dirDelete(curPath);
- } else { // delete file
- fs.unlinkSync(curPath);
- }
- }
- fs.rmdirSync(filePath);
- }
- }
- }
- module.exports = PatentwarningService;
|