/**
 * Created by Mai on 2017/1/18.
 */
import UnitPriceFileModel from "../../glj/models/unit_price_file_model";
import moment from 'moment';
import CompilationModel from "../../users/models/compilation_model";
import UserModel from "../../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');
import SectionTreeDao from '../../complementary_ration_lib/models/sectionTreeModel';
const uuidV1 = require('uuid/v1');
let sectionTreeDao = new SectionTreeDao();
let consts = require('../../main/models/project_consts');
import multiparty from 'multiparty';
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;
                callback(true, result, isOpenShareProject, allowCooperate);
            } 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, projects){
            if (projects) {
                callback(req, res, err, message, projects);
            } else {
                callback(req, res, err, message, null);
            }
        });
    },
    updateProjects: async function (req, res) {
        try {
            let data = JSON.parse(req.body.data);
            await ProjectsData.updateUserProjects(req.session.sessionUser.id, req.session.sessionCompilation._id, req.session.sessionCompilation, data.updateData, function (err, message, data) {
                if (err === 0) {
                    callback(req, res, err, message, data);
                } else {
                    callback(req, res, err, message, null);
                }
            });
        } catch (err) {
            console.log(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'];
            }
            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.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.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, 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, 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;
            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 basicInfo = await ProjectsData.getBasicInfo(projectID);
            if(basicInfo !== null){
                projInfo.property.basicInformation = basicInfo;
            }
            //获取单位工程完整目录结构
            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 basicInfo = await ProjectsData.getBasicInfo(projectID);
                if(basicInfo !== null){
                    projInfo.property.basicInformation = basicInfo;
                }
                //获取单位工程完整目录结构
                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,showTime] = 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,
            showTime:showTime,
            userAccount: request.session.userAccount,
            userID: request.session.sessionUser.id,
            compilationData: JSON.stringify(sessionCompilation),
            overWriteUrl: overWriteUrl,
            billValuation: JSON.stringify(billValuation),
            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);
        }
    },

    getGC: async function(req, res) {
        const userID = req.session.sessionUser.id;
        const compilationId = req.session.sessionCompilation._id;
        try {
            const rst = [];
            const priceFilesTask = ProjectsData.getGCFiles(fileType.unitPriceFile, userID);
            const feeRateFilesTask = ProjectsData.getGCFiles(fileType.feeRateFile, userID);
            const tendersTask = ProjectsData.getGCFiles(projType.tender, userID);
            const [priceFiles, rateFiles, tenders] = await Promise.all([priceFilesTask, feeRateFilesTask, tendersTask]);
            // 建设项目
            let projectIDs = tenders.reduce((acc, cur) => {
                acc.push(cur.ParentID);
                return acc;
            }, []);
            projectIDs = [...new Set(projectIDs)];
            const projects = await ProjectsData.getProjectsByIds(userID, compilationId, projectIDs);
            projects.forEach(project => {
                const projectDoc = project._doc;
                const relTenders = tenders.filter(tender => tender.ParentID === projectDoc.ID);
                const unitPriceFiles = priceFiles.filter(file => relTenders.find(tender => tender.property.unitPriceFile.id === file.id));
                const feeRateFiles = rateFiles.filter(file => relTenders.find(tender => tender.property.feeFile.id === file.ID));
                projectDoc.children = relTenders;
                projectDoc.unitPriceFiles = unitPriceFiles;
                projectDoc.feeRateFiles = feeRateFiles;
                rst.push(projectDoc);
            });
            callback(req, res, 0, 'success', rst);
        } catch (err) {
            console.log(err);
            callback(req, res, true, err.message, null);
        }
    },

    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 theProj = _projs[prefix + gc_t.ParentID] || null;
                    if(!theProj){
                        let tempProjs = await ProjectsData.getProjectsByIds(userID, compilatoinId, [gc_t.ParentID]);
                        if(tempProjs.length > 0 && tempProjs[0].projType === projType.project){
                            theProj = _projs[prefix + gc_t.ParentID] = tempProjs[0]._doc;
                            buildProj(theProj);
                        }
                    }
                    if(theProj) {
                        theProj.children.push(gc_t);
                    }
                }
            }
            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] || [];
            callback(req, res, 0, 'success', shareInfo);
        }
        catch (err){
            callback(req, res, 1, err, null);
        }
    },
    getRecentShareInfo: async function (req, res) {
        try {
            const { count } = JSON.parse(req.body.data);
            const userID = req.session.sessionUser.id;
            const recentUsers = await pm_facade.getRecentShareList(userID, count);
            const contacts = await userModelObj.getContacts(userID);
            callback(req, res, 0, 'success', { recentUsers, contacts });
        } catch (err) {
            console.log(err);
            callback(req, res, 1, err.message, 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);
        }
    },
    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);
            const rstTask = [
                pm_facade.getRecentShareList(userID, count),
                userModelObj.getContacts(userID)
            ]
            // 获取需要广播推送的单位工程
            // shareData数组的形式是以前需求需要，现在的需求下，shareData数组必定只有一个元素
            const emitTenders = await pm_facade.getShareInfoAfterChangePermission(permissionType, shareData[0].userID, projectID);
            let rst = { emitTenders };
            if (!isSimpleUpdate) {
                const [recentUsers, contacts] = await Promise.all(rstTask);
                Object.assign(rst, { recentUsers, contacts });
            }
            callback(req, res, 0, 'success', rst);
        }
        catch (err) {
            console.log(err);
            callback(req, res, 1, String(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.valuationType = proj.property.valuationType === 'bill' ? '预算' : '工程量清单';
                        //设置工程专业
                        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.valuationType = projC.property.valuationType === 'bill' ? '预算' : '工程量清单';
                                //设置工程专业
                                projC.feeStandardName = projC.property.feeStandardName || '';
                            }
                            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);
    },
    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);
    }
};


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);
}
