Authored by lzhy

增加导出功能

@@ -60,7 +60,7 @@ import _ from 'lodash'; @@ -60,7 +60,7 @@ import _ from 'lodash';
60 import moment from 'moment'; 60 import moment from 'moment';
61 import qs from 'querystringify'; 61 import qs from 'querystringify';
62 import FinanceService from 'services/finance/finance-service'; 62 import FinanceService from 'services/finance/finance-service';
63 - 63 +import baseExportApi from 'util/excel';
64 export default { 64 export default {
65 data() { 65 data() {
66 return { 66 return {
@@ -292,8 +292,10 @@ export default { @@ -292,8 +292,10 @@ export default {
292 }, 292 },
293 //导出列表 293 //导出列表
294 exportList() { 294 exportList() {
295 - const queryString = qs.stringify(this.filterValues, true);  
296 - const href = `${FinanceService.exportSettlementDetail}${queryString}`; 295 + this.enableFilter = true;
  296 + const queryString = { ...this.filterValues(), excelConf: 'shopBill' };
  297 + const params = qs.stringify(queryString, true);
  298 + const href = `${baseExportApi}${params}`;
297 window.open(href, '_blank'); 299 window.open(href, '_blank');
298 }, 300 },
299 }, 301 },
@@ -175,10 +175,17 @@ class FinanceService extends Service { @@ -175,10 +175,17 @@ class FinanceService extends Service {
175 shopBillList(params) { 175 shopBillList(params) {
176 return this.post(apiUrl.queryShopBillList, params); 176 return this.post(apiUrl.queryShopBillList, params);
177 } 177 }
  178 +
  179 + /**
  180 + * 导出交易账务明细
  181 + * @param params
  182 + */
  183 + exportBillList(params) {
  184 + return this.post('/export/excel', params);
  185 + }
178 } 186 }
179 187
180 FinanceService.exportBalanceList = '/Api/erp/exportBalanceList'; // 导出对账单列表, 结算单列表 188 FinanceService.exportBalanceList = '/Api/erp/exportBalanceList'; // 导出对账单列表, 结算单列表
181 FinanceService.exportBalanceDetail = '/Api/erp/exportBalanceDetail'; // 导出对账单详情 189 FinanceService.exportBalanceDetail = '/Api/erp/exportBalanceDetail'; // 导出对账单详情
182 -FinanceService.exportSettlementDetail = '/Api/erp/exportSettlementDetail'; // 导出结算单详情  
183 FinanceService.exportInventory = '/Api/erp/exportInventoryLedgerList'; // 导出结算单库存 190 FinanceService.exportInventory = '/Api/erp/exportInventoryLedgerList'; // 导出结算单库存
184 export default FinanceService; 191 export default FinanceService;
  1 +const baseExportApi = '/Api/export/excel';
  2 +
  3 +export default baseExportApi;
@@ -15,6 +15,7 @@ const FileController = require('./file-controller'); @@ -15,6 +15,7 @@ const FileController = require('./file-controller');
15 const ImportController = require('./import-controller'); 15 const ImportController = require('./import-controller');
16 const CaptchaController = require('./captcha-controller'); 16 const CaptchaController = require('./captcha-controller');
17 const GeeCaptchaController = require('./gee-captcha-controller'); 17 const GeeCaptchaController = require('./gee-captcha-controller');
  18 +const OutputController = require('./output-controller');
18 19
19 let router = Express.Router(); // eslint-disable-line 20 let router = Express.Router(); // eslint-disable-line
20 21
@@ -23,6 +24,7 @@ router.post('/logout', middleware(UserController, 'logout')); @@ -23,6 +24,7 @@ router.post('/logout', middleware(UserController, 'logout'));
23 router.post('/switchShop', before, auth, middleware(UserController, 'switchShop')); 24 router.post('/switchShop', before, auth, middleware(UserController, 'switchShop'));
24 router.post('/upload/image', before, auth, middleware(FileController, 'uploadImage')); 25 router.post('/upload/image', before, auth, middleware(FileController, 'uploadImage'));
25 router.post('/import', before, auth, middleware(ImportController, 'import')); 26 router.post('/import', before, auth, middleware(ImportController, 'import'));
  27 +router.get('/export/excel', before, middleware(OutputController, 'exportExcel'));
26 router.post('/config', middleware(UserController, 'config')); 28 router.post('/config', middleware(UserController, 'config'));
27 router.get('/captcha.jpg', middleware(CaptchaController, 'captcha')); 29 router.get('/captcha.jpg', middleware(CaptchaController, 'captcha'));
28 router.get('/geeCaptcha', middleware(GeeCaptchaController, 'captcha')); 30 router.get('/geeCaptcha', middleware(GeeCaptchaController, 'captcha'));
1 const Context = require('../framework/context'); 1 const Context = require('../framework/context');
2 const nodeExcel = require('excel-export'); 2 const nodeExcel = require('excel-export');
  3 +const ExportExcelService = require('../service/export-excel-service');
  4 +const _ = require('lodash');
  5 +const exportExcelConfs = require('../service/excel-conf/exprot-excel-conf');
  6 +const config = global.yoho.config;
  7 +const moment = require('moment');
3 8
4 // 暂时弃用 9 // 暂时弃用
5 class OutputController extends Context { 10 class OutputController extends Context {
6 constructor() { 11 constructor() {
7 super(); 12 super();
  13 + this.exportExcelService = this.instance(ExportExcelService);
8 } 14 }
  15 +
9 productList(req, res) { 16 productList(req, res) {
10 const conf = { 17 const conf = {
11 name: 'mysheet', 18 name: 'mysheet',
@@ -19,7 +26,11 @@ class OutputController extends Context { @@ -19,7 +26,11 @@ class OutputController extends Context {
19 type: 'string', 26 type: 'string',
20 }, 27 },
21 ], 28 ],
22 - rows: [['1', '2'], ['3', '2'], ['4', '2']], 29 + rows: [
  30 + ['1', '2'],
  31 + ['3', '2'],
  32 + ['4', '2'],
  33 + ],
23 }; 34 };
24 const result = nodeExcel.execute(conf); 35 const result = nodeExcel.execute(conf);
25 36
@@ -27,6 +38,95 @@ class OutputController extends Context { @@ -27,6 +38,95 @@ class OutputController extends Context {
27 res.setHeader('Content-Disposition', 'attachment; filename=productList.xlsx'); 38 res.setHeader('Content-Disposition', 'attachment; filename=productList.xlsx');
28 res.end(result, 'binary'); 39 res.end(result, 'binary');
29 } 40 }
  41 +
  42 + /**
  43 + * 导出
  44 + * @param req
  45 + * @param res
  46 + */
  47 + exportExcel(req, res) {
  48 + //获取导出表格的配置文件
  49 + const { apiUrl, conf } = exportExcelConfs[req.query.excelConf];
  50 + const searchParams = this.createSearchParams(req);
  51 + //请求服务数据
  52 + this.exportExcelService.getExportData(apiUrl, searchParams).then(result => {
  53 + const totalPage = result.totalPage || 0;
  54 + if (totalPage < 1) {
  55 + res.end('', 'binary');
  56 + }
  57 + const apis = [];
  58 + for (let i = 1; i <= totalPage; i++) {
  59 + searchParams.pageNo = i;
  60 + apis.push(this.exportExcelService.getExportData(apiUrl, searchParams));
  61 + }
  62 + Promise.all(apis).then(result => {
  63 + //获取结果集中的records
  64 + const excel = this.createExcelData(result, conf);
  65 + res.setHeader('Content-Type', 'application/vnd.openxmlformats');
  66 + res.setHeader('Content-Disposition', 'attachment; filename=download.xlsx');
  67 + res.end(excel, 'binary');
  68 + });
  69 + });
  70 + }
  71 +
  72 + /**
  73 + * 组织查询数据
  74 + * @param req
  75 + */
  76 + createSearchParams(req) {
  77 + //获取导出配置
  78 + const currentShop = _.find(req.user.shops, shop => shop.shopsId === _.parseInt(req.cookies._sign));
  79 + let baseParams = {};
  80 + if (currentShop) {
  81 + baseParams = {
  82 + pid: req.user.uid,
  83 + shopsId: currentShop.shopsId,
  84 + shopId: currentShop.shopsId,
  85 + shop: currentShop.shopsId,
  86 + supplierId: currentShop.shopsBrands.length
  87 + ? req.user.supplier_id
  88 + ? req.user.supplier_id
  89 + : _.first(currentShop.shopsBrands).supplierId
  90 + : 0,
  91 + platform_id: config.platform,
  92 + };
  93 + }
  94 + return { ...req.query, ...baseParams };
  95 + }
  96 +
  97 + /**
  98 + * 组织表格要用的数据
  99 + * @param columnFields
  100 + * @param rows
  101 + */
  102 + createExcelData(dataList, config) {
  103 + const { cols, rows } = config;
  104 + const conf = { ...{}, cols, rows: [] };
  105 + const list = _.flattenDeep(_.map(dataList, 'records'));
  106 + //组织导出数据
  107 + _.forEach(list, item => {
  108 + //组织导出的每一列数据
  109 + const excelRow = [];
  110 + _.forEach(rows, row => {
  111 + if (!item.hasOwnProperty(row)) {
  112 + excelRow.push(String(''));
  113 + return true;
  114 + }
  115 + //如果导出的列是时间,则格式化时间
  116 + if ((row.indexOf('time') > -1 || row.indexOf('Time') > -1) && item[row] > 0) {
  117 + excelRow.push(String(moment(item[row] * 1000).format('YYYY-MM-DD HH:mm:ss')));
  118 + return true;
  119 + }
  120 + if (_.isNaN(item[row])) {
  121 + excelRow.push(String(item[row]));
  122 + return true;
  123 + }
  124 + excelRow.push(item[row]);
  125 + });
  126 + conf.rows.push(excelRow);
  127 + });
  128 + return nodeExcel.execute(conf);
  129 + }
30 } 130 }
31 131
32 module.exports = OutputController; 132 module.exports = OutputController;
  1 +const exportExcelConfs = {
  2 + shopBill: {
  3 + apiUrl: '/erp/queryShopBillList',
  4 + conf: {
  5 + cols: [
  6 + {
  7 + caption: '账务ID',
  8 + type: 'number',
  9 + },
  10 + {
  11 + caption: '结算时间',
  12 + type: 'string',
  13 + },
  14 + {
  15 + caption: '订单号',
  16 + type: 'string',
  17 + },
  18 + {
  19 + caption: 'SKU',
  20 + type: 'string',
  21 + },
  22 + {
  23 + caption: '数量',
  24 + type: 'number',
  25 + },
  26 + {
  27 + caption: '商品名称',
  28 + type: 'string',
  29 + },
  30 + {
  31 + caption: '账务类型',
  32 + type: 'string',
  33 + },
  34 + {
  35 + caption: '业务描述',
  36 + type: 'string',
  37 + },
  38 + {
  39 + caption: '成交价/优惠价',
  40 + type: 'number',
  41 + },
  42 + {
  43 + caption: '商家应收/分摊比例',
  44 + type: 'number',
  45 + },
  46 + {
  47 + caption: '商家应收',
  48 + type: 'number',
  49 + },
  50 + {
  51 + caption: '提现服务费',
  52 + type: 'number',
  53 + },
  54 + {
  55 + caption: '商家实收',
  56 + type: 'number',
  57 + },
  58 + {
  59 + caption: '提现状态',
  60 + type: 'string',
  61 + },
  62 + {
  63 + caption: '可提现日期',
  64 + type: 'string',
  65 + },
  66 + {
  67 + caption: '提现申请日期',
  68 + type: 'string',
  69 + },
  70 + ],
  71 + rows: [
  72 + 'id',
  73 + 'businessTime',
  74 + 'orderCode',
  75 + 'productSku',
  76 + 'quantity',
  77 + 'productName',
  78 + 'billTypeDesc',
  79 + 'clearingTypeName',
  80 + 'lastPrice',
  81 + 'clearingDiscount',
  82 + 'shopDeserveAmount',
  83 + 'withdrawServiceAmount',
  84 + 'shopNetAmount',
  85 + 'statusName',
  86 + 'withdrawalTime',
  87 + 'withdrawApplyTime',
  88 + ],
  89 + },
  90 + },
  91 +};
  92 +module.exports = exportExcelConfs;
  1 +'use strict';
  2 +
  3 +const _ = require('lodash');
  4 +const Context = require('../framework/context');
  5 +const Api = require('../common/api');
  6 +const config = global.yoho.config;
  7 +class ExportExcelService extends Context {
  8 + constructor() {
  9 + super();
  10 + this.api = this.instance(Api);
  11 + }
  12 + //获取要导出的数据
  13 + getExportData(apiUrl, params) {
  14 + const apiArr = _.split(apiUrl, '/');
  15 + const platform = apiArr[1];
  16 + const method = apiArr[2];
  17 + return this.api
  18 + .post(config.apiDomain[platform][method], params)
  19 + .then(res => {
  20 + if (res.code !== 200) {
  21 + return Promise.reject({ code: 500, message: res.message });
  22 + }
  23 + return res.data;
  24 + })
  25 + .catch(error => {
  26 + return Promise.reject({ code: 400, message: error.message });
  27 + });
  28 + }
  29 +}
  30 +module.exports = ExportExcelService;