Sfoglia il codice sorgente

导入工料功能

laiguoran 2 anni fa
parent
commit
026ca1e6ba

+ 28 - 24
app/controller/material_controller.js

@@ -310,30 +310,31 @@ module.exports = app => {
          * @private
          */
         async _getMaterialMonthsData(ctx, materialBillsData) {
-            // 取月信息价表
-            const monthsList = [];
-            if (ctx.material.months) {
-                const material_month = ctx.material.months.split(',');
-                material_month.sort();
-                const materialMonthList = await ctx.service.materialMonth.getListByMid(ctx.material.id);
-                for (const mbd of materialBillsData) {
-                    const one_mb = {
-                        code: mbd.code,
-                        name: mbd.name,
-                        unit: mbd.unit,
-                        origin: mbd.origin,
-                        mb_id: mbd.id,
-                        order: mbd.order,
-                    };
-                    for (const m of material_month) {
-                        const mb_id = ctx.material.highOrder !== ctx.material.order ? mbd.mb_id : mbd.id;
-                        const one_mm = _.find(materialMonthList, { mb_id, yearmonth: m });
-                        one_mb[m] = one_mm.msg_tp;
-                    }
-                    monthsList.push(one_mb);
-                }
-            }
-            return monthsList;
+            return await ctx.service.materialMonth.getMonthList(materialBillsData);
+            // // 取月信息价表
+            // const monthsList = [];
+            // if (ctx.material.months) {
+            //     const material_month = ctx.material.months.split(',');
+            //     material_month.sort();
+            //     const materialMonthList = await ctx.service.materialMonth.getListByMid(ctx.material.id);
+            //     for (const mbd of materialBillsData) {
+            //         const one_mb = {
+            //             code: mbd.code,
+            //             name: mbd.name,
+            //             unit: mbd.unit,
+            //             origin: mbd.origin,
+            //             mb_id: mbd.id,
+            //             order: mbd.order,
+            //         };
+            //         for (const m of material_month) {
+            //             const mb_id = ctx.material.highOrder !== ctx.material.order ? mbd.mb_id : mbd.id;
+            //             const one_mm = _.find(materialMonthList, { mb_id, yearmonth: m });
+            //             one_mb[m] = one_mm.msg_tp;
+            //         }
+            //         monthsList.push(one_mb);
+            //     }
+            // }
+            // return monthsList;
         }
 
         /**
@@ -944,6 +945,9 @@ module.exports = app => {
                     case 'add-glj':
                         responseData.data = await ctx.service.materialBills.addByGlj(data.postData, data.order);
                         break;
+                    case 'export':
+                        responseData.data = await ctx.service.materialBills.exportData(data.postData, data.includeSpec, data.ms_id);
+                        break;
                     default: throw '参数有误';
                 }
                 if (ctx.material.material_tax) {

+ 1 - 1
app/controller/setting_controller.js

@@ -1103,7 +1103,7 @@ module.exports = app => {
                     categoryData,
                     tenders,
                     dcTenders,
-                    is_dz1: ctx.session.sessionProject.code === 'P0505' ? 5 : false,
+                    is_dz1: ['P0505', 'MI22U'].indexOf(ctx.session.sessionProject.code) !== -1 ? 5 : false,
                 }, 'setting/datacollect_modal.ejs');
             } catch (error) {
                 ctx.helper.log(error);

+ 135 - 0
app/public/js/material.js

@@ -1558,6 +1558,108 @@ $(document).ready(() => {
                 $('#remove-month').modal('hide');
             });
         });
+
+        // 导入功能
+        let importFile = null;
+        $('#upload-xls-file').change(function () {
+            const file = this.files[0];
+            importFile = file;
+        });
+
+        $('#import-bills-btn').click(function() {
+            if (!importFile) {
+                toastr.error('请选择excel文件再确定');
+                return;
+            }
+            const ext = importFile.name.toLowerCase().split('.').splice(-1)[0];
+            const imgStr = /(xls|xlsx|XLS|XLSX)$/;
+            if (!imgStr.test(ext)) {
+                toastr.error('请导入正确格式的excel文件。');
+                return
+            }
+            const fileReader = new FileReader();
+            fileReader.onload = async function(ev) {
+                try{
+                    const data = ev.target.result;
+                    let tree = [];
+                    const includeSpec = $('#xls-spec').is(':checked');
+                    if (/(xls|xlsx|XLS|XLSX)$/.test(ext)) {
+                        const workbook = XLSX.read(data, {type: 'binary'}); // 以二进制流方式读取得到整份excel表格对象
+                        const jsonData = transExcel(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], { defval: null }));
+                        if (!(jsonData[0] && jsonData[0].code !== undefined && jsonData[0].code !== null && jsonData[0].unit !== undefined && jsonData[0].name !== undefined &&
+                            jsonData[0].spec !== undefined && jsonData[0].msg_tp !== undefined && jsonData[0].msg_times !== undefined)) {
+                            throw 'excel必须按指定格式内容上传';
+                        }
+                        // 去重
+                        tree = _.unionWith(jsonData, function (item1, item2) {
+                            return item1.code === item2.code && item1.name === item2.name && item1.unit === item2.unit && (!includeSpec || (includeSpec && item1.spec === item2.spec));
+                        });
+                    }
+                    if (tree.length === 0) {
+                        throw '该excel不存在导入的数据';
+                    }
+                    // 判断msg_tp格式,不符合则无法导入,还有excel日期转换问题
+                    for (const t of tree) {
+                        t.code = t.code.toString();
+                        if (t.msg_tp) {
+                            if (_.isNumber(t.msg_tp)) {
+                                const num = parseFloat(t.msg_tp);
+                                const reg = materialDecimal.up ? new RegExp("^\\d+(\\.\\d{1,"+ materialDecimal.up +"})?$") : new RegExp("^\\d+?$");
+                                if (num < 0 || !reg.test(num)) {
+                                    t.msg_tp = ZhCalc.round(num, materialDecimal.up);
+                                }
+                            } else {
+                                throw '信息价数据存在非数字字符,无法导入';
+                            }
+                        }
+                        if (_.isNumber(t.msg_times)) {
+                            t.msg_times = formatDate(t.msg_times, '/');
+                        }
+                    }
+                    console.log(tree);
+                    postData(window.location.pathname + '/save', { type:'export', postData: tree, includeSpec, ms_id: $('#myTab').find('.active').data('msid') || null }, function (result) {
+                        m_tp = result.m_tp;
+                        if (materialTax) {
+                            m_tax_tp = result.m_tax_tp;
+                        }
+                        materialBillsData = result.billsData;
+                        if (isStageSelf) {
+                            materialStageData = result.stageData;
+                            materialStageBillsData = result.stageBillsData;
+                        }
+                        materialSpreadObj.getMaterialBillsData();
+                        materialSpreadObj.materialSheetReset(true);
+                        if (months.length > 0) {
+                            monthsList = result.monthsList;
+                            monthFunGather.monthsListSet();
+                        }
+                        resetTpTable();
+                        if (result.addNum || result.updateNum) {
+                            let msg = [];
+                            if (result.addNum !== undefined && result.addNum !== 0) {
+                                msg.push('成功导入工料 ' + result.addNum + ' 条');
+                            }
+                            if (result.updateNum !== undefined && result.updateNum !== 0) {
+                                msg.push('成功更新工料 ' + result.updateNum + ' 条');
+                            }
+                            toastr.success(msg.length > 1 ? msg.join(',并') : msg[0]);
+                        } else {
+                            toastr.warning('导入的工料数据都已存在');
+                        }
+                        $('#import-info').modal('hide');
+                    });
+                } catch (error) {
+                    console.log(error);
+                    toastr.error(error);
+                    return
+                }
+            };
+
+            // 以二进制方式打开文件
+            fileReader.readAsBinaryString(importFile);
+            $('#upload-xls-file').val('');
+            importFile = null;
+        });
     } else {
         // SpreadJsObj.forbiddenSpreadContextMenu('#material-spread', materialSpread);
     }
@@ -1801,4 +1903,37 @@ $(document).ready(() => {
     function getObjHeight(select) {
         return select.length > 0 ? select.height() : 0;
     }
+
+    function formatDate(numb, format) {
+        const old = numb - 1;
+        const t = Math.round((old - Math.floor(old)) * 24 * 60 * 60);
+        const time = new Date(1900, 0, old, 0, 0, t);
+        const year = time.getFullYear();
+        const month = time.getMonth() + 1;
+        const date = time.getDate();
+        return year + format + (month < 10 ? '0' + month : month) + format + (date < 10 ? '0' + date : date);
+    }
+
+    function transExcel(results) {
+        const mapInfo = {
+            '编号': 'code',
+            '名称': 'name',
+            '单位': 'unit',
+            '规格': 'spec',
+            '信息价': 'msg_tp',
+            '时间': 'msg_times',
+        };
+        return results.map(zhObj => {
+            const enObj = {}
+            const zhKeys = Object.keys(zhObj);
+
+            zhKeys.forEach(zhKey => {
+                const enKey = mapInfo[zhKey];
+
+                enObj[enKey] = zhObj[zhKey];
+            });
+
+            return enObj
+        })
+    }
 });

+ 146 - 0
app/service/material_bills.js

@@ -76,6 +76,152 @@ module.exports = app => {
         }
 
         /**
+         * 导入工料
+         * @return {void}
+         */
+        async exportData(datas, includeSpec = false, ms_id = null) {
+            if (!this.ctx.tender || !this.ctx.material) {
+                throw '数据错误';
+            }
+            let order = await this._getMaxOrder(this.ctx.tender.id);
+            const transaction = await this.db.beginTransaction();
+            try {
+                const resultData = {};
+                let needUpdateTp = false;
+                // 找出需要导入的工料
+                const bills = await this.getAllDataByCondition({ where: { tid: this.ctx.tender.id } });
+                const newBills = this._.differenceWith(datas, bills, function(item1, item2) {
+                    return item1.code.toString() === item2.code.toString() && item1.name === item2.name && item1.unit === item2.unit && (!includeSpec || (includeSpec && item1.spec.toString() === item2.spec.toString()));
+                });
+                const material_month = this.ctx.material.months ? this.ctx.material.months.split(',') : [];
+                if (newBills.length !== 0) {
+                    const newBillsData = [];
+                    const newMonthList = [];
+                    for (const t of newBills) {
+                        // 判断msg_tp是否为数字,不是则报错
+                        if (t.msg_tp && !this._.isNumber(t.msg_tp)) {
+                            throw '信息价数据存在非数字字符,无法导入';
+                        }
+                        t.msg_tp = t.msg_tp ? this.ctx.helper.round(t.msg_tp, this.ctx.material.decimal.up) : null;
+                        const newBill = {
+                            tid: this.ctx.tender.id,
+                            mid: this.ctx.material.id,
+                            order: order + 1,
+                            code: t.code.toString(),
+                            name: t.name,
+                            unit: t.unit,
+                            spec: t.spec,
+                            msg_tp: this.ctx.material.is_stage_self ? null : t.msg_tp,
+                            msg_times: this.ctx.material.is_stage_self ? null : t.msg_times,
+                            msg_spread: this.ctx.material.is_stage_self ? null : t.msg_tp,
+                            m_spread: this.ctx.material.is_stage_self ? null : t.msg_tp,
+                            m_tp: 0,
+                            m_tax_tp: 0,
+                            in_time: new Date(),
+                        };
+                        order = order + 1;
+                        newBillsData.push(newBill);
+                    }
+                    const result = await transaction.insert(this.tableName, newBillsData);
+                    resultData.addNum = newBillsData.length;
+                    for (let j = 0; j < newBills.length; j++) {
+                        newBills[j].id = result.insertId + j;
+                        if (material_month.length > 0) {
+                            for (const ym of material_month) {
+                                const one_month = {
+                                    tid: this.ctx.tender.id,
+                                    mid: this.ctx.material.id,
+                                    mb_id: newBills[j].id,
+                                    msg_tp: newBills[j].msg_tp,
+                                    yearmonth: ym,
+                                };
+                                newMonthList.push(one_month);
+                            }
+                        }
+                    }
+                    if (this.ctx.material.is_stage_self) {
+                        // 获取刚批量添加的所有list
+                        await this.ctx.service.materialStageBills.adds(transaction, newBills, null, ms_id);
+                    }
+                    if (newMonthList.length > 0) await transaction.insert(this.ctx.service.materialMonth.tableName, newMonthList);
+                }
+                // 找出需要更新的工料
+                const updateBills = this._.intersectionWith(bills, datas, function(item1, item2) {
+                    return item1.code.toString() === item2.code.toString() && item1.name === item2.name && item1.unit === item2.unit && (!includeSpec || (includeSpec && item1.spec.toString() === item2.spec.toString()));
+                });
+                if (updateBills.length !== 0) {
+                    const updateDatas = [];
+                    const updateMonthList = [];
+                    for (const u of updateBills) {
+                        const oneData = this._.find(datas, function(item) {
+                            return item.code.toString() === u.code.toString() && item.name === u.name && item.unit === u.unit && (!includeSpec || (includeSpec && item.spec.toString() === u.spec.toString()));
+                        });
+                        const upd = { id: u.id };
+                        oneData.msg_tp = this.ctx.helper.round(oneData.msg_tp, this.ctx.material.decimal.up);
+                        // 判断msg_tp是否为数字,不是则报错
+                        if (oneData.msg_tp && !this._.isNumber(oneData.msg_tp)) {
+                            throw '信息价数据存在非数字字符,无法导入';
+                        }
+                        if (!this.ctx.material.is_stage_self) {
+                            if (oneData.msg_tp !== u.msg_tp) {
+                                needUpdateTp = true;
+                                upd.msg_tp = oneData.msg_tp;
+                                const [newmsg_spread, newm_spread] = await this.getSpread(u, oneData.msg_tp);
+                                upd.msg_spread = newmsg_spread;
+                                upd.m_spread = newm_spread;
+                                const newTp = this.ctx.helper.round(this.ctx.helper.mul(u.quantity, newm_spread), this.ctx.material.decimal.tp);
+                                upd.m_tp = newTp;
+                                upd.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(u.m_tax, 100))), this.ctx.material.decimal.tp);
+                            }
+                            if (oneData.msg_times !== u.msg_times) {
+                                upd.msg_times = oneData.msg_times;
+                            }
+                        }
+                        if (!includeSpec && oneData.spec !== u.spec) {
+                            upd.spec = oneData.spec;
+                        }
+                        if (!this._.isEqual(upd, { id: u.id })) updateDatas.push(upd);
+                        // 判断是否有月信息价,如果有则msg_tp都更改为统一值
+                        if (material_month.length > 0) {
+                            const monthList = await transaction.select(this.ctx.service.materialMonth.tableName, { where: { mb_id: u.id, mid: this.ctx.material.id } });
+                            if (monthList.length !== 0) {
+                                for (const m of monthList) {
+                                    // 更新月信息单价小数位
+                                    if (oneData.msg_tp !== m.msg_tp) {
+                                        m.msg_tp = oneData.msg_tp;
+                                        updateMonthList.push({ id: m.id, msg_tp: m.msg_tp });
+                                    }
+                                }
+                            }
+                        }
+                    }
+                    if (updateDatas.length !== 0) await transaction.updateRows(this.tableName, updateDatas);
+                    resultData.updateNum = updateDatas.length;
+                    if (updateMonthList.length !== 0) await transaction.updateRows(this.ctx.service.materialMonth.tableName, updateMonthList);
+                    if (this.ctx.material.is_stage_self) {
+                        needUpdateTp = await this.ctx.service.materialStageBills.updateByExport(transaction, updateBills, datas, includeSpec, ms_id);
+                    }
+                }
+                // 更新materialStage 值
+                if (this.ctx.material.is_stage_self) {
+                    resultData.stageBillsData = await transaction.select(this.ctx.service.materialStageBills.tableName, { where: { mid: this.ctx.material.id } });
+                    resultData.stageData = await transaction.select(this.ctx.service.materialStage.tableName, { where: { mid: this.ctx.material.id } });
+                }
+                resultData.billsData = await transaction.select(this.tableName, { where: { tid: this.ctx.tender.id }, orders: [['order', 'asc']] });
+                if (material_month.length > 0) {
+                    resultData.monthsList = await this.ctx.service.materialMonth.getMonthList(resultData.billsData, transaction);
+                }
+                resultData.m_tp = needUpdateTp ? await this.calcMaterialMTp(transaction) : this.ctx.material.m_tp;
+                await transaction.commit();
+                return resultData;
+            } catch (error) {
+                console.log(error);
+                await transaction.rollback();
+                throw error;
+            }
+        }
+
+        /**
          * 添加工料
          * @return {void}
          */

+ 29 - 2
app/service/material_month.js

@@ -29,8 +29,8 @@ module.exports = app => {
          * 返回月信息价列表
          * @return {void}
          */
-        async getListByMid(mid) {
-            return await this.getAllDataByCondition({ where: { mid } });
+        async getListByMid(mid, transaction = null) {
+            return transaction ? await transaction.select(this.tableName, { where: { mid } }) : await this.getAllDataByCondition({ where: { mid } });
         }
 
         /**
@@ -229,6 +229,33 @@ module.exports = app => {
                 throw err;
             }
         }
+
+        async getMonthList(materialBillsData, transaction = null) {
+            // 取月信息价表
+            const monthsList = [];
+            if (this.ctx.material.months) {
+                const material_month = this.ctx.material.months.split(',');
+                material_month.sort();
+                const materialMonthList = await this.getListByMid(this.ctx.material.id, transaction);
+                for (const mbd of materialBillsData) {
+                    const one_mb = {
+                        code: mbd.code,
+                        name: mbd.name,
+                        unit: mbd.unit,
+                        origin: mbd.origin,
+                        mb_id: mbd.id,
+                        order: mbd.order,
+                    };
+                    for (const m of material_month) {
+                        const mb_id = this.ctx.material.highOrder !== this.ctx.material.order ? mbd.mb_id : mbd.id;
+                        const one_mm = this._.find(materialMonthList, { mb_id, yearmonth: m });
+                        one_mb[m] = one_mm.msg_tp;
+                    }
+                    monthsList.push(one_mb);
+                }
+            }
+            return monthsList;
+        }
     }
 
     return MaterialMonth;

+ 61 - 2
app/service/material_stage_bills.js

@@ -110,7 +110,7 @@ module.exports = app => {
         }
 
         // 批量添加工料时同步生成
-        async adds(transaction, billsList, remark = null) {
+        async adds(transaction, billsList, remark = null, ms_id = null) {
             const insertList = [];
             for (const sid of this.ctx.material.stage_id.split(',')) {
                 const msInfo = await transaction.get(this.ctx.service.materialStage.tableName, { tid: this.ctx.tender.id, sid });
@@ -122,12 +122,70 @@ module.exports = app => {
                         mb_id: b.id,
                     };
                     if (remark) insertData.remark = remark;
+                    if (ms_id && parseInt(ms_id) === msInfo.id) {
+                        if (b.msg_tp) {
+                            insertData.msg_tp = b.msg_tp;
+                            insertData.msg_spread = b.msg_tp;
+                            insertData.m_spread = b.msg_tp;
+                            insertData.m_tp = 0;
+                            insertData.m_tax_tp = 0;
+                        }
+                        if (b.msg_times) insertData.msg_times = b.msg_times;
+                    }
                     insertList.push(insertData);
                 }
             }
             if (insertList.length > 0) await transaction.insert(this.tableName, insertList);
         }
 
+        async updateByExport(transaction, bills, datas, includeSpec, ms_id) {
+            const materialStageBillsList = await this.getAllDataByCondition({ where: { ms_id, mb_id: this._.map(bills, 'id') } });
+            const updateDatas = [];
+            let needUpdateTp = false;
+            const updateBillsDatas = [];
+            for (const m of materialStageBillsList) {
+                const oneBill = this._.find(bills, { id: m.mb_id });
+                const oneData = this._.find(datas, function(item) {
+                    return item.code.toString() === oneBill.code.toString() && item.name === oneBill.name && item.unit === oneBill.unit && (!includeSpec || (includeSpec && item.spec === oneBill.spec));
+                });
+                const upd = { id: m.id };
+                if (oneData.msg_tp !== m.msg_tp) {
+                    needUpdateTp = true;
+                    upd.msg_tp = oneData.msg_tp;
+                    const [newmsg_spread, newm_spread] = await this.getSpread(m, oneData.msg_tp);
+                    upd.msg_spread = newmsg_spread;
+                    upd.m_spread = newm_spread;
+                    const newTp = this.ctx.helper.round(this.ctx.helper.mul(m.quantity, newm_spread), this.ctx.material.decimal.tp);
+                    upd.m_tp = newTp;
+                    upd.m_tax_tp = this.ctx.helper.round(this.ctx.helper.mul(newTp, (1 + this.ctx.helper.div(oneBill.m_tax, 100))), this.ctx.material.decimal.tp);
+                    // 金额发生变化,返回重新计算本期这条工料的金额
+                    const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price' +
+                        ' FROM ' + this.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
+                    const sqlParam = [this.ctx.tender.id, this.ctx.material.id, m.id];
+                    const tp = await transaction.queryOne(sql, sqlParam);
+                    updateBillsDatas.push({
+                        id: m.id,
+                        m_tp: tp.total_price,
+                        m_tax_tp: tp.tax_total_price,
+                    });
+                }
+                if (oneData.msg_times !== m.msg_times) {
+                    upd.msg_times = oneData.msg_times;
+                }
+                if (!this._.isEqual(upd, { id: m.id })) updateDatas.push(upd);
+            }
+            if (updateDatas.length !== 0) {
+                await transaction.updateRows(this.tableName, updateDatas);
+                if (needUpdateTp) {
+                    // 更新到materialStage金额
+                    await this.ctx.service.materialStage.updateMtp(transaction, ms_id);
+                    // 更新到materialBills金额
+                    await transaction.updateRows(this.ctx.service.materialBills.tableName, updateBillsDatas);
+                }
+            }
+            return needUpdateTp;
+        }
+
         // 单个修改工料时同步修改
         async update(transaction, data, ms_id) {
             const msbInfo = await transaction.get(this.tableName, { tid: this.ctx.tender.id, ms_id, mb_id: data.id });
@@ -139,7 +197,8 @@ module.exports = app => {
             }
             await transaction.update(this.tableName, updateData);
             // 金额发生变化,返回重新计算本期这条工料的金额
-            const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price FROM ' + this.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
+            const sql = 'SELECT SUM(`m_tp`) as total_price, SUM(IF(`m_tax_tp` is null, `m_tp`, `m_tax_tp`)) as tax_total_price' +
+                ' FROM ' + this.tableName + ' WHERE `tid` = ? AND `mid` = ? AND `mb_id` = ? AND `is_summary` = 1';
             const sqlParam = [this.ctx.tender.id, this.ctx.material.id, data.id];
             const tp = await transaction.queryOne(sql, sqlParam);
             return [tp.total_price, tp.tax_total_price];

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

@@ -91,7 +91,7 @@
             <div class="modal-body">
                 <p>请上传指定格式(.xls或.xlsx或.json) 的文件,<a href="https://jiliang-qa.oss-cn-shenzhen.aliyuncs.com/loginimg/%E6%B8%85%E5%8D%95%E6%9D%90%E6%96%99%E5%8D%95%E4%BD%8D%E6%B6%88%E8%80%97%E9%87%8FExcel%E7%A4%BA%E4%BE%8B.xlsx">下载示例</a>。</p>
                 <div class="form-group">
-                    <label for="exampleFormControlFile1">选择文件</label>
+                    <label for="upload-list-file">选择文件</label>
                     <input type="file" class="form-control-file" id="upload-list-file" accept=".xls,.xlsx,.json">
                 </div>
                 <!--导入后选项-->

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

@@ -30,6 +30,9 @@
                             <label class="custom-control-label text-primary" for="bills0_list">过滤数量为0的工料</label>
                         </div>
                     </a>
+                    <% if ((material.status === auditConst.status.uncheck || material.status === auditConst.status.checkNo) && ctx.session.sessionUser.accountId === material.user_id) { %>
+                    <a href="#import-info" class="btn btn-sm btn-primary" data-toggle="modal" data-target="#import-info">导入信息价</a>
+                    <% } %>
                 </div>
             </div>
             <div class="ml-auto">

+ 27 - 0
app/view/material/info_modal.ejs

@@ -82,4 +82,31 @@
         </div>
     </div>
 </div>
+<!-- 导入信息价 -->
+<div class="modal fade" id="import-info" data-backdrop="static">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">导入信息价</h5>
+            </div>
+            <div class="modal-body">
+                <p>请上传指定格式的( .xls和.xlsx)的文件,<a href="https://jiliang-qa.oss-cn-shenzhen.aliyuncs.com/loginimg/%E5%AF%BC%E5%85%A5%E6%9D%90%E6%96%99%E4%BF%A1%E6%81%AF%E4%BB%B7%E6%A0%BC%E5%BC%8F.xls">下载示例</a>。</p>
+                <div class="form-group">
+                    <label for="upload-xls-file">选择文件</label>
+                    <input type="file" class="form-control-file" id="upload-xls-file" accept=".xls,.xlsx">
+                </div>
+            </div>
+            <div class="modal-footer d-flex justify-content-between">
+                <div class="custom-control custom-checkbox custom-control-inline">
+                    <input type="checkbox" class="custom-control-input" name="customRadioInline1" id="xls-spec">
+                    <label class="custom-control-label" for="xls-spec">规格</label>
+                </div>
+                <div>
+                    <button type="button" class="btn btn-sm btn-secondary" data-dismiss="modal">取消</button>
+                    <button type="button" class="btn btn-sm btn-primary" id="import-bills-btn">确定导入</button>
+                </div>
+            </div>
+        </div>
+    </div>
+</div>
 <% include ./audit_modal.ejs %>

+ 6 - 1
config/web.js

@@ -651,7 +651,12 @@ const JsFiles = {
         },
         material: {
             info: {
-                files: ['/public/js/spreadjs/sheets/v11/gc.spread.sheets.all.11.2.2.min.js', '/public/js/decimal.min.js'],
+                files: ['/public/js/spreadjs/sheets/v11/gc.spread.sheets.all.11.2.2.min.js', '/public/js/decimal.min.js',
+                    '/public/js/js-xlsx/xlsx.full.min.js',
+                    '/public/js/js-xlsx/xlsx.utils.js',
+                    '/public/js/export/jschardet.min.js',
+                    '/public/js/export/iconv-lite.js',
+                ],
                 mergeFiles: [
                     '/public/js/sub_menu.js',
                     '/public/js/div_resizer.js',