|
@@ -3,12 +3,17 @@ const { CrudService } = require('naf-framework-mongoose-free/lib/service');
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const { BusinessError, ErrorCode } = require('naf-core').Error;
|
|
const _ = require('lodash');
|
|
const _ = require('lodash');
|
|
const assert = require('assert');
|
|
const assert = require('assert');
|
|
|
|
+const fs = require('fs');
|
|
|
|
+const { sep } = require('path');
|
|
|
|
+const Excel = require('exceljs');
|
|
|
|
+const moment = require('moment');
|
|
|
|
|
|
// 申请表
|
|
// 申请表
|
|
class ApplyService extends CrudService {
|
|
class ApplyService extends CrudService {
|
|
constructor(ctx) {
|
|
constructor(ctx) {
|
|
super(ctx, 'apply');
|
|
super(ctx, 'apply');
|
|
this.model = this.ctx.model.Apply;
|
|
this.model = this.ctx.model.Apply;
|
|
|
|
+ this.limit = 50;
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
@@ -33,6 +38,136 @@ class ApplyService extends CrudService {
|
|
}
|
|
}
|
|
return order;
|
|
return order;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 检查路径,创建路径;返回前端接收路径
|
|
|
|
+ */
|
|
|
|
+ async checkPath() {
|
|
|
|
+ const thisDir = 'apply';
|
|
|
|
+ const { root_path, export_dir } = this.ctx.app.config.export;
|
|
|
|
+ const arr = [ root_path, export_dir, thisDir ];
|
|
|
|
+ let rPath = '';
|
|
|
|
+ for (const i of arr) {
|
|
|
|
+ rPath = `${rPath}${i}${sep}`;
|
|
|
|
+ if (!fs.existsSync(rPath)) {
|
|
|
|
+ fs.mkdirSync(rPath);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ arr.shift();
|
|
|
|
+ arr.unshift('files');
|
|
|
|
+ const path = `/${arr.join('/')}`;
|
|
|
|
+ return { path, rPath };
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 导出
|
|
|
|
+ * @param {Object} query 查询条件
|
|
|
|
+ * @property {String} rPath 服务器位置(不包含文件名)
|
|
|
|
+ * @property {String} path 前端接收位置(不包含文件名)
|
|
|
|
+ */
|
|
|
|
+ async export(query) {
|
|
|
|
+ const { path, rPath } = await this.checkPath();
|
|
|
|
+ const fileName = `导出申请-${new Date().getTime()}.xlsx`;
|
|
|
|
+ const fullPath = `${path}/${fileName}`;
|
|
|
|
+ const fullRealPath = `${rPath}${sep}${fileName}`;
|
|
|
|
+ const total = await this.count(query);
|
|
|
|
+ const options = {
|
|
|
|
+ filename: fullRealPath,
|
|
|
|
+ useStyles: true,
|
|
|
|
+ };
|
|
|
|
+ const workbook = new Excel.stream.xlsx.WorkbookWriter(options);
|
|
|
|
+ const sheet = workbook.addWorksheet('sheet', {
|
|
|
|
+ pageSetup: {
|
|
|
|
+ horizontalCentered: true,
|
|
|
|
+ verticalCentered: true,
|
|
|
|
+ },
|
|
|
|
+ });
|
|
|
|
+ // 添加列头
|
|
|
|
+ const meta = this.getMeta();
|
|
|
|
+ const orderMeta = this.getOrderMeta();
|
|
|
|
+ const orderHead = orderMeta.map(i => i.zh);
|
|
|
|
+ const head = meta.map(i => i.zh);
|
|
|
|
+ sheet.addRow(head);
|
|
|
|
+ sheet.mergeCells(1, 4, 1, 6);
|
|
|
|
+ sheet.getRow(1).alignment = { vertical: 'middle', horizontal: 'center' };
|
|
|
|
+ let skip = 0;
|
|
|
|
+ for (let i = 0; i < total; i += this.limit) {
|
|
|
|
+ const data = await this.query(query, { skip, limit: this.limit });
|
|
|
|
+ // 去导出
|
|
|
|
+ for (let k = 0; k < data.length; k++) {
|
|
|
|
+ const e = data[k];
|
|
|
|
+ const arr = [];
|
|
|
|
+ for (const m of meta) {
|
|
|
|
+ const { key, format = i => i } = m;
|
|
|
|
+ const val = format(_.get(e, key));
|
|
|
|
+ // order额外处理
|
|
|
|
+ if (key !== 'order') arr.push(val);
|
|
|
|
+ }
|
|
|
|
+ arr.push(...orderHead);
|
|
|
|
+ sheet.addRow(arr).commit();
|
|
|
|
+ const orders = e.order;
|
|
|
|
+ for (const order of orders) {
|
|
|
|
+ // 商品,每行前3个都是空的
|
|
|
|
+ const orderArr = [];
|
|
|
|
+ for (let j = 0; j < orderHead.length; j++) orderArr.push('');
|
|
|
|
+ for (const om of orderMeta) {
|
|
|
|
+ const { key, format = i => i } = om;
|
|
|
|
+ const val = format(_.get(order, key));
|
|
|
|
+ orderArr.push(val);
|
|
|
|
+ }
|
|
|
|
+ sheet.addRow(orderArr).commit();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ skip += this.limit;
|
|
|
|
+ }
|
|
|
|
+ sheet.commit();
|
|
|
|
+ await workbook.commit();
|
|
|
|
+ return fullPath;
|
|
|
|
+ }
|
|
|
|
+ // excel表头配置
|
|
|
|
+ getMeta() {
|
|
|
|
+ return [
|
|
|
|
+ { key: 'user_name', zh: '申请人' },
|
|
|
|
+ { key: 'status', zh: '状态', format: i => {
|
|
|
|
+ let val = '';
|
|
|
|
+ switch (i) {
|
|
|
|
+ case '0':
|
|
|
|
+ val = '待审核';
|
|
|
|
+ break;
|
|
|
|
+ case '1':
|
|
|
|
+ val = '通过';
|
|
|
|
+ break;
|
|
|
|
+ case '-1':
|
|
|
|
+ val = '拒绝';
|
|
|
|
+ break;
|
|
|
|
+ case '2':
|
|
|
|
+ val = '有货,可领取';
|
|
|
|
+ break;
|
|
|
|
+ case '3':
|
|
|
|
+ val = '无货,需采买';
|
|
|
|
+ break;
|
|
|
|
+ case '4':
|
|
|
|
+ val = '领取确认完成';
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ return val;
|
|
|
|
+ } },
|
|
|
|
+ { key: 'meta.createdAt', zh: '时间', format: i => moment(i).format('YYYY-MM-DD') },
|
|
|
|
+ { key: 'order', zh: '商品' },
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
|
|
+ // 商品表头
|
|
|
|
+ getOrderMeta() {
|
|
|
|
+ return [
|
|
|
|
+ { key: 'name', zh: '名称' },
|
|
|
|
+ { key: 'num', zh: '数量' },
|
|
|
|
+ { key: 'desc', zh: '特殊说明' },
|
|
|
|
+ ];
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
module.exports = ApplyService;
|
|
module.exports = ApplyService;
|