Browse Source

Merge branch 'master' of http://192.168.1.41:3000/maixinrong/Calculation

MaiXinRong 5 years atrás
parent
commit
17cacc0d18

+ 1 - 1
app/const/account_group.js

@@ -18,10 +18,10 @@ const accountGroup = {
 
 const group = [];
 group[accountGroup.JSDW] = '建设单位';
+group[accountGroup.DJDW] = '代建单位';
 group[accountGroup.JLDW] = '监理单位';
 group[accountGroup.SGDW] = '施工单位';
 group[accountGroup.SJDW] = '设计单位';
-group[accountGroup.DJDW] = '代建单位';
 group[accountGroup.GZSJ] = '跟踪审计';
 
 module.exports = {

+ 30 - 0
app/const/material.js

@@ -0,0 +1,30 @@
+'use strict';
+
+/**
+ * 材料调差
+ *
+ * @author ELlisran
+ * @date 2019/10/20
+ * @version
+ */
+
+// 调差类型
+const t_type = [
+    { key: 1, value: '消耗量' },
+    { key: 2, value: '费用' },
+];
+// 工料分类
+const m_type = [
+    { key: 1, value: '分类' },
+    { key: 2, value: '钢材' },
+    { key: 3, value: '地材' },
+    { key: 4, value: '油料' },
+    { key: 5, value: '水泥' },
+    { key: 6, value: '半成品' },
+    { key: 7, value: '其他' },
+];
+
+module.exports = {
+    t_type,
+    m_type,
+};

+ 5 - 0
app/controller/material_controller.js

@@ -15,6 +15,7 @@ const spreadConst = require('../const/spread');
 const tenderConst = require('../const/tender');
 const measureType = tenderConst.measureType;
 const accountGroup = require('../const/account_group').group;
+const materialConst = require('../const/material');
 
 module.exports = app => {
     class MaterialController extends app.BaseController {
@@ -113,6 +114,9 @@ module.exports = app => {
                     throw '您无权创建材料调差期';
                 }
                 const data = ctx.request.body;
+                if (data.s_order === '') {
+                    throw '没有选中计量期';
+                }
                 const newMaterial = await ctx.service.material.addMaterial(ctx.tender.id, data);
                 if (!newMaterial) {
                     throw '新增材料调差期失败,请重试';
@@ -244,6 +248,7 @@ module.exports = app => {
                 const renderData = await this._getDefaultRenderData(ctx);
                 [renderData.billsSpread] = this._getSpreadSetting();
                 // renderData.ledgerData = await ctx.service.ledger.getData(ctx.tender.id);
+                renderData.materialType = JSON.stringify(materialConst);
                 renderData.jsFiles = this.app.jsFiles.common.concat(this.app.jsFiles.material.info);
                 await this.layout('material/info.ejs', renderData, 'material/info_modal.ejs');
             } catch (err) {

+ 490 - 2
app/public/js/material.js

@@ -11,8 +11,496 @@
 $(document).ready(() => {
     autoFlashHeight();
     const materialSpread = SpreadJsObj.createNewSpread($('#material-spread')[0]);
-    materialSpread.options.allowUserDragFill = true;
-    materialSpread.options.defaultDragFillType = spreadNS.Fill.AutoFillType.fillSeries;
 
     SpreadJsObj.initSheet(materialSpread.getActiveSheet(), billsSpreadSetting);
+
+    const paySpreadObj = {
+        _checkExprValid(expr, invalidParam) {
+            if (!expr) return [true, null];
+            const param = [];
+            let num = '', base = '';
+            for (let i = 0, iLen = expr.length; i < iLen; i++) {
+                if (/^[\d\.%]+/.test(expr[i])) {
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    num = num + expr[i];
+                } else if (/^[a-z]/.test(expr[i])) {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    base = base + expr[i];
+                } else if (expr[i] === '(') {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'left', value: '('});
+                } else if (expr[i] === ')') {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'right', value: ')'});
+                } else if (/^[\+\-*\/]/.test(expr[i])) {
+                    if (num !== '') {
+                        param.push({type: 'num', value: num});
+                        base = '';
+                    }
+                    if (base !== '') {
+                        param.push({type: 'base', value: base});
+                        base = '';
+                    }
+                    param.push({type: 'calc', value: expr[i]});
+                } else {
+                    return [false, '输入的表达式含有非法字符: ' + expr[i]];
+                }
+            }
+            if (num !== '') {
+                param.push({type: 'num', value: num});
+                base = '';
+            }
+            if (base !== '') {
+                param.push({type: 'base', value: base});
+                base = '';
+            }
+            if (param.length === 0) return true;
+            if (param.length > 1) {
+                if (param[0].value === '-') {
+                    param[1].value = '-' + param[1];
+                }
+                param.unshift();
+            }
+            const iLen = param.length;
+            let iLeftCount = 0, iRightCount = 0;
+            for (const [i, p] of param.entries()) {
+                if (p.type === 'calc') {
+                    if (i === 0 || i === iLen - 1)
+                        return [false, '输入的表达式非法:计算符号' + p.value + '前后应有数字或计算基数'];
+                }
+                if (p.type === 'num') {
+                    num = p.value.replace('%', '');
+                    if (p.value.length - num.length > 1)
+                        return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
+                    num = _.toNumber(num);
+                    if (num === undefined || num === null || _.isNaN(num))
+                        return [false, '输入的表达式非法:' + p.value + '不是一个有效的数字'];
+                    if (i > 0) {
+                        if (param[i - 1].type !== 'calc') {
+                            return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
+                        } else if (param[i - 1].value === '/' && num === 0) {
+                            return [false, '输入的表达式非法:请勿除0'];
+                        }
+                    }
+                }
+                if (p.type === 'base') {
+                    const baseParam = _.find(calcBase, {code: p.value});
+                    if (!baseParam)
+                        return [false, '输入的表达式非法:不存在计算基数' + p.value];
+                    if (invalidParam && invalidParam.indexOf(p.value) >= 0)
+                        return [false, '不可使用计算基数' + p.value];
+                    if (i > 0 && param[i - 1].type === 'calc')
+                        return [false, '输入的表达式非法:' + p.value + '前应有运算符'];
+                }
+                if (p.type === 'left') {
+                    iLeftCount += 1;
+                    if (i !== 0 && param[i-1].type !== 'calc')
+                        return [false, '输入的表达式非法:(前应有运算符'];
+                }
+                if (p.type === 'right') {
+                    iRightCount += 1;
+                    if (i !== iLen - 1 && param[i+1].type !== 'calc')
+                        return [false, '输入的表达式非法:)后应有运算符'];
+                    if (iRightCount > iLeftCount)
+                        return [false, '输入的表达式非法:")"前无对应的"("'];
+                }
+            }
+            if (iLeftCount > iRightCount)
+                return [false, '输入的表达式非法:"("后无对应的")"'];
+            return [true, ''];
+        },
+        _checkSExpr: function (payNode, text, data) {
+            if (!payNode) return [false, '数据错误'];
+
+            const num = text ? _.toNumber(text) : null;
+            let expr = text ? (num ? null : text) : null;
+            expr = expr ? expr.replace('=', '').toLowerCase(): null;
+            const [valid, msg] = this._checkExprValid(expr, ['bqwc', 'ybbqwc']);
+            if (!valid) return [valid, msg];
+
+            if (payBase.isStarted(payNode)) {
+                return [false, '已经开始计量,请勿修改起扣金额'];
+            } else {
+                if (stage.order > 1) {
+                    const value = expr ? payCalc.calculateExpr(expr) : num;
+                    if (wcPay.pre_tp && value < wcPay.pre_tp)
+                        return [false, '已进行到第' + stage.order + '期,起扣金额请勿少于本期完成截止上期计量金额' + wcPay.pre_tp];
+                    data.sprice = num;
+                    data.sexpr = expr;
+                    return [true, ''];
+                } else {
+                    data.sprice = num;
+                    data.sexpr = expr;
+                    return [true, ''];
+                }
+            }
+        },
+        _checkRExpr: function (payNode, text, data) {
+            if (!payNode) return [false, '数据错误'];
+
+            const num = text ? _.toNumber(text) : null;
+            let expr = text ? (num ? null : text) : null;
+            expr = expr ? expr.replace('=', '').toLowerCase(): null;
+            const [valid, msg] = this._checkExprValid(expr, ['bqwc', 'ybbqwc']);
+            if (!valid) return [valid, msg];
+
+            if (payBase.isStarted(payNode)) {
+                if (payNode.pre_finish) return [false, '已达扣款限额,请勿修改'];
+                const value = expr ? payCalc.calculateExpr(expr) : num;
+                if (payNode.pre_tp && value < payNode.pre_tp) return [false, '截止上期已计量' + payNode.pre_tp + ',扣款限额请勿少于改值'];
+                data.rprice = num;
+                data.rexpr = expr;
+                return [true, ''];
+            } else {
+                data.rprice = num;
+                data.rexpr = expr;
+                return [true, ''];
+            }
+        },
+        _checkExpr: function (text, data) {
+            if (text) {
+                const num = _.toNumber(text);
+                if (num) {
+                    data.tp = num;
+                    data.expr = null;
+                } else {
+                    const expr = text.replace('=', '').toLowerCase();
+                    const [valid, msg] = this._checkExprValid(expr);
+                    if (!valid) return [valid, msg];
+                    data.expr = expr;
+                    data.tp = null;
+                }
+            } else {
+                data.tp = null;
+                data.expr = null;
+            }
+            return [true, ''];
+        },
+        refreshActn: function () {
+            const setObjEnable = function (obj, enable) {
+                if (enable) {
+                    obj.removeClass('disabled');
+                } else {
+                    obj.addClass('disabled');
+                }
+            };
+            const sheet = paySpread.getActiveSheet();
+            const select = SpreadJsObj.getSelectObject(sheet);
+            setObjEnable($('#add'), !readOnly);
+            const delValid = payBase.isOld(select)
+                ? !payBase.isStarted(select) && payBase.isYB()
+                : payBase.isYB() || payBase.isOwner(select);
+            setObjEnable($('#del'), !readOnly && select && delValid);
+            setObjEnable($('#up-move'), !readOnly && select && !payBase.isSpecial(select) && dealPay.indexOf(select) > 3);
+            setObjEnable($('#down-move'), !readOnly && select && !payBase.isSpecial(select) && dealPay.indexOf(select) < dealPay.length - 1);
+        },
+        add: function () {
+            const sheet = billsSpread.getActiveSheet();
+            postData(window.location.pathname + '/save', {type: 'add'}, function (result) {
+                if (result) {
+                    dealPay.push(result);
+                    sheet.addRows(dealPay.length - 1, 1);
+                    SpreadJsObj.reLoadRowData(sheet, dealPay.length - 1);
+                    sheet.setSelection(dealPay.length - 1, 0, 1, 1);
+                    paySpreadObj.refreshActn();
+                }
+            });
+        },
+        del: function () {
+            const sheet = billsSpread.getActiveSheet();
+            const select = SpreadJsObj.getSelectObject(sheet);
+            if (payBase.isNonZero(select.tp)) {
+                toast('该支付(扣款)项存在数据,如需删除请先清除本期金额!');
+                return;
+            } else if (payBase.isOld(select)) {
+                if (payBase.isStarted(select)) {
+                    toast('该合同支付项往期已进行计算,不允许删除');
+                    return;
+                }
+            }
+            postData(window.location.pathname + '/save', {type: 'del', id: select.pid}, function (result) {
+                const index = dealPay.indexOf(select);
+                dealPay.splice(index, 1);
+                sheet.deleteRows(index, 1);
+                loadUpdateDealPays(result);
+                SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                const sel = sheet.getSelections();
+                sheet.setSelection(index > 0 ? index - 1 : 0, sel.length > 0 ? sel[0].col : 0, 1, 1);
+                paySpreadObj.refreshActn();
+            });
+        },
+        selectionChanged: function (e, info) {
+            paySpreadObj.refreshActn();
+            const sel = info.sheet.getSelections()[0];
+            const col = info.sheet.zh_setting.cols[sel.col];
+            const data = SpreadJsObj.getSelectObject(info.sheet);
+            if (col.field === 'tp') {
+                $('#expr').val(data.expr).attr('field', 'expr').attr('org', data.expr)
+                    .attr('readOnly', readOnly|| payBase.isSpecial(data));
+            } else if (col.field === 'sprice') {
+                $('#expr').val(data.sexpr).attr('field', 'sexpr').attr('org', data.sexpr)
+                    .attr('readOnly', readOnly|| payCol.readOnly.sprice(data));
+            } else if (col.field === 'rprice') {
+                $('#expr').val(data.rexpr).attr('field', 'rexpr').attr('org', data.rexpr)
+                    .attr('readOnly', readOnly|| payCol.readOnly.rprice(data));
+            } else {
+                $('#expr').val('').attr('readOnly', true);
+            }
+        },
+        editEnded: function (e, info) {
+            if (info.sheet.zh_setting) {
+                const select = SpreadJsObj.getSelectObject(info.sheet);
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (col.field === 'minus') {
+                    return;
+                }
+                // 未改变值则不提交
+                const validText = info.editingText ? info.editingText.replace('\n', '') : null;
+                let orgValue;
+                if (col.field === 'tp') {
+                    orgValue = _.toNumber(validText) ? select.tp : select.expr;
+                } else if (col.field === 'sprice') {
+                    orgValue = _.toNumber(validText) ? select.sprice : select.sexpr;
+                } else if (col.field === 'rprice') {
+                    orgValue = _.toNumber(validText) ? select.rexpr : select.rexpr;
+                } else {
+                    orgValue = select[col.field];
+                }
+                if (orgValue == validText || ((!orgValue || orgValue === '') && (validText === ''))) {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                    return;
+                }
+                // 获取更新信息
+                const data = {
+                    type: (col.field === 'tp' || col.field === 'name') ? 'stage' : 'info',
+                    updateData: {}
+                };
+                // 获取更新数据
+                if (col.field === 'tp') {
+                    data.updateData.pid = select.pid;
+                    const [valid, msg] = paySpreadObj._checkExpr(validText, data.updateData);
+                    if (!valid) {
+                        toastr.warning(msg);
+                        SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                        return;
+                    }
+                } else if (col.field === 'name') {
+                    data.updateData.pid = select.pid;
+                    data.updateData.name = validText;
+                } else {
+                    data.updateData.id = select.pid;
+                    if (validText) {
+                        if (col.field === 'sprice') {
+                            const [valid, msg] = paySpreadObj._checkSExpr(select, validText, data.updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
+                        } else if (col.field === 'rprice') {
+                            const [valid, msg] = paySpreadObj._checkRExpr(select, validText, data.updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                                return;
+                            }
+                        } else {
+                            data.updateData[col.field] = validText;
+                        }
+                    } else {
+                        data.updateData[col.field] = null;
+                    }
+                }
+                // 更新至服务器
+                postData(window.location.pathname + '/save', data, function (result) {
+                    loadUpdateDealPays(result, col.field === 'name' ? ['name'] : null);
+                    SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                }, function () {
+                    SpreadJsObj.reLoadRowData(info.sheet, info.row);
+                });
+            }
+        },
+        buttonClicked: function (e, info) {
+            if (info.sheet.zh_setting) {
+                const select = SpreadJsObj.getSelectObject(info.sheet);
+                const col = info.sheet.zh_setting.cols[info.col];
+                if (payCol.readOnly.minus(select)) {
+                    return;
+                }
+                if (col.field === 'minus') {
+                    if (info.sheet.isEditing) {
+                        info.sheet.endEdit(true);
+                    }
+                    // 获取更新数据
+                    // 获取更新信息
+                    const data = {
+                        type: 'info',
+                        updateData: {id: select.pid},
+                    };
+                    data.updateData.minus = info.sheet.getValue(info.row, info.col) || false;
+                    // 更新至服务器
+                    postData(window.location.pathname + '/save', data, function (result) {
+                        loadUpdateDealPays(result);
+                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                    });
+                }
+            }
+        },
+        editStarting: function (e, info) {
+            const col = info.sheet.zh_setting.cols[info.col];
+            if (col.field === 'tp') {
+                const select = SpreadJsObj.getSelectObject(info.sheet);
+                if (select.expr && select.expr !== '') {
+                    info.sheet.getCell(info.row, info.col).text(select.expr);
+                }
+            } else if (col.field === 'sprice') {
+                const select = SpreadJsObj.getSelectObject(info.sheet);
+                if (select.sexpr && select.sexpr !== '') {
+                    info.sheet.getCell(info.row, info.col).text(select.sexpr);
+                }
+            } else if (col.field === 'rprice') {
+                const select = SpreadJsObj.getSelectObject(info.sheet);
+                if (select.rexpr && select.rexpr !== '') {
+                    info.sheet.getCell(info.row, info.col).text(select.rexpr);
+                }
+            }
+        },
+        deletePress: function (sheet) {
+            if (sheet.zh_setting && sheet.zh_data) {
+                const sel = sheet.getSelections()[0];
+                if (!sel) return;
+
+                const col = sheet.zh_setting.cols[sel.col];
+                if (col.readOnly === true) { return; }
+                if (sel.colCount > 1) {
+                    toast('请勿同时删除多列数据', 'warning');
+                }
+
+                const data = {type: col.field === 'tp' ? 'stage' : 'info', updateData: []};
+                for (let iRow = sel.row; iRow < sel.row + sel.rowCount; iRow++) {
+                    const node = sheet.zh_data[iRow];
+                    if (node && (node.ptype === 1 || node.ptype === 3)) {
+                        const updateData = {};
+                        if (col.field === 'tp') {
+                            updateData.pid = node.pid;
+                            updateData.tp = null;
+                            updateData.expr = null;
+                        } else {
+                            updateData.id = node.pid;
+                            if (col.field === 'sprice') {
+                                const [valid, msg] = paySpreadObj._checkSExpr(node, null, updateData);
+                                if (!valid) {
+                                    toastr.warning(msg);
+                                    return;
+                                }
+                            } else if (col.field === 'rprice') {
+                                const [valid, msg] = paySpreadObj._checkRExpr(node, null, updateData);
+                                if (!valid) {
+                                    toastr.warning(msg);
+                                    return;
+                                }
+                            } else {
+                                updateData[col.field] = null;
+                            }
+                        }
+                        data.updateData.push(updateData);
+                    }
+                }
+                if (data.updateData.length > 0) {
+                    if (data.updateData.length === 1 && sel.rowCount === 1) {
+                        data.updateData = data.updateData[0];
+                    }
+                    postData(window.location.pathname + '/save', data, function (result) {
+                        loadUpdateDealPays(result, col.field === 'name' ? ['name'] : null);
+                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                    })
+                }
+            }
+        },
+        clipboardPasted: function (e, info) {
+            if (info.sheet.zh_setting && info.sheet.zh_data) {
+                const col = info.sheet.zh_setting.cols[info.cellRange.col];
+                if (col.readOnly === true) {
+                    SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                    return;
+                }
+                if (info.cellRange.colCount > 1) {
+                    toast('请勿同时复制粘贴多列数据', 'warning');
+                }
+
+                const sortData = info.sheet.zh_data;
+                const data = {type: col.field === 'tp' ? 'stage' : 'info', updateData: []};
+
+                for (let iRow = 0; iRow < info.cellRange.rowCount; iRow++) {
+                    const curRow = info.cellRange.row + iRow;
+                    const node = sortData[curRow];
+                    if (node && (node.ptype === 1 || node.ptype === 3)) {
+                        const validText = info.sheet.getText(curRow, info.cellRange.col).replace('\n', '');
+                        const updateData = {};
+                        if (col.field === 'tp') {
+                            updateData.pid = node.pid;
+                            const [valid, msg] = paySpreadObj._checkExpr(validText, updateData);
+                            if (!valid) {
+                                toastr.warning(msg);
+                                SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                return;
+                            }
+                        } else {
+                            updateData.id = node.pid;
+                            if (validText) {
+                                if (col.field === 'sprice') {
+                                    const [valid, msg] = paySpreadObj._checkSExpr(node, validText, updateData);
+                                    if (!valid) {
+                                        toastr.warning(msg);
+                                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                        return;
+                                    }
+                                } else if (col.field === 'rprice') {
+                                    const [valid, msg] = paySpreadObj._checkRExpr(node, validText, updateData);
+                                    if (!valid) {
+                                        toastr.warning(msg);
+                                        SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                                        return;
+                                    }
+                                } else {
+                                    updateData[col.field] = validText;
+                                }
+                            } else {
+                                updateData[col.field] = null;
+                            }
+                        }
+                        data.updateData.push(updateData);
+                    }
+                    if (data.updateData.length > 0) {
+                        postData(window.location.pathname + '/save', data, function (result) {
+                            loadUpdateDealPays(result, col.field === 'name' ? ['name'] : null);
+                            SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                        }, function () {
+                            SpreadJsObj.reLoadSheetData(paySpread.getActiveSheet());
+                        });
+                    }
+                }
+            }
+        },
+    };
 });

+ 8 - 0
app/public/js/measure_material.js

@@ -96,5 +96,13 @@ $(function () {
             $('#show_order').show();
             $('#s_order').val(order_array.join(','));
         }
+    });
+
+    // 提交表单判断
+    $('#addMaterial').click(function () {
+        if ($('#s_order').val() == '') {
+            toastr.error('请选择计量期');
+            return false;
+        }
     })
 });

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

@@ -5,6 +5,10 @@
             <% include ./material_sub_mini_menu.ejs %>
             <div>
                 <div class="d-inline-block">
+                    <a href="javascript: void(0);" id="add" class="btn btn-sm btn-light text-primary" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="新增材料"><i class="fa fa-plus" aria-hidden="true"></i></a>
+                    <a href="javascript: void(0);" id="del" class="btn btn-sm btn-light text-primary disabled" data-toggle="tooltip" data-placement="bottom" title="" data-original-title="删除材料"><i class="fa fa-remove" aria-hidden="true"></i></a>
+                </div>
+                <div class="d-inline-block">
                     本期调差计量期:第<span class="mx-2"><%= ctx.material.s_order.split(',').join(',') %></span>期
                 </div>
             </div>
@@ -47,6 +51,7 @@
 <% if (ctx.material.status === auditConst.status.uncheck && ctx.session.sessionUser.accountId === ctx.material.user_id) {%>
 <script>
     const accountList = JSON.parse('<%- JSON.stringify(accountList) %>');
+    const materialType = JSON.parse('<%- materialType %>');
     const billsSpreadSetting = JSON.parse('<%- JSON.stringify(billsSpread) %>');
 </script>
 <% } %>

+ 1 - 1
app/view/material/modal.ejs

@@ -30,7 +30,7 @@
                 <input type="hidden" name="_csrf" value="<%= ctx.csrf %>" />
                 <input type="hidden" name="s_order" value="" id="s_order" />
                 <button type="button" class="btn btn-secondary" data-dismiss="modal">关闭</button>
-                <button type="submit" class="btn btn-primary">确定添加</button>
+                <button type="submit" id="addMaterial" class="btn btn-primary">确定添加</button>
             </div>
         </form>
     </div>