浏览代码

调差权限控制

laiguoran 2 年之前
父节点
当前提交
917f78974b

+ 22 - 2
app/const/account_permission.js

@@ -29,10 +29,29 @@ const permission = {
             { title: '创建标段', value: 1 },
             { title: '查阅所有标段', value: 2 },
             { title: '维护签约清单', value: 3, hint: '开启该选项,台账审批通过后,可上传签约清单', hintIcon: 'fa-question-circle' },
-            { title: '变更意向', value: 5, hint: '开启该选项,变更立项可新建变更意向书', hintIcon: 'fa-question-circle' },
-            { title: '材差清单设置', value: 4, hint: '开启该选项,当前账号可设置允许调差的清单', hintIcon: 'fa-question-circle' },
+            { title: '批量设置材差清单', value: 4, show: false, hint: '开启该选项,当前账号可设置允许调差的清单', hintIcon: 'fa-question-circle' },
+            { title: '变更意向', value: 5, show: false, hint: '开启该选项,变更立项可新建变更意向书', hintIcon: 'fa-question-circle' },
             { title: '查看项目管理报表数据', value: 6, hint: '开启该选项,当前账号在报表下可查看项目管理数据', hintIcon: 'fa-question-circle' },
         ],
+        tips: '勾选「创建标段」该用户默认具有「新建标段」及标段内「台账分解」「创建台账修订」「创建计量期」「创建工程变更」的权限。',
+    },
+    change: {
+        class: 'fa fa-retweet',
+        title: '工程变更',
+        type: 'checkbox',
+        children: [
+            { title: '变更意向', value: 1, hint: '开启该选项,变更立项可新建变更意向书', hintIcon: 'fa-question-circle' },
+        ],
+    },
+    material: {
+        class: 'fa fa-line-chart fa-fw',
+        title: '材料调差',
+        type: 'checkbox',
+        children: [
+            { title: '批量设置材差清单', value: 1, hint: '开启该选项,当前账号可设置允许调差的清单', hintIcon: 'fa-question-circle' },
+            { title: '修改调差工料消耗量', value: 2, hint: '开启该选项,可在新材差期修改工料的消耗量', hintIcon: 'fa-question-circle' },
+            { title: '修改材料税税率', value: 3, hint: '开启该选项,可在新材差期修改材料税税率', hintIcon: 'fa-question-circle' },
+        ],
     },
     // cooperation: {
     //     class: '',
@@ -42,6 +61,7 @@ const permission = {
     //         { title: '启用', value: 1 },
     //         { title: '关闭', value: 0 },
     //     ],
+    //     tips: '启用「协作办公」,则该用户可以为他创建的标段添加其他用户进行协作办公。',
     // },
     project_msg: {
         class: '',

+ 2 - 0
app/const/page_show.js

@@ -39,6 +39,8 @@ const defaultSetting = {
     closeWapYfSf: 0,
     openManagement: 0,
     openMaterialChecklist: 0,
+    openMaterialSelf: 0,
+    openMaterialEditForAudit: 0,
     close1stStageCheckDealParam: 0,
     openChangeProject: 0,
     openChangeApply: 0,

+ 17 - 1
app/controller/material_controller.js

@@ -378,6 +378,7 @@ module.exports = app => {
             try {
                 await this._getMaterialAuditViewData(ctx);
                 const renderData = await this._getDefaultRenderData(ctx);
+                await this._setEditTaxPermission(ctx);
                 renderData.materialBillsData = await this._getMaterialBillsData(ctx);
                 // 取对应期的截取上期的调差金额和应耗数量
                 if (ctx.material.highOrder !== ctx.material.order) {
@@ -442,6 +443,7 @@ module.exports = app => {
             try {
                 await this._getMaterialAuditViewData(ctx);
                 const renderData = await this._getDefaultRenderData(ctx);
+                await this._setEditListPermission(ctx);
                 // 根据期判断需要获取的工料信息值表
                 const searchsql = { tid: ctx.tender.id };
                 let midList = [];
@@ -783,6 +785,10 @@ module.exports = app => {
                 if (ctx.session.sessionProject.page_show.openMaterialChecklist && ctx.app._.indexOf(notControlList, data.type) === -1) {
                     throw '清单设置功能已启动,请前往清单设置页操作清单内容';
                 }
+                const selfControlList = ['self', 'noself', 'add', 'del', 'update', 'paste'];
+                if (!ctx.session.sessionProject.page_show.openMaterialSelf && ctx.app._.indexOf(selfControlList, data.type) !== -1) {
+                    throw '单独设置工料功能已关闭,无法设置';
+                }
                 switch (data.type) {
                     case 'add':
                         responseData.data = await ctx.service.materialList.add(data.postData, data.ms_id);
@@ -1426,12 +1432,22 @@ module.exports = app => {
             }
         }
 
+        async _setEditListPermission(ctx) {
+            const permission = ctx.session.sessionUser.permission;
+            ctx.material.editListPermission = permission && permission.material !== undefined && permission.material.indexOf('2') !== -1;
+        }
+
+        async _setEditTaxPermission(ctx) {
+            const permission = ctx.session.sessionUser.permission;
+            ctx.material.editTaxPermission = permission && permission.material !== undefined && permission.material.indexOf('3') !== -1;
+        }
+
         async _setChecklistPermission(ctx) {
             // 清单设置权限判断
             ctx.material.checklistPermission = false;
             if (ctx.session.sessionProject.page_show.openMaterialChecklist && ctx.material.highOrder === ctx.material.order && ctx.material.status !== auditConst.status.checked) {
                 const permission = ctx.session.sessionUser.permission;
-                if ((permission && permission.tender !== undefined && permission.tender.indexOf('4') !== -1) || (ctx.material.order === 1 && ctx.session.sessionUser.accountId === ctx.material.user_id && (ctx.material.status === auditConst.status.uncheck || ctx.material.status === auditConst.status.checkNo))) {
+                if ((permission && ((permission.tender !== undefined && permission.tender.indexOf('4') !== -1) || (permission.material !== undefined && permission.material.indexOf('1') !== -1))) || (ctx.material.order === 1 && ctx.session.sessionUser.accountId === ctx.material.user_id && (ctx.material.status === auditConst.status.uncheck || ctx.material.status === auditConst.status.checkNo))) {
                     ctx.material.checklistPermission = true;
                 }
             }

+ 2 - 0
app/controller/setting_controller.js

@@ -954,6 +954,8 @@ module.exports = app => {
                 this.ctx.session.sessionProject.page_show.openChangePlan = data.openChangePlan ? 1 : 0;
                 this.ctx.session.sessionProject.page_show.openMaterialTax = data.openMaterialTax ? 1 : 0;
                 this.ctx.session.sessionProject.page_show.openMaterialChecklist = data.openMaterialChecklist ? 1 : 0;
+                this.ctx.session.sessionProject.page_show.openMaterialSelf = data.openMaterialSelf ? 1 : 0;
+                this.ctx.session.sessionProject.page_show.openMaterialEditForAudit = data.openMaterialEditForAudit ? 1 : 0;
                 const result2 = await ctx.service.project.updatePageshow(projectId);
                 if (!result2) throw '保存数据失败';
 

+ 1 - 1
app/public/js/material.js

@@ -136,7 +136,7 @@ $(document).ready(() => {
         {title: '工料分类', colSpan: '1', rowSpan: '2', field: 'm_type', hAlign: 1, width: 60, readOnly: 'readOnly.isEdit', cellType: 'customizeCombo', comboItems: materialType.m_type, cellTypeKey: 2},
     ];
     if (materialTax) {
-        materialSpreadSettingCols.push({title: '税率(%)', colSpan: '1', rowSpan: '2', field: 'm_tax', hAlign: 2, width: 50, type: 'Number', readOnly: 'readOnly.remark'});
+        materialSpreadSettingCols.push({title: '税率(%)', colSpan: '1', rowSpan: '2', field: 'm_tax', hAlign: 2, width: 50, type: 'Number', readOnly: editTaxPermission ? 'readOnly.remark' : 'readOnly.isEdit'});
     }
     materialSpreadSettingCols = _.concat(materialSpreadSettingCols, [
         {title: '上涨 幅度(%)', colSpan: '1', rowSpan: '2', field: 'm_up_risk', hAlign: 2, width: 50, type: 'Number', readOnly: 'readOnly.isEdit'},

+ 255 - 227
app/public/js/material_list.js

@@ -525,7 +525,7 @@ $(document).ready(() => {
             // 是否本期添加的工料
             // return data.order === stage_order && !openMaterialChecklist;
             let flag = true;
-            if (type === 'del') {
+            if (type === 'del' || !editListPermission) {
                 flag = data.order === stage_order;
             }
             return flag && !openMaterialChecklist;
@@ -613,7 +613,7 @@ $(document).ready(() => {
                 // const select = SpreadJsObj.getSelectObject(sheet);
                 // const notx = findNotJoinLeafXmj(select);
                 // return !(!readOnly && notx === undefined && materialBase.isEdit(data));
-                return !(!readOnly && materialSelfBase.isEdit(data));
+                return openMaterialSelf && !(!readOnly && materialSelfBase.isEdit(data));
             },
         },
     };
@@ -928,6 +928,9 @@ $(document).ready(() => {
                         leafXmjSpreadObj.checkSelfMaterial('self');
                     },
                     visible: function (key, opt) {
+                        if (!openMaterialSelf) {
+                            return false;
+                        }
                         const sheet = leafXmjSpread.getActiveSheet();
                         const select = SpreadJsObj.getSelectObject(sheet);
                         const sel = sheet.getSelections()[0];
@@ -950,6 +953,9 @@ $(document).ready(() => {
                         // leafXmjSpreadObj.checkSelfMaterial('noself');
                     },
                     visible: function (key, opt) {
+                        if (!openMaterialSelf) {
+                            return false;
+                        }
                         const sheet = leafXmjSpread.getActiveSheet();
                         const select = SpreadJsObj.getSelectObject(sheet);
                         const sel = sheet.getSelections()[0];
@@ -1450,148 +1456,66 @@ $(document).ready(() => {
         materialSpread.bind(spreadNS.Events.ClipboardPasted, materialSpreadObj.clipboardPasted);
         SpreadJsObj.addDeleteBind(materialSpread, materialSpreadObj.deletePress);
         // material-spread右键功能
-        const materialSelfSpreadObj = {
-            del: function () {
-                const sheet = materialSelfSpread.getActiveSheet();
-                const select = SpreadJsObj.getSelectObject(sheet);
-                console.log(select);
-                postData(window.location.pathname + '/save', {type: 'del', id: select.id, mb_id: select.mb_id, ms_id: $('#myTab').find('.active').data('msid') || null}, function (result) {
-                    const index = materialListSelf.indexOf(select);
-                    materialListSelf.splice(index, 1);
-                    sheet.deleteRows(index, 1);
-                    SpreadJsObj.reLoadSheetData(materialSelfSpread.getActiveSheet());
-                    const sel = sheet.getSelections();
-                    sheet.setSelection(index > 0 ? index - 1 : 0, sel.length > 0 ? sel[0].col : 0, 1, 1);
-                    const materialListIndex = materialListData.indexOf(select);
-                    materialListData.splice(materialListIndex, 1);
-                    const [iGclRow, iRow, nRow, lsheet, lselect, color] = leafXmjSpreadObj.getSelect();
-                    gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
-                    calculateJiaCha(gclGatherData, iGclRow);
-                    SpreadJsObj.reLoadRowData(lsheet, nRow);
-                    lsheet.getRange(nRow, -1, 1, -1).backColor(color);
-                    SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
-                });
-            },
-            deletePress: function (sheet) {
-                return;
-            },
-            editStarting: function (e, info) {
-                const col = info.sheet.zh_setting.cols[info.col];
-                const select = SpreadJsObj.getSelectObject(info.sheet);
-                if (col.field === 'quantity') {
-                    if (select.expr && select.expr !== '') {
-                        info.sheet.getCell(info.row, info.col).text(select.expr);
-                    }
-                }
-            },
-            editEnded: function (e, info) {
-                if (info.sheet.zh_setting) {
-                    const select = SpreadJsObj.getSelectObject(info.sheet);
-                    const col = info.sheet.zh_setting.cols[info.col];
-                    // 未改变值则不提交
-                    // const validText = info.editingText ? (typeof(info.editingText) === 'String' ? info.editingText.replace('\n', '') : info.editingText) : null;
-                    // const validText = is_numeric(info.editingText) ? parseFloat(info.editingText) : (info.editingText ? trimInvalidChar(info.editingText) : null);
-                    // let orgValue = select[col.field];
-                    const validText = info.editingText ? info.editingText.replace('\n', '') : null;
-                    let orgValue;
-                    if (col.field === 'quantity') {
-                        orgValue = validText && validText !== ''
-                            ? _.toNumber(validText) ? select.quantity : select.expr
-                            : (select.expr && select.expr !== '') ? select.expr : select.quantity;
-                    } else {
-                        orgValue = select[col.field];
-                    }
-                    if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === '' || validText === null))) {
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
-                        return;
-                    }
-                    const exprQuantity = {
-                        expr: '',
-                        quantity: 0,
-                    };
-                    const [valid, msg] = materialSpreadObj._checkExpr(validText, exprQuantity);
-                    if (!valid) {
-                        toastr.error(msg);
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
-                        return;
-                    }
-                    if (isNaN(exprQuantity.quantity)) {
-                        toastr.error('不能输入其它非数字类型字符');
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
-                        return;
-                    }
-                    const num = parseFloat(exprQuantity.quantity);
-                    if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
-                        // toastr.error('数量值必须大于0并且小于6位小数的浮点数');
-                        // SpreadJsObj.reLoadRowData(info.sheet, info.row);
-                        // return;
-                        toastr.warning('已保留6位小数');
-                        exprQuantity.quantity = ZhCalc.round(num, 6);
-                    }
-                    // 更新至服务器
-                    console.log(exprQuantity, select.mb_id);
-                    postData(window.location.pathname + '/save', { type:'update', updateData: { id: select.id, expr: exprQuantity.expr, quantity: exprQuantity.quantity, mb_id: select.mb_id }, ms_id: $('#myTab').find('.active').data('msid') || null }, function (result) {
+        if (openMaterialSelf) {
+            const materialSelfSpreadObj = {
+                del: function () {
+                    const sheet = materialSelfSpread.getActiveSheet();
+                    const select = SpreadJsObj.getSelectObject(sheet);
+                    console.log(select);
+                    postData(window.location.pathname + '/save', {
+                        type: 'del',
+                        id: select.id,
+                        mb_id: select.mb_id,
+                        ms_id: $('#myTab').find('.active').data('msid') || null
+                    }, function (result) {
+                        const index = materialListSelf.indexOf(select);
+                        materialListSelf.splice(index, 1);
+                        sheet.deleteRows(index, 1);
+                        SpreadJsObj.reLoadSheetData(materialSelfSpread.getActiveSheet());
+                        const sel = sheet.getSelections();
+                        sheet.setSelection(index > 0 ? index - 1 : 0, sel.length > 0 ? sel[0].col : 0, 1, 1);
                         const materialListIndex = materialListData.indexOf(select);
-                        const index = materialList.indexOf(select);
-                        select.quantity = exprQuantity.quantity;
-                        select.expr = exprQuantity.expr;
-                        materialListData.splice(materialListIndex, 1, select);
-                        materialList.indexOf(index, 1, select);
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
-                        const [iGclRow, iRow, nRow, sheet, lselect, color] = leafXmjSpreadObj.getSelect();
+                        materialListData.splice(materialListIndex, 1);
+                        const [iGclRow, iRow, nRow, lsheet, lselect, color] = leafXmjSpreadObj.getSelect();
                         gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
                         calculateJiaCha(gclGatherData, iGclRow);
-                        SpreadJsObj.reLoadRowData(sheet, nRow);
-                        console.log(lselect, color);
-                        sheet.getRange(nRow, -1, 1, -1).backColor(color);
+                        SpreadJsObj.reLoadRowData(lsheet, nRow);
+                        lsheet.getRange(nRow, -1, 1, -1).backColor(color);
                         SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
-                    }, function () {
-                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
                     });
-                }
-            },
-            clipboardPasted(e, info) {
-                const hint = {
-                    cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
-                    numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
-                    numberCan: {type: 'warning', msg: '已保留6位小数'},
-                };
-                const range = info.cellRange;
-                const sortData = info.sheet.zh_data || [];
-                if (range.row + range.rowCount > sortData.length) {
-                    toastMessageUniq(hint.cellError);
-                    SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
-                    SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
-                    return;
-                }
-                if (sortData.length > 0 && range.col + range.colCount > 5) {
-                    toastMessageUniq(hint.cellError);
-                    SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
-                    SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
+                },
+                deletePress: function (sheet) {
                     return;
-                }
-                const data = [];
-                for (let iRow = 0; iRow < range.rowCount; iRow++) {
-                    let bPaste = true;
-                    const curRow = range.row + iRow;
-                    const materialData = { id: sortData[curRow].id, mb_id: sortData[curRow].mb_id };
-                    const hintRow = range.rowCount > 1 ? curRow : '';
-                    let sameCol = 0;
-                    for (let iCol = 0; iCol < range.colCount; iCol++) {
-                        const curCol = range.col + iCol;
-                        const colSetting = info.sheet.zh_setting.cols[curCol];
-                        if (!colSetting) continue;
-
-                        // let validText = info.sheet.getText(curRow, curCol);
-                        // validText = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : null);
-                        const validText = info.sheet.getText(curRow, curCol).replace('\n', '');
-                        const orgValue = sortData[curRow][colSetting.field];
-                        if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
-                            sameCol++;
-                            if (range.colCount === sameCol)  {
-                                bPaste = false;
-                            }
-                            continue;
+                },
+                editStarting: function (e, info) {
+                    const col = info.sheet.zh_setting.cols[info.col];
+                    const select = SpreadJsObj.getSelectObject(info.sheet);
+                    if (col.field === 'quantity') {
+                        if (select.expr && select.expr !== '') {
+                            info.sheet.getCell(info.row, info.col).text(select.expr);
+                        }
+                    }
+                },
+                editEnded: function (e, info) {
+                    if (info.sheet.zh_setting) {
+                        const select = SpreadJsObj.getSelectObject(info.sheet);
+                        const col = info.sheet.zh_setting.cols[info.col];
+                        // 未改变值则不提交
+                        // const validText = info.editingText ? (typeof(info.editingText) === 'String' ? info.editingText.replace('\n', '') : info.editingText) : null;
+                        // const validText = is_numeric(info.editingText) ? parseFloat(info.editingText) : (info.editingText ? trimInvalidChar(info.editingText) : null);
+                        // let orgValue = select[col.field];
+                        const validText = info.editingText ? info.editingText.replace('\n', '') : null;
+                        let orgValue;
+                        if (col.field === 'quantity') {
+                            orgValue = validText && validText !== ''
+                                ? _.toNumber(validText) ? select.quantity : select.expr
+                                : (select.expr && select.expr !== '') ? select.expr : select.quantity;
+                        } else {
+                            orgValue = select[col.field];
+                        }
+                        if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === '' || validText === null))) {
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            return;
                         }
                         const exprQuantity = {
                             expr: '',
@@ -1599,55 +1523,157 @@ $(document).ready(() => {
                         };
                         const [valid, msg] = materialSpreadObj._checkExpr(validText, exprQuantity);
                         if (!valid) {
-                            toastMessageUniq(getPasteHint(msg, hintRow));
-                            bPaste = false;
-                            continue;
+                            toastr.error(msg);
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            return;
                         }
                         if (isNaN(exprQuantity.quantity)) {
-                            toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
-                            bPaste = false;
-                            continue;
+                            toastr.error('不能输入其它非数字类型字符');
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            return;
                         }
                         const num = parseFloat(exprQuantity.quantity);
                         if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
-                            toastMessageUniq(getPasteHint(hint.numberCan, hintRow));
-                            // bPaste = false;
-                            // continue;
+                            // toastr.error('数量值必须大于0并且小于6位小数的浮点数');
+                            // SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            // return;
+                            toastr.warning('已保留6位小数');
                             exprQuantity.quantity = ZhCalc.round(num, 6);
                         }
-                        // materialData[colSetting.field] = validText;
-                        materialData.expr = exprQuantity.expr;
-                        materialData.quantity = exprQuantity.quantity;
+                        // 更新至服务器
+                        console.log(exprQuantity, select.mb_id);
+                        postData(window.location.pathname + '/save', {
+                            type: 'update',
+                            updateData: {
+                                id: select.id,
+                                expr: exprQuantity.expr,
+                                quantity: exprQuantity.quantity,
+                                mb_id: select.mb_id
+                            },
+                            ms_id: $('#myTab').find('.active').data('msid') || null
+                        }, function (result) {
+                            const materialListIndex = materialListData.indexOf(select);
+                            const index = materialList.indexOf(select);
+                            select.quantity = exprQuantity.quantity;
+                            select.expr = exprQuantity.expr;
+                            materialListData.splice(materialListIndex, 1, select);
+                            materialList.indexOf(index, 1, select);
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                            const [iGclRow, iRow, nRow, sheet, lselect, color] = leafXmjSpreadObj.getSelect();
+                            gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
+                            calculateJiaCha(gclGatherData, iGclRow);
+                            SpreadJsObj.reLoadRowData(sheet, nRow);
+                            console.log(lselect, color);
+                            sheet.getRange(nRow, -1, 1, -1).backColor(color);
+                            SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
+                        }, function () {
+                            SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        });
                     }
-                    if (bPaste) {
-                        data.push(materialData);
-                        // rowData.push(curRow);
-                    } else {
-                        SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                },
+                clipboardPasted(e, info) {
+                    const hint = {
+                        cellError: {type: 'error', msg: '粘贴内容超出了表格范围'},
+                        numberExpr: {type: 'error', msg: '不能粘贴其它非数字类型字符'},
+                        numberCan: {type: 'warning', msg: '已保留6位小数'},
+                    };
+                    const range = info.cellRange;
+                    const sortData = info.sheet.zh_data || [];
+                    if (range.row + range.rowCount > sortData.length) {
+                        toastMessageUniq(hint.cellError);
+                        SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
+                        SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
+                        return;
                     }
-                }
-                if (data.length === 0) {
-                    SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
-                    return;
-                }
-                console.log(data);
-                postData(window.location.pathname + '/save', { type:'paste', updateData: data, ms_id: $('#myTab').find('.active').data('msid') || null }, function (result) {
-                    materialListData = result;
-                    const [iGclRow, iRow, nRow, sheet, lselect] = leafXmjSpreadObj.getSelect();
-                    gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
-                    calculateJiaCha(gclGatherData, iGclRow);
-                    SpreadJsObj.reLoadRowData(sheet, nRow);
-                    SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
-                    loadXmjMaterialData(iGclRow, nRow);
-                }, function () {
-                    SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
-                });
-            },
-        };
-        materialSelfSpread.bind(spreadNS.Events.EditStarting, materialSelfSpreadObj.editStarting);
-        materialSelfSpread.bind(spreadNS.Events.EditEnded, materialSelfSpreadObj.editEnded);
-        materialSelfSpread.bind(spreadNS.Events.ClipboardPasted, materialSelfSpreadObj.clipboardPasted);
-        SpreadJsObj.addDeleteBind(materialSelfSpread, materialSelfSpreadObj.deletePress);
+                    if (sortData.length > 0 && range.col + range.colCount > 5) {
+                        toastMessageUniq(hint.cellError);
+                        SpreadJsObj.reLoadSheetHeader(materialSpread.getActiveSheet());
+                        SpreadJsObj.reLoadSheetData(materialSpread.getActiveSheet());
+                        return;
+                    }
+                    const data = [];
+                    for (let iRow = 0; iRow < range.rowCount; iRow++) {
+                        let bPaste = true;
+                        const curRow = range.row + iRow;
+                        const materialData = {id: sortData[curRow].id, mb_id: sortData[curRow].mb_id};
+                        const hintRow = range.rowCount > 1 ? curRow : '';
+                        let sameCol = 0;
+                        for (let iCol = 0; iCol < range.colCount; iCol++) {
+                            const curCol = range.col + iCol;
+                            const colSetting = info.sheet.zh_setting.cols[curCol];
+                            if (!colSetting) continue;
+
+                            // let validText = info.sheet.getText(curRow, curCol);
+                            // validText = is_numeric(validText) ? parseFloat(validText) : (validText ? trimInvalidChar(validText) : null);
+                            const validText = info.sheet.getText(curRow, curCol).replace('\n', '');
+                            const orgValue = sortData[curRow][colSetting.field];
+                            if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
+                                sameCol++;
+                                if (range.colCount === sameCol) {
+                                    bPaste = false;
+                                }
+                                continue;
+                            }
+                            const exprQuantity = {
+                                expr: '',
+                                quantity: 0,
+                            };
+                            const [valid, msg] = materialSpreadObj._checkExpr(validText, exprQuantity);
+                            if (!valid) {
+                                toastMessageUniq(getPasteHint(msg, hintRow));
+                                bPaste = false;
+                                continue;
+                            }
+                            if (isNaN(exprQuantity.quantity)) {
+                                toastMessageUniq(getPasteHint(hint.numberExpr, hintRow));
+                                bPaste = false;
+                                continue;
+                            }
+                            const num = parseFloat(exprQuantity.quantity);
+                            if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
+                                toastMessageUniq(getPasteHint(hint.numberCan, hintRow));
+                                // bPaste = false;
+                                // continue;
+                                exprQuantity.quantity = ZhCalc.round(num, 6);
+                            }
+                            // materialData[colSetting.field] = validText;
+                            materialData.expr = exprQuantity.expr;
+                            materialData.quantity = exprQuantity.quantity;
+                        }
+                        if (bPaste) {
+                            data.push(materialData);
+                            // rowData.push(curRow);
+                        } else {
+                            SpreadJsObj.reLoadRowData(info.sheet, curRow);
+                        }
+                    }
+                    if (data.length === 0) {
+                        SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                        return;
+                    }
+                    console.log(data);
+                    postData(window.location.pathname + '/save', {
+                        type: 'paste',
+                        updateData: data,
+                        ms_id: $('#myTab').find('.active').data('msid') || null
+                    }, function (result) {
+                        materialListData = result;
+                        const [iGclRow, iRow, nRow, sheet, lselect] = leafXmjSpreadObj.getSelect();
+                        gclGatherData[iGclRow].leafXmjs[iRow].jiacha = calcOneBQJC(lselect);
+                        calculateJiaCha(gclGatherData, iGclRow);
+                        SpreadJsObj.reLoadRowData(sheet, nRow);
+                        SpreadJsObj.reLoadRowData(ledgerSpread.getActiveSheet(), iGclRow);
+                        loadXmjMaterialData(iGclRow, nRow);
+                    }, function () {
+                        SpreadJsObj.reLoadRowData(info.sheet, info.cellRange.row, info.cellRange.rowCount);
+                    });
+                },
+            };
+            materialSelfSpread.bind(spreadNS.Events.EditStarting, materialSelfSpreadObj.editStarting);
+            materialSelfSpread.bind(spreadNS.Events.EditEnded, materialSelfSpreadObj.editEnded);
+            materialSelfSpread.bind(spreadNS.Events.ClipboardPasted, materialSelfSpreadObj.clipboardPasted);
+            SpreadJsObj.addDeleteBind(materialSelfSpread, materialSelfSpreadObj.deletePress);
+        }
         if (!openMaterialChecklist) {
             $.contextMenu({
                 selector: '#material-spread',
@@ -1702,58 +1728,60 @@ $(document).ready(() => {
                 }
             });
         }
-        $.contextMenu({
-            selector: '#material-self-spread',
-            build: function ($trigger, e) {
-                const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialSelfSpread);
-                return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
-            },
-            items: {
-                'create': {
-                    name: '添加工料',
-                    icon: 'fa-sign-in',
-                    callback: function (key, opt) {
-                        // 获取已选清单
-                        changeMaterialTable('self');
-                        $('#add_type').val('self');
-                        $('#addgl').modal('show');
-                    },
-                    disabled: function (key, opt) {
-                        const sheet = leafXmjSpread.getActiveSheet();
-                        const select = SpreadJsObj.getSelectObject(sheet);
-                        // const notx = findNotJoinLeafXmj(select);
-                        if (!select) {
-                            return true;
-                        }
-                        // if (!readOnly && notx === undefined) {
-                        //     return false;
-                        // } else {
-                        //     return true;
-                        // }
-                        return readOnly;
-                    }
+        if (openMaterialSelf) {
+            $.contextMenu({
+                selector: '#material-self-spread',
+                build: function ($trigger, e) {
+                    const target = SpreadJsObj.safeRightClickSelection($trigger, e, materialSelfSpread);
+                    return target.hitTestType === GC.Spread.Sheets.SheetArea.viewport || target.hitTestType === GC.Spread.Sheets.SheetArea.rowHeader;
                 },
-                'delete': {
-                    name: '删除工料',
-                    icon: 'fa-remove',
-                    callback: function (key, opt) {
-                        materialSelfSpreadObj.del(materialSelfSpread.getActiveSheet());
+                items: {
+                    'create': {
+                        name: '添加工料',
+                        icon: 'fa-sign-in',
+                        callback: function (key, opt) {
+                            // 获取已选清单
+                            changeMaterialTable('self');
+                            $('#add_type').val('self');
+                            $('#addgl').modal('show');
+                        },
+                        disabled: function (key, opt) {
+                            const sheet = leafXmjSpread.getActiveSheet();
+                            const select = SpreadJsObj.getSelectObject(sheet);
+                            // const notx = findNotJoinLeafXmj(select);
+                            if (!select) {
+                                return true;
+                            }
+                            // if (!readOnly && notx === undefined) {
+                            //     return false;
+                            // } else {
+                            //     return true;
+                            // }
+                            return readOnly;
+                        },
                     },
-                    disabled: function (key, opt) {
-                        const sheet = materialSelfSpread.getActiveSheet();
-                        const select = SpreadJsObj.getSelectObject(sheet);
-                        if (!select) {
-                            return true;
-                        }
-                        if (!readOnly && select) {
-                            return false;
-                        } else {
-                            return true;
+                    'delete': {
+                        name: '删除工料',
+                        icon: 'fa-remove',
+                        callback: function (key, opt) {
+                            materialSelfSpreadObj.del(materialSelfSpread.getActiveSheet());
+                        },
+                        disabled: function (key, opt) {
+                            const sheet = materialSelfSpread.getActiveSheet();
+                            const select = SpreadJsObj.getSelectObject(sheet);
+                            if (!select) {
+                                return true;
+                            }
+                            if (!readOnly && select) {
+                                return false;
+                            } else {
+                                return true;
+                            }
                         }
-                    }
-                },
-            }
-        });
+                    },
+                }
+            });
+        }
     }
 
     // 应用调差工料至其他清单明细

+ 6 - 0
app/public/js/setting.js

@@ -149,6 +149,12 @@ $(document).ready(() => {
                 } else {
                     $('#edit-user2 input[name="cooperation"]').attr('disabled', true);
                 }
+                if (pm === 'tender' && permission[pm].indexOf('5') !== -1) {
+                    $('#edit-user2 input:checkbox[id="change_1"]').prop('checked', true);
+                }
+                if (pm === 'tender' && permission[pm].indexOf('4') !== -1) {
+                    $('#edit-user2 input:checkbox[id="material_1"]').prop('checked', true);
+                }
                 if (allPermission[pm].type === 'checkbox') {
                     for (const index of permission[pm]) {
                         $('#edit-user2 input:checkbox[id="' + pm + '_' + index + '"]').prop('checked', true);

+ 1 - 1
app/view/change/project.ejs

@@ -52,7 +52,7 @@
                     </div>
                 </div>
             </div>
-            <% if (tender.user_id === uid || (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('5') !== -1)) { %>
+            <% if (tender.user_id === uid || (userPermission !== null && ((userPermission.tender !== undefined && userPermission.tender.indexOf('5') !== -1) || (userPermission.change !== undefined && userPermission.change.indexOf('1') !== -1)))) { %>
             <div class="ml-auto">
                 <a href="#add-bj" data-toggle="modal" data-target="#add-bj" class="btn btn-sm btn-primary pull-right ml-1">新建变更立项</a>
                 <a href="#setting" data-toggle="modal" data-target="#setting" class="btn btn-sm btn-outline-primary pull-right ml-1"><i class="fa fa-cog"></i></a>

+ 1 - 1
app/view/change/project_modal.ejs

@@ -18,7 +18,7 @@
     </div>
 </div>
 
-<% if (tender.user_id === uid || (userPermission !== null && userPermission.tender !== undefined && userPermission.tender.indexOf('5') !== -1)) { %>
+<% if (tender.user_id === uid || (userPermission !== null && ((userPermission.tender !== undefined && userPermission.tender.indexOf('5') !== -1) || (userPermission.change !== undefined && userPermission.change.indexOf('1') !== -1)))) { %>
 <!--弹出添加变更令-->
 <div class="modal fade" id="add-bj-modal" data-backdrop="static">
     <div class="modal-dialog" role="document">

+ 1 - 0
app/view/material/info.ejs

@@ -228,6 +228,7 @@
 <script>
     const materialType = JSON.parse('<%- materialType %>');
     const isStageSelf = parseInt('<%- material.is_stage_self %>');
+    const editTaxPermission = <%- material.editTaxPermission %>;
     let materialBillsData = JSON.parse(unescape('<%- escape(JSON.stringify(materialBillsData)) %>'));
     let materialStageData = isStageSelf ? JSON.parse(unescape('<%- escape(JSON.stringify(materialStageData)) %>')) : [];
     let materialStageBillsData = isStageSelf ? JSON.parse(unescape('<%- escape(JSON.stringify(materialStageBillsData)) %>')) : [];

+ 3 - 0
app/view/material/list.ejs

@@ -103,6 +103,9 @@
     const materialStageData = isStageSelf ? JSON.parse(unescape('<%- escape(JSON.stringify(materialStageData)) %>')) : [];
     const materialStageBillsData = isStageSelf ? JSON.parse(unescape('<%- escape(JSON.stringify(materialStageBillsData)) %>')) : [];
     const readOnly = <%- material.readOnly %>;
+    const openMaterialSelf = parseInt(<%- ctx.session.sessionProject.page_show.openMaterialSelf %>);
+    const editListPermission = <%- material.editListPermission %>;
+    console.log(editListPermission);
     const stage_order = <%- material.order %>;
     const materialID = <%- material.id %>;
     const tenderID = <%- tender.id %>;

+ 16 - 0
app/view/setting/fun.ejs

@@ -100,6 +100,20 @@
                                                 <label class="form-check-label" for="openMaterialChecklist">开启「批量设置调差清单」添加调差工料功能</label>
                                             </div>
                                         </div>
+                                        <div class="form-group mb-1">
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="checkbox" id="openMaterialSelf" <% if(ctx.session.sessionProject.page_show.openMaterialSelf) { %>checked<% } %> onchange="updateSetting();">
+                                                <label class="form-check-label" for="openMaterialSelf">开启所调差清单-所属项目节「单独添加工料」功能
+                                                    <a href="javascript:void(0);"  data-toggle="tooltip" data-placement="bottom" title="" data-original-title="开启该选项,调差清单的所属项目节,允许单独添加工料"><i class="fa fa-question-circle "></i></a></label>
+                                            </div>
+                                        </div>
+                                        <div class="form-group mb-1">
+                                            <div class="form-check form-check-inline">
+                                                <input class="form-check-input" type="checkbox" id="openMaterialEditForAudit" <% if(ctx.session.sessionProject.page_show.openMaterialEditForAudit) { %>checked<% } %> onchange="updateSetting();">
+                                                <label class="form-check-label" for="openMaterialEditForAudit">开启「审核人修改数据」功能
+                                                    <a href="javascript:void(0);"  data-toggle="tooltip" data-placement="bottom" title="" data-original-title="开启该选项,审核人允许修改部分调差工料数据"><i class="fa fa-question-circle "></i></a></label>
+                                            </div>
+                                        </div>
                                     </div>
                                 </div>
                             </div>
@@ -155,6 +169,8 @@
             openChangePlan: $('#openChangePlan')[0].checked,
             openMaterialTax: $('#openMaterialTax')[0].checked,
             openMaterialChecklist: $('#openMaterialChecklist')[0].checked,
+            openMaterialSelf: $('#openMaterialSelf')[0].checked,
+            openMaterialEditForAudit: $('#openMaterialEditForAudit')[0].checked,
         });
     }
 </script>

+ 11 - 5
app/view/setting/user_permission_modal.ejs

@@ -84,6 +84,7 @@
                     <label><i <% if (permission[pm].class !== '') { %>class="<%= permission[pm].class %>"<% } %>></i> <%= permission[pm].title %> <sup><%= index %></sup></label>
                     <div>
                         <% for (const ip of permission[pm].children) { %>
+                        <% if (ip.show === undefined && ip.show !== false) { %>
                         <div class="form-check form-check-inline">
                             <input class="form-check-input" type="<%= permission[pm].type %>" id="<%= pm %>_<%= ip.value %>" name="<%= pm %><% if (permission[pm].type === 'checkbox') { %>[]<% } %>" value="<%= ip.value %>">
                             <label class="form-check-label" for="<%= pm %>_<%= ip.value %>"><%= ip.title %></label>
@@ -92,14 +93,19 @@
                             <% } %>
                         </div>
                         <% } %>
+                        <% } %>
+                    </div>
+                    <% if (permission[pm].tips) { %>
+                    <!--需要勾选  创建标段 ,协作办公才能勾选-->
+                    <div class="alert alert-secondary">
+                        <p class="mb-0"><%- permission[pm].tips %></p>
                     </div>
+                    <% } %>
                 </div>
+                <% if (ctx.helper._.size(permission) !== index) { %>
+                <hr>
+                <% } %>
                 <% } %>
-                <!--需要勾选  创建标段 ,协作办公才能勾选-->
-                <div class="alert alert-secondary">
-                    <p>1.勾选「创建标段」该用户默认具有「新建标段」及标段内「台账分解」「创建台账修订」「创建计量期」「创建工程变更」的权限。</p>
-                    <!--2.启用「协作办公」,则该用户可以为他创建的标段添加其他用户进行协作办公。-->
-                </div>
             </div>
             <div class="modal-footer">
                 <input type="hidden" name="id" value="">