/** * Created by Mai on 2017/1/18. */ const UnitPriceFileModel = require("../../glj/models/unit_price_file_model"); const moment = require('moment'); const CompilationModel = require("../../users/models/compilation_model"); const UserModel = require("../../users/models/user_model"); const userModelObj = new UserModel(); let mongoose = require('mongoose'); let ProjectsData = require('../models/project_model').project; let labourCoe = require('../../main/facade/labour_coe_facade'); let projType = require('../models/project_model').projType; let fileType = require('../models/project_model').fileType; const engineering = require("../../common/const/engineering"); let EngineeringLibModel = require("../../users/models/engineering_lib_model"); let fee_rate_facade = require("../../fee_rates/facade/fee_rates_facade"); let billsModel = require('../../main/models/bills').model; let rationsModel = require('../../main/models/ration').model; let projectModel = mongoose.model('projects'); let unitPriceFileModel = mongoose.model('unit_price_file'); let feeRateFileModel = mongoose.model('fee_rate_file'); let asyncTool = require('async'); let pm_facade = require('../facade/pm_facade'); const userModel = mongoose.model('user'); let config = require("../../../config/config.js"); const optionModel = mongoose.model('options'); const stdBillsGuidanceLibModel = mongoose.model('std_billsGuidance_lib'); const fs = require('fs'); const _ = require('lodash'); const SectionTreeDao = require('../../complementary_ration_lib/models/sectionTreeModel'); const uuidV1 = require('uuid/v1'); let sectionTreeDao = new SectionTreeDao(); let consts = require('../../main/models/project_consts'); const rationLibModel = mongoose.model('std_ration_lib_map'); const multiparty = require("multiparty"); let logger = require("../../../logs/log_helper").logger; let rp = require('request-promise'); const commonUtil = require('../../../public/common_util'); //统一回调函数 let callback = function (req, res, err, message, data) { res.json({ error: err, message: message, data: data }); }; module.exports = { checkRight: function (req, res) { if (typeof req.body.data === 'object') { req.body.data = JSON.stringify(req.body.data); } let data = JSON.parse(req.body.data); if (data.user_id) { return data.user_id === req.session.sessionUser.id; } else { return false; } }, checkProjectRight: function (userId, projectId, callback) { ProjectsData.getProject(projectId).then(async function (result) { /** * result._doc.userID(Number): MongoDB * userId(String): Session.userID */ let shareInfo = null; let isOpenShareProject = false; //判断是否是打开分享的项目,分享项目shareInfo不为null if (userId !== result.userID) { shareInfo = await pm_facade.getShareInfo(userId, result.ID); isOpenShareProject = true; } if ((userId === result.userID || shareInfo) && result._doc.projType === projType.tender) { const allowCooperate = (shareInfo || {}).allowCooperate; const allowCopy = (shareInfo || {}).allowCopy; callback(true, result, isOpenShareProject, allowCooperate,allowCopy); } else { callback(false); } }).catch(function (err) { callback(false); }); }, getProjects: async function (req, res) { await ProjectsData.getUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, function (err, message, data) { console.log(err); callback(req, res, err, message, data); }); }, updateProjects: async function (req, res) { let data = JSON.parse(req.body.data); try { await ProjectsData.updateUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, req.session.sessionCompilation.name, req.session.sessionCompilation.overWriteUrl, data.updateData, function (err, message, data) { if (err === 0) { callback(req, res, err, message, data); } else { callback(req, res, 1, message, null); } }); } catch (err) { callback(req, res, 1, String(err), null); } }, // CSL, 2017-12-14 该方法用于项目属性:提交保存混合型数据,这些数据来自不同的表,包括projects.property、ration、bills、labour_coes. updateMixDatas: async function (req, res) { let datas = JSON.parse(req.body.data).mixDataArr; let functions = []; function updateFunc(model, cod, doc) { return function (cb) { model.update(cod, doc, cb); } }; function updateLC() { return function (cb) { datas.labourCoes.updateData.projectID = datas.projectID; labourCoe.save(datas.labourCoes.updateData, cb); } }; // 项目属性 if (Object.keys(datas.properties).length > 0) { //基本信息特殊处理,更新建设项目 if (datas.properties['property.basicInformation']) { let constructionProject = await pm_facade.getConstructionProject(datas.projectID); if (constructionProject) { functions.push(updateFunc(projectModel, { ID: constructionProject.ID }, { 'property.basicInformation': datas.properties['property.basicInformation'] })); } delete datas.properties['property.basicInformation']; } //建设项目-编制说明,更新建设项目 if (datas.properties['property.compilationIllustrationProject']) { let constructionProject = await pm_facade.getConstructionProject(datas.projectID); if (constructionProject) { functions.push(updateFunc(projectModel, { ID: constructionProject.ID }, { 'property.compilationIllustration': datas.properties['property.compilationIllustrationProject'] })); } delete datas.properties['property.compilationIllustrationProject']; } functions.push(updateFunc(projectModel, { ID: datas.projectID }, datas.properties)); }; //选项 if (datas.options && datas.options.updateData) { functions.push(updateFunc(optionModel, { user_id: req.session.sessionUser.id, compilation_id: req.session.sessionCompilation._id }, { 'options.GENERALOPTS': datas.options.updateData })); } // 人工系数 if (datas.labourCoes && datas.labourCoes.updateData) { functions.push(updateLC()); }; // 清单:每文档doc只存储一条清单,每条清单都必须定位一次文档,无法合并处理 if (datas.bills && datas.bills.length > 0) { for (let bill of datas.bills) { functions.push(updateFunc(billsModel, { projectID: datas.projectID, ID: bill.ID, deleteInfo: null }, bill)); }; }; // 定额:每文档doc只存储一条定额,每条定额都必须定位一次文档,无法合并处理 if (datas.rations && datas.rations.length > 0) { for (let ration of datas.rations) { functions.push(updateFunc(rationsModel, { projectID: datas.projectID, ID: ration.ID, deleteInfo: null }, ration)); }; }; asyncTool.parallel(functions, function (err, result) { { if (!err) { res.json({ error: 0, message: err, data: result }); } else { res.json({ error: 1, message: err, data: null }); } } }); }, updateFiles: async function (req, res) { let data = JSON.parse(req.body.data); let updateDatas = data.updateDatas; await ProjectsData.udpateUserFiles(req.session.sessionUser.id, updateDatas, function (err, message, data) { callback(req, res, err, message, data); }); }, defaultSettings: async function (req, res) { try { let data = JSON.parse(req.body.data); let projectID = data.projectID; let defaultSettingSc = await ProjectsData.defaultSettings(req.session.sessionUser.id, req.session.sessionCompilation._id, projectID); if (!defaultSettingSc) { throw '恢复失败'; } res.json({ error: 0, message: '恢复成功', data: null }); } catch (error) { console.log(error); res.json({ error: 1, message: error, data: null }); } }, /* copyProjects: function (req, res) { let data = JSON.parse(req.body.data); ProjectsData.copyUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, data.updateData, function (err, message, data) { if (err === 0) { callback(req, res, err, message, data); } else { callback(req, res, err, message, null); } }); },*/ rename: function (req, res) { let data = JSON.parse(req.body.data); ProjectsData.rename(req.session.sessionUser.id, req.session.sessionCompilation._id, data, function (err, message) { callback(req, res, err, message, null); }); }, //project getData接口 getData: function (projectID, callback, isReport, userID) { projectModel.findOne({ $or: [{ deleteInfo: null }, { 'deleteInfo.deleted': false }], ID: projectID }, '-_id').then(async function (project) { if (!project) { callback('', consts.projectConst.PROJECT_INFO, {}); } let engineeringLibModel = new EngineeringLibModel(); let engineeringInfo = project !== null && project.property.engineering_id !== undefined ? await engineeringLibModel.getEngineering(project.property.engineering_id) : null; //查找定额库的定额库编码 if (Array.isArray(engineeringInfo.ration_lib)) { let rationLibIDs = engineeringInfo.ration_lib.map(data => data.id); let rationLibs = await rationLibModel.find({ ID: { $in: rationLibIDs } }, 'ID libCode'); for (let rationLib of rationLibs) { let lib = engineeringInfo.ration_lib.find(data => data.id == rationLib.ID); lib.libCode = rationLib.libCode; } } let projInfo = project._doc; if (engineeringInfo !== null) { if (engineeringInfo.billsGuidance_lib) { for (let billsGuidanceLib of engineeringInfo.billsGuidance_lib) { let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ ID: billsGuidanceLib.id }); if (stdBillsGuidanceLib) { billsGuidanceLib.type = stdBillsGuidanceLib.type ? stdBillsGuidanceLib.type : 1; } } } projInfo.engineeringInfo = engineeringInfo; } //读取建设项目的项目属性 let constructionProperty = await ProjectsData.getConstructionProperty(projectID); // 文件类型(招/投标) projInfo.property.fileKind = constructionProperty && constructionProperty.fileKind || 1; //基本信息 projInfo.property.basicInformation = constructionProperty && constructionProperty.basicInformation ? constructionProperty.basicInformation : []; //编制说明 projInfo.property.compilationIllustrationProject = constructionProperty && constructionProperty.compilationIllustration ? constructionProperty.compilationIllustration : ''; //获取单位工程完整目录结构 let fullPath = await pm_facade.getFullPath(projectID); projInfo.fullPath = fullPath; // 获取分享的tip projInfo.shareTip = await pm_facade.getShareTip(projectID, 2); // 获取分享状态 if (typeof userID === 'string') { projInfo.shareState = await pm_facade.getShareState(projectID, userID); } // 获取项目所属用户 projInfo.owner = await userModel.findOne({_id: mongoose.Types.ObjectId(project.userID)}, 'real_name mobile').lean(); projInfo.opener = await userModel.findOne({_id: mongoose.Types.ObjectId(userID)}, 'real_name mobile').lean(); callback('', consts.projectConst.PROJECT_INFO, project); }, function (err) { callback(err, consts.projectConst.PROJECT_INFO, {}); }); }, getProject: function (req, res) { let data = JSON.parse(req.body.data); let projectID = data.proj_id; ProjectsData.getUserProject(req.session.sessionUser.id, data.proj_id, async function (err, message, data) { if (err === 0) { let engineeringLibModel = new EngineeringLibModel(); let engineeringInfo = data !== null && data.property.engineering_id !== undefined ? await engineeringLibModel.getEngineering(data.property.engineering_id) : null; let strData = JSON.stringify(data); let projInfo = JSON.parse(strData); if (engineeringInfo !== null) { if (engineeringInfo.billsGuidance_lib) { for (let billsGuidanceLib of engineeringInfo.billsGuidance_lib) { let stdBillsGuidanceLib = await stdBillsGuidanceLibModel.findOne({ ID: billsGuidanceLib.id }); if (stdBillsGuidanceLib) { billsGuidanceLib.type = stdBillsGuidanceLib.type ? stdBillsGuidanceLib.type : 1; } } } projInfo.engineeringInfo = engineeringInfo; } //读取建设项目的项目属性 let constructionProperty = await ProjectsData.getConstructionProperty(projectID); console.log(projectID); console.log(constructionProperty); //基本信息 projInfo.property.basicInformation = constructionProperty && constructionProperty.basicInformation ? constructionProperty.basicInformation : []; //编制说明 projInfo.property.compilationIllustrationProject = constructionProperty && constructionProperty.compilationIllustration ? constructionProperty.compilationIllustration : ''; //获取单位工程完整目录结构 let fullPath = await pm_facade.getFullPath(projectID); projInfo.fullPath = fullPath; callback(req, res, err, message, projInfo); } else { callback(req, res, err, message, null); } }); }, beforeOpenProject: function (req, res) { let data = JSON.parse(req.body.data); ProjectsData.beforeOpenProject(req.session.sessionUser.id, data.proj_id, data.updateData, function (err, message, data) { callback(req, res, err, message, data); }); }, getNewProjectID: function (req, res) { let data = JSON.parse(req.body.data); ProjectsData.getNewProjectID(data.count, function (err, message, data) { callback(req, res, err, message, data); }); }, // 项目管理首页 index: async function (request, response) { //await pm_facade.prepareShareList(); // 获取编办信息 let sessionCompilation = request.session.sessionCompilation; if (sessionCompilation === undefined || sessionCompilation === null) { return response.redirect('/logout'); } let compilationModel = new CompilationModel(); //更新编办信息 let compilationData = await compilationModel.getCompilationById(sessionCompilation._id); request.session.sessionCompilation = compilationData; sessionCompilation = request.session.sessionCompilation; //更新用户的使用过的费用定额列表 let isFirst = await pm_facade.isFirst(request.session.sessionUser.id, compilationData._id.toString()); // 清单计价 let billValuation = sessionCompilation.bill_valuation !== undefined ? sessionCompilation.bill_valuation : []; // 获取标准库数据 let engineeringLibModel = new EngineeringLibModel(); billValuation = await engineeringLibModel.getLib(billValuation); // 定额计价 let rationValuation = sessionCompilation.ration_valuation !== undefined ? sessionCompilation.ration_valuation : []; rationValuation = await engineeringLibModel.getLib(rationValuation); let absoluteUrl = compilationData.overWriteUrl ? request.app.locals.rootDir + compilationData.overWriteUrl : request.app.locals.rootDir; let overWriteUrl = fs.existsSync(absoluteUrl) && fs.statSync(absoluteUrl).isFile() ? compilationData.overWriteUrl : null; //欢迎页显示控制 let [isShow, context] = await pm_facade.getWelcomeInfo(sessionCompilation._id, request.session.sessionUser, request.session.compilationVersion.includes('免费')); // 未读的分享项目数量 const unreadShareList = await pm_facade.getUnreadShareListByCompilation(request.session.sessionUser.id, sessionCompilation._id); let renderData = { unreadShareList: JSON.stringify(unreadShareList), isFirst: isFirst, isShow: isShow, context: context, userAccount: request.session.userAccount, userID: request.session.sessionUser.id, compilationData: JSON.stringify(sessionCompilation), overWriteUrl: overWriteUrl, billValuation: JSON.stringify(billValuation.reverse()), // 按最新排序 rationValuation: JSON.stringify(rationValuation), engineeringList: JSON.stringify(engineering.List), compilationName: sessionCompilation.name, versionName: request.session.compilationVersion, LicenseKey: config.getLicenseKey(process.env.NODE_ENV) }; response.render('building_saas/pm/html/project-management.html', renderData); }, //第一次进入该费用定额时准备的初始数据 prepareInitialData: async function (request, response) { try { const data = { userID: request.session.sessionUser.id, compilationID: request.session.sessionCompilation._id, example: request.session.sessionCompilation.example }; await redirectToImportServer(data, 'prepareInitialData', request); callback(request, response, 0, 'success', null); } catch (err) { console.log(err); callback(request, response, 1, err.toString(), null); } }, // 获取单价文件列表 getUnitFileList: async function (request, response) { let data = request.body.data; try { data = JSON.parse(data); let projectId = data.parentID !== undefined ? data.parentID : 0; if (isNaN(projectId) && projectId <= 0) { throw { msg: 'id数据有误!', err: 1 }; } /*// 获取对应建设项目下所有的单位工程id let idList = await ProjectsData.getTenderByProjectId(projectId); if (idList.length <= 0) { throw {msg: '不存在对应单位工程', err: 0}; }*/ // 获取对应的单价文件 let unitPriceFileModel = new UnitPriceFileModel(); let unitPriceFileData = await unitPriceFileModel.getDataByRootProject(projectId); if (unitPriceFileData === null) { throw { msg: '不存在对应单价文件', err: 0 }; } // 整理数据 let unitPriceFileList = []; for (let unitPriceFile of unitPriceFileData) { let tmp = { name: unitPriceFile.name, id: unitPriceFile.id }; unitPriceFileList.push(tmp); } callback(request, response, 0, '', unitPriceFileList); } catch (error) { console.log(error); let responseData = error.err === 1 ? null : []; callback(request, response, error.err, error.msg, responseData); } }, getFeeRateFileList: async function (request, response) { let data = request.body.data; try { data = JSON.parse(data); let projectId = data.parentID !== undefined ? data.parentID : 0; if (isNaN(projectId) && projectId <= 0) { throw { msg: 'id数据有误!', err: 1 }; } // 获取对应建设项目下所有的单位工程id let feeRateFileList = await fee_rate_facade.getFeeRatesByProject(projectId); callback(request, response, 0, '', feeRateFileList); } catch (error) { console.log(error); let responseData = error.err === 1 ? null : []; callback(request, response, error.err, error.msg, responseData); } }, getGCDatas: async function (request, response) { let userID = request.session.sessionUser.id; let compilatoinId = request.session.sessionCompilation._id; let rst = []; let _projs = Object.create(null), _engs = Object.create(null), prefix = 'ID_'; try { let gc_unitPriceFiles = await ProjectsData.getGCFiles(fileType.unitPriceFile, userID); let gc_feeRateFiles = await ProjectsData.getGCFiles(fileType.feeRateFile, userID); let gc_tenderFiles = await ProjectsData.getGCFiles(projType.tender, userID); for (let i = 0, len = gc_unitPriceFiles.length; i < len; i++) { let gc_uf = gc_unitPriceFiles[i]; let theProj = _projs[prefix + gc_uf.root_project_id] || null; if (!theProj) { let tempProj = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_uf.root_project_id]); if (tempProj.length > 0 && tempProj[0].projType !== projType.folder) { theProj = _projs[prefix + gc_uf.root_project_id] = tempProj[0]._doc; buildProj(theProj); } } if (theProj) { theProj.unitPriceFiles.push(gc_uf); } } for (let i = 0, len = gc_feeRateFiles.length; i < len; i++) { let gc_ff = gc_feeRateFiles[i]; let theProj = _projs[prefix + gc_ff.rootProjectID] || null; if (!theProj) { let tempProj = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_ff.rootProjectID]); if (tempProj.length > 0 && tempProj[0].projType !== projType.folder) { theProj = _projs[prefix + gc_ff.rootProjectID] = tempProj[0]._doc; buildProj(theProj); } } if (theProj) { theProj.feeRateFiles.push(gc_ff); } } if (gc_tenderFiles.length > 0) { for (let i = 0, len = gc_tenderFiles.length; i < len; i++) { let gc_t = gc_tenderFiles[i]; let theEng = _engs[prefix + gc_t.ParentID] || null; if (!theEng) { let tempEngs = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_t.ParentID]); if (tempEngs.length > 0 && tempEngs[0].projType === projType.engineering) { theEng = _engs[prefix + gc_t.ParentID] = tempEngs[0]._doc; theEng.children = []; } } if (theEng) { theEng.children.push(gc_t); let theProj = _projs[prefix + theEng.ParentID] || null; if (!theProj) { let tempProj = await ProjectsData.getProjectsByIds(userID, compilatoinId, [theEng.ParentID]); if (tempProj.length > 0 && tempProj[0].projType === projType.project) { theProj = _projs[prefix + theEng.ParentID] = tempProj[0]._doc; buildProj(theProj); } } if (theProj) { let isExist = false; for (let j = 0, jLen = theProj.children.length; j < jLen; j++) { if (theProj.children[j].ID === theEng.ID) { isExist = true; break; } } if (!isExist) { theProj.children.push(theEng); } } } } } for (let i in _projs) { rst.push(_projs[i]); } function buildProj(proj) { proj.children = []; proj.unitPriceFiles = []; proj.feeRateFiles = []; } callback(request, response, 0, 'success', rst); } catch (error) { callback(request, response, true, error, null); } }, recGC: function (request, response) { let userID = request.session.sessionUser.id, compilationId = request.session.sessionCompilation._id; let data = JSON.parse(request.body.data); let nodes = data.nodes; ProjectsData.recGC(userID, compilationId, nodes, function (err, msg, data) { callback(request, response, err, msg, data); }); }, delGC: async function (request, response) { let data = JSON.parse(request.body.data); let delDatas = data.delDatas; let bulkProjs = [], bulkUFs = [], bulkFFs = []; try { for (let data of delDatas) { if (data.updateType === 'Project') { bulkProjs.push({ updateOne: { filter: { ID: data.ID }, update: { 'deleteInfo.completeDeleted': true } } }); } else if (data.updateType === fileType.unitPriceFile) { bulkUFs.push({ updateOne: { filter: { id: data.ID }, update: { 'deleteInfo.completeDeleted': true } } }); } else { bulkFFs.push({ updateOne: { filter: { ID: data.ID }, update: { 'deleteInfo.completeDeleted': true } } }); } } if (bulkProjs.length > 0) { await projectModel.bulkWrite(bulkProjs); } if (bulkUFs.length > 0) { await unitPriceFileModel.bulkWrite(bulkUFs); } if (bulkFFs.length > 0) { await feeRateFileModel.bulkWrite(bulkFFs); } callback(request, response, 0, 'success', null); } catch (err) { callback(request, response, 1, err, null); } }, moveProject: async function (req, res) { let result = { error: 0 }; try { let data = req.body.data; let rdata = await pm_facade.moveProject(data); result.data = rdata; } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, copyProjects: async function (req, res) { let result = { error: 0 }; try { let data = { dataString: req.body.data, userID: req.session.sessionUser.id, compilationID: req.session.sessionCompilation._id }; result = await redirectToImportServer(data, "copyProject", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, projectShareInfo: async function (req, res) { try { const data = JSON.parse(req.body.data); const shareList = await pm_facade.getShareList({ projectID: data.projectID }); const shareInfoMap = await pm_facade.getShareInfoMap(null, shareList); const shareInfo = shareInfoMap[data.projectID] || []; //let shareInfo = await projectModel.findOne({ID: data.projectID, $or: [{deleteInfo: null}, {'deleteInfo.deleted': false}]}, '-_id shareInfo'); callback(req, res, 0, 'success', shareInfo); } catch (err) { callback(req, res, 1, err, null); } }, getInitialShareData: async function (req, res) { try { const { count, projectID } = JSON.parse(req.body.data); // 分享文件夹、建设项目,仅提供给专业版用户 const proShareProjType = [projType.folder, projType.project]; const project = await projectModel.findOne({ ID: projectID }, 'projType'); if (project && proShareProjType.indexOf(project.projType) >= 0) { const isFree = userModelObj.isFreeFromSession(req.session.compilationVersion); if (isFree) { callback(req, res, 0, 'success', { isFree }); return; } } const userID = req.session.sessionUser.id; // 最近分享 const recentUsers = await pm_facade.getRecentShareList(userID, count); // 联系人 const contacts = await userModelObj.getContacts(userID); // 分享过的人 const sharedUsers = await pm_facade.getProjectShareList(projectID); callback(req, res, 0, 'success', { recentUsers, contacts, sharedUsers }); } catch (err) { console.log(err); callback(req, res, 1, err.message, null); } }, getReceiveLibList: async function (req, res) { try { const { libType } = JSON.parse(req.body.data); const userID = req.session.sessionUser.id; const compilationID = req.session.sessionCompilation._id; const list = await pm_facade.getReceiveLibList(userID, compilationID, libType); callback(req, res, 0, 'success', list); } catch (err) { callback(req, res, 1, err.message, null); } }, getInitialShareLibData: async function (req, res) { try { const { libType, count } = JSON.parse(req.body.data); const userID = req.session.sessionUser.id; const compilationID = req.session.sessionCompilation._id; // 最近分享 const recentUsers = await pm_facade.getRecentShareList(userID, count); // 联系人 const contacts = await userModelObj.getContacts(userID); // 分享过的人 const sharedUsers = await pm_facade.getLibShareList(userID, compilationID, libType, count); callback(req, res, 0, 'success', { recentUsers, contacts, sharedUsers }); } catch (err) { console.log(err); callback(req, res, 1, err.message, null); } }, shareLib: async function (req, res) { try { const { type, libType, shareData, count } = JSON.parse(req.body.data); const owner = req.session.sessionUser.id; const compilationID = req.session.sessionCompilation._id; const shareDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'); shareData.forEach(item => item.shareDate = shareDate); const task = []; // 是否只是单纯的更新分享选项,如果不是,需要重新获取最近分享和联系人 let isSimpleUpdate = true; if (type === 'create') { isSimpleUpdate = false; // 生成分享记录 const docs = shareData.map(item => ({ compilationID, owner, libType, ID: uuidV1(), receiver: item.receiver, allowCooperate: false, shareDate: item.shareDate, updateDate: item.shareDate })); task.push(pm_facade.addShareList(docs, true)); // 分享即互相添加为联系人 task.push(userModelObj.addContact(docs[0].owner, docs[0].receiver)); } else if (type === 'cancel') { // 取消分享 const cancelReceivers = shareData.map(item => item.receiver); task.push(pm_facade.deleteShareList({ owner, libType, compilationID, receiver: { $in: cancelReceivers } }, true)); } await Promise.all(task); const rst = {}; if (!isSimpleUpdate) { const rstTask = [ pm_facade.getRecentShareList(owner, count), userModelObj.getContacts(owner) ]; const [recentUsers, contacts] = await Promise.all(rstTask); Object.assign(rst, { recentUsers, contacts }); } callback(req, res, 0, 'success', rst); } catch (err) { console.log(err); logger.info(err); callback(req, res, 1, err, null); } }, share: async function (req, res) { try { const data = JSON.parse(req.body.data); const { type, permissionType, shareData, projectID, count } = data; const userID = req.session.sessionUser.id; const shareDate = moment(Date.now()).format('YYYY-MM-DD HH:mm:ss'); shareData.forEach(item => item.shareDate = shareDate); const task = []; // 是否只是单纯的更新分享选项,如果不是,需要重新获取最近分享和联系人 let isSimpleUpdate = true; if (type === 'create') { isSimpleUpdate = false; // 生成分享记录 const docs = shareData.map(item => ({ ID: uuidV1(), projectID, owner: userID, receiver: item.userID, allowCooperate: item.allowCooperate, allowCopy: item.allowCopy, shareDate: item.shareDate, updateDate: item.shareDate })); task.push(pm_facade.addShareList(docs)); // 分享即互相添加为联系人 task.push(userModelObj.addContact(docs[0].owner, docs[0].receiver)); } else if (type === 'update') { // 取消分享(以前项目管理界面可一次进行更新和取消) const cancelReceivers = shareData .filter(item => item.isCancel) .map(item => item.userID); if (cancelReceivers.length) { isSimpleUpdate = false; task.push(pm_facade.deleteShareList({ projectID, receiver: { $in: cancelReceivers } })); } // 更新分享选项 const updateData = shareData .filter(item => !item.isCancel) .map(item => { const update = { updateDate: shareDate }; if (commonUtil.isDef(item.allowCopy)) { update.allowCopy = item.allowCopy; } if (commonUtil.isDef(item.allowCooperate)) { update.allowCooperate = item.allowCooperate; } return { query: { projectID, receiver: item.userID }, update }; }); if (updateData.length) { task.push(pm_facade.updateShareList(updateData)) } } else { // 取消分享 const cancelReceivers = shareData.map(item => item.userID); task.push(pm_facade.deleteShareList({ projectID, receiver: { $in: cancelReceivers } })); } await Promise.all(task); // 获取需要广播推送的单位工程 // shareData数组的形式是以前需求需要,现在的需求下,shareData数组必定只有一个元素 const emitTenders = await pm_facade.getShareInfoAfterChangePermission(permissionType, shareData[0].userID, projectID); let rst = { emitTenders }; if (!isSimpleUpdate) { const rstTask = [ pm_facade.getRecentShareList(userID, count), userModelObj.getContacts(userID) ]; const [recentUsers, contacts] = await Promise.all(rstTask); Object.assign(rst, { recentUsers, contacts }); } callback(req, res, 0, 'success', rst); } catch (err) { callback(req, res, 1, err, null); } }, receiveProjects: async function (req, res) { try { let rst = { grouped: [], ungrouped: [], summaryInfo: null }; let userID = req.session.sessionUser.id; const shareList = await pm_facade.getShareList({ receiver: userID }); const receiveProjectIDs = shareList.map(item => item.projectID); const compilation = req.session.sessionCompilation._id; const notDeleted = [{ deleteInfo: null }, { 'deleteInfo.deleted': false }]; const receiveProjects = await projectModel.find({ ID: { $in: receiveProjectIDs }, compilation, $or: notDeleted }, '-_id').lean(); //设置原项目用户信息 const shareInfoMap = await pm_facade.getShareInfoMap(null, shareList); if (receiveProjects.length > 0) { let orgUserIDs = []; for (let proj of receiveProjects) { orgUserIDs.push(proj.userID); if (proj.projType === projType.tender) { //设置工程专业 proj.feeStandardName = proj.property.feeStandardName || ''; //设置计税方法 proj.taxType = proj.property.taxType; } delete proj.property; } orgUserIDs = Array.from(new Set(orgUserIDs)); let userObjIDs = []; for (let uID of orgUserIDs) { userObjIDs.push(mongoose.Types.ObjectId(uID)); } let orgUsersInfo = await userModel.find({ _id: { $in: userObjIDs } }); //建设项目 let consProjIDs = [], ungroupedTenders = []; for (let proj of receiveProjects) { // 设置分享信息 proj.shareInfo = shareInfoMap[proj.ID] || []; if (proj.projType === projType.project) { consProjIDs.push(proj.ID); } //获取分享项目子项 if (proj.projType !== projType.tender) { proj.children = await pm_facade.getPosterityProjects([proj.ID]); for (let projC of proj.children) { // 设置分享信息 projC.shareInfo = shareInfoMap[projC.ID] || []; if (projC.projType === projType.project) { consProjIDs.push(projC.ID); } else if (projC.projType === projType.tender) { //设置工程专业 projC.feeStandardName = projC.property.feeStandardName || ''; //设置计税方法 projC.taxType = projC.property.taxType; if (proj.projType === projType.engineering) { ungroupedTenders.push(projC); } } delete projC.property; } } else {//未分类的单位工程不进行汇总,只取价格信息 ungroupedTenders.push(proj); } //设置分组,单位工程及单项工程分到未分组那 if (proj.projType === projType.tender || proj.projType === projType.engineering) { rst.ungrouped.push(proj); } else { rst.grouped.push(proj); } //设置项目类型为来自别人分享 proj.shareType = 'receive'; for (let userData of orgUsersInfo) { if (proj.userID == userData._id.toString()) { let userInfo = { name: userData.real_name, mobile: userData.mobile, company: userData.company, email: userData.email }; proj.userInfo = userInfo; } } } consProjIDs = Array.from(new Set(consProjIDs)); let summaryInfo = await pm_facade.getSummaryInfo(consProjIDs); let tendersFeeInfo = await pm_facade.getTendersFeeInfo(ungroupedTenders); rst.summaryInfo = { grouped: summaryInfo, ungrouped: tendersFeeInfo }; } callback(req, res, 0, 'success', rst); } catch (err) { console.log(err); callback(req, res, 1, err, null); } }, getProjectsByQuery: async function (req, res) { try { let data = JSON.parse(req.body.data); let compilation = req.session.sessionCompilation._id; let query = data.query; query.compilation = compilation; let options = data.options; let projects = await projectModel.find(query, options); callback(req, res, 0, 'success', projects); } catch (err) { callback(req, res, 1, err, null); } }, getSummaryInfo: async function (req, res) { try { let data = JSON.parse(req.body.data); let summaryInfo = await pm_facade.getSummaryInfo(data.projectIDs); callback(req, res, 0, 'success', summaryInfo); } catch (err) { callback(req, res, 1, err, null); } }, changeFile: async function (req, res) { try { let data = JSON.parse(req.body.data); console.log(data); await pm_facade.changeFile(data.projects, data.user_id, data.fileID, data.name, data.from, data.type); callback(req, res, 0, 'success', []); } catch (err) { console.log(err); callback(req, res, 1, err, null); } }, exportProject: async function (req, res) { let result = { error: 0 }; try { let data = { dataString: req.body.data, userID: req.session.sessionUser.id }; result = await redirectToImportServer(data, "exportProject", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, importProject: async function (req, res) { let data = JSON.parse(req.body.data); let result = { error: 0 }; try { data.session = req.session; result = await redirectToImportServer(data, "importProject", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, importChongqingProject: async function (req, res) { let data = JSON.parse(req.body.data); let result = { error: 0 }; try { data.session = req.session; result.data = await redirectToImportServer(data, "importChongqingProject", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, copyConstructionProject: async function (req, res) { let data = JSON.parse(req.body.data); let result = { error: 0 }; try { data.session = req.session; result.data = await redirectToImportServer(data, "copyConstructionProject", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, importProcessChecking: async function (req, res) { let result = { error: 0 }; try { let data = JSON.parse(req.body.data); data.userID = req.session.sessionUser.id; data.compilationID = req.session.sessionCompilation._id; result.data = await pm_facade.importProcessChecking(data); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, getUploadToken: function (req, res) { let result = { error: 0 }; try { result = pm_facade.uploadToken(); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, getBasicInfo: async function (req, res) { try { let data = JSON.parse(req.body.data); let infoLib = await pm_facade.getBasicInfo(req.session.sessionCompilation._id, data.fileKind); callback(req, res, 0, 'success', infoLib ? infoLib.info : []); } catch (err) { console.log(err); callback(req, res, 1, err, []); } }, getProjectFeature: async function (req, res) { try { let data = JSON.parse(req.body.data); let featureLib = await pm_facade.getProjectFeature(data.valuationID, data.engineeringName, data.feeName); //工程专业设置为费用标准名称 if (featureLib) { let engData = featureLib.feature.find(function (d) { return d.key === 'engineering'; }); if (engData) { engData.value = data.feeName; } } callback(req, res, 0, 'success', featureLib ? featureLib.feature : []); } catch (err) { console.log(err); callback(req, res, 1, err, []); } }, getProjectByGranularity: async function (req, res) { try { let data = JSON.parse(req.body.data); const userID = req.session.sessionUser.id; const version = req.session.compilationVersion; let projData = await pm_facade.getProjectByGranularity(data.tenderID, data.granularity, data.summaryObj, userID, version); callback(req, res, 0, 'success', projData); } catch (err) { callback(req, res, 1, err, null); } }, getProjectPlaceholder: async function (req, res) { let data = JSON.parse(req.body.data); try { let countRst = await pm_facade.getProjectPlaceholder(data); callback(req, res, 0, 'succes', countRst); } catch (err) { console.log(err); callback(req, res, 1, err, null); } }, /* importInterface: async function(req, res) { logger.info(`${req.ip} importInterface`); const uploadOption = { uploadDir: './public' }; let uploadFullName = ''; const form = new multiparty.Form(uploadOption); form.parse(req, async function(err, fields, files) { try { let file = files.file && files.file.length ? files.file[0] : null; if (!file) { throw '无有效数据'; } uploadFullName = file.path; //获取源数据 let srcStr = fs.readFileSync(file.path, 'utf8'); if (!srcStr) { throw '无有效数据' } let importData = JSON.parse(srcStr); fs.unlinkSync(file.path); let projectData = await pm_facade.importProject(importData, req.session.sessionUser.id, req.session.sessionCompilation._id); callback(req, res, 0, '', projectData); } catch (err) { console.log(err); if(uploadFullName && fs.existsSync(uploadFullName)){ fs.unlinkSync(uploadFullName); } callback(req, res, 1, err, null); } }); } */ importInterface: async function (req, res) { const data = JSON.parse(req.body.data); let result = { error: 0 }; try { data.session = req.session; result = await redirectToImportServer(data, "importInterface", req); } catch (err) { console.log(err); result.error = 1; result.message = err.message; } res.json(result); }, redirectToImportServer: redirectToImportServer }; async function redirectToImportServer(data, action, req) { let importURL = config.getImportURL(process.env.NODE_ENV, req.headers.origin); let options = { method: 'POST', uri: `http://${importURL}/import/${action}`, body: data, timeout: 220000, json: true }; console.log("post import data to:" + options.uri); return await rp.post(options); }