diff --git a/ant-design-vue-jeecg/src/views/modulex/ModulexList.vue b/ant-design-vue-jeecg/src/views/modulex/ModulexList.vue index b20bd0e..c3040e8 100644 --- a/ant-design-vue-jeecg/src/views/modulex/ModulexList.vue +++ b/ant-design-vue-jeecg/src/views/modulex/ModulexList.vue @@ -79,8 +79,27 @@ 导入规则 - - 导入实体 + + 导入实体 + +

当前状态:{{ ModalData.status }}

+

总记录数:{{ ModalData.records }}

+

已上传:{{ ModalData.uploaded }}

+ +
返回 @@ -212,6 +231,13 @@ export default { }, data () { return { + ModalData:{ + uploaded: '0', + isVisible: 'false', + records: '0', + status: '判断文件结构' + }, + visible:false, description: '模块管理管理页面', // 表头 columns: [ @@ -427,6 +453,7 @@ export default { this.loginRole(usercode) //console.log('userole1',this.userRole1) this.getSuperFieldList() + this.showProcess() }, computed: { importExcelUrl: function () { @@ -450,6 +477,20 @@ export default { }, }, methods: { + // 显示进度 + showProcess(){ + let userId = store.getters.userInfo.id + let base_url = window._CONFIG['domianURL'] + base_url = base_url.replace('http', 'ws') + let ws = new WebSocket(`${base_url}/uploadProcess/${userId}`) + ws.onmessage = (e) =>{ + this.ModalData=JSON.parse(e.data) + if (this.visible===false) { + // this.getList() + console.log("重新获取列表") + } + } + }, // 多选框的事件回调 checkChange (checked) { // 初始是默认全选的,假设此刻点击了name的选择框 diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java index 65db351..3714a10 100644 --- a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java +++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java @@ -72,6 +72,7 @@ public class ShiroConfig { } // 配置不会被拦截的链接 顺序判断 filterChainDefinitionMap.put("/createtp/createtp/maketupu","anon"); // 知识图谱排除 + filterChainDefinitionMap.put("/uploadProcess/**", "anon"); //上传进度条 filterChainDefinitionMap.put("/sys/cas/client/validateLogin", "anon"); //cas验证登录 filterChainDefinitionMap.put("/sys/randomImage/**", "anon"); //登录验证码接口排除 filterChainDefinitionMap.put("/sys/checkCaptcha", "anon"); //登录验证码接口排除 diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/controller/TablexController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/controller/TablexController.java index 5dac3f3..34b8049 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/controller/TablexController.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/controller/TablexController.java @@ -37,12 +37,14 @@ import lombok.extern.slf4j.Slf4j; import org.jeecg.modules.tablex.service.ITablexVoService; import org.jeecg.modules.tablex.vo.TablexVo; +import org.jeecg.modules.tablex.ws.WebSocketUtils; import org.jeecgframework.poi.excel.ExcelImportUtil; import org.jeecgframework.poi.excel.def.NormalExcelConstants; import org.jeecgframework.poi.excel.entity.ExportParams; import org.jeecgframework.poi.excel.entity.ImportParams; import org.jeecgframework.poi.excel.view.JeecgEntityExcelView; import org.jeecg.common.system.base.controller.JeecgController; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; @@ -81,6 +83,9 @@ public class TablexController extends JeecgController { @Autowired private IRequirementEntityService requirementEntityService; + @Autowired + private WebSocketUtils webSocketUtils; + /** * 分页列表查询 * @@ -269,14 +274,23 @@ public class TablexController extends JeecgController { */ @RequestMapping(value = "/importExcel", method = RequestMethod.POST) public Result importExcel(MultipartFile file) { - try { - LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + LoginUser loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal(); + + Map message = new HashMap<>(); + message.put("isVisible", "true"); + message.put("uploaded", "0"); + message.put("status", "判断文件结构"); + webSocketUtils.sendMessage(loginUser.getId(), message); + + try { // 判断文件是否是表格 String originalFilename = file.getOriginalFilename(); if (StringUtils.isBlank(originalFilename) || (!originalFilename.endsWith("xls") && !originalFilename.endsWith("xlsx"))) { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("文件格式不正确"); } @@ -286,17 +300,25 @@ public class TablexController extends JeecgController { params.setHeadRows(1);//表头行数,默认1 params.setNeedSave(true);//是否需要保存上传的Excel,默认为false List list = null; + message.put("status", "数据预读入"); + webSocketUtils.sendMessage(loginUser.getId(), message); try { //读取excel数据 list = ExcelImportUtil.importExcel(file.getInputStream(), TablexVo.class, params); } catch (Exception e) { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("文件读取失败"); } //判断文件中是否存在数据 if (list == null || list.size() == 0) { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("Excel数据为空"); } + message.put("status", "数据预读入"); + webSocketUtils.sendMessage(loginUser.getId(), message); for (TablexVo tablexVo : list) { //判断当前存入行是否为空值 if (tablexVo.getModuleId() == null && @@ -307,13 +329,17 @@ public class TablexController extends JeecgController { tablexVo.getStatus() == null && tablexVo.getVerisonStatus() == null && tablexVo.getVerison() == null) continue; + // 将总的记录数传递给前端 + message.put("records", String.valueOf(list.size())); + webSocketUtils.sendMessage(loginUser.getId(), message); //判断版本号长度 String verison = tablexVo.getVerison(); if (verison.length() > 5) { - return Result.error("导入失败,版本号格式错误"); + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); + return Result.error("预读入失败,版本号格式错误"); } - //存入临时表中 tablexVoService.save(tablexVo); } @@ -324,20 +350,30 @@ public class TablexController extends JeecgController { tablexVoService.removeAll(voList); if (voList.size() == 0) { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,数据为空"); } - Tablex tablex = new Tablex(); + message.put("status", "开始数据校验"); + webSocketUtils.sendMessage(loginUser.getId(), message); for (int i = 0; i < voList.size(); i++) { + List tablexList = new ArrayList<>(); + Tablex tablex = new Tablex(); + String moduleId = voList.get(i).getModuleId(); if (moduleId == null || moduleId.equals("")){ + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("对应模块填写不能为空"); } LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Modulex::getId,moduleId); Modulex modulex = modulexService.getOne(queryWrapper); if(modulex == null){ + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("对应模块填写错误"); } String modulexId = modulex.getId(); @@ -346,9 +382,9 @@ public class TablexController extends JeecgController { String verisonStatus = voList.get(i).getVerisonStatus(); //判断实体状态 - int statusInt = status.equals("正常") ? 1 : status.equals("停用") ? 0 : status.equals("废弃") ? 9 : 3; + //int statusInt = status.equals("正常") ? 1 : status.equals("停用") ? 0 : status.equals("废弃") ? 9 : 3; //判断版本状态 - int verisonStatusInt = verisonStatus.equals("当前") ? 1 : verisonStatus.equals("历史") ? 0 : 3; + //int verisonStatusInt = verisonStatus.equals("当前") ? 1 : verisonStatus.equals("历史") ? 0 : 3; //判断对应模块 if (modulexId != null && voList.get(i).getModuleId() != null && !voList.get(i).getModuleId().equals("")) { @@ -357,47 +393,64 @@ public class TablexController extends JeecgController { //判断英文名称 if (voList.get(i).getTableEnName() != null && !voList.get(i).getTableEnName().equals("") && !voList.get(i).getTableEnName().equals(modulex.getModuleEnName())) { //判断实体状态 - if (statusInt == 1 || statusInt == 0 || statusInt == 9) { + if (status.equals("1") || status.equals("0") || status.equals("9")) { //判断版本状态 - if (verisonStatusInt == 1 || verisonStatusInt == 0) { + if (verisonStatus.equals("1") || verisonStatus.equals("0")) { //判断版本号 if (voList.get(i).getVerison() != null && !voList.get(i).getVerison().equals("")) { - tablex.setModuleId(voList.get(i).getModuleId()); - tablex.setTableName(voList.get(i).getTableName()); - tablex.setTableEnName(voList.get(i).getTableEnName()); - tablex.setTableStructure(voList.get(i).getTableStructure()); - tablex.setStructuralDiagram(voList.get(i).getStructuralDiagram()); - tablex.setCreateBy(loginUser.getRealname()); - tablex.setStatus(statusInt); - tablex.setVerisonStatus(verisonStatusInt); - tablex.setVerison(Integer.valueOf(voList.get(i).getVerison())); - - //保存到真实表中 - tablexService.save(tablex); + tablex.setModuleId(voList.get(i).getModuleId()); + tablex.setTableName(voList.get(i).getTableName()); + tablex.setTableEnName(voList.get(i).getTableEnName()); + tablex.setTableStructure(voList.get(i).getTableStructure()); + tablex.setStructuralDiagram(voList.get(i).getStructuralDiagram()); + tablex.setCreateBy(loginUser.getRealname()); + tablex.setStatus(Integer.valueOf(voList.get(i).getStatus())); + tablex.setVerisonStatus(Integer.valueOf(voList.get(i).getVerisonStatus())); + tablex.setVerison(Integer.valueOf(voList.get(i).getVerison())); + + tablexList.add(tablex); + + //单条保存到真实表中 + tablexService.saveSingleBatch(tablexList,loginUser,message); } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的版本号填写错误!"); } } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的版本状态填写错误!"); } } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的实体状态填写错误!"); } } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的英文名称填写错误!"); } } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的中文名称填写错误!"); } } else { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("导入失败,第" + i + 1 + "行的对应模块填写错误!"); } } } catch (Exception e) { - + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.error("文件导入失败"); } + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); return Result.OK("文件导入成功!"); } } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/ITablexService.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/ITablexService.java index 6ebabc4..2d7685d 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/ITablexService.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/ITablexService.java @@ -1,7 +1,12 @@ package org.jeecg.modules.tablex.service; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.tablex.entity.Tablex; import com.baomidou.mybatisplus.extension.service.IService; +import org.jeecg.modules.tablex.vo.TablexVo; + +import java.util.List; +import java.util.Map; /** * @Description: 实体表 @@ -15,4 +20,5 @@ public interface ITablexService extends IService { void updateVersion(String tableId, int i); + void saveSingleBatch(List tablexList, LoginUser loginUser, Map message); } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/impl/TablexServiceImpl.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/impl/TablexServiceImpl.java index 4fabd87..7b5b0ff 100644 --- a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/impl/TablexServiceImpl.java +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/service/impl/TablexServiceImpl.java @@ -1,13 +1,19 @@ package org.jeecg.modules.tablex.service.impl; +import org.jeecg.common.system.vo.LoginUser; import org.jeecg.modules.tablex.entity.Tablex; import org.jeecg.modules.tablex.mapper.TablexMapper; import org.jeecg.modules.tablex.service.ITablexService; +import org.jeecg.modules.tablex.vo.TablexVo; +import org.jeecg.modules.tablex.ws.WebSocketUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import java.util.List; +import java.util.Map; + /** * @Description: 实体表 * @Author: jeecg-boot @@ -20,6 +26,9 @@ public class TablexServiceImpl extends ServiceImpl impleme @Autowired private TablexMapper tablexMapper; + @Autowired + private WebSocketUtils webSocketUtils; + @Override public void updateSql(String tableId, String sql) { tablexMapper.updateSql(tableId,sql); @@ -29,4 +38,22 @@ public class TablexServiceImpl extends ServiceImpl impleme public void updateVersion(String tableId, int i) { tablexMapper.updateVersion(tableId,i); } + + @Override + public void saveSingleBatch(List tablexList, LoginUser loginUser, Map message) { + for (int i = 0; i < tablexList.size(); i++){ + try { + Thread.sleep(1000L); + message.put("uploaded", String.valueOf(i + 1)); + this.save(tablexList.get(i)); + webSocketUtils.sendMessage(loginUser.getId(), message); + } catch (InterruptedException e) { + message.put("isVisible", "false"); + webSocketUtils.sendMessage(loginUser.getId(), message); + log.error(e.getMessage(), e); + } + } + } + + } diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/MyWebSocket.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/MyWebSocket.java new file mode 100644 index 0000000..9b93afd --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/MyWebSocket.java @@ -0,0 +1,63 @@ +package org.jeecg.modules.tablex.ws; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Component; + +import javax.websocket.*; +import javax.websocket.server.PathParam; +import javax.websocket.server.ServerEndpoint; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +@Slf4j +@Component +@ServerEndpoint(value = "/uploadProcess/{val}") +public class MyWebSocket { + + + /** + * 已经建立连接的对话,ConcurrentHashMap是一个线程安全的Map + */ + private static final Map sessionPool = + new ConcurrentHashMap<>(); + + + /** + * 连接建立成功触发 + * + * @param session 会话 + */ + @OnOpen + public void onOpen(Session session, EndpointConfig endpointConfig, + @PathParam("val") String key) { + // 将session进行保存 + sessionPool.put(key, session); + log.info("创建一个连接,当前连接的连接数量是:{}", sessionPool.size()); + + } + + /** + * 发送消息 + * + * @param info 信息 + */ + @OnMessage + public void onMessage(String info) { + log.info("接受到的消息是:{}", info); + } + + public Map getSessionPool() { + return sessionPool; + } + + /** + * 关闭连接时触发 + * + * @param session 会话 + */ + @OnClose + public void onClose(Session session, @PathParam("val") String key) { + sessionPool.remove(key); + log.info("关闭一个连接,当前剩余连接数为:{}", sessionPool.size()); + } +} diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/WebSocketUtils.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/WebSocketUtils.java new file mode 100644 index 0000000..4d36280 --- /dev/null +++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/tablex/ws/WebSocketUtils.java @@ -0,0 +1,53 @@ +package org.jeecg.modules.tablex.ws; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.websocket.Session; +import java.util.Map; + +@Slf4j +@Component +public class WebSocketUtils { + @Autowired + MyWebSocket webSocket; + + + private static Map sessionPool; + + + @PostConstruct + private void init() { + sessionPool = webSocket.getSessionPool(); + } + + + private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper(); + + + public void sendMessage(String key, Map message) { + Session session = sessionPool.get(key); + try { + session.getBasicRemote() + .sendText(OBJECT_MAPPER + .writeValueAsString(message)); + } catch (Exception e) { + log.error(e.getMessage()); + } + } + + public void sendAllMessage(Map message) { + sessionPool.values().forEach(session -> { + try { + session.getBasicRemote() + .sendText(OBJECT_MAPPER + .writeValueAsString(message)); + } catch (Exception e) { + log.error(e.getMessage()); + } + }); + } +}