'use strict'; /** * * * @author Mai * @date 2018/5/7 * @version */ const fs = require('fs'); const path = require('path'); const excel = require('node-xlsx'); const xlsx = require('js-xlsx'); const sendToWormhole = require('stream-wormhole'); const loadExcelType = { display: 1, actual: 2, }; const loadType = loadExcelType.display; const auditConst = require('../const/audit').ledger; const permissionConst = require('../const/account_permission'); module.exports = app => { class DealBillsController extends app.BaseController { /** * 获取标段的签约清单数据 * @param ctx * @return {Promise} */ async getData(ctx) { const responseData = { err: 0, msg: '', data: [], }; try { responseData.data = await ctx.service.dealBills.getAllDataByCondition({ where: { tender_id: ctx.tender.id }, orders: [['order', 'asc']], }); } catch (error) { this.log(error); responseData.err = 1; responseData.msg = error.toString(); } ctx.body = responseData; } async checkPermisision(ctx) { if (!ctx.tender.data) throw '标段数据错误'; const tender = ctx.tender.data; const isUser = tender.user_id === this.ctx.session.sessionUser.accountId; const auditors = await this.service.ledgerAudit.getAuditors(tender.id, tender.ledger_times); const auditorsId = this.ctx.helper._.map(auditors, 'audit_id'); const isAuditor = auditorsId.indexOf(this.ctx.session.sessionUser.accountId) >= 0; const upPermision = this.ctx.session.sessionUser.permission ? this.ctx.session.sessionUser.permission.tender.indexOf('3') >= 0 : false; if (!(((tender.ledger_status === auditConst.status.uncheck || tender.ledger_status === auditConst.status.checkNo) && isUser) || (tender.ledger_status === auditConst.status.checking && isAuditor) || (tender.ledger_status === auditConst.status.checked && isAuditor && upPermision))) { throw '您无权进行该操作'; } } /** * 导入Excel数据 * @param ctx * @return {Promise} */ async loadExcel(ctx) { let stream; try { await this.checkPermisision(ctx); stream = await ctx.getFileStream(); const create_time = Date.parse(new Date()) / 1000; const fileInfo = path.parse(stream.filename); const fileName = this.app.config.filePath + '/cache/deal_bills/uploads/' + 'deal_bills' + create_time + fileInfo.ext; // 保存文件 await ctx.helper.saveStreamFile(stream, fileName); if (loadType === loadExcelType.display) { const wb = xlsx.readFile(fileName); const name = wb.SheetNames[0]; const sheetData = { rows: xlsx.utils.sheet_to_json(wb.Sheets[name], {header: 1}), merge: wb.Sheets[name]["!merges"], }; const result = await ctx.service.dealBills.importDataJsXlsx(sheetData, ctx.tender.id); if (!result) { throw '导入数据失败'; } } else { // 读取文件 const sheet = excel.parse(fileName); if (!sheet || sheet.length === 0 || sheet[0] === undefined || sheet[0].data === undefined) { throw 'excel没有对应数据'; } const result = await ctx.service.dealBills.importData(sheet[0], ctx.tender.id); if (!result) { throw '导入数据失败'; } } const dealBills = await this.ctx.service.dealBills.getAllDataByCondition({ where: { tender_id: ctx.tender.id }, orders: [['order', 'asc']], }); ctx.body = {err: 0, msg: '', data: dealBills}; } catch (err) { this.log(err); // 失败需要消耗掉stream 以防卡死 if (stream) { await sendToWormhole(stream); } this.ajaxErrorBody(err, '导入数据失败'); } } /** * 下载模板文件 * @param ctx * @return {Promise} */ async download(ctx) { const file = ctx.params.file; if (file) { try { let fileName; if (file === '签约清单导入格式.xls') { fileName = this.app.baseDir + '/app/public/deal_bills/签约清单导入格式.xls'; ctx.body = await fs.readFileSync(fileName); } else if (file === '签约清单转换格式.xls') { fileName = this.app.baseDir + '/app/public/deal_bills/转换格式.xls'; ctx.body = await fs.readFileSync(fileName); } else if (file === '签约清单.xlsx') { const create_time = Date.parse(new Date()) / 1000; fileName = this.app.baseDir + '/app/public/deal_bills/downloads/' + ctx.tender.id + '-' + create_time + '.xlsx'; await this.ctx.helper.recursiveMkdirSync(this.app.baseDir + '/app/public/deal_bills/downloads'); // todo 导出签约清单Excel const setting = { header: ['清单编号', '名称', '单位', '数量', '单价', '金额'], width: [80, 150, 60, 80, 80, 80], hAlign: ['left', 'left', 'center', 'right', 'right', 'right'], }; const dealBills = await ctx.service.dealBills.getAllDataByCondition({ where: { tender_id: ctx.tender.id } }); const data = []; for (const db of dealBills) { data.push([db.code, db.name, db.unit, db.quantity, db.unit_price, db.total_price]); } const arraySheetData = this.ctx.helper.simpleXlsxSheetData(setting, data); xlsx.writeFile({ SheetNames: ['Sheet1'], Sheets: { 'Sheet1': arraySheetData, }, }, fileName); ctx.body = await fs.readFileSync(fileName); // 输出文件后删除 fs.unlinkSync(fileName); } } catch (err) { this.log(err); } } } async _base(ctx, type, data) { if (isNaN(data.id) || data.id <= 0) throw '数据错误'; if (type !== 'add') { if (isNaN(data.count) || data.count <= 0) data.count = 1; } switch (type) { case 'add': return await ctx.service.dealBills.addNodeBatch(ctx.tender.id, data.id, {}, data.count); case 'delete': return await ctx.service.dealBills.delete(ctx.tender.id, data.id, data.count); } } /** * 更新清单相关 (Ajax) * @param ctx * @return {Promise} */ async update(ctx) { try { await this.checkPermisision(ctx); const data = JSON.parse(ctx.request.body.data); const result = await ctx.service.dealBills.updateDatas(data); ctx.body = { err: 0, msg: '', data: result }; } catch (err) { this.log(err); ctx.body = this.ajaxErrorBody(err); } } } return DealBillsController; };