Browse Source

Merge branch 'master' into GuangdongTax

zhangweicheng 5 years ago
parent
commit
b50353794c

+ 1 - 1
modules/main/facade/project_facade.js

@@ -665,7 +665,7 @@ async function getMainMaterialDatas(projectID,property) {
     let [gljList, mixRatioConnectData,mixRatioMap,unitPriceMap] = await gljListModel.getListByProjectId(projectID, property.unitPriceFile?property.unitPriceFile.id:null);
     gljList = JSON.parse(JSON.stringify(gljList));
     await calcProjectGLJQuantity(projectID,{gljList:gljList,mixRatioMap:mixRatioMap},property);
-    return gljUtil.getMainMaterialDatas(property.engineerFeatures,property.materials,{gljList:gljList},property.calcOptions,property.decimal,false,_,scMathUtil)
+    return gljUtil.getMainMaterialDatas(property,property.engineerFeatures,property.materials,{gljList:gljList},property.calcOptions,property.decimal,false,_,scMathUtil)
 
 }
 

+ 142 - 2
modules/users/controllers/cld_controller.js

@@ -11,6 +11,7 @@
 import CLDModel from "../models/cld_model";
 import UserModel from "../models/user_model"
 import CompilationModel from "../models/compilation_model";
+let online_facade = require('../facade/online_facade')
 
 class CLDController {
 
@@ -62,10 +63,12 @@ class CLDController {
             if (userData === null || userData === '') {
                 throw '不存在该建筑用户';
             }
+            let userList = [userData];
+            await online_facade.setOnlineTimes(userList, {});
             userData = JSON.parse(JSON.stringify(userData));
 
-            userData.company_scale = userData.company_scale === null || userData.company_scale === undefined ? '' : userModel.companyScale[userData.company_scale] + '人';
-            userData.company_type = userData.company_type === null || userData.company_type === undefined ? '' : userModel.companyType[userData.company_type];
+            userData.company_scale = userData.company_scale === null || userData.company_scale === undefined || userData.company_scale === -1 ? '' : userModel.companyScale[userData.company_scale] + '人';
+            userData.company_type = userData.company_type === null || userData.company_type === undefined || userData.company_type === -1 ? '' : userModel.companyType[userData.company_type];
             userData.province = userModel.province[userData.province];
 
             let date = new Date(userData.create_time);
@@ -161,6 +164,143 @@ class CLDController {
         const compilationList = await compilationModel.getList();
         response.json({error: 0, msg: 'success', data: compilationList});
     }
+
+    /**
+     * 获取个人和已使用编办信息
+     * @param request
+     * @param response
+     * @returns {Promise<void>}
+     */
+    async getUsersInfo(request, response) {
+        let ssoID = request.query.ssoID;
+        try {
+            //获取用户信息
+            if (ssoID === undefined) {
+                throw '传参有误';
+            }
+            let userModel = new UserModel();
+            let userData = await userModel.findDataBySsoId(ssoID);
+            if (userData === null || userData === '') {
+                throw '不存在该建筑用户';
+            }
+            userData = JSON.parse(JSON.stringify(userData));
+
+            userData.company_scale = userData.company_scale === null || userData.company_scale === undefined ? '' : userModel.companyScale[userData.company_scale] + '人';
+            userData.company_type = userData.company_type === null || userData.company_type === undefined ? '' : userModel.companyType[userData.company_type];
+            userData.province = userModel.province[userData.province];
+
+            let date = new Date(userData.create_time);
+            userData.create_time = date.getFullYear() + '年' +
+                (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1) : date.getMonth()+1) + '月' +
+                (date.getDate() < 10 ? '0' + date.getDate() : date.getDate()) + '日';
+
+            //获取编办列表
+            let compilationModel = new CompilationModel();
+            let compilationList = JSON.parse(JSON.stringify(await compilationModel.getList()));
+            if (userData.upgrade_list !== undefined) {
+                let userUpgradeList = userData.upgrade_list;
+                for (let i in userUpgradeList) {
+                    let oneCompilationIndex = await compilationList.findIndex(function (item) {
+                        return item._id === userUpgradeList[i].compilationID;
+                    });
+                    if (oneCompilationIndex !== -1) {
+                        // compilationList[oneCompilationIndex].isUpgrade = userUpgradeList[i].isUpgrade;
+                        userData.upgrade_list[i].name = compilationList[oneCompilationIndex].name;
+                        userData.upgrade_list[i].description = compilationList[oneCompilationIndex].description;
+                        userData.upgrade_list[i].categoryID = compilationList[oneCompilationIndex].categoryID;
+                    }
+                }
+            }
+            response.json({error: 0, msg: 'success', data: { userInfo: userData }});
+        } catch (err) {
+            response.json({error: 1, msg: err});
+        }
+    }
+
+    /**
+     * 获取用户列表分页
+     * @param request
+     * @param response
+     * @returns {Promise<void>}
+     */
+    async getUserList(request, response) {
+        let userModel = new UserModel();
+        let total = 0;
+        let pageSize = 12;
+        let pageData = {};
+        let userList = [];
+        let compilationList =[];
+        let filter = request.query;
+        try {
+            //获取编办列表
+            let  compilationModel = new CompilationModel();
+            compilationList = await compilationModel.getCompilationList({_id: 1, name: 1, is_release: 1});
+            let condition = userModel.getFilterCondition(request);
+            //设置搜索普通用户:
+            condition.user_type = 'normal';
+
+            //获取注册时间
+            let regtime = request.query.regtime;
+            if(regtime !== '' && regtime !== undefined){
+                filter.regtimeMsg = userModel.getDayMsg(regtime);
+            }
+
+            //获取注册时间
+            let loginTime = request.query.loginTime;
+            if(loginTime !== '' && loginTime !== undefined){
+                filter.loginMsg = userModel.getDayMsg(loginTime);
+            }
+
+            // 排序方式
+            let sortType = request.query.sortType !== '' && request.query.sortType !== undefined ? request.query.sortType : -1;
+
+            // 排序条件
+            let sortField = request.query.sortField;
+            let sort = sortField !== '' && sortField !== undefined && sortField === 'latest_login' ? {latest_login: sortType}: {_id: sortType};
+
+            // 获取用户总数
+            total = await userModel.count(condition);
+
+            // 分页数据
+            let page = request.query.page === undefined ? 1 : request.query.page;
+            pageSize = request.query.pageSize === undefined ? 12 : parseInt(request.query.pageSize);
+            pageData = {
+                current: page,
+                total: total,
+                queryData: response.locals.urlQuery
+            };
+            // console.log("取用户信息=========================");
+            // console.log(condition);
+            // 获取用户列表
+            userList = await userModel.getList(condition, page, pageSize, sort);
+            await online_facade.setOnlineTimes(userList,condition);
+            response.json({error: 0, msg: 'success', data: {
+                    userInfo: userList,
+                    pageData: pageData,
+                    compilationList:compilationList,
+                }});
+        } catch (error) {
+            response.json({error: 1, msg: error});
+        }
+    }
+
+    async getUserOnlineInfo(request, response){
+        let filter = JSON.parse(request.body.data);
+        let responseData = {
+            error: 0,
+            msg: '',
+            data: null
+        };
+        try{
+            let info = await online_facade.getOnlineInfo(filter);
+            responseData.data = info;
+        } catch (error) {
+            console.log(error);
+            responseData.error = error.code;
+            responseData.msg = error.err;
+        }
+        response.json(responseData);
+    }
 }
 
 export default CLDController;

+ 62 - 0
modules/users/facade/online_facade.js

@@ -0,0 +1,62 @@
+/**
+ * Created by zhang on 2019/4/16.
+ */
+
+module.exports = {
+    setOnlineTimes:setOnlineTimes,
+    getOnlineInfo:getOnlineInfo
+};
+
+let mongoose = require("mongoose");
+let logs_model = mongoose.model("online_logs");
+
+async function getOnlineInfo(filter) {
+    let datas = [];
+    let logs = await logs_model.find(filter);
+    let less = 0;
+    for(let l of logs){
+        let d = getTimeString(l.online_times);
+        let online_times = d.s;
+        less += d.less;
+        if(online_times!=""){
+            datas.push({dateString:l.dateString,dateTime:l.online_times,online_times:online_times})
+        }
+    }
+    if(datas.length>1){//大于2个才把不够1分钟的累积到最后一条记录
+        let last =  datas[datas.length - 1];
+        last.online_times = getTimeString(last.dateTime + less).s;
+    }
+
+    return datas;
+}
+
+
+async function setOnlineTimes(userList,condition){
+    for(let u of userList){
+        let filter = {'userID':u._id.toString()};
+        if(u.latest_used) filter["compilationID"] = u.latest_used;
+        if(condition.latest_login && condition.latest_login == ""){
+            let startTime = condition.latest_login['$gte']; //- 24*60*60*1000 //往前推一天  {'$gte': startTime, '$lt': endTime}latest_login
+            filter['dateTime'] = {'$gte': startTime, '$lt':  condition.latest_login['$lt']}
+        }
+
+        let result =  await logs_model.aggregate([
+            {$match: filter},
+            {$group: {_id: "$userID", total: {$sum: "$online_times"}}}
+        ]);
+        u._doc.filter = JSON.stringify(filter);
+        if(result.length > 0)  u._doc.online_times = getTimeString(result[0].total).s;
+        u._doc.online_list = await this.getOnlineInfo(filter);
+    }
+}
+
+
+function getTimeString(times) {
+    let s = "",perHour = 1000 * 60 * 60,perMin = 1000 * 60;
+    let hour = parseInt(times/perHour);
+    let min = parseInt((times % perHour)/perMin);
+    let less =  (times % perHour)%perMin;//不够一分钟的时间
+    if(hour > 0) s = s+`${hour}小时`;
+    if(min > 0)  s= s+`${min}分钟`;
+    return {s:s,less:less}
+}

+ 14 - 0
modules/users/models/compilation_model.js

@@ -26,6 +26,20 @@ class CompilationModel extends BaseModel {
      *
      * @return {Promise}
      */
+    async getCompilationList(fields = null) {
+        // 筛选字段
+        let field = fields == null ?{_id: 1, name: 1, is_release: 1, categoryID: 1, description: 1,overWriteUrl: 1,example: 1, "ration_valuation.id": 1, "ration_valuation.name": 1, "ration_valuation.enable": 1,
+            "bill_valuation.id": 1, "bill_valuation.name": 1, "bill_valuation.enable": 1}:fields;
+        let compilationData = await this.findDataByCondition({name: {$ne: ''}}, field, false);
+
+        return compilationData === null ? [] : compilationData;
+    }
+
+    /**
+     * 获取编办列表
+     *
+     * @return {Promise}
+     */
     async getList() {
         // 筛选字段
         let field = {_id: 1, name: 1, is_release: 1, description: 1, categoryID: 1};

+ 106 - 0
modules/users/models/user_model.js

@@ -36,6 +36,13 @@ class UserModel extends BaseModel {
      */
     companyScale = ['1-50', '50-100', '100-500', '500+'];
 
+    /**
+     * 最近天数
+     *
+     * @var
+     */
+    dayMsg = ['所有', '最近24小时', '最近3天', '最近7天', '最近30天'];
+
 
     /**
      * 构造函数
@@ -279,6 +286,7 @@ class UserModel extends BaseModel {
             username: userData.username,
             email: userData.email,
             mobile: userData.mobile,
+            qq: userData.qq,
             create_time: new Date().getTime(),
             latest_login: new Date().getTime(),
             isUserActive: userData.isUserActive,
@@ -387,6 +395,104 @@ class UserModel extends BaseModel {
         const users = await this.model.find({_id: {$in: userIDList}}, 'real_name mobile company');
         return users;
     }
+
+    /**
+     * 获取列表
+     *
+     * @param {object} condition
+     * @param {number} page
+     * @param {Number} pageSize
+     * @return {promise}
+     */
+    async getList(condition = null, page = 1, pageSize = 30, sort = {_id:-1}) {
+        page = parseInt(page);
+        page = page <= 1 ? 1 : page;
+        let option = {pageSize: pageSize, offset: parseInt((page - 1) * pageSize), sort: sort};
+
+        let userList = await this.db.find(condition, null, option);
+        userList = userList.length > 0 ? userList : [];
+
+        return userList;
+    }
+
+    /**
+     * 获取过滤条件
+     *
+     * @return {Object}
+     */
+    getFilterCondition(request) {
+        let condition = {};
+        let regtime = request.query.regtime;
+        regtime = regtime !== '' && regtime !== undefined ? parseInt(regtime) : 0;
+        if (regtime !== 0) {
+            condition.create_time = this.getTimestamp(regtime);
+        }
+
+        //最近登录时间
+        let loginTime = request.query.loginTime;
+        loginTime = loginTime !== '' && loginTime !== undefined ? parseInt(loginTime) : 0;
+        if (loginTime !== 0) {
+            condition.latest_login = this.getTimestamp(loginTime);
+        }
+
+        let version = request.query.version;
+        if(version !== '' && version !== undefined) {
+            condition.version = version;
+        }
+        // 已升级费用定额
+        let upGrade = request.query.upGrade;
+        if(upGrade !== '' && upGrade !== undefined){
+            condition.upgrade_list = {"$elemMatch":{"compilationID":upGrade,"isUpgrade":true}};
+        }
+
+        // 最近使用费用定额
+        let latestUsed = request.query.latestUsed;
+        if(latestUsed !== '' && latestUsed !== undefined){
+            condition.latest_used = latestUsed;
+        }
+
+        let keyword = request.query.keyword;
+        if (keyword !== '' && keyword !== undefined) {
+            condition.$or = [{real_name : {$regex: keyword}},{email : {$regex: keyword}},{mobile : {$regex: keyword}},{company : {$regex: keyword}}];
+        }
+
+        return condition;
+    }
+
+    /**
+     * 获取时间戳区间
+     *
+     * @return {Object}
+     */
+    getTimestamp(type) {
+        let startTime = '';
+        switch (type) {
+            case 1 :
+                startTime = Date.parse(new Date())-86400*1000;
+                break;
+            case 2 :
+                startTime = Date.parse(new Date())-86400*1000*3;
+                break;
+            case 3 :
+                startTime = Date.parse(new Date())-86400*1000*7;
+                break;
+            case 4 :
+                startTime = Date.parse(new Date())-86400*1000*30;
+                break;
+            default :
+                break;
+        }
+        let endTime =  Date.parse(new Date());
+        return startTime === '' ? '' : {'$gte': startTime, '$lt': endTime};
+    }
+
+    /**
+     * 获取daymsg
+     *
+     */
+    getDayMsg(index){
+        return this.dayMsg[index];
+    }
 }
 
 export default UserModel;

+ 6 - 0
modules/users/routes/cld_route.js

@@ -24,5 +24,11 @@ module.exports = function (app) {
 
     router.post('/setUserUpgrade', cldController.setUsersUpgrade);
 
+    router.get('/getUsersInfo', cldController.getUsersInfo);
+
+    router.get('/getUserList', cldController.getUserList);
+
+    router.post('/getUserOnlineInfo', cldController.getUserOnlineInfo);
+
     app.use('/cld',router)
 };

+ 2 - 2
public/gljUtil.js

@@ -64,8 +64,8 @@ function getEconomicDatas(engineerFeatures,economics,bills,fixedFlag,_,scMathUti
     return gljNodeUtil.getEconomicDatas(engineerFeatures,economics,bills,fixedFlag,_,scMathUtil,decimal);
 }
 
-function getMainMaterialDatas(engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
-    return gljNodeUtil.getMainMaterialDatas(engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil);
+function getMainMaterialDatas(projectProperty,engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
+    return gljNodeUtil.getMainMaterialDatas(projectProperty,engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil);
 }
 
 function getQuantityDatas(engineerFeatures,mainQuantities,billsList,fixedFlag,_,scMathUtil,decimal) {

+ 8 - 7
public/web/gljUtil.js

@@ -401,7 +401,7 @@ let gljUtil = {
         if(b.fees && b.fees.length > 0){
             for(let f of b.fees){
                 if(f.fieldName == "common"){
-                    total = scMathUtil.roundForObj(f.totalFee,decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice"));
+                    total = scMathUtil.roundForObj(f.tenderTotalFee,decimal?decimal.bills.totalPrice:getDecimal("bills.totalPrice"));
                 }
             }
         }
@@ -447,7 +447,7 @@ let gljUtil = {
                 i.totalFee =  scMathUtil.roundForObj(i.totalFee,priceDe);
                 cost = scMathUtil.roundForObj(cost + i.totalFee,decimal?decimal.process:getDecimal("process"))//getDecimal("process");
             }
-            data.cost = scMathUtil.roundForObj(cost,priceDe,_);
+            data.cost = scMathUtil.roundForObj(cost,priceDe);
             data.unitCost = gljUtil.calUnitWidthCoe(data.cost,true,engineerFeatures,_,scMathUtil);//noNeedCoe = true 这里不需要乘以系数
             data.per = engineerCost?scMathUtil.roundForObj(data.cost/engineerCost * 100,2):0;
         }
@@ -508,7 +508,7 @@ let gljUtil = {
             }
         }
     },
-    getMainMaterialDatas:function (engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
+    getMainMaterialDatas:function (projectProperty,engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
         let datas = [];
         let materialGroup = _.groupBy(projectGLJData.gljList,'materialIndexType');
         if(!materials) return datas;
@@ -528,12 +528,13 @@ let gljUtil = {
         function setMainMaterial(gljs,data) {
             let quantity = 0 ,unitPrice=0;
             for(let g of gljs){
-                if(!g.quantity || g.quantity=="") continue;
-                let marketPrice = gljUtil.getMarketPrice(g,projectGLJData,calcOptions,decimalObj,false,_,scMathUtil); // gljOprObj.setGLJPrice(tem,g);
+                if(!g.tenderQuantity || g.tenderQuantity=="") continue;
+                let tenderCoe = gljUtil.getTenderPriceCoe(g,projectProperty);
+                let marketPrice = gljUtil.getMarketPrice(g,projectGLJData,calcOptions,decimalObj,false,_,scMathUtil,tenderCoe); // gljOprObj.setGLJPrice(tem,g);
                 let materialIndexCoe = g.materialIndexCoe?scMathUtil.roundForObj(g.materialIndexCoe,decimalObj.process):0;
-                let t_quantity = scMathUtil.roundForObj(g.quantity * materialIndexCoe,decimalObj.process);
+                let t_quantity = scMathUtil.roundForObj(g.tenderQuantity * materialIndexCoe,decimalObj.process);
                 quantity = scMathUtil.roundForObj(t_quantity + quantity,decimalObj.process);
-                let temPrice = scMathUtil.roundForObj(g.quantity * marketPrice,decimalObj.process);
+                let temPrice = scMathUtil.roundForObj(g.tenderQuantity * marketPrice,decimalObj.process);
                 unitPrice = scMathUtil.roundForObj(temPrice + unitPrice,decimalObj.process);
             }
             data.quantity = scMathUtil.roundForObj(quantity,2);

+ 53 - 1
web/building_saas/main/html/main.html

@@ -105,7 +105,7 @@
                     <a class="dropdown-toggle" href="#" data-toggle="dropdown"><i class="fa  fa-code-fork"></i></a>
                     <div class="dropdown-menu" id="exportMenu">
                         <a class="dropdown-item" href="#export" data-toggle="modal" data-target="#export">导出<%= region %>电子招投标数据文件</a>
-                        <a class="dropdown-item" href="javascript:void(0)" id="SEIMenu"  >导出<%= region %>指标成果文件</a>
+                        <a class="dropdown-item" href="#exportIndex"  data-toggle="modal" data-target="#exportIndex" >导出<%= region %>指标成果文件</a>
                     </div>
                 </span>
                       <% } %>
@@ -2142,6 +2142,37 @@
         </div>
     </div>
 </div>
+
+<!--弹出 数据接口导出-->
+<div class="modal fade" id="exportIndex" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title"><%= region %>指标成果文件接口<!-- 重庆其他电子招投标数据接口 --></h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">&times;</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <!--检测提醒-->
+                <div class="card">
+                    <div class="card-body">
+                        <h5 class="card-title">导出<%= region %>电子招投标数据接口文件</h5>
+                        <p class="card-text">导出之前,建议您执行项目自检功能,避免出现错误。</p>
+                        <a id="export-index-check" href="javascript:void(0);" class="btn btn-primary">自检</a>
+                    </div>
+                </div>
+            </div>
+            <div class="modal-footer">
+                <a id="export-index-confirm" href="javascript:void(0);" class="btn btn-primary">确定导出</a>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
+            </div>
+        </div>
+    </div>
+</div>
+
+
+
 <!--设置导出工程编号-->
 <div class="modal fade" id="exportCode" data-backdrop="static">
     <div class="modal-dialog" role="document">
@@ -2156,6 +2187,27 @@
                 <div class="modal-auto-height" style="overflow: hidden" id="exportSpread">
                 </div>
                 <p>*工程编号作为单项、单位工程的标识,要求在建设项目下唯一。</p>
+
+
+                <div class="form-group" style="">
+                    <div class="form-check ml-4">
+                        <input class="form-check-input" type="checkbox"  id="sei1" checked>
+                        <label class="form-check-label" for="sei1">
+                            投标文件
+                        </label>
+                        <small class="form-text text-muted">投标工程数据文件</small>
+                        <input class="form-check-input" type="checkbox"  id="sei2" checked>
+                        <label class="form-check-label" for="sei2">
+                            投标文件
+                        </label>
+                        <small class="form-text text-muted">投标工程数据文件</small>
+                        <input class="form-check-input" type="checkbox"  id="sei3" checked>
+                        <label class="form-check-label" for="sei3">
+                            投标文件
+                        </label>
+                        <small class="form-text text-muted">投标工程数据文件</small>
+                    </div>
+                </div>
             </div>
             <div class="modal-footer">
                 <button type="button" class="btn btn-primary" id="exportCode-confirm">确定</button>

+ 31 - 9
web/building_saas/main/html/tender_price.html

@@ -1,26 +1,48 @@
 
 <div class="toolsbar px-1">
     <div class="btn-toolbar py-1">
+        <!--<div class="input-group input-group-sm mr-2" style="margin-left:10px; margin-top:4px;">-->
         <div class="input-group input-group-sm mr-2">
             <select class="form-control form-control-sm" style="width: auto; font-size: .875rem" id="calcPriceOption">
                 <option value="coeBase">按调价系数计算</option>
-                <option value="priceBase" >按目标价计算</option>
+                <option value="priceBase_RCJ" >按目标价调整人材机消耗</option>
+                <option value="priceBase_ZM" >按目标价调整子目工程量</option>
             </select>
+<!--            <div class="form-check">
+                <label class="form-check-label">
+                    <input class="form-check-input" name="tenderCalcType" id="tenderCalcByXS" value="0" type="radio">
+                    按调价系数正算 
+                </label>
+            </div>
+            <div class="form-check">
+                <label class="form-check-label">
+                    <input class="form-check-input" name="tenderCalcType" id="tenderCalcByTargetRCJ" value="1" type="radio">
+                    按目标价反算人材机消耗 
+                </label>
+            </div>
+            <div class="form-check">
+                <label class="form-check-label">
+                    <input class="form-check-input" name="tenderCalcType" id="tenderCalcByTargetZM" value="2" type="radio">
+                    按目标价反算子目工程量 
+                </label>
+            </div>-->
         </div>
-        <div class="input-group input-group-sm mr-2" style="width:240px">
+        <div class="input-group input-group-sm mr-2" style="width:200px">
             <div class="input-group-prepend">
                 <span class="input-group-text" id="inputGroup-sizing-sm">人材机单价调整系数</span>
             </div>
             <input id = 'gljPriceTenderCoe' type="number" step="0.1" class="form-control" placeholder="请输入系数" value="1">
         </div>
-        <div class="btn-group mr-2">
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderGLJQuantity">调整人材机消耗</button>
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderRationQuantity">调整子目工程量</button>
-           <!-- <button type="button" class="btn btn-outline-primary btn-sm">反调单价</button>-->
-            <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderPrice">调价计算</button>
-        </div>
+        <!--<div class="btn-group mr-2">-->
+            <!--<button type="button" class="btn btn-outline-primary btn-sm" id = "tenderGLJQuantity">调整人材机消耗</button>-->
+            <!--<button type="button" class="btn btn-outline-primary btn-sm" id = "tenderRationQuantity">调整子目工程量</button>-->
+           <!--&lt;!&ndash; <button type="button" class="btn btn-outline-primary btn-sm">反调单价</button>&ndash;&gt;-->
+            <!--<button type="button" class="btn btn-outline-primary btn-sm" id = "tenderPrice">调价计算2</button>-->
+        <!--</div>-->
+        <button type="button" class="btn btn-outline-primary btn-sm" id = "tenderPrice">调价计算</button>
+        <span>&nbsp</span>
         <button type="button" class="btn btn-outline-danger btn-sm" id = "cleanTender">清空调价</button>
-        <div class="form-check" style="margin-left:40px; margin-top:5px;">
+        <div class="form-check" style="margin-left:40px; margin-top:4px;">
             <label class="form-check-label">
                 <input class="form-check-input" name="cbShowTenderFields" id="cbShowTenderFields" value="true" type="checkbox">
                 <span data-toggle="tooltip" data-original-title="造价书界面定额人材机的调价、人材机汇总界面的调价">显示调价后数据</span>

+ 43 - 0
web/building_saas/main/js/models/calc_program.js

@@ -1043,6 +1043,12 @@ let calcTools = {
             return false;
         }
         return totalFee > maxPrice;
+    },
+    getTenderCalcType: function () {
+        let tenderSetting = projectObj.project.property.tenderSetting;
+        let ct = tenderSetting && tenderSetting.calcPriceOption? tenderSetting.calcPriceOption : "coeBase";
+        if (ct == 'priceBase') ct = 'priceBase_RCJ';   // 兼容旧项目
+        return ct;
     }
 };
 
@@ -2207,6 +2213,26 @@ class CalcProgram {
         return me.getTotalFee(baseNodes, excludeNodes, tender);
     };
 
+    // 反向调价需初始化调价树、缓存数据等
+    initReverseTenderDatas (){
+        for(let node of tender_obj.tenderTree.items){
+            if (node.data.rationQuantityCoe) node.data.rationQuantityCoe = null;
+            let qcObj = node.data.quantityCoe;
+            if (qcObj){
+                for (let pn in qcObj){
+                    qcObj[pn] = null;
+                };
+            };
+            this.clearTenderCache(node);
+        };
+        // 反向调价时人材机单价调整系数要归1:因为既可以调量又可以调价,以哪个为基准进行反调?过于复杂,仅以通用的调量逻辑为基准即可满足需求。
+        if (projectObj.project.property.tenderSetting && projectObj.project.property.tenderSetting.gljPriceTenderCoe
+            && (projectObj.project.property.tenderSetting.gljPriceTenderCoe != 1)){
+            projectObj.project.property.tenderSetting.gljPriceTenderCoe = 1;    // 修改缓存值,用于计算
+            projectObj.project.property.needRestoreGgljPriceTenderCoe = true;   // 做个标记,告诉回调函数
+        }
+    };
+
     // 反向调价
     calcTenderReverse(treeNode, tender){
         if (tender == tenderTypes.ttReverseRation) {
@@ -2420,6 +2446,23 @@ class CalcProgram {
             return result;
         }
     };
+
+    doTenderCalc(callback){
+        let sOption = calcTools.getTenderCalcType();
+        let tender;
+        if (sOption =='coeBase')
+            tender = tenderTypes.ttCalc
+        else if (sOption =='priceBase_RCJ')
+            tender = tenderTypes.ttReverseGLJ
+        else if (sOption =='priceBase_ZM')
+            tender = tenderTypes.ttReverseRation;
+        if (tender == tenderTypes.ttReverseGLJ || tender == tenderTypes.ttReverseRation){
+            this.initReverseTenderDatas();
+            this.prepareForDistribute(tender_obj.tenderTree.roots[0]);
+            this.distributeTargetTotalFee(tender_obj.tenderTree.roots[0]);
+        };
+        this.calcAllNodesAndSave(calcAllType.catAll, callback, tender);
+    };
 };
 
 // export default analyzer;

+ 8 - 7
web/building_saas/main/js/views/index_view.js

@@ -273,7 +273,7 @@ let indexObj= {
         this.spread.setActiveSheetIndex(3);
         let property = projectObj.project.property;
         let sheet = this.spread.getActiveSheet();
-        let mainDatas = this.getMainMaterialDatas(property.materials,projectObj.project.projectGLJ.datas,property.calcOptions,property.decimal,false,_,scMathUtil);
+        let mainDatas = this.getMainMaterialDatas(property,property.materials,projectObj.project.projectGLJ.datas,property.calcOptions,property.decimal,false,_,scMathUtil);
         sheetCommonObj.showData(sheet, this.mainMaterialSetting,mainDatas);
         sheet.setRowCount(mainDatas.length);
     },
@@ -324,8 +324,8 @@ let indexObj= {
         return gljUtil.getEconomicDatas(projectObj.project.property.engineerFeatures,economics,billsList,fixedFlag,_,scMathUtil);
     },
 
-    getMainMaterialDatas:function (materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
-        return gljUtil.getMainMaterialDatas(projectObj.project.property.engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil);
+    getMainMaterialDatas:function (property,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil) {
+        return gljUtil.getMainMaterialDatas(property,projectObj.project.property.engineerFeatures,materials,projectGLJData,calcOptions,decimalObj,isRadio,_,scMathUtil);
     },
     showEcoQuantity:function () {
         let parentMap = {};
@@ -368,8 +368,8 @@ let indexObj= {
                 name:d.name,
                 unit:d.unit,
                 quantity:d.quantity,
-                totalFee:d.feesIndex && d.feesIndex.common && d.feesIndex.common.totalFee?d.feesIndex.common.totalFee:0,
-                unitFee:d.feesIndex && d.feesIndex.common && d.feesIndex.common.unitFee?d.feesIndex.common.unitFee:0,
+                totalFee:d.feesIndex && d.feesIndex.common && d.feesIndex.common.tenderTotalFee?d.feesIndex.common.tenderTotalFee:0,
+                unitFee:d.feesIndex && d.feesIndex.common && d.feesIndex.common.tenderUnitFee?d.feesIndex.common.tenderUnitFee:0,
                 economicType:d.economicType,
                 quantityIndexType:d.quantityIndexType,
                 quantityIndexUnit:d.quantityIndexUnit,
@@ -415,13 +415,14 @@ let indexObj= {
                     specs:glj.specs,
                     unit:glj.unit,
                     type:glj.type,
-                    quantity:glj.quantity,
+                    quantity:glj.tenderQuantity,
                     materialIndexType:glj.materialIndexType,
                     materialIndexUnit:glj.materialIndexUnit,
                     materialIndexCoe:glj.materialIndexCoe
                 };
                 gljOprObj.setGLJPrice(tem,glj);
-                tem.totalPrice = scMathUtil.roundForObj(tem.marketPrice * glj.quantity,getDecimal("glj.unitPrice"))
+                tem.marketPrice =tem.tenderPrice;
+                tem.totalPrice = scMathUtil.roundForObj(tem.tenderPrice * glj.tenderQuantity,getDecimal("glj.unitPrice"))
                 datas.push(tem);
             }
             return datas;

+ 9 - 1
web/building_saas/main/js/views/project_view.js

@@ -1025,6 +1025,14 @@ var projectObj = {
                 if(projectReadOnly){
                     disableSpread(that.mainSpread);
                 }
+
+                // 检查旧项目是否有调价数据,没有则自动生成
+                let node = projectObj.project.mainTree.firstNode();
+                if (node.data.feesIndex && node.data.feesIndex.common && node.data.feesIndex.common.totalFee
+                    && node.data.feesIndex.common.totalFee != 0){
+                    if (node.data.feesIndex.common.tenderTotalFee == undefined || node.data.feesIndex.common.tenderTotalFee == 0)
+                        projectObj.project.calcProgram.doTenderCalc();
+                };
                 $.bootstrapLoading.end();
             }
             else {
@@ -3412,7 +3420,7 @@ function disableTools(){
     $('#gljPriceTenderCoe').prop('disabled', 'disabled');
     $('#tenderGLJQuantity').prop('disabled', 'disabled');
     $('#tenderRationQuantity').prop('disabled', 'disabled');
-    $('#tenderPrice').prop('disabled', 'disabled');
+    // $('#tenderPrice').prop('disabled', 'disabled');
     $('#cleanTender').prop('disabled', 'disabled');
 }
 //项目只读,表格只读

+ 24 - 54
web/building_saas/main/js/views/tender_price_view.js

@@ -272,7 +272,7 @@ let tender_obj={
             let tem_updateData = {type:node.sourceType,data:{}};
             if(option == 'coeBase') {                           // 正向:当值为“根据调整系数计算报价”时,清空目标报价。
                 me.cleanTargetPrice(tem_updateData,node);
-            }else if(option == 'priceBase'){                    // 反向:当值为“根据报价计算调整系数”时,清空调整系数。
+            }else if(option == 'priceBase_RCJ' || option == 'priceBase_ZM'){                    // 反向:当值为“根据报价计算调整系数”时,清空调整系数。
                 me.cleanTenderCoe(tem_updateData,node);
             }
             if(!_.isEmpty(tem_updateData.data)){//如果需要更新
@@ -384,7 +384,7 @@ let tender_obj={
             }
         }
         if(dataCode.indexOf('Coe') != -1){//如果是调整系数列
-            if($('#calcPriceOption').val() =='priceBase'){//下拉按钮显示为“根据报价计算调整系数”时,只读。
+            if($('#calcPriceOption').val() =='priceBase_RCJ' || $('#calcPriceOption').val() =='priceBase_ZM'){//下拉按钮显示为“根据报价计算调整系数”时,只读。
                 return false;
             }else if(me.tenderTree.items[row].data.is_adjust_price === 1){//打勾了不调价,只读。
                 return false;
@@ -392,11 +392,11 @@ let tender_obj={
         }
         return true;
     },
-    initPageContent : function () {
+    initPageContent: function () {
         let tenderSetting = projectObj.project.property.tenderSetting;
-        let calcPriceOption = tenderSetting && tenderSetting.calcPriceOption? tenderSetting.calcPriceOption :"coeBase";
         let gljPriceTenderCoe = tenderSetting && tenderSetting.gljPriceTenderCoe?tenderSetting.gljPriceTenderCoe:1;
         let showTenderFields = tenderSetting && tenderSetting.showTenderFields?tenderSetting.showTenderFields:false;
+        let calcPriceOption = calcTools.getTenderCalcType();
         $('#calcPriceOption').val(calcPriceOption);
         $('#gljPriceTenderCoe').val(gljPriceTenderCoe);
         if(calcPriceOption == 'coeBase'){
@@ -410,49 +410,9 @@ let tender_obj={
             $('#gljPriceTenderCoe').attr("disabled",true);
             $('#tenderGLJQuantity').removeAttr("disabled");
             $('#tenderRationQuantity').removeAttr("disabled");
-            $('#tenderPrice').attr("disabled",true);
+            // $('#tenderPrice').attr("disabled",true);
         };
         $('#cbShowTenderFields').prop("checked", showTenderFields);
-    },
-    doTenderCalc: function(tender){
-        function initReverseTenderDatas (){
-            for(let node of tender_obj.tenderTree.items){
-                if (node.data.rationQuantityCoe) node.data.rationQuantityCoe = null;
-                let qcObj = node.data.quantityCoe;
-                if (qcObj){
-                    for (let pn in qcObj){
-                        qcObj[pn] = null;
-                    };
-                };
-                projectObj.project.calcProgram.clearTenderCache(node);
-            };
-            // 反向调价时人材机单价调整系数要归1:因为既可以调量又可以调价,以哪个为基准进行反调?过于复杂,仅以通用的调量逻辑为基准即可满足需求。
-            if (projectObj.project.property.tenderSetting && projectObj.project.property.tenderSetting.gljPriceTenderCoe
-                && (projectObj.project.property.tenderSetting.gljPriceTenderCoe != 1)){
-                projectObj.project.property.tenderSetting.gljPriceTenderCoe = 1;    // 修改缓存值,用于计算
-                projectObj.project.property.needRestoreGgljPriceTenderCoe = true;   // 标记:需保存入库
-            }
-
-        };
-
-        if (tender != tenderTypes.ttCalc) initReverseTenderDatas();
-        let callback = function () {
-            projectObj.project.saveProperty('hasTender', true);
-            if (projectObj.project.property.needRestoreGgljPriceTenderCoe){         // 入库存储,清理标记,刷新UI显示
-                projectObj.project.saveProperty('tenderSetting.gljPriceTenderCoe', 1);
-                delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
-                $('#gljPriceTenderCoe').val(1);
-            }
-
-            tender_obj.showTenderData();
-            projectObj.project.projectGLJ.calcQuantity();
-            // projectGljObject.refreshViewsData();
-        };
-        if (tender == tenderTypes.ttReverseGLJ || tender == tenderTypes.ttReverseRation){
-            projectObj.project.calcProgram.prepareForDistribute(tender_obj.tenderTree.roots[0]);
-            projectObj.project.calcProgram.distributeTargetTotalFee(tender_obj.tenderTree.roots[0]);
-        };
-        projectObj.project.calcProgram.calcAllNodesAndSave(calcAllType.catAll, callback, tender);
     }
 };
 
@@ -488,7 +448,7 @@ $(function () {
             }
         }
         datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.tenderSetting.gljPriceTenderCoe':1}});//恢复人材机单价调整系数为1。
-        datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
+        // datas.push({type:ModuleNames.project,data:{'ID' : projectObj.project.ID(),'property.hasTender': false}});
         me.updateTenderData(datas,function () {
             me.refreshTenderTreeByDatas(datas);
         });
@@ -517,16 +477,26 @@ $(function () {
     });
 
     $('#tenderPrice').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttCalc);
-    });
-
-    $('#tenderGLJQuantity').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttReverseGLJ);
+        let callback = function () {
+            // projectObj.project.saveProperty('hasTender', true);  // 一定调价,这个属性已失去意义
+            if (projectObj.project.property.needRestoreGgljPriceTenderCoe){         // 入库存储,清理标记,刷新UI显示
+                projectObj.project.saveProperty('tenderSetting.gljPriceTenderCoe', 1);
+                delete projectObj.project.property.needRestoreGgljPriceTenderCoe;
+                $('#gljPriceTenderCoe').val(1);
+            }
+            tender_obj.showTenderData();
+            projectObj.project.projectGLJ.calcQuantity();
+        };
+        projectObj.project.calcProgram.doTenderCalc(callback);
     });
 
-    $('#tenderRationQuantity').on('click', function () {
-        tender_obj.doTenderCalc(tenderTypes.ttReverseRation);
-    });
+    // $('#tenderGLJQuantity').on('click', function () {
+    //     tender_obj.doTenderCalc(tenderTypes.ttReverseGLJ);
+    // });
+    //
+    // $('#tenderRationQuantity').on('click', function () {
+    //     tender_obj.doTenderCalc(tenderTypes.ttReverseRation);
+    // });
 
     $('#cbShowTenderFields').on('click', function () {
         let showFields = $('#cbShowTenderFields').prop("checked");

+ 102 - 32
web/over_write/js/chongqing_2018_export_sei.js

@@ -26,40 +26,92 @@ let exportUtil = {
     }
 };
 
-async function exportSEI(projectID) {
+let SEIObject = {};
 
-    let tenderProjects = [];
-    let errorMap = {};
-    let result = await ajaxPost("/project/getSEIProjects",{projectID:projectID});
+async function selfChecking(projectID,exprotCall=false) {//自检和正式导出共用接口
     let pr = new SCComponent.InitProgressBar();
-    pr.start('导出数据接口', '正在导出文件,请稍候……');
-    let project = getProject(result);
-    await prepareTenderDatas(tenderProjects,project);
+   if(!exprotCall) pr.start('导出数据接口', '正在自检,请稍候……');
 
-    if(!_.isEmpty(errorMap)){
-        showError(errorMap);
-        return pr.end();
+    //先检查招投标数据  - todo
+
+    //检查重庆指标接口数量
+    if(_.isEmpty(SEIObject.errorMap)){
+        let [errorMap,SEIFile] = await getSEIIndexFile(projectID);
+        if(errorMap) {
+            SEIObject.errorMap = errorMap;
+        }else {
+            SEIObject.fileCache.push(SEIFile);
+        }
     }
+    _.isEmpty(SEIObject.errorMap)?alert("自检完成,未检测到错误数据。"): showExportError(SEIObject.errorMap);
+    SEIObject.selfChecked = true;
+    if(!exprotCall) pr.end();
+}
 
-    toXml(project);
 
-    pr.end();
+async function exportSEI(projectID){
+    if(!_.isEmpty(SEIObject.errorMap)) return showExportError(SEIObject.errorMap);//如果自检的时候已经有错误,直接提示;
+    let pr = new SCComponent.InitProgressBar();
+    pr.start('导出数据接口', '正在导出文件,请稍候……');
+    SEIObject.exporting = true;
+    try {
+        if(!SEIObject.selfChecked){//没有经过自检,则从招投标接口开始取数据
+            await selfChecking(projectID,true);
+            if(!_.isEmpty(SEIObject.errorMap)) return  pr.end();
+        }
+        //导出建设项目数据
+        //导出压缩包
+       // saveZBFX(SEIObject.fileCache);
+
+    }catch (e){
+        console.log(e);
+    }finally {
+        pr.end();
+        $('#exportCode').modal('show');
+        //SEIObject.exporting = false;
+    }
 
-    
-    function showError(errorMap) {
-        let infoList = [];
-        for(let name in errorMap){
-            infoList.push(`<span style="font-weight: bold">单位工程“${name}”下:</span>`);
-            for(let err of errorMap[name]){
-                infoList.push(err);
-            }
+
+    async function saveZBFX(fileData) {
+        let zip = new JSZip();
+        for (let file of fileData) {
+            zip.file(file.fileName, file.blob, {binary: true});
         }
-        if(infoList.length > 20){
-            $('#hintBox_caption').addClass('export-check');
+        let zipFile = await zip.generateAsync({type: 'blob'});
+        saveAs(zipFile, '经济指标.ZBFX');
+    }
+
+}
+
+function showExportError(errorMap) {
+    let infoList = [];
+    for(let name in errorMap){
+        infoList.push(`<span style="font-weight: bold">单位工程“${name}”下:</span>`);
+        for(let err of errorMap[name]){
+            infoList.push(err);
         }
-        let msg = infoList.join(`<br>`);
-        alert(msg);
     }
+    if(infoList.length > 20){
+        $('#hintBox_caption').addClass('export-check');
+    }
+    let msg = infoList.join(`<br>`);
+    alert(msg);
+}
+
+async function getSEIIndexFile(projectID) {
+
+    let tenderProjects = [];
+    let errorMap = {};
+    let result = await ajaxPost("/project/getSEIProjects",{projectID:projectID});
+    let project = getProject(result);
+    await prepareTenderDatas(tenderProjects,project);
+
+    if(!_.isEmpty(errorMap)){
+        return [errorMap,null];
+    }
+    let file = toXml(project);
+
+    return [null,file];
 
     function getProject(orignal) {//取建设项目信息
         let basicInformation = getBaseInfo(orignal);
@@ -158,7 +210,7 @@ async function exportSEI(projectID) {
                 children:[]
             };
             if(projectData) gljUtil.calcProjectGLJQuantity(projectData.projectGLJs,projectData.ration_gljs,projectData.rations,projectData.bills,getDecimal("glj.quantity"),_,scMathUtil);
-            let materials = indexObj.getMainMaterialDatas(tender.property.materials,projectData.projectGLJs,tender.property.calcOptions,tender.property.decimal,false,_,scMathUtil);
+            let materials = indexObj.getMainMaterialDatas(tender.property,tender.property.materials,projectData.projectGLJs,tender.property.calcOptions,tender.property.decimal,false,_,scMathUtil);
             for(let m of materials){
                 if(m.name == "其他材料") continue;//2020-01-08  其他材料 不输出字段(不管是否有值)。
                 mainIndex.children.push(getMaterial(m))
@@ -262,11 +314,12 @@ async function exportSEI(projectID) {
 
     function setGLJDetail(projectData,property,gljs) {
         if(projectData){
-            gljUtil.calcProjectGLJQuantity(projectData.projectGLJs,projectData.ration_gljs,projectData.rations,projectData.bills,getDecimal("glj.quantity"),_,scMathUtil);
+            gljUtil.calcProjectGLJQuantity(projectData.projectGLJs,projectData.ration_gljs,projectData.rations,projectData.bills,getDecimal("glj.quantity"),_,scMathUtil,true);
         }
         for(let g of projectData.projectGLJs.gljList) {
             if (!g.quantity || g.quantity == "") continue;
-            g.marketPrice = gljUtil.getMarketPrice(g,projectData.projectGLJs,property.calcOptions,property.decimal,false,_,scMathUtil);
+            let tenderCoe = gljUtil.getTenderPriceCoe(g,property);
+            g.marketPrice = gljUtil.getMarketPrice(g,projectData.projectGLJs,property.calcOptions,property.decimal,false,_,scMathUtil,tenderCoe);
             gljs.children.push(setEachGLJ(g));
         }
     }
@@ -514,15 +567,32 @@ async function exportSEI(projectID) {
          //格式化
          xmlStr = formatXml(xmlStr);
          let blob = new Blob([xmlStr], {type: 'text/plain;charset=utf-8'});
-         saveAs(blob, '经济指标.ZBF');
+         return {
+             blob: blob,
+             fileName: "经济指标.ZBF"
+         };
+         //saveAs(blob, '经济指标.ZBF');
      }
 
 }
 
 $(function () {
-   $("#SEIMenu").click(async function () {
-       await exportSEI(projectObj.project.property.rootProjectID);
-       $("#exportMenu").removeClass("show");
-   })
+
+    $("#export-index-check").click( function (){
+        selfChecking(projectObj.project.property.rootProjectID);
+    });
+    $("#export-index-confirm").click(async function (){
+        await  exportSEI(projectObj.project.property.rootProjectID);
+       // $("#exportIndex").modal("hide");
+    });
+
+    $('#exportIndex').on('hide.bs.modal', function() {
+        SEIObject = {
+            exporting:false,
+            fileCache:[],
+            errorMap:{},
+            selfChecked:false
+        }
+    })
 
 });