Browse Source

feat: 材料信息价类别总表支持导入excel数据

vian 1 year ago
parent
commit
836654eb66

+ 51 - 0
modules/price_info_class/controllers/index.js

@@ -3,6 +3,7 @@ const facade = require('../facade/index');
 const config = require("../../../config/config.js");
 const excel = require('node-xlsx');
 const fs = require('fs');
+const multiparty = require('multiparty');
 
 class PriceInfoClassController extends BaseController {
     async main(req, res) {
@@ -59,6 +60,56 @@ class PriceInfoClassController extends BaseController {
         }
     }
 
+    async importExcel(req, res) {
+        let responseData = {
+            err: 0,
+            msg: ''
+        };
+        res.setTimeout(1000 * 60 * 10);
+        const allowHeader = ['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
+        const uploadOption = {
+            uploadDir: './public'
+        };
+        const form = new multiparty.Form(uploadOption);
+        let uploadFullName;
+        form.parse(req, async function (err, fields, files) {
+            try {
+                const file = files.file !== undefined ? files.file[0] : null;
+                if (err || file === null) {
+                    throw '上传失败。';
+                }
+                // 判断类型
+                if (file.headers['content-type'] === undefined || allowHeader.indexOf(file.headers['content-type']) < 0) {
+                    throw '不支持该类型';
+                }
+                // 重命名文件名
+                uploadFullName = uploadOption.uploadDir + '/' + file.originalFilename;
+                fs.renameSync(file.path, uploadFullName);
+
+                const sheet = excel.parse(uploadFullName);
+                if (sheet[0] === undefined || sheet[0].data === undefined || sheet[0].data.length <= 0) {
+                    throw 'excel没有对应数据。';
+                }
+                // 提取excel数据并入库
+                await facade.importExcelData(sheet[0].data);
+                // 删除文件
+                if (uploadFullName && fs.existsSync(uploadFullName)) {
+                    fs.unlink(uploadFullName);
+                }
+                res.json(responseData);
+            }
+            catch (error) {
+                console.log(error);
+                if (uploadFullName && fs.existsSync(uploadFullName)) {
+                    fs.unlink(uploadFullName);
+                }
+                responseData.err = 1;
+                responseData.msg = error.toString();
+                res.json(responseData);
+            }
+        });
+    }
+
 
 }
 

+ 27 - 1
modules/price_info_class/facade/index.js

@@ -117,10 +117,36 @@ async function exportExcelData() {
     return excelData;
 }
 
+async function importExcelData(sheetData) {
+    const newClassData = [];
+    for (let row = 1; row < sheetData.length; row++) {
+        const classItem = {
+            ID: uuidV1(),
+            classCode: sheetData[row][1] || '',
+            code: sheetData[row][2] || '',
+            name: sheetData[row][3] || '',
+            specs: sheetData[row][4] || '',
+            unit: sheetData[row][5] || '',
+        }
+        const classVal = sheetData[row][0];
+        if (classVal !== undefined && !isNaN(classVal)) {
+            classItem.class = +classVal;
+        }
+        newClassData.push(classItem);
+    }
+    if (newClassData.length) {
+        await priceInfoClassModel.remove({});
+        await priceInfoClassModel.insertMany(newClassData);
+    } else {
+        throw 'excel没有有效数据。'
+    }
+}
+
 
 module.exports = {
     setIDForData,
     getPagingData,
     editClassData,
-    exportExcelData
+    exportExcelData,
+    importExcelData
 }

+ 1 - 0
modules/price_info_class/routes/index.js

@@ -11,6 +11,7 @@ module.exports = function (app) {
     router.post("/getPagingData", priceInfoClassController.auth, priceInfoClassController.init, priceInfoClassController.getPagingData);
     router.post("/editClassData", priceInfoClassController.auth, priceInfoClassController.init, priceInfoClassController.editClassData);
     router.get("/export", priceInfoClassController.auth, priceInfoClassController.init, priceInfoClassController.exportClassData);
+    router.post("/importExcel", priceInfoClassController.auth, priceInfoClassController.init, priceInfoClassController.importExcel);
 
 
     app.use("/priceInfoClass", router);

+ 30 - 0
web/maintain/price_info_class/html/main.html

@@ -19,6 +19,7 @@
             <a class="lock" data-locked="true" href="javascript:void(0);" title="解锁"><i
                 class="fa fa-unlock-alt"></i></a>
                 <a id="export" class="btn btn-success btn-sm" href="javascript:void(0);" title="导出" style="margin-left: 10px;"><i class="fa fa-sign-out fa-rotate-270"></i>导出</a>
+                <a id="import" class="btn btn-success btn-sm" href="javascript:void(0);" title="导入" style="margin-left: 10px;"><i class="fa fa-sign-in fa-rotate-270"></i>导入</a>
         </nav>
     </div>
     <div class="search">
@@ -28,6 +29,35 @@
     <div class="main">
         <div class="sheet" id="summary-spread"></div>
     </div>
+
+    <!--弹出导入数据-->
+<div class="modal fade" id="import-modal" data-backdrop="static" style="display: none;" aria-hidden="true">
+    <div class="modal-dialog" role="document">
+        <div class="modal-content">
+            <div class="modal-header">
+                <h5 class="modal-title">导入数据</h5>
+                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
+                    <span aria-hidden="true">×</span>
+                </button>
+            </div>
+            <div class="modal-body">
+                <div class="alert alert-warning" role="alert">
+                    导入操作会覆盖数据,请谨慎操作!!
+                </div>
+                <form>
+                    <div class="form-group">
+                        <label>请选择Excel格式文件</label>
+                        <input class="form-control-file" type="file" accept=".xlsx,.xls" name="import_data" />
+                    </div>
+                </form>
+            </div>
+            <div class="modal-footer">
+                <button type="button" class="btn btn-primary" id="import-confirm">确定导入</button>
+                <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
+            </div>
+        </div>
+    </div>
+</div>
     <!-- JS. -->
     <script src="/lib/jquery/jquery.min.js"></script>
     <script src="/lib/jquery-contextmenu/jquery.contextMenu.min.js"></script>

+ 57 - 0
web/maintain/price_info_class/js/index.js

@@ -23,4 +23,61 @@ $(document).ready(() => {
     $('#export').click(() => {
         window.location.href = '/priceInfoClass/export';
     });
+
+    $('#import').click(() => {
+        $('#import-modal').modal('show');
+    });
+
+    // 导入确认
+
+    $('#import-confirm').click(function () {
+        const self = $(this);
+        try {
+            const formData = new FormData();
+            const file = $("input[name='import_data']")[0];
+            if (file.files.length <= 0) {
+                throw '请选择文件!';
+            }
+            formData.append('file', file.files[0]);
+            $.ajax({
+                url: '/priceInfoClass/importExcel',
+                type: 'POST',
+                data: formData,
+                cache: false,
+                contentType: false,
+                processData: false,
+                beforeSend: function () {
+                    self.attr('disabled', 'disabled');
+                    self.text('上传中...');
+                },
+                success: function (response) {
+                    self.removeAttr('disabled');
+                    self.text('确定导入');
+                    if (response.err === 0) {
+                        $.bootstrapLoading.end();
+                        const message = response.msg !== undefined ? response.msg : '';
+                        if (message !== '') {
+                            alert(message);
+                        }
+                        // 成功则关闭窗体
+                        $('#import').modal("hide");
+                        window.location.reload();
+                    } else {
+                        $.bootstrapLoading.end();
+                        const message = response.msg !== undefined ? response.msg : '上传失败!';
+                        alert(message);
+                    }
+                },
+                error: function () {
+                    $.bootstrapLoading.end();
+                    alert("与服务器通信发生错误");
+                    self.removeAttr('disabled');
+                    self.text('确定导入');
+                }
+            });
+        } catch (error) {
+            alert(error);
+        }
+
+    });
 });