瀏覽代碼

逆变器信息导入

xusl 7 月之前
父節點
當前提交
616a864859

+ 5 - 0
cpp-admin/pom.xml

@@ -75,6 +75,11 @@
             <artifactId>commons-net</artifactId>
             <version>3.3</version>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.8.12</version>
+        </dependency>
     </dependencies>
     <profiles>    <!--考虑到window 和linux环境 npm命令格式的问题,使用maven的profile实现动态指定命令-->
         <profile>

+ 129 - 7
cpp-admin/src/main/java/com/cpp/web/controller/configManager/InverterInfoController.java

@@ -1,19 +1,34 @@
 package com.cpp.web.controller.configManager;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.NumberUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cpp.common.core.domain.R;
+import com.cpp.web.domain.station.ElectricField;
 import com.cpp.web.domain.station.InverterInfo;
+import com.cpp.web.service.station.ElectricFieldService;
 import com.cpp.web.service.station.InverterInfoService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.net.URLEncoder;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 /**
@@ -27,8 +42,10 @@ import java.util.Map;
 @RequestMapping("/inverterinfo")
 @Api(value = "inverterinfo", tags = "idp_inverter_info管理")
 public class InverterInfoController {
-
-    private final InverterInfoService inverterInfoService;
+    @Autowired
+    InverterInfoService inverterInfoService;
+    @Autowired
+    ElectricFieldService electricFieldService;
 
     /**
      * 分页查询
@@ -98,7 +115,7 @@ public class InverterInfoController {
     /**
      * 通过id删除idp_inverter_info
      *
-     * @param id id
+     * @param inverterInfo
      * @return R
      */
     @ApiOperation(value = "通过id删除idp_inverter_info", notes = "通过id删除idp_inverter_info")
@@ -139,4 +156,109 @@ public class InverterInfoController {
         }
         return R.ok(list);
     }
+
+    @GetMapping(value = {"/exportTemplateEvent" })
+    public R exportTemplateEvent(HttpServletResponse response) {
+        try {
+            ExcelWriter writer = ExcelUtil.getWriter(true);
+            writer.renameSheet(0, "逆变器信息");
+            List<String> headFieldName = Arrays.asList("场站编号","设备名称","制造商","型号","是否样板(1=>是,0=>否)");
+            List<List<String>> rowHeather = CollUtil.newArrayList();
+            rowHeather.add(headFieldName);
+            writer.write(rowHeather, true);
+            String fileName = "逆变器信息"+ ".xlsx";
+            response.setContentType("application/x-msdownload;charset=utf-8");
+            response.setHeader("Content-disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
+            ServletOutputStream out = null;
+            out = response.getOutputStream();
+            writer.flush(out, true);
+            // 关闭writer,释放内存
+            writer.close();
+            //此处记得关闭输出Servlet流
+            IoUtil.close(out);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        return R.ok();
+    }
+
+    /**
+     * 上传升级文件
+     */
+    @PostMapping(value = "/uploadNbqTemplate")
+    public R uploadNbqTemplate(@RequestParam(value="file") MultipartFile file){
+        try (InputStream inputStream = file.getInputStream();) {
+            ExcelReader excelReader = ExcelUtil.getReader(inputStream, 0);
+            List<Map<String, Object>> readAll = excelReader.readAll();
+            if (readAll.size() > 0) {
+                List<List<Object>> newList = new ArrayList<>();
+                for (Map<String, Object> row : readAll) {
+                    Iterator<Map.Entry<String, Object>> rowMap = row.entrySet().iterator();
+                    List<Object> tempList = new ArrayList<>();
+                    while (rowMap.hasNext()) {
+                        Map.Entry<String, Object> entry = rowMap.next();
+                        if (entry.getValue() == null) {
+                            tempList.add("");
+                        } else {
+                            tempList.add(entry.getValue());
+                        }
+                    }
+                    newList.add(tempList);
+                }
+                List<ElectricField> electricFieldList = electricFieldService.list();
+                List<InverterInfo> inverterInfoList = new ArrayList<>();
+                for (int i = 0; i < newList.size(); i++) {
+                    List<Object> objects = newList.get(i);
+                    InverterInfo inverterInfo = new InverterInfo();
+                    // 验证模板内容
+                    if (StrUtil.isBlankIfStr(objects.get(0))) {
+                        return R.fail("第" + (i + 1) + "行,场站编号不能为空!");
+                    } else {
+                        // 判断库中是否存在该编号
+                        List<ElectricField> collect = electricFieldList.stream().filter(t -> t.getStationCode().equals(objects.get(0).toString().trim())).collect(Collectors.toList());
+                        if (collect.isEmpty()) {
+                            return R.fail("第" + (i + 1) + "行,场站编号不存在!");
+                        } else {
+                            inverterInfo.setStationCode(objects.get(0).toString().trim());
+                        }
+                    }
+
+                    if (StrUtil.isBlankIfStr(objects.get(1))) {
+                        return R.fail("第" + (i + 1) + "行,设备名称不能为空!");
+                    } else {
+                        inverterInfo.setName(objects.get(1).toString().trim());
+                    }
+                    if (StrUtil.isBlankIfStr(objects.get(2))) {
+                        return R.fail("第" + (i + 1) + "行,制造商不能为空!");
+                    } else {
+                        inverterInfo.setManufacturer(objects.get(2).toString().trim());
+                    }
+
+                    if (StrUtil.isBlankIfStr(objects.get(3))) {
+                        return R.fail("第" + (i + 1) + "行,型号不能为空!");
+                    } else {
+                        inverterInfo.setModelNumber(objects.get(3).toString().trim());
+                    }
+
+                    if (StrUtil.isBlankIfStr(objects.get(4))) {
+                        return R.fail("第" + (i + 1) + "行,是否样板不能为空!");
+                    } else {
+                        if (NumberUtil.isNumber(objects.get(4).toString().trim())) {
+                            inverterInfo.setSample(objects.get(4).toString().trim());
+                        } else {
+                            return R.fail("第" + (i + 1) + "行,是否样板不是数值!");
+                        }
+                    }
+                    inverterInfoList.add(inverterInfo);
+                }
+                inverterInfoService.saveBatch(inverterInfoList);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+//            log.error("导入风机信息文件失败",e);
+            return R.fail("导入逆变器信息文件失败");
+        }
+        return R.ok();
+    }
 }

+ 1 - 1
cpp-ui/src/main.js

@@ -48,7 +48,7 @@ import VueMeta from 'vue-meta'
 import DictData from '@/components/DictData'
 import {getToken} from "@/utils/auth";
 import cache from "@/plugins/cache";
-Vue.prototype.$request = request
+Vue.prototype.$axios = request
 
 import 'xe-utils'
 import VXETable from 'vxe-table'

+ 77 - 43
cpp-ui/src/utils/request.js

@@ -1,15 +1,15 @@
 import axios from 'axios'
-import { Notification, MessageBox, Message, Loading } from 'element-ui'
+import {Notification, MessageBox, Message, Loading} from 'element-ui'
 import store from '@/store'
-import { getToken } from '@/utils/auth'
+import {getToken} from '@/utils/auth'
 import errorCode from '@/utils/errorCode'
-import { tansParams, blobValidate } from "@/utils/ruoyi";
+import {tansParams, blobValidate} from "@/utils/ruoyi";
 import cache from '@/plugins/cache'
-import { saveAs } from 'file-saver'
+import {saveAs} from 'file-saver'
 
 let downloadLoadingInstance;
 // 是否显示重新登录
-export let isRelogin = { show: false };
+export let isRelogin = {show: false};
 
 axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
 // 创建axios实例
@@ -67,49 +67,77 @@ service.interceptors.request.use(config => {
   }
   return config
 }, error => {
-    console.log(error)
-    Promise.reject(error)
+  console.log(error)
+  Promise.reject(error)
 })
 
 // 响应拦截器
 service.interceptors.response.use(res => {
-    // 未设置状态码则默认成功状态
-    const code = res.data.code || 200;
-    // 获取错误信息
-    const msg = errorCode[code] || res.data.msg || errorCode['default']
-    // 二进制数据则直接返回
-    if (res.request.responseType ===  'blob' || res.request.responseType ===  'arraybuffer') {
-      return res.data
-    }
-    if (code === 401) {
-      if (!isRelogin.show) {
-        isRelogin.show = true;
-        MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
-          isRelogin.show = false;
-          store.dispatch('LogOut').then(() => {
-            location.href = '/index';
-          })
-      }).catch(() => {
-        isRelogin.show = false;
-      });
-    }
-      return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
-    } else if (code === 500) {
-      Message({ message: msg, type: 'error' })
-      return Promise.reject(new Error(msg))
-    } else if (code === 601) {
-      Message({ message: msg, type: 'warning' })
-      return Promise.reject('error')
-    } else if (code !== 200) {
-      Notification.error({ title: msg })
-      return Promise.reject('error')
+    if (res.headers && res.headers['content-type'] && (res.headers['content-type'].indexOf('application/x-msdownload') != -1)) {
+      // 创建一个blob对象,file的一种
+      const blob = new Blob([res.data], {type: res.headers['content-type']})
+      const fileName = decodeURI(res.headers['content-disposition'].split('=')[1])
+      if (window.navigator.msSaveOrOpenBlob) {
+        // 兼容IE10
+        navigator.msSaveBlob(blob, fileName)
+      } else {
+        // 非IE下载
+        const elink = document.createElement('a')
+        elink.download = fileName
+        elink.style.display = 'none'
+        elink.href = URL.createObjectURL(blob)
+        document.body.appendChild(elink)
+        elink.click()
+        URL.revokeObjectURL(elink.href) // 释放URL 对象
+        document.body.removeChild(elink)
+      }
+
+      res.data = ''
+      res.headers['content-type'] = 'text/json'
+      return res
     } else {
-      return res.data
+      // 未设置状态码则默认成功状态
+      const code = res.data.code || 200;
+      // 获取错误信息
+      const msg = errorCode[code] || res.data.msg || errorCode['default']
+      // 二进制数据则直接返回
+      if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
+        return res.data
+      }
+      if (code === 401) {
+        if (!isRelogin.show) {
+          isRelogin.show = true;
+          MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
+            confirmButtonText: '重新登录',
+            cancelButtonText: '取消',
+            type: 'warning'
+          }).then(() => {
+            isRelogin.show = false;
+            store.dispatch('LogOut').then(() => {
+              location.href = '/index';
+            })
+          }).catch(() => {
+            isRelogin.show = false;
+          });
+        }
+        return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
+      } else if (code === 500) {
+        Message({message: msg, type: 'error'})
+        return Promise.reject(new Error(msg))
+      } else if (code === 601) {
+        Message({message: msg, type: 'warning'})
+        return Promise.reject('error')
+      } else if (code !== 200) {
+        Notification.error({title: msg})
+        return Promise.reject('error')
+      } else {
+        return res.data
+      }
     }
   },
   error => {
     console.log('err' + error)
-    let { message } = error;
+    let {message} = error;
     if (message == "Network Error") {
       message = "后端接口连接异常";
     } else if (message.includes("timeout")) {
@@ -117,17 +145,23 @@ service.interceptors.response.use(res => {
     } else if (message.includes("Request failed with status code")) {
       message = "系统接口" + message.substr(message.length - 3) + "异常";
     }
-    Message({ message: message, type: 'error', duration: 5 * 1000 })
+    Message({message: message, type: 'error', duration: 5 * 1000})
     return Promise.reject(error)
   }
 )
 
 // 通用下载方法
 export function download(url, params, filename, config) {
-  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
+  downloadLoadingInstance = Loading.service({
+    text: "正在下载数据,请稍候",
+    spinner: "el-icon-loading",
+    background: "rgba(0, 0, 0, 0.7)",
+  })
   return service.post(url, params, {
-    transformRequest: [(params) => { return tansParams(params) }],
-    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+    transformRequest: [(params) => {
+      return tansParams(params)
+    }],
+    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     responseType: 'blob',
     ...config
   }).then(async (data) => {

+ 79 - 27
cpp-ui/src/views/configManager/inverterinfo/index.vue

@@ -25,7 +25,6 @@
             icon="el-icon-plus"
             size="mini"
             @click="handleAdd"
-            v-hasPermi="['system:user:add']"
         >新增
         </el-button>
       </el-col>
@@ -35,9 +34,7 @@
             plain
             icon="el-icon-edit"
             size="mini"
-            :disabled="single"
             @click="handleUpdate"
-            v-hasPermi="['system:user:edit']"
         >修改
         </el-button>
       </el-col>
@@ -48,33 +45,33 @@
             icon="el-icon-delete"
             size="mini"
             @click="handleDelete"
-            v-hasPermi="['system:user:remove']"
         >删除
         </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button
-            type="info"
-            plain
-            icon="el-icon-upload2"
-            size="mini"
-            @click="handleImport"
-            v-hasPermi="['system:user:import']"
-        >导入
-        </el-button>
-      </el-col>
-      <el-col :span="1.5">
-        <el-button
             type="warning"
             plain
             icon="el-icon-download"
             size="mini"
-            @click="handleExport"
-            v-hasPermi="['system:user:export']"
-        >导出
+            @click="exportTemplateEvent"
+        >逆变器模板下载
         </el-button>
       </el-col>
-      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
+      <el-col :span="1.5">
+        <el-upload
+          :auto-upload="true"
+          ref="uploadNbqTemplate"
+          action="/inverterinfo/uploadNbqTemplate"
+          :http-request="dataUpload"
+          :on-change="beforeUpload"
+          :on-error="onError"
+          :file-list="fileList"
+          :show-file-list="false"
+        >
+          <el-button type="info" plain size="mini" :loading="loading">逆变器模板导入</el-button>
+        </el-upload>
+      </el-col>
     </el-row>
 
     <div style="padding-top: 10px">
@@ -163,9 +160,6 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-
-          </el-col>
         </el-row>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -225,6 +219,8 @@ export default {
           {required: true, message: "是否样板不能为空", trigger: "blur"}
         ],
       },
+
+      fileList: [],
     }
   },
   mounted() {
@@ -232,6 +228,62 @@ export default {
   },
   computed: {},
   methods: {
+    dataUpload(item) {
+      const formData = new FormData()
+      formData.append('file', item.file)
+
+      this.$axios({
+        url: '/inverterinfo/uploadNbqTemplate',
+        method: 'post',
+        //删除默认的Content-Type
+        transformRequest: [(data, headers) => {
+          delete headers.post['Content-Type']
+          return data
+        }],
+        data: formData
+      }).then((response) => {
+        this.stationChange()
+        this.dataQuery()
+        this.$message.success("导入成功")
+      }).catch((error) => {
+        this.$message.error("导入失败" + error)
+      })
+    },
+    onError(err, file, fileList){
+      console.log(JSON.parse(err.message).msg)
+      alert('失败')
+    },
+    beforeUpload(file, fileList){
+      if (fileList.length > 1) {
+        // 移除旧文件
+        this.fileList = [file];
+      } else {
+        this.fileList = fileList;
+      }
+      let index = file.name.lastIndexOf(".");
+      let suffixName = file.name.substr(index+1);
+      if (suffixName=='xls' || suffixName=='xlsx'){
+        return true
+      }
+      else{
+        this.$message({
+          type: 'warning',
+          message: '请导入excel模板文件!'
+        })
+        this.fileList=[]
+        return false
+      }
+    },
+    exportTemplateEvent() {
+      this.$axios.get("/inverterinfo/exportTemplateEvent/", {
+        responseType: 'blob'// 用于解决中文乱码
+      }).then((response) => {
+        this.loading = false
+      }).catch((error) => {
+        this.loading = false
+        this.$message.error('下载模板失败' + error)
+      })
+    },
     // 表单重置
     reset() {
       this.edit = false;
@@ -278,7 +330,7 @@ export default {
         if (valid) {
           if (this.form.id != undefined) {
             // 更新操作
-            this.$request.post('/inverterinfo/updateById', this.form).then((res) => {
+            this.$axios.post('/inverterinfo/updateById', this.form).then((res) => {
               this.$message.success('修改成功')
               this.open = false;
               this.stationChange()
@@ -287,7 +339,7 @@ export default {
             })
           } else {
             // 新增操作
-            this.$request.post('/inverterinfo/save', this.form).then((res) => {
+            this.$axios.post('/inverterinfo/save', this.form).then((res) => {
               if (res == undefined) {
                 this.$message.success('新增失败')
               } else {
@@ -326,7 +378,7 @@ export default {
      * 删除提交
      */
     doDelete(row) {
-      this.$request.post('/inverterinfo/remove', row).then((res) => {
+      this.$axios.post('/inverterinfo/remove', row).then((res) => {
         this.$message.success('删除成功!')
         this.stationChange()
         this.dataQuery()
@@ -362,7 +414,7 @@ export default {
         "stationCode": this.stationCode
       }
 
-      this.$request.get('/inverterinfo/getByStationCode', {params: param}).then(response => {
+      this.$axios.get('/inverterinfo/getByStationCode', {params: param}).then(response => {
         this.tableData = response.data.records
         this.page.total = response.data.total
         this.loading = false
@@ -371,7 +423,7 @@ export default {
       })
     },
     getStationCode() {
-      this.$request({url: '/electricfield/all', method: 'get'}).then(response => {
+      this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
         this.stationList = response.data
         if (this.stationList.length > 0) {
           this.stationCode = this.stationList[0].value