import BaseController from "../../common/base/base_controller"; import CompilationModel from '../../users/models/compilation_model'; import { checkCompilationPermission } from '../../common/base/base_util'; const multiparty = require('multiparty'); const excel = require('node-xlsx'); const fs = require('fs'); const facade = require('../facade/index'); const config = require("../../../config/config.js"); class PriceInfoController extends BaseController { async main(req, res) { const compilationModel = new CompilationModel(); const compilationList = await compilationModel.getPermissionCompilationList(req, { _id: 1, name: 1 }); compilationList.unshift({ _id: 'all', name: '所有' }); const activeCompilation = compilationList.find(compilation => compilation._id.toString() === req.query.filter); if (activeCompilation) { activeCompilation.active = 'active'; } else { compilationList[0].active = 'active' } const filter = req.query.filter ? { compilationID: req.query.filter } : {}; let libs = await facade.getLibs(filter); const compilationPermission = req.session.managerData.compilationPermission || []; libs = libs.filter(lib => compilationPermission.includes(lib.compilationID)); libs.forEach(lib => { compilationList.forEach(compilation => { if (compilation._id.toString() === lib.compilationID) { lib.compilationName = compilation.name; } }); }); const listItem = ` ` const renderData = { title: '材料信息价库', userAccount: req.session.managerData.username, userID: req.session.managerData.userID, libs: libs, compilationList: compilationList, listItem, layout: 'maintain/common/html/layout' }; res.render("maintain/price_info_lib/html/main.html", renderData); } async editView(req, res) { const { libID } = req.query; const libs = await facade.getLibs({ ID: libID }); if (!libs.length) { return res.send(404); } checkCompilationPermission(req, res, libs[0].compilationID, '/priceInfo/main'); const areaList = await facade.getAreas(libs[0].compilationID); const renderData = { compilationID: libs[0].compilationID, libName: libs[0].name, period: libs[0].period, areaList: JSON.stringify(areaList), userAccount: req.session.managerData.username, userID: req.session.managerData.userID, LicenseKey: config.getLicenseKey(process.env.NODE_ENV), }; res.render("maintain/price_info_lib/html/edit.html", renderData); } async addLib(req, res) { try { const { name, period, compilationID } = req.body; await facade.createLib(name, period, compilationID) } catch (err) { console.log(err); } res.redirect(req.headers.referer); } async renameLib(req, res) { try { const { libID, name } = JSON.parse(req.body.data); await facade.updateLib({ ID: libID }, { name }); res.json({ error: 0, message: 'rename success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async deleteLib(req, res) { try { const { libID } = JSON.parse(req.body.data); await facade.deleteLib(libID); res.json({ error: 0, message: 'delete success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getAreas(req, res) { try { const { compilationID } = JSON.parse(req.body.data); const data = await facade.getAreas(compilationID); res.json({ error: 0, message: 'getAreas success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getAllLibs(req, res) { try { const data = await facade.getAllLibs(); res.json({ error: 0, message: 'getAreas success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async processChecking(req, res) { try { const { key } = JSON.parse(req.body.data); const data = await facade.processChecking(key); res.json({ error: 0, message: 'processChecking', data }); } catch (err) { res.json({ error: 1, message: err.toString() }); } } // 爬取数据 async crawlData(req, res) { try { const { from, to, compilationID } = JSON.parse(req.body.data); //res.setTimeout(1000 * 60 * 60 * 2); // 不设置的话,处理时间过长,会触发默认的响应超时,报错(前端报错,后台还继续在处理) await facade.crawlDataByCompilation(compilationID, from, to); res.json({ error: 0, message: 'crawl processing' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async importExcel(req, res) { let responseData = { err: 0, msg: '' }; res.setTimeout(1000 * 60 * 10); const allowHeader = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']; const uploadOption = { uploadDir: './public' }; const form = new multiparty.Form(uploadOption); let uploadFullName; form.parse(req, async function (err, fields, files) { try { const libID = fields.libID !== undefined && fields.libID.length > 0 ? fields.libID[0] : null; const areaID = fields.areaID !== undefined && fields.areaID.length > 0 ? fields.areaID[0] : null; const importType = fields.importType !== undefined && fields.importType.length > 0 ? fields.importType[0] : null; if (!libID || !importType) { throw '参数错误。'; } const file = files.file !== undefined ? files.file[0] : null; if (err || file === null) { throw '上传失败。'; } // 判断类型 if (file.headers['content-type'] === undefined || allowHeader.indexOf(file.headers['content-type']) < 0) { throw '不支持该类型'; } // 重命名文件名 uploadFullName = uploadOption.uploadDir + '/' + file.originalFilename; fs.renameSync(file.path, uploadFullName); const sheet = excel.parse(uploadFullName); if (sheet[0] === undefined || sheet[0].data === undefined || sheet[0].data.length <= 0) { throw 'excel没有对应数据。'; } // 提取excel数据并入库 if (importType === 'originalData') { // 导入原始数据 await facade.importExcelData(libID, sheet[0].data); } else if (importType === 'mainSub') { // 导入主从表 await facade.importMainSubData(libID, areaID, sheet[0].data, sheet[1].data) } else if (importType === 'keys') { // 导入关键字 await facade.importKeyData(libID, areaID, sheet[0].data) } // 删除文件 if (uploadFullName && fs.existsSync(uploadFullName)) { fs.unlink(uploadFullName); } res.json(responseData); } catch (error) { console.log(error); if (uploadFullName && fs.existsSync(uploadFullName)) { fs.unlink(uploadFullName); } responseData.err = 1; responseData.msg = error.toString(); res.json(responseData); } }); } async editArea(req, res) { try { const { updateData } = JSON.parse(req.body.data); await facade.updateAres(updateData); res.json({ error: 0, message: 'update areas success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async insertArea(req, res) { try { const { insertData } = JSON.parse(req.body.data); await facade.insertAreas(insertData); res.json({ error: 0, message: 'update areas success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async deleteArea(req, res) { try { const { deleteData } = JSON.parse(req.body.data); await facade.deleteAreas(deleteData); res.json({ error: 0, message: 'update areas success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getClassData(req, res) { try { const { libID, areaID } = JSON.parse(req.body.data); const data = await facade.getClassData(libID, areaID); res.json({ error: 0, message: 'getCLass success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async calcPriceIndex(req, res) { try { const { period, libID, compilationID } = JSON.parse(req.body.data); const areaID = '971fb9a0-0f93-11eb-b53c-45271c1df90f';//写死珠海地区 const data = await facade.calcPriceIndex(libID, period, areaID, compilationID); res.json({ error: 0, message: 'getCLass success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getPriceData(req, res) { try { const { classIDList } = JSON.parse(req.body.data); const data = await facade.getPriceData(classIDList); res.json({ error: 0, message: 'getPriceData success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getPriceEmptyData(req, res) { try { const { libID, compilationID, areaID } = JSON.parse(req.body.data); const data = await facade.getPriceEmptyData(compilationID, libID, areaID); res.json({ error: 0, message: 'getPriceEmptyData success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async getRecommendPriceSummaryData(req, res) { try { const { keyword } = JSON.parse(req.body.data); const data = await facade.getRecommendPriceSummaryData(keyword); res.json({ error: 0, message: 'getRecommendPriceSummaryData success', data }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async editPriceData(req, res) { try { const { postData } = JSON.parse(req.body.data); await facade.editPriceData(postData); res.json({ error: 0, message: 'editPrice success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async editClassData(req, res) { try { const { updateData } = JSON.parse(req.body.data); await facade.editClassData(updateData); res.json({ error: 0, message: 'editClass success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } // 匹配总表 async matchSummary(req, res) { try { const { compilationID, libID, areaID } = JSON.parse(req.body.data); await facade.matchSummary(compilationID, libID, areaID); res.json({ error: 0, message: 'matchSummary success' }); } catch (err) { console.log(err); res.json({ error: 1, message: err.toString() }); } } async exportPriceData(request, response) { const libID = request.query.libID; const areaID = request.query.areaID; try { const excelData = await facade.exportExcelData(libID, areaID); const buffer = excel.build([{ name: "信息价主表", data: excelData }]); const filePath = './public/exportInfo.xlsx'; fs.writeFileSync(filePath, buffer, 'binary'); const stats = fs.statSync(filePath); // 下载相关header response.set({ 'Content-Type': 'application/octet-stream', 'Content-Disposition': 'attachment; filename=infoPrice.xlsx', 'Content-Length': stats.size }); fs.createReadStream(filePath).pipe(response); fs.unlink(filePath); } catch (error) { response.end(error); } } async exportInfoPriceByLib(request, response) { const libID = request.query.libID; try { const { jsonStr, period, name } = await facade.exportInfoPriceByLib(libID); const filePath = './public/exportInfoPriceByLib.json'; fs.writeFileSync(filePath, jsonStr, 'utf8'); const stats = fs.statSync(filePath); // 下载相关header response.set({ 'Content-Type': 'application/octet-stream', 'Content-Disposition': `attachment; filename=${encodeURI(name)}.json`, 'Content-Length': stats.size }); fs.createReadStream(filePath).pipe(response); fs.unlink(filePath); } catch (error) { response.end(error); } } async exportInfoPriceByCompilation(request, response) { const compilationID = request.query.compilationID; try { const compilationModel = new CompilationModel(); const compilation = await compilationModel.getCompilationById(compilationID); if (!compilation) { throw new Error('不存在此编办!'); } const { jsonStr } = await facade.exportInfoPriceByCompilation(compilationID); const filePath = './public/exportInfoPriceByCompilation.json'; fs.writeFileSync(filePath, jsonStr, 'utf8'); const stats = fs.statSync(filePath); const fileName = `${compilation.name}信息价`; // 下载相关header response.set({ 'Content-Type': 'application/octet-stream', 'Content-Disposition': `attachment; filename=${encodeURI(fileName)}.json`, 'Content-Length': stats.size }); fs.createReadStream(filePath).pipe(response); fs.unlink(filePath); } catch (error) { response.end(error); } } } module.exports = { priceInfoController: new PriceInfoController() };