Showing
7 changed files
with
241 additions
and
5 deletions
@@ -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; |
app/util/excel.js
0 → 100644
@@ -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; |
server/service/export-excel-service.js
0 → 100644
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; |
-
Please register or login to post a comment