|
@@ -1,6 +1,7 @@
|
|
'use strict';
|
|
'use strict';
|
|
const { CrudService } = require('naf-framework-mongoose/lib/service');
|
|
const { CrudService } = require('naf-framework-mongoose/lib/service');
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
|
|
+const Path = require('path');
|
|
const _ = require('lodash');
|
|
const _ = require('lodash');
|
|
const moment = require('moment');
|
|
const moment = require('moment');
|
|
const assert = require('assert');
|
|
const assert = require('assert');
|
|
@@ -18,6 +19,15 @@ class DisclosureService extends CrudService {
|
|
this.personalModel = this.ctx.model.Personal;
|
|
this.personalModel = this.ctx.model.Personal;
|
|
this.organizationModel = this.ctx.model.Organization;
|
|
this.organizationModel = this.ctx.model.Organization;
|
|
this.itemp = this.ctx.model.Patent.ImportTemp;
|
|
this.itemp = this.ctx.model.Patent.ImportTemp;
|
|
|
|
+
|
|
|
|
+ this.root_path = _.get(this.ctx.app.config.export, 'root_path');
|
|
|
|
+ if (!fs.existsSync(`${this.root_path}`)) {
|
|
|
|
+ // 如果不存在文件夹,就创建
|
|
|
|
+ fs.mkdirSync(`${this.root_path}`);
|
|
|
|
+ }
|
|
|
|
+ this.excel_path = `${sep}excel${sep}`;
|
|
|
|
+ this.domain = _.get(this.ctx.app.config.export, 'domain');
|
|
|
|
+ this.export_limit = 50;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -68,7 +78,6 @@ class DisclosureService extends CrudService {
|
|
async check({ id, status, remark }) {
|
|
async check({ id, status, remark }) {
|
|
const data = { status };
|
|
const data = { status };
|
|
if (status === '4') data['meta.state'] = 1;
|
|
if (status === '4') data['meta.state'] = 1;
|
|
- console.log(data);
|
|
|
|
await this.model.updateOne({ _id: ObjectId(id) }, data);
|
|
await this.model.updateOne({ _id: ObjectId(id) }, data);
|
|
// 换成对应的状态码,record在下面
|
|
// 换成对应的状态码,record在下面
|
|
return await this.record({ id, method: status, remark });
|
|
return await this.record({ id, method: status, remark });
|
|
@@ -187,9 +196,8 @@ class DisclosureService extends CrudService {
|
|
|
|
|
|
// 导入
|
|
// 导入
|
|
async import({ uri }) {
|
|
async import({ uri }) {
|
|
- const domain = process.env.NODE_ENV === 'development' ? 'http://broadcast.waityou24.cn/' : 'http://127.0.0.1';
|
|
|
|
assert(uri, '未获取到文件地址');
|
|
assert(uri, '未获取到文件地址');
|
|
- const file = await this.ctx.curl(`${domain}${uri}`);
|
|
|
|
|
|
+ const file = await this.ctx.curl(`${this.domain}${uri}`);
|
|
if (!(file && file.data)) {
|
|
if (!(file && file.data)) {
|
|
throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到指定文件');
|
|
throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到指定文件');
|
|
}
|
|
}
|
|
@@ -368,6 +376,163 @@ class DisclosureService extends CrudService {
|
|
return base64;
|
|
return base64;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
|
|
|
|
+
|
|
|
|
+ async toExport({ id, ...others }) {
|
|
|
|
+ const data = {
|
|
|
|
+ title: '专利运营-专利导出',
|
|
|
|
+ params: {
|
|
|
|
+ project: 'market',
|
|
|
|
+ service: 'patent.disclosure',
|
|
|
|
+ method: 'exportAction',
|
|
|
|
+ body: { id, ...others },
|
|
|
|
+ },
|
|
|
|
+ tenant: 'disclosure.export',
|
|
|
|
+ user: id,
|
|
|
|
+ };
|
|
|
|
+ try {
|
|
|
|
+ await this.ctx.service.util.httpUtil.cpost('/api/mission', 'mission', data);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.log(error);
|
|
|
|
+ throw new BusinessError(ErrorCode.SERVICE_FAULT, '任务创建失败');
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async exportAction({ missionid, ...body }) {
|
|
|
|
+ const nowDate = new Date().getTime();
|
|
|
|
+ const filename = `专利运营-专利导出-${nowDate}.xlsx`;
|
|
|
|
+ const path = `${this.root_path}${this.excel_path}`;
|
|
|
|
+ if (!path) {
|
|
|
|
+ throw new BusinessError(ErrorCode.BUSINESS, '服务端没有设置存储路径');
|
|
|
|
+ }
|
|
|
|
+ if (!fs.existsSync(path)) {
|
|
|
|
+ // 如果不存在文件夹,就创建
|
|
|
|
+ fs.mkdirSync(path);
|
|
|
|
+ }
|
|
|
|
+ // 整理条件
|
|
|
|
+ const total = await this.ctx.service.dock.patent.count(body);
|
|
|
|
+ console.log(total);
|
|
|
|
+ if (total === 0) {
|
|
|
|
+ try {
|
|
|
|
+ const data = {
|
|
|
|
+ progress: 0,
|
|
|
|
+ status: '3',
|
|
|
|
+ remark: '未查到任何数据,无法导出',
|
|
|
|
+ };
|
|
|
|
+ await this.ctx.service.util.httpUtil.cpost(`/api/mission/update/${missionid}`, 'mission', data);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.logger.error(`任务id:${missionid},更新失败操作 失败`);
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ let skip = 0;
|
|
|
|
+ let downloadPath;
|
|
|
|
+ // 将数据分割,否则容易直接把js堆栈干满了,服务就炸了
|
|
|
|
+ for (let i = 0; i < total; i = i + this.export_limit) {
|
|
|
|
+ const list = await this.ctx.service.dock.patent.query(body, { skip, limit: this.export_limit });
|
|
|
|
+ skip = skip + this.export_limit;
|
|
|
|
+ downloadPath = await this.asyncExport(list, filename, path, downloadPath);
|
|
|
|
+ try {
|
|
|
|
+ const data = {
|
|
|
|
+ progress: _.ceil((skip / total) * 100),
|
|
|
|
+ status: '1',
|
|
|
|
+ id: missionid,
|
|
|
|
+ };
|
|
|
|
+ this.ctx.service.util.httpUtil.cpost('/api/mission/progress', 'mission', data);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.logger.error(`任务id:${missionid},进度更新失败`);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ const data = {
|
|
|
|
+ progress: 100,
|
|
|
|
+ status: '2',
|
|
|
|
+ uri: downloadPath,
|
|
|
|
+ };
|
|
|
|
+ await this.ctx.service.util.httpUtil.cpost(`/api/mission/update/${missionid}`, 'mission', data);
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.logger.error(`任务id:${missionid},已完成更新失败`);
|
|
|
|
+ }
|
|
|
|
+ return downloadPath;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ async asyncExport(list, filename, path, downloadPath) {
|
|
|
|
+ const workbook = new Excel.Workbook();
|
|
|
|
+ let sheet;
|
|
|
|
+ if (!downloadPath) {
|
|
|
|
+ sheet = workbook.addWorksheet('sheet');
|
|
|
|
+ } else {
|
|
|
|
+ const file = await this.ctx.curl(`${this.domain}${downloadPath}`);
|
|
|
|
+ if (!(file && file.data)) {
|
|
|
|
+ throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到指定文件');
|
|
|
|
+ }
|
|
|
|
+ await workbook.xlsx.load(file.data);
|
|
|
|
+ sheet = workbook.getWorksheet('sheet');
|
|
|
|
+ }
|
|
|
|
+ const rowNumber = sheet.rowCount || 1;
|
|
|
|
+ const meta = this.getHeader();
|
|
|
|
+ sheet.columns = meta;
|
|
|
|
+ sheet.addRows(list);
|
|
|
|
+ for (let i = 0; i < list.length; i++) {
|
|
|
|
+ const e = list[i];
|
|
|
|
+ const { img_url, _id } = e;
|
|
|
|
+ try {
|
|
|
|
+ if (img_url) {
|
|
|
|
+ const is_base64 = img_url.includes('base64,');
|
|
|
|
+ let imgid;
|
|
|
|
+ if (is_base64) {
|
|
|
|
+ imgid = workbook.addImage({
|
|
|
|
+ base64: img_url,
|
|
|
|
+ extension: 'jpeg',
|
|
|
|
+ });
|
|
|
|
+ } else if (img_url.includes('/files')) {
|
|
|
|
+ const prefix = `${this.root_path}`;
|
|
|
|
+ const new_url = img_url.replace('/files', prefix);
|
|
|
|
+ const suffix = Path.extname(img_url).substring(1);
|
|
|
|
+ imgid = workbook.addImage({
|
|
|
|
+ filename: new_url,
|
|
|
|
+ extension: suffix,
|
|
|
|
+ });
|
|
|
|
+ } else {
|
|
|
|
+ // 什么都不是,那就下一个
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ sheet.addImage(imgid, {
|
|
|
|
+ tl: { col: 13.2, row: i + rowNumber + 0.2 },
|
|
|
|
+ br: { col: 14, row: i + rowNumber + 1 },
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ } catch (error) {
|
|
|
|
+ this.ctx.logger.error(`导出,id为:${_id}的图片处理出现错误!`);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ const filepath = `${path}${filename}`;
|
|
|
|
+ if (list.length <= 0) return;
|
|
|
|
+ await workbook.xlsx.writeFile(filepath);
|
|
|
|
+ return `/files/excel/${filename}`;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ getHeader() {
|
|
|
|
+ const arr = [
|
|
|
|
+ { header: '申请号', key: 'create_number', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '申请日', key: 'create_date', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '公开(公告)号', key: 'success_number', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '公开(公告)日', key: 'success_date', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '发明人', key: 'inventor', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '代理机构', key: 'agent', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '代理人', key: 'agent_personal', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '摘要', key: 'abstract', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '发明人地址', key: 'address', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '标题', key: 'name', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '申请人', key: 'apply_personal', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '专利有效性', key: 'term', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '专利类型', key: 'type', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ { header: '首页附图', width: 30, style: { alignment: { wrapText: true, vertical: 'middle', horizontal: 'center' } } },
|
|
|
|
+ ];
|
|
|
|
+ return arr;
|
|
|
|
+ }
|
|
|
|
+}
|
|
module.exports = DisclosureService;
|
|
module.exports = DisclosureService;
|