Quellcode durchsuchen

07 26 05 用户导入导出 全局统一异常拦截问题

hr vor 4 Jahren
Ursprung
Commit
1097dbf0b6

+ 14 - 37
pom.xml

@@ -118,7 +118,7 @@
         <dependency>
             <groupId>cn.hutool</groupId>
             <artifactId>hutool-all</artifactId>
-            <version>5.5.7</version>
+            <version>5.4.7</version>
         </dependency>
 
         <!--lombok-->
@@ -161,6 +161,19 @@
             <artifactId>spring-boot-starter-data-redis</artifactId>
         </dependency>
 
+        <!--处理2003 excel-->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi</artifactId>
+            <version>3.16</version>
+        </dependency>
+        <!--处理2007 excel-->
+        <dependency>
+            <groupId>org.apache.poi</groupId>
+            <artifactId>poi-ooxml</artifactId>
+            <version>3.16</version>
+        </dependency>
+
     </dependencies>
 
     <build>
@@ -171,41 +184,5 @@
             </plugin>
         </plugins>
     </build>
-    <repositories>
-        <repository>
-            <id>spring-milestones</id>
-            <name>Spring Milestones</name>
-            <url>https://repo.spring.io/milestone</url>
-            <snapshots>
-                <enabled>false</enabled>
-            </snapshots>
-        </repository>
-        <repository>
-            <id>spring-snapshots</id>
-            <name>Spring Snapshots</name>
-            <url>https://repo.spring.io/snapshot</url>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-        </repository>
-    </repositories>
-    <pluginRepositories>
-        <pluginRepository>
-            <id>spring-milestones</id>
-            <name>Spring Milestones</name>
-            <url>https://repo.spring.io/milestone</url>
-            <snapshots>
-                <enabled>false</enabled>
-            </snapshots>
-        </pluginRepository>
-        <pluginRepository>
-            <id>spring-snapshots</id>
-            <name>Spring Snapshots</name>
-            <url>https://repo.spring.io/snapshot</url>
-            <releases>
-                <enabled>false</enabled>
-            </releases>
-        </pluginRepository>
-    </pluginRepositories>
 
 </project>

+ 78 - 0
src/main/java/com/imed/costaccount/common/exception/CostExceptionHandler.java

@@ -0,0 +1,78 @@
+package com.imed.costaccount.common.exception;
+
+import com.imed.costaccount.common.util.Result;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.shiro.authz.UnauthorizedException;
+import org.springframework.dao.DataAccessException;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.MethodArgumentNotValidException;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.bind.annotation.RestControllerAdvice;
+
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+@Slf4j
+@RestControllerAdvice
+public class CostExceptionHandler {
+
+
+//    @ResponseStatus(HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(value = CostException.class)
+    public Result handlerEmosException(CostException e) {
+        e.printStackTrace();
+        log.info("GlobalExceptionHandler...");
+        log.info("错误代码:" + e.getMessage());
+        return Result.errorMsg(500, e.getMessage());
+    }
+
+//    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(value = MethodArgumentNotValidException.class)
+    public Result handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {
+        e.printStackTrace();
+        log.info("GlobalExceptionHandler...");
+        log.info("错误代码:" + e.getMessage());
+        return Result.errorMsg(500, this.formatAllErrorMessages(e.getBindingResult().getAllErrors()));
+    }
+
+//    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
+    @ExceptionHandler(value = UnauthorizedException.class)
+    public Result handlerUnauthorizedException(UnauthorizedException e) {
+        e.printStackTrace();
+        log.info("GlobalExceptionHandler...");
+        log.info("错误代码:" + e.getMessage());
+        return Result.errorMsg(403,"您的权限不足,请联系管理员添加");
+    }
+
+//    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
+    @ExceptionHandler(value = Exception.class)
+    public Result handlerException(Exception e) {
+        e.printStackTrace();
+        log.info("===============================GlobalExceptionHandler异常信息===============================");
+        log.info("错误代码:" + e.getLocalizedMessage());
+        return Result.errorMsg("预期之外错误,请联系管理员~");
+    }
+
+    private String formatAllErrorMessages(List<ObjectError> errors) {
+        StringBuffer errorMsg = new StringBuffer();
+        errors.forEach(error -> {
+            String defaultMessage = error.getDefaultMessage();
+            try {
+                defaultMessage = new String(defaultMessage.getBytes("UTF-8"), "UTF-8");
+            } catch (UnsupportedEncodingException e) {
+                e.printStackTrace();
+            }
+            errorMsg.append(defaultMessage).append(';');
+        });
+        return errorMsg.toString();
+    }
+
+    @ExceptionHandler(DataAccessException.class)
+    @ResponseBody
+    public Result handleDataAccessException(DataAccessException e) {
+        log.error("数据库错误:{}", e.getMessage(), e);
+        return Result.errorMsg("数据库错误");
+
+    }
+}

+ 2 - 0
src/main/java/com/imed/costaccount/common/shiro/ShiroConfig.java

@@ -46,6 +46,8 @@ public class ShiroConfig {
         filterMap.put("/swagger-resources/**", "anon");
         filterMap.put("/captcha.jpg", "anon");
         filterMap.put("/costAccount/user/**","anon");
+        filterMap.put("/costAccount/getHospArea/**","anon");
+        filterMap.put("/costAccount/excel/**","anon");
         filterMap.put("/costAccount/login", "anon");
         filterMap.put("/**/*.jpg", "anon");
         filterMap.put("/**/*.png", "anon");

+ 13 - 0
src/main/java/com/imed/costaccount/model/dto/ImportUserDTO.java

@@ -0,0 +1,13 @@
+package com.imed.costaccount.model.dto;
+
+import lombok.Data;
+
+@Data
+public class ImportUserDTO {
+
+    private String userName;
+
+    private String account;
+
+    private String password;
+}

+ 9 - 0
src/main/java/com/imed/costaccount/service/UserService.java

@@ -2,10 +2,12 @@ package com.imed.costaccount.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.imed.costaccount.common.util.PageUtils;
+import com.imed.costaccount.common.util.Result;
 import com.imed.costaccount.model.User;
 import com.imed.costaccount.model.dto.LoginDTO;
 import com.imed.costaccount.model.dto.UserDto;
 import com.imed.costaccount.model.vo.LoginVO;
+import org.springframework.web.multipart.MultipartFile;
 import com.imed.costaccount.model.vo.UserVO;
 
 import java.util.List;
@@ -55,5 +57,12 @@ public interface UserService extends IService<User> {
      * @param userDto
      */
     void updateByUser(UserDto userDto);
+
+    /**
+     * 导入用户操作
+     * @param list 读取的列表
+     * @param user
+     */
+    Result importUser(List<List<Object>> list, User user);
 }
 

+ 81 - 8
src/main/java/com/imed/costaccount/service/impl/UserServiceImpl.java

@@ -1,5 +1,6 @@
 package com.imed.costaccount.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.crypto.SecureUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
@@ -10,7 +11,7 @@ import com.imed.costaccount.common.exception.CostException;
 import com.imed.costaccount.common.token.JwtUtil;
 import com.imed.costaccount.common.util.BeanUtil;
 import com.imed.costaccount.common.util.PageUtils;
-import com.imed.costaccount.constants.NumberConstant;
+import com.imed.costaccount.common.util.Result;
 import com.imed.costaccount.mapper.UserMapper;
 import com.imed.costaccount.model.Hosptail;
 import com.imed.costaccount.model.User;
@@ -20,16 +21,14 @@ import com.imed.costaccount.model.vo.LoginVO;
 import com.imed.costaccount.model.vo.UserVO;
 import com.imed.costaccount.service.HosptailService;
 import com.imed.costaccount.service.UserService;
-import org.apache.shiro.SecurityUtils;
-import org.springframework.beans.BeanUtils;
-import org.springframework.beans.factory.annotation.Autowired;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
-import org.springframework.util.ObjectUtils;
+import org.springframework.transaction.annotation.Propagation;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.StringUtils;
 
-import javax.jws.soap.SOAPBinding;
-import javax.validation.constraints.NotBlank;
+import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 import java.util.Objects;
 import java.util.stream.Collectors;
@@ -38,6 +37,7 @@ import java.util.stream.Collectors;
 /**
  * @author 11290
  */
+@Slf4j
 @Service("userService")
 public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
 
@@ -162,6 +162,79 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         baseMapper.insert(userRequest);
     }
 
+    /**
+     *  导入用户
+     * @param list 上传的文件读取的内容
+     * @param currentUser 当前登录用户
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
+    public Result importUser(List<List<Object>> list, User currentUser) {
+        // TODO: 2021/7/26 校验excel格式是否正确
+        for (int i = list.size() - 1; i >= 0; i--) {
+            if (i == 0 || i == 1 || i == 2 || i == 3) {
+                list.remove(list.get(i));
+            }
+        }
+        log.info("读取的数据为:{}", list);
+        List<User> users = new ArrayList<>();
+        List<String> errRowNums = new ArrayList<>();
+        for (int i = 0; i < list.size(); i++) {
+            List<Object> data = list.get(i);
+            log.info("得到用户输入的数据为:{}",data);
+            User user = new User();
+            // TODO: 2021/7/26 暂时写死
+//            user.setHospId(currentUser.getHospId());
+            user.setHospId(1);
+            user.setCreateTime(new Date().getTime());
+            int size = data.size();
+            if (size != 3) {
+                // 补充读取的null问题
+                if (size == 2) {
+                    data.add(StrUtil.EMPTY);
+                }
+                for (int j = 0; j < 3; j++) {
+                    if (Objects.isNull(data.get(j))) {
+                        data.set(j, StrUtil.EMPTY);
+                    }
+                }
+            }
+            for (int j = 0; j < 3; j++) {
+                String str = String.valueOf(data.get(j));
+                log.info("得到的字符串{}",str);
+                if (StrUtil.isBlank(str)) {
+                    errRowNums.add("" + (i + 5));
+                }
+                if (j == 0) {
+                    user.setName(str);
+                } else if (j == 1) {
+                    user.setAccount(str);
+                } else {
+                    user.setPassword(SecureUtil.md5(str));
+                }
+            }
+            users.add(user);
+        }
+        if (CollUtil.isNotEmpty(errRowNums)) {
+            String collect = errRowNums.stream().collect(Collectors.joining(StrUtil.COMMA));
+            throw new CostException(500, "第" + collect + "行数据异常");
+        }
+        // 校验users
+        List<User> realUsers = new ArrayList<>();
+        users.forEach(i -> {
+            User one = getOne(
+                    new QueryWrapper<User>().lambda()
+                            .eq(User::getAccount, i.getAccount())
+                            .eq(User::getHospId, i.getHospId())
+            );
+            if (Objects.nonNull(one)) {
+                realUsers.add(one);
+            }
+        });
+        users = users.stream().filter(i -> !realUsers.stream().map(User::getAccount).collect(Collectors.toList()).contains(i.getAccount())).collect(Collectors.toList());
+        this.saveBatch(users);
+        return Result.build(200, "有" + realUsers.size() + "条数据已存在,未被导入", null);
+    }
 
 
 }

+ 89 - 20
src/main/java/com/imed/costaccount/web/ExcelController.java

@@ -1,26 +1,95 @@
 package com.imed.costaccount.web;
 
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.poi.excel.ExcelReader;
+import cn.hutool.poi.excel.ExcelUtil;
+import cn.hutool.poi.excel.ExcelWriter;
+import com.imed.costaccount.common.util.Result;
 import com.imed.costaccount.model.User;
+import com.imed.costaccount.service.UserService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.ss.usermodel.Sheet;
 import org.apache.shiro.SecurityUtils;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
-
-///**
-// * 相关导入导出操作
-// */
-//@Api(tags = "excel导入导出")
-//@RequestMapping("/excel")
-//public class ExcelController {
-//
-//    @ApiOperation("用户导入模板设置")
-//    @GetMapping("/getImportUserTemplate")
-//    public void getImportUserTemplate() {
-//        User user = (User) SecurityUtils.getSubject().getPrincipal();
-//
-//        ExcelUtil
-//    }
-//
-//}
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+/**
+ * 相关导入导出操作
+ */
+@Slf4j
+@Api(tags = "excel导入导出")
+@RestController
+@RequestMapping("/costAccount/excel")
+public class ExcelController {
+
+    private UserService userService;
+
+    public ExcelController(UserService userService) {
+        this.userService = userService;
+    }
+
+    @ApiOperation("用户导出模板设置")
+    @GetMapping("/getImportUserTemplate")
+    public void getImportUserTemplate(HttpServletResponse response) throws IOException {
+        User user = (User) SecurityUtils.getSubject().getPrincipal();
+        // TODO: 2021/7/26 暂时没有登录
+        String uuid = UUID.randomUUID().toString();
+        String url = System.getProperty("java.io.tmpdir") + File.separator + uuid + File.separator + uuid + ".xls";
+        FileUtil.del(FileUtil.file(url));
+
+        ExcelWriter writer = new ExcelWriter(url, "sheet0");
+        // 样式
+        Sheet sheet = writer.getSheet();
+        sheet.setColumnWidth(0, 20);
+
+        // 内容
+        writer.merge(0, 1, 0, 2, "为了保证成功导入,请勿修改模板格式", false);
+        writer.passCurrentRow();
+        writer.passCurrentRow();
+        writer.merge(2, 2, 0, 2, "测试医院用户导入", false);
+        writer.passCurrentRow();
+        writer.writeRow(Arrays.asList("姓名", "账户", "密码"));
+
+        // 写入响应
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8");
+        response.setHeader("Content-Disposition", "attachment;filename=" + uuid + ".xls");
+        ServletOutputStream out = null;
+
+        out = response.getOutputStream();
+        writer.flush(out, true);
+        writer.close();
+        IoUtil.close(out);
+    }
+
+    @PostMapping("/importUser")
+    @ApiOperation("导入用户")
+    public Result importUser(@RequestParam("file") MultipartFile file) {
+        InputStream in;
+        try {
+            in = file.getInputStream();
+            ExcelReader reader = ExcelUtil.getReader(in);
+            List<List<Object>> read = reader.read();
+            log.info("最开始:read={}",read);
+            log.info("-------------------------------假装我是个分割线------------------------------------");
+            User user = (User) SecurityUtils.getSubject().getPrincipal();
+            return userService.importUser(read, user);
+        } catch (IOException e) {
+            e.printStackTrace();
+            return Result.errorMsg("导入失败");
+        }
+    }
+
+
+}

+ 1 - 2
src/main/resources/application.yml

@@ -10,8 +10,7 @@ mybatis-plus:
   global-config:
     db-config:
       id-type: auto
-      logic-not-delete-value: NULL
-      logic-delete-value: UNIX_TIMESTAMP(NOW()) * 1000
+
     banner: false
   configuration:
     log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

+ 0 - 1
src/main/resources/mapper/UserMapper.xml

@@ -9,7 +9,6 @@
         <result property="name" column="name"/>
         <result property="account" column="account"/>
         <result property="password" column="password"/>
-        <result property="dbBedno" column="DB_BedNo"/>
         <result property="hospId" column="hosp_id"/>
         <result property="createTime" column="create_time"/>
         <result property="deleteTime" column="delete_time"/>