From f52362127751004c996ca9ee2f6f87d7e010b424 Mon Sep 17 00:00:00 2001
From: luoyb <412940104@qq.com>
Date: 星期五, 19 二月 2021 17:14:06 +0800
Subject: [PATCH] Merge branch 'lybDevelop'

---
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java                |   45 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpDimissionLogController.java    |  106 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpAccessoryMapper.xml                |    2 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.xml                |    5 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/properties/FebsServerHrProperties.java       |    5 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpDimissionLogServiceImpl.java |  100 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.java               |   41 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiImportExcel.java                     |  190 +++
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.java            |   41 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpJobChangeServiceImpl.java    |  100 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java        |   12 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java                      |   11 
 febs-common/febs-common-core/src/main/java/cc/mrbird/febs/common/core/utils/MyUtil.java                        |  129 ++
 febs-server/febs-server-hr/pom.xml                                                                             |   21 
 febs-common/febs-common-core/pom.xml                                                                           |   11 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpAccessory.java                     |   30 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.xml             |    5 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpAccessoryService.java            |   19 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/LabelServiceImpl.java           |   19 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpDimissionLogService.java         |   69 +
 febs-server/febs-server-hr/src/main/resources/febs-server-hr.properties                                        |    4 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IFilesUploadService.java             |    2 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiExportExcel.java                     | 1480 ++++++++++++++++++++++++
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FilesUploadServiceImpl.java     |  145 -
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpJobChangeService.java            |   69 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java             |   30 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/ILabelService.java                   |    3 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpJobChangeController.java       |  106 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FolderServiceImpl.java          |    8 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpJobChange.java                     |  131 ++
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/FilesUploadController.java        |   14 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpDimissionLog.java                  |  112 +
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java     |  122 ++
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpAccessoryController.java       |   48 
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpAccessoryServiceImpl.java    |  155 ++
 febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/ModelUtil.java                          |  163 ++
 36 files changed, 3,394 insertions(+), 159 deletions(-)

diff --git a/febs-common/febs-common-core/pom.xml b/febs-common/febs-common-core/pom.xml
index e7ad386..a22ff92 100644
--- a/febs-common/febs-common-core/pom.xml
+++ b/febs-common/febs-common-core/pom.xml
@@ -100,5 +100,16 @@
             <groupId>io.micrometer</groupId>
             <artifactId>micrometer-registry-prometheus</artifactId>
         </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.5.8</version>
+        </dependency>
+        <dependency>
+            <groupId>cn.hutool</groupId>
+            <artifactId>hutool-all</artifactId>
+            <version>5.5.8</version>
+            <scope>compile</scope>
+        </dependency>
     </dependencies>
 </project>
diff --git a/febs-common/febs-common-core/src/main/java/cc/mrbird/febs/common/core/utils/MyUtil.java b/febs-common/febs-common-core/src/main/java/cc/mrbird/febs/common/core/utils/MyUtil.java
new file mode 100644
index 0000000..aee937c
--- /dev/null
+++ b/febs-common/febs-common-core/src/main/java/cc/mrbird/febs/common/core/utils/MyUtil.java
@@ -0,0 +1,129 @@
+package cc.mrbird.febs.common.core.utils;
+
+import cc.mrbird.febs.common.core.exception.FebsException;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.Dict;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.multipart.MultipartFile;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.util.Date;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+@Slf4j
+public class MyUtil {
+
+    public static void downloadFile(File file, HttpServletResponse response) throws IOException {
+        try (InputStream fin = new FileInputStream(file); ServletOutputStream out = response.getOutputStream()) {
+            response.setCharacterEncoding("utf-8");
+            response.setContentType("application/x-download");
+            response.addHeader("Content-Disposition", "attachment;filename=resume.doc");
+
+            byte[] buffer = new byte[1024];
+            int bytesToRead = -1;
+            // 通过循环将读入的Word文件的内容输出到浏览器中
+            while ((bytesToRead = fin.read(buffer)) != -1) {
+                out.write(buffer, 0, bytesToRead);
+            }
+        } catch (Exception e) {
+            log.error("下载文件异常" + e);
+            e.printStackTrace();
+        }
+    }
+
+    public static void  download(HttpServletRequest request, HttpServletResponse response, List<File> files , List<String> fileName){
+        //设置压缩包的名字
+        //解决不同浏览器压缩包名字含有中文时乱码的问题
+        String downloadName ="PersonnelInformation-" + DateUtil.format(new Date(), "yyyyMMddhhmmsss") + ".zip";
+        String agent = request.getHeader("USER-AGENT");
+        try {
+            if (agent.contains("MSIE") || agent.contains("Trident")) {
+                downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
+            } else {
+                downloadName = new String(downloadName.getBytes("UTF-8"), "ISO-8859-1");
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");
+
+
+        //设置压缩流:直接写入response,实现边压缩边下载
+        ZipOutputStream zipos = null;
+        try {
+            zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
+            //设置压缩方法
+            zipos.setMethod(ZipOutputStream.DEFLATED);
+        } catch (Exception e) {
+            log.error("设置压缩流出现异常" + e);
+            e.printStackTrace();
+        }
+
+        //循环将文件写入压缩流
+        DataOutputStream os = null;
+        for (int i = 0; i < files.size(); i++) {
+            File file = files.get(i);
+            try {
+                //添加ZipEntry,并ZipEntry中写入文件流
+                //这里,加上i是防止要下载的文件有重名的导致下载失败
+                zipos.putNextEntry(new ZipEntry(fileName.get(i)));
+                os = new DataOutputStream(zipos);
+                InputStream is = new FileInputStream(file);
+                byte[] b = new byte[100];
+                int length;
+                while ((length = is.read(b)) != -1) {
+                    os.write(b, 0, length);
+                }
+                is.close();
+                zipos.closeEntry();
+            } catch (IOException e) {
+                log.error("循环将文件写入压缩流出现异常" + e.getMessage());
+                e.printStackTrace();
+            }
+        }
+
+        //关闭流
+        try {
+            os.flush();
+            os.close();
+            zipos.close();
+        } catch (IOException e) {
+            log.error("关闭流现异常" + e.getMessage());
+            e.printStackTrace();
+        }
+
+    }
+
+    public static Dict filesUpload(MultipartFile file, String uploadPpath, String nextIdStr) throws FebsException, IOException {
+        if (file.isEmpty()) {
+            throw new FebsException("上传的文件不能为空!请重新上传");
+        }
+        if (file.getSize() <= 0) {
+            throw new FebsException("上传的文件大小需要大于0kb");
+        }
+        if (file.getSize() > 50 * 1024* 1024) {
+            throw new FebsException("上传的文件大于50M");
+        }
+        if (!FileUtil.exist(uploadPpath)) {
+            FileUtil.mkdir(uploadPpath);
+        }
+        //原本名字
+        String fileName = file.getOriginalFilename();
+        String suffix = "";
+        if (fileName.indexOf(".") > 0) {
+            //后缀
+            suffix = fileName.substring(fileName.indexOf("."), fileName.length());
+        }
+        //生成新的名字
+        String newName = nextIdStr + suffix;
+        //上传
+        file.transferTo(new File(uploadPpath + newName));
+        return Dict.create().set("fileName",fileName).set("suffix",suffix).set("newName",newName);
+
+    }
+}
diff --git a/febs-server/febs-server-hr/pom.xml b/febs-server/febs-server-hr/pom.xml
index e5b7796..bd12f7a 100644
--- a/febs-server/febs-server-hr/pom.xml
+++ b/febs-server/febs-server-hr/pom.xml
@@ -58,20 +58,29 @@
             <version>2.2-RELEASE</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>cn.hutool</groupId>
-            <artifactId>hutool-all</artifactId>
-            <version>5.5.8</version>
-        </dependency>
     </dependencies>
 
 	<build>
-
         <resources>
+            <resource>
+                <directory>src/main/resources</directory>
+            </resource>
+            <resource>
+                <directory>src/main/resources</directory>
+                <includes>
+                    <include>**/*.properties</include>
+                    <include>**/*.xml</include>
+                    <include>**/*.tld</include>
+                    <include>**/*.yml</include>
+                </includes>
+                <filtering>false</filtering>
+            </resource>
             <resource>
                 <directory>src/main/java</directory>
                 <includes>
+                    <include>**/*.properties</include>
                     <include>**/*.xml</include>
+                    <include>**/*.tld</include>
                 </includes>
                 <filtering>false</filtering>
             </resource>
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpAccessoryController.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpAccessoryController.java
index 41e93fd..a144f95 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpAccessoryController.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpAccessoryController.java
@@ -12,8 +12,13 @@
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
 import javax.validation.Valid;
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
 import java.util.Map;
 
 /**
@@ -46,9 +51,9 @@
 
     @PostMapping
     @PreAuthorize("hasAuthority('empAccessory:add')")
-    public void addEmpAccessory(@Valid EmpAccessory empAccessory) throws FebsException {
+    public void addEmpAccessory(@NotNull(message = "{required}") Long labelid,@NotNull(message = "{required}") Long empId, MultipartFile file) throws FebsException {
         try {
-            this.empAccessoryService.createEmpAccessory(empAccessory);
+            this.empAccessoryService.createEmpAccessory(labelid,file,empId);
         } catch (Exception e) {
             String message = "新增EmpAccessory失败";
             log.error(message, e);
@@ -58,9 +63,9 @@
 
     @DeleteMapping
     @PreAuthorize("hasAuthority('empAccessory:delete')")
-    public void deleteEmpAccessory(EmpAccessory empAccessory) throws FebsException {
+    public void deleteEmpAccessory(@NotBlank(message = "{required}")  String accessoryids) throws FebsException {
         try {
-            this.empAccessoryService.deleteEmpAccessory(empAccessory);
+            this.empAccessoryService.deleteEmpAccessory(accessoryids);
         } catch (Exception e) {
             String message = "删除EmpAccessory失败";
             log.error(message, e);
@@ -79,4 +84,39 @@
             throw new FebsException(message);
         }
     }
+
+    @PostMapping("/download")
+    @PreAuthorize("hasAuthority('empAccessory:download')")
+    public void download(@NotBlank(message = "{required}")  String accessoryids, HttpServletRequest request, HttpServletResponse response) throws FebsException {
+        try {
+            this.empAccessoryService.download(accessoryids,request,response);
+        } catch (Exception e) {
+            String message = "下载文件失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @PostMapping("/mvFiles")
+    @PreAuthorize("hasAuthority('empAccessory:mv')")
+    public void mvFiles(@NotBlank(message = "{required}")  String accessoryids,@NotNull(message = "{required}") Long labelid,@NotNull(message = "{required}")  Long empId) throws FebsException {
+        try {
+            this.empAccessoryService.mvFiles(accessoryids,labelid,empId);
+        } catch (Exception e) {
+            String message = "移动文件失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+    @PostMapping("/singledownload")
+    @PreAuthorize("hasAuthority('empAccessory:singledownload')")
+    public void singledownload(@NotBlank(message = "{required}")  String empIds, @NotNull(message = "{required}")  Long labelid, HttpServletRequest request, HttpServletResponse response) throws FebsException {
+        try {
+            this.empAccessoryService.singledownload(empIds,labelid,request,response);
+        } catch (Exception e) {
+            String message = "下载文件失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java
index 73916b6..430a036 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpBaseInfoController.java
@@ -1,6 +1,5 @@
 package cc.mrbird.febs.server.hr.controller;
 
-import cc.mrbird.febs.common.core.entity.system.Role;
 import cc.mrbird.febs.server.hr.entity.EmpBaseInfo;
 import cc.mrbird.febs.server.hr.feign.IRemoteDeptService;
 import cc.mrbird.febs.server.hr.feign.IRemoteUserService;
@@ -9,7 +8,6 @@
 import cc.mrbird.febs.common.core.entity.QueryRequest;
 import cc.mrbird.febs.common.core.exception.FebsException;
 import cc.mrbird.febs.common.core.utils.FebsUtil;
-import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
@@ -20,7 +18,6 @@
 
 import javax.validation.Valid;
 import javax.validation.constraints.NotBlank;
-import java.util.List;
 import java.util.Map;
 
 /**
@@ -57,14 +54,7 @@
         Map<String, Object> dataTable = FebsUtil.getDataTable(this.empBaseInfoService.findEmpBaseInfos(request, empBaseinfo));
         return new FebsResponse().data(dataTable);
     }
-    @GetMapping("options")
-    public FebsResponse roles() {
-        QueryWrapper<EmpBaseInfo> queryWrapper=new QueryWrapper();
-        queryWrapper.eq("delFlag",0);
-        queryWrapper.eq("empStatus",0);
-        List<EmpBaseInfo> allRoles = empBaseInfoService.list(queryWrapper);
-        return new FebsResponse().data(allRoles);
-    }
+
     @ApiOperation(value = "人员基本信息增加")
     @PostMapping
     @PreAuthorize("hasAuthority('empBaseinfo:add')")
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpDimissionLogController.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpDimissionLogController.java
new file mode 100644
index 0000000..bd2e8c9
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpDimissionLogController.java
@@ -0,0 +1,106 @@
+package cc.mrbird.febs.server.hr.controller;
+
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+import cc.mrbird.febs.server.hr.service.IEmpDimissionLogService;
+import cc.mrbird.febs.common.core.entity.FebsResponse;
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.exception.FebsException;
+import cc.mrbird.febs.common.core.utils.FebsUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Map;
+
+/**
+ * name:EmpDimissionlog
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工离职记录控制器
+ *
+ * @author luoyibo
+ * @date 2021-02-18 16:04:42
+ * @since JDK1.8
+ */
+@Api(tags = "员工离职记录管理接口")
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("empDimissionlog")
+@RequiredArgsConstructor
+public class EmpDimissionLogController {
+
+    private final IEmpDimissionLogService empDimissionlogService;
+
+    @ApiOperation(value = "员工离职记录无翻页列表")
+    @GetMapping
+    @PreAuthorize("hasAuthority('empDimissionlog:list')")
+    public FebsResponse getAllEmpDimissionlogs(EmpDimissionLog empDimissionlog) {
+        return new FebsResponse().data(empDimissionlogService.findEmpDimissionLogs(empDimissionlog));
+    }
+
+    @ApiOperation(value = "员工离职记录翻页列表")
+    @GetMapping("list")
+    @PreAuthorize("hasAuthority('empDimissionlog:list')")
+    public FebsResponse empDimissionlogList(QueryRequest request, EmpDimissionLog empDimissionlog) {
+        Map
+                <String, Object> dataTable = FebsUtil.getDataTable(this.empDimissionlogService.findEmpDimissionLogs(request, empDimissionlog));
+        return new FebsResponse().data(dataTable);
+    }
+
+    @ApiOperation(value = "员工离职记录增加")
+    @PostMapping
+    @PreAuthorize("hasAuthority('empDimissionlog:add')")
+    public void addEmpDimissionlog(@Valid EmpDimissionLog empDimissionlog) throws FebsException {
+        try {
+            this.empDimissionlogService.createEmpDimissionLog(empDimissionlog);
+        } catch (Exception e) {
+            String message = "新增员工离职记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工离职记录物理删除")
+    @DeleteMapping
+    @PreAuthorize("hasAuthority('empDimissionlog:delete')")
+    public void deleteEmpDimissionlog(EmpDimissionLog empDimissionlog) throws FebsException {
+        try {
+            this.empDimissionlogService.deleteEmpDimissionLog(empDimissionlog);
+        } catch (Exception e) {
+            String message = "删除员工离职记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工离职记录逻辑删除")
+    @DeleteMapping("{ids}")
+    @PreAuthorize("hasAuthority('empDimissionlog:delete')")
+    public void logicDeleteEmpDimissionlog(@PathVariable("ids") String ids) throws FebsException {
+        try {
+            this.empDimissionlogService.logicDelEmpDimissionLog(ids);
+        } catch (Exception e) {
+            String message = "逻辑删除员工离职记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工离职记录修改")
+    @PutMapping
+    @PreAuthorize("hasAuthority('empDimissionlog:update')")
+    public void updateEmpDimissionlog(EmpDimissionLog empDimissionlog) throws FebsException {
+        try {
+            this.empDimissionlogService.updateEmpDimissionLog(empDimissionlog);
+        } catch (Exception e) {
+            String message = "修改员工离职记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpJobChangeController.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpJobChangeController.java
new file mode 100644
index 0000000..71abac3
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/EmpJobChangeController.java
@@ -0,0 +1,106 @@
+package cc.mrbird.febs.server.hr.controller;
+
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
+import cc.mrbird.febs.server.hr.service.IEmpJobChangeService;
+import cc.mrbird.febs.common.core.entity.FebsResponse;
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.exception.FebsException;
+import cc.mrbird.febs.common.core.utils.FebsUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.Map;
+
+/**
+ * name:EmpJobchange
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工调岗记录控制器
+ *
+ * @author luoyibo
+ * @date 2021-02-18 17:57:36
+ * @since JDK1.8
+ */
+@Api(tags = "员工调岗记录管理接口")
+@Slf4j
+@Validated
+@RestController
+@RequestMapping("empJobChange")
+@RequiredArgsConstructor
+public class EmpJobChangeController {
+
+    private final IEmpJobChangeService empJobchangeService;
+
+    @ApiOperation(value = "员工调岗记录无翻页列表")
+    @GetMapping
+    @PreAuthorize("hasAuthority('empJobchange:list')")
+    public FebsResponse getAllEmpJobchanges(EmpJobChange empJobchange) {
+        return new FebsResponse().data(empJobchangeService.findEmpJobChanges(empJobchange));
+    }
+
+    @ApiOperation(value = "员工调岗记录翻页列表")
+    @GetMapping("list")
+    @PreAuthorize("hasAuthority('empJobchange:list')")
+    public FebsResponse empJobchangeList(QueryRequest request, EmpJobChange empJobchange) {
+        Map
+                <String, Object> dataTable = FebsUtil.getDataTable(this.empJobchangeService.findEmpJobChanges(request, empJobchange));
+        return new FebsResponse().data(dataTable);
+    }
+
+    @ApiOperation(value = "员工调岗记录增加")
+    @PostMapping
+    @PreAuthorize("hasAuthority('empJobchange:add')")
+    public void addEmpJobchange(@Valid EmpJobChange empJobchange) throws FebsException {
+        try {
+            this.empJobchangeService.createEmpJobChange(empJobchange);
+        } catch (Exception e) {
+            String message = "新增员工调岗记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工调岗记录物理删除")
+    @DeleteMapping
+    @PreAuthorize("hasAuthority('empJobchange:delete')")
+    public void deleteEmpJobchange(EmpJobChange empJobchange) throws FebsException {
+        try {
+            this.empJobchangeService.deleteEmpJobChange(empJobchange);
+        } catch (Exception e) {
+            String message = "删除员工调岗记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工调岗记录逻辑删除")
+    @DeleteMapping("{ids}")
+    @PreAuthorize("hasAuthority('empJobchange:delete')")
+    public void logicDeleteEmpJobchange(@PathVariable("ids") String ids) throws FebsException {
+        try {
+            this.empJobchangeService.logicDelEmpJobChange(ids);
+        } catch (Exception e) {
+            String message = "逻辑删除员工调岗记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+
+    @ApiOperation(value = "员工调岗记录修改")
+    @PutMapping
+    @PreAuthorize("hasAuthority('empJobchange:update')")
+    public void updateEmpJobchange(EmpJobChange empJobchange) throws FebsException {
+        try {
+            this.empJobchangeService.updateEmpJobChange(empJobchange);
+        } catch (Exception e) {
+            String message = "修改员工调岗记录失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/FilesUploadController.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/FilesUploadController.java
index 2a61f45..d5d2834 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/FilesUploadController.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/controller/FilesUploadController.java
@@ -50,7 +50,7 @@
 
     @PostMapping
     @PreAuthorize("hasAuthority('filesUpload:add')")
-    public void addFilesUpload(@NotNull(message = "{required}") Long folderid, MultipartFile file, HttpServletRequest request) throws FebsException {
+    public void addFilesUpload(@NotNull(message = "{required}") Long folderid, MultipartFile file) throws FebsException {
         try {
             this.filesUploadService.createFilesUpload(folderid, file);
         } catch (Exception e) {
@@ -96,4 +96,16 @@
             throw new FebsException(message);
         }
     }
+
+    @PostMapping("/mvFiles")
+    @PreAuthorize("hasAuthority('filesUpload:mv')")
+    public void mvFiles(@NotBlank(message = "{required}")  String fileids,@NotNull(message = "{required}")  Long folderid) throws FebsException {
+        try {
+            this.filesUploadService.mvFiles(fileids,folderid);
+        } catch (Exception e) {
+            String message = "移动文件失败";
+            log.error(message, e);
+            throw new FebsException(message);
+        }
+    }
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpAccessory.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpAccessory.java
index cbf4dd1..802e8b0 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpAccessory.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpAccessory.java
@@ -20,14 +20,8 @@
     /**
      * 附件Id
      */
-    @TableId(value = "accessoryId", type = IdType.AUTO)
+    @TableId(value = "accessoryId")
     private Long accessoryid;
-
-    /**
-     * 处罚数量
-     */
-    @TableField("cf")
-    private Integer cf;
 
     /**
      * 记录创建时间
@@ -42,17 +36,27 @@
     private String creator;
 
     /**
-     * 辞职申请数量
-     */
-    @TableField("czsq")
-    private Integer czsq;
-
-    /**
      * 记录删除标志。0-未删除 1-已删除,默认0
      */
     @TableField("delFlag")
     private Integer delFlag = 0;
     /**
+     * 记录最后更新人
+     */
+    @TableField("modifier")
+    private String modifier;
+    /**
+     * 记录最后更新时间
+     */
+    @TableField("modifyTime")
+    private Date modifytime;
+
+    /**
+     * 记录版本号,用来进行乐观锁控制
+     */
+    @TableField("version")
+    private Integer version;
+    /**
      * 员工Id
      */
     @TableField("empId")
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java
index 111cf3c..ba0037b 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpBaseInfo.java
@@ -258,6 +258,11 @@
     
 
 
+    @FieldInfo(name = "dimissionType", type = "varchar", explain = "离职类型")
+    @TableField("dimissionType")
+    private String dimissionType;
+
+
     @FieldInfo(name = "createTime", type = "datetime", explain = "记录创建时间")
     @TableField("createTime")
     @JsonSerialize(using = DateTimeSerializer.class)
@@ -288,7 +293,11 @@
     @TableField("version")
     @Version
     private Integer version = 0;
-    
+
+    @FieldInfo(name = "remark", type = "varchar", explain = "离职备注")
+    @TableField("remark")
+    private String remark = "";
+
 	@TableField(exist = false)
 	private String ageStr = "";
 	
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpDimissionLog.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpDimissionLog.java
new file mode 100644
index 0000000..e9244da
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpDimissionLog.java
@@ -0,0 +1,112 @@
+package cc.mrbird.febs.server.hr.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import cc.mrbird.febs.common.core.annotation.FieldInfo;
+import cc.mrbird.febs.common.core.utils.DateDeSerializer;
+import cc.mrbird.febs.common.core.utils.DateSerializer;
+import cc.mrbird.febs.common.core.utils.DateTimeDeserializer;
+import cc.mrbird.febs.common.core.utils.DateTimeSerializer;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+
+import java.math.BigDecimal;
+
+import lombok.Data;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * name:EmpDimissionlog
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工离职记录数据表映射实体
+ *
+ * @author luoyibo
+ * @date 2021-02-18 16:04:42
+ * @since JDK1.8
+ */
+@Data
+@TableName("t_emp_dimissionlog")
+public class EmpDimissionLog implements Serializable {
+
+    @FieldInfo(name = "closeId", type = "bigint", explain = "档案关闭Id")
+    @TableId(value = "closeId")
+    private Long closeId = 0L;
+
+    @FieldInfo(name = "empId", type = "bigint", explain = "员工Id")
+    @TableField("empId")
+    private Long empId = 0L;
+
+    @FieldInfo(name = "entryDate", type = "date", explain = "入职日期")
+    @TableField("entryDate")
+    @JsonSerialize(using = DateSerializer.class)
+    @JsonDeserialize(using = DateDeSerializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date entryDate;
+
+    @FieldInfo(name = "dimissionDate", type = "date", explain = "离职日期")
+    @TableField("dimissionDate")
+    @JsonSerialize(using = DateSerializer.class)
+    @JsonDeserialize(using = DateDeSerializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date dimissionDate;
+
+    @FieldInfo(name = "dimissionType", type = "varchar", explain = "离职类型")
+    @TableField("dimissionType")
+    private String dimissionType = "1";
+
+    @FieldInfo(name = "selfLeaveDay", type = "decimal", explain = "自离天数")
+    @TableField("selfLeaveDay")
+    private BigDecimal selfLeaveDay = BigDecimal.ZERO;
+
+    @FieldInfo(name = "reporter", type = "varchar", explain = "报备人")
+    @TableField("reporter")
+    private String reporter = "";
+
+    @FieldInfo(name = "remark", type = "varchar", explain = "备注")
+    @TableField("remark")
+    private String remark = "";
+
+    @FieldInfo(name = "createTime", type = "datetime", explain = "记录创建时间")
+    @TableField("createTime")
+    @JsonSerialize(using = DateTimeSerializer.class)
+    @JsonDeserialize(using = DateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @FieldInfo(name = "creator", type = "varchar", explain = "记录创建人")
+    @TableField("creator")
+    private String creator = "";
+
+    @FieldInfo(name = "modifyTime", type = "datetime", explain = "记录最后更新时间")
+    @TableField("modifyTime")
+    @JsonSerialize(using = DateTimeSerializer.class)
+    @JsonDeserialize(using = DateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date modifyTime;
+
+    @FieldInfo(name = "modifier", type = "varchar", explain = "记录最后更新人")
+    @TableField("modifier")
+    private String modifier = "";
+
+    @FieldInfo(name = "delFlag", type = "bit", explain = "记录删除标志。0-未删除 1-已删除 2-暂存,默认0")
+    @TableField("delFlag")
+    private Integer delFlag = 0;
+
+    @FieldInfo(name = "version", type = "int", explain = "记录版本号,用来进行乐观锁控制")
+    @TableField("version")
+    @Version
+    private Integer version = 0;
+
+    @FieldInfo(name = "empIds", explain = "关闭档案人员Id")
+    @TableField(exist = false)
+    private String empIds;
+
+    @FieldInfo(name = "entryDates", explain = "关闭档案人员入职日期")
+    @TableField(exist = false)
+    private String entryDates;
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpJobChange.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpJobChange.java
new file mode 100644
index 0000000..548221e
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/entity/EmpJobChange.java
@@ -0,0 +1,131 @@
+package cc.mrbird.febs.server.hr.entity;
+
+import java.io.Serializable;
+import java.util.Date;
+
+import cc.mrbird.febs.common.core.annotation.FieldInfo;
+import cc.mrbird.febs.common.core.utils.DateDeSerializer;
+import cc.mrbird.febs.common.core.utils.DateSerializer;
+import cc.mrbird.febs.common.core.utils.DateTimeDeserializer;
+import cc.mrbird.febs.common.core.utils.DateTimeSerializer;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import lombok.Data;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.annotation.Version;
+import org.springframework.format.annotation.DateTimeFormat;
+
+/**
+ * name:EmpJobchange
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工调岗记录数据表映射实体
+ *
+ * @author luoyibo
+ * @date 2021-02-18 17:57:36
+ * @since JDK1.8
+ */
+@Data
+@TableName("t_emp_jobchange")
+public class EmpJobChange implements Serializable {
+
+    private static final long serialVersionUID = 4229887878987429956L;
+    @FieldInfo(name = "jobChangeId", type = "bigint", explain = "岗位调整Id")
+    @TableId(value = "jobChangeId")
+    private Long jobChangeId = 0L;
+
+    @FieldInfo(name = "empId", type = "bigint", explain = "员工Id")
+    @TableField("empId")
+    private Long empId = 0L;
+
+    @FieldInfo(name = "empName", type = "varchar", explain = "员工姓名")
+    @TableField("empName")
+    private String empName = "";
+
+    @FieldInfo(name = "oldDeptName", type = "varchar", explain = "原部门")
+    @TableField("oldDeptName")
+    private String oldDeptName = "";
+
+    @FieldInfo(name = "oldJobName", type = "varchar", explain = "原岗位")
+    @TableField("oldJobName")
+    private String oldJobName = "";
+
+    @FieldInfo(name = "newDeptName", type = "varchar", explain = "新部门")
+    @TableField("newDeptName")
+    private String newDeptName = "";
+
+    @FieldInfo(name = "newJobName", type = "varchar", explain = "新岗位")
+    @TableField("newJobName")
+    private String newJobName = "";
+
+    @FieldInfo(name = "changeType", type = "varchar", explain = "调岗类型")
+    @TableField("changeType")
+    private String changeType = "";
+
+    @FieldInfo(name = "changeDate", type = "date", explain = "调岗位日期")
+    @TableField("changeDate")
+    @JsonSerialize(using = DateSerializer.class)
+    @JsonDeserialize(using = DateDeSerializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private Date changeDate;
+
+    @FieldInfo(name = "changeReason", type = "varchar", explain = "调岗原因")
+    @TableField("changeReason")
+    private String changeReason = "";
+
+    @FieldInfo(name = "createTime", type = "datetime", explain = "记录创建时间")
+    @TableField("createTime")
+    @JsonSerialize(using = DateTimeSerializer.class)
+    @JsonDeserialize(using = DateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createTime;
+
+    @FieldInfo(name = "creator", type = "varchar", explain = "记录创建人")
+    @TableField("creator")
+    private String creator = "";
+
+    @FieldInfo(name = "modifyTime", type = "datetime", explain = "记录最后更新时间")
+    @TableField("modifyTime")
+    @JsonSerialize(using = DateTimeSerializer.class)
+    @JsonDeserialize(using = DateTimeDeserializer.class)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date modifyTime;
+
+    @FieldInfo(name = "modifier", type = "varchar", explain = "记录最后更新人")
+    @TableField("modifier")
+    private String modifier = "";
+
+    @FieldInfo(name = "delFlag", type = "bit", explain = "记录删除标志。0-未删除 1-已删除 2-暂存,默认0")
+    @TableField("delFlag")
+    private Integer delFlag = 0;
+
+    @FieldInfo(name = "version", type = "int", explain = "记录版本号,用来进行乐观锁控制")
+    @TableField("version")
+    @Version
+    private Integer version = 0;
+
+    @FieldInfo(name = "jobId", explain = "现岗位Id")
+    @TableField(exist = false)
+    private String jobId;
+
+    @FieldInfo(name = "deptId", explain = "现部门Id")
+    @TableField(exist = false)
+    private String deptId;
+
+    @FieldInfo(name = "empIds", explain = "调岗人员Id")
+    @TableField(exist = false)
+    private String empIds;
+
+    @FieldInfo(name = "empNames", explain = "调岗人员姓名")
+    @TableField(exist = false)
+    private String empNames;
+
+    @FieldInfo(name = "oldDeptNames", explain = "调岗人员原部门")
+    @TableField(exist = false)
+    private String oldDeptNames;
+
+    @FieldInfo(name = "oldJobNames", explain = "调岗人员原岗位")
+    @TableField(exist = false)
+    private String oldJobNames;
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpAccessoryMapper.xml b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpAccessoryMapper.xml
index d49f51e..861948d 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpAccessoryMapper.xml
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpAccessoryMapper.xml
@@ -7,7 +7,7 @@
        (select dept_Name from t_dept as dept where dept.dept_Id= a.deptId) as deptName,a.jobName,',(SELECT
   GROUP_CONCAT(DISTINCT
     CONCAT(
-      '(SELECT  COUNT(1) FROM  t_emp_accessory accessory inner join t_label label where label.labelId=accessory.labelId and accessory.delFlag = 0 and label.delFlag = 0) AS ''',
+      '(SELECT  COUNT(1) FROM  t_emp_accessory accessory inner join t_label label where label.labelId=accessory.labelId and accessory.delFlag = 0 and label.delFlag = 0 and a.empId = accessory.empId  and label.labelCode = ''',label.labelCode,''') AS ''',
       label.labelCode, ''''
     )
   )
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java
index e9b8723..dd8ad42 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpBaseInfoMapper.java
@@ -1,5 +1,7 @@
 package cc.mrbird.febs.server.hr.mapper;
 
+import cc.mrbird.febs.server.hr.entity.EmpBaseInfo;
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
 import cc.mrbird.febs.server.hr.entity.*;
 import com.baomidou.mybatisplus.annotation.SqlParser;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@@ -8,6 +10,7 @@
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -64,6 +67,48 @@
             "        </foreach>\n" +
             "</script>")
     int momentToNormal(@Param("list") List<String> list, @Param("operatorId") String operatorId);
+    /**
+     *
+     * 关闭员工档案
+     *
+     * date 2021-02-18 12:54
+     * @author: luoyibo
+     * @param ids 待关闭档案员工 Id
+     * @param dimissionType 离职类型
+     * @param dimissionDate 离职日期
+     * @param remark 备注
+     * @return boolean
+     */
+    @Update("<script> " +
+            " UPDATE t_emp_baseinfo SET empStatus = 1,\n" +
+            " dimissionDate = #{dimissionDate},\n" +
+            " dimissionType = #{dimissionType},\n" +
+            " remark = #{remark},\n" +
+            " modifyTime = NOW(),\n" +
+            " modifier = #{operatorId}, \n" +
+            " version = version+1 \n" +
+            " WHERE empId IN \n" +
+            "        <foreach item=\"delId\" collection=\"list\" open=\"(\" close=\")\" separator=\",\">\n" +
+            "          #{delId}  \n" +
+            "        </foreach>\n" +
+            "</script>")
+    int closeEmpArchives(@Param("list") List<String> list, @Param("dimissionType") String dimissionType, @Param("dimissionDate") Date dimissionDate, @Param("remark") String remark, @Param("operatorId") String operatorId);
+
+    @Update("<script> " +
+            " UPDATE t_emp_baseinfo SET \n" +
+            " deptId = #{mapParams.deptId},\n" +
+            " deptName = #{mapParams.deptName},\n" +
+            " jobId = #{mapParams.jobId},\n" +
+            " jobName = #{mapParams.jobName},\n" +
+            " modifyTime = NOW(),\n" +
+            " modifier = #{mapParams.operatorId}, \n" +
+            " version = version+1 \n" +
+            " WHERE empId IN \n" +
+            "        <foreach item=\"delId\" collection=\"list\" open=\"(\" close=\")\" separator=\",\">\n" +
+            "          #{delId}  \n" +
+            "        </foreach>\n" +
+            "</script>")
+    int changeEmpJob(@Param("list") List<String> list, @Param("mapParams") Map<String,Object> mapParams);
     @SqlParser(filter=true)
     Map<String, Object> countBaseInfoList(@Param("index") String index,@Param("btime") String btime,@Param("etime") String etime);
 
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.java
new file mode 100644
index 0000000..c790120
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.java
@@ -0,0 +1,41 @@
+package cc.mrbird.febs.server.hr.mapper;
+
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * name:EmpDimissionlog
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工离职记录实体Mapper
+ *
+ * @author luoyibo
+ * @date 2021-02-18 16:04:42
+ * @since JDK1.8
+ */
+public interface EmpDimissionLogMapper extends BaseMapper<EmpDimissionLog> {
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date luoyibo
+     *
+     * @param list       待删除Id
+     * @param operatorId 操作员Id
+     * @return void
+     * @author: 2021-02-18 16:04:42
+     */
+    @Update("<script> " +
+            " UPDATE t_emp_dimissionLog SET delFlag = 1,\n" +
+            " modifyTime = NOW(),\n" +
+            " modifier = #{operatorId}, \n" +
+            " version = version+1 \n" +
+            " WHERE closeId IN \n" +
+            "        <foreach item=\"delId\" collection=\"list\" open=\"(\" close=\")\" separator=\",\">\n" +
+            "            #{delId} \n" +
+            "        </foreach>\n" +
+            "</script>")
+    void logicDeleteByIds(@Param("list") List<String> list, @Param("operatorId") String operatorId);
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.xml b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.xml
new file mode 100644
index 0000000..f311303
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpDimissionLogMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cc.mrbird.febs.server.hr.mapper.EmpDimissionLogMapper">
+
+</mapper>
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.java
new file mode 100644
index 0000000..86ad595
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.java
@@ -0,0 +1,41 @@
+package cc.mrbird.febs.server.hr.mapper;
+
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+import java.util.List;
+
+/**
+ * name:EmpJobchange
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工调岗记录实体Mapper
+ *
+ * @author luoyibo
+ * @date 2021-02-18 17:57:36
+ * @since JDK1.8
+ */
+public interface EmpJobChangeMapper extends BaseMapper<EmpJobChange> {
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date luoyibo
+     *
+     * @param list       待删除Id
+     * @param operatorId 操作员Id
+     * @return void
+     * @author: 2021-02-18 17:57:36
+     */
+    @Update("<script> " +
+            " UPDATE t_emp_jobchange SET delFlag = 1,\n" +
+            " modifyTime = NOW(),\n" +
+            " modifier = #{operatorId}, \n" +
+            " version = version+1 \n" +
+            " WHERE jobChangeId IN \n" +
+            "        <foreach item=\"delId\" collection=\"list\" open=\"(\" close=\")\" separator=\",\">\n" +
+            "            #{delId} \n" +
+            "        </foreach>\n" +
+            "</script>")
+    void logicDeleteByIds(@Param("list") List<String> list, @Param("operatorId") String operatorId);
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.xml b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.xml
new file mode 100644
index 0000000..b43c997
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/mapper/EmpJobChangeMapper.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cc.mrbird.febs.server.hr.mapper.EmpJobChangeMapper">
+
+</mapper>
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/properties/FebsServerHrProperties.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/properties/FebsServerHrProperties.java
index a30c238..9d83604 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/properties/FebsServerHrProperties.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/properties/FebsServerHrProperties.java
@@ -16,5 +16,8 @@
     /**
      * 文件上传地址
      */
-    private String uploadPpath = "D:/upload/hr/";
+    private String uploadCommonPath = "C:/upload/hr/commonfile/";
+
+    private String uploadSinglePath = "C:/upload/hr/singlefile/";
+
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpAccessoryService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpAccessoryService.java
index 8b64848..b6a5da9 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpAccessoryService.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpAccessoryService.java
@@ -2,11 +2,17 @@
 
 
 import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.exception.FebsException;
 import cc.mrbird.febs.server.hr.entity.EmpAccessory;
 import cc.mrbird.febs.server.hr.vo.EmpAccessoryVO;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.constraints.NotNull;
+import java.io.IOException;
 import java.util.List;
 import java.util.Map;
 
@@ -36,10 +42,8 @@
 
     /**
      * 新增
-     *
-     * @param empAccessory empAccessory
      */
-    void createEmpAccessory(EmpAccessory empAccessory);
+    void createEmpAccessory(Long labelid, MultipartFile file,Long empId) throws FebsException, IOException;
 
     /**
      * 修改
@@ -51,7 +55,12 @@
     /**
      * 删除
      *
-     * @param empAccessory empAccessory
      */
-    void deleteEmpAccessory(EmpAccessory empAccessory);
+    void deleteEmpAccessory(String accessoryids);
+
+    void download(String accessoryids, HttpServletRequest request, HttpServletResponse response);
+
+    void mvFiles(String accessoryids,Long labelid,Long empId);
+
+    void singledownload(String empIds, Long labelid, HttpServletRequest request, HttpServletResponse response) throws Exception;
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java
index c67a4d6..fb0ceef 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpBaseInfoService.java
@@ -3,6 +3,8 @@
 import cc.mrbird.febs.server.hr.entity.*;
 
 import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
 
@@ -134,4 +136,32 @@
     IPage<EmpUnemployment> empBaseInfoSyjList(String index, String btime, String etime, String pageSize, String pageNum, String number, String name);
 
     IPage<EmpBadRecord> empBaseInfoBlList(String index, String btime, String etime, String pageSize, String pageNum, String number, String name);
+
+    /**
+     *
+     * 关闭员工档案
+     *
+     * date 2021-02-18 12:54
+     * @author: luoyibo
+     * @param empDimissionLog
+     * @return boolean
+     */
+    boolean closeEmpArchives(EmpDimissionLog empDimissionLog);
+
+    /**
+     *
+     * 员工岗位变更
+     *
+     * date 2021-02-18 20:32
+     * @author: luoyibo
+     * @param empJobChange 1
+     * @return boolean
+     */
+    boolean changeEmpJob(EmpJobChange empJobChange);
+
+    /**
+     * 导入员工
+     * @param listObject
+     */
+	void importEmpBaseInfo(List<List<Object>> listObject);
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpDimissionLogService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpDimissionLogService.java
new file mode 100644
index 0000000..7ea7138
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpDimissionLogService.java
@@ -0,0 +1,69 @@
+package cc.mrbird.febs.server.hr.service;
+
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * name:EmpDimissionlog
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工离职记录服务接口
+ *
+ * @author luoyibo
+ * @date 2021-02-18 16:04:42
+ * @since JDK1.8
+ */
+public interface IEmpDimissionLogService extends IService<EmpDimissionLog> {
+    /**
+     * 查询(分页)
+     *
+     * @param request         QueryRequest
+     * @param empDimissionlog empDimissionlog
+     * @return IPage<EmpDimissionlog>
+     */
+    IPage<EmpDimissionLog> findEmpDimissionLogs(QueryRequest request, EmpDimissionLog empDimissionlog);
+
+    /**
+     * 查询(所有)
+     *
+     * @param empDimissionlog empDimissionlog
+     * @return List<EmpDimissionlog>
+     */
+    List<EmpDimissionLog> findEmpDimissionLogs(EmpDimissionLog empDimissionlog);
+
+    /**
+     * 新增
+     *
+     * @param empDimissionlog empDimissionlog
+     */
+    void createEmpDimissionLog(EmpDimissionLog empDimissionlog);
+
+    /**
+     * 修改
+     *
+     * @param empDimissionlog empDimissionlog
+     */
+    void updateEmpDimissionLog(EmpDimissionLog empDimissionlog);
+
+    /**
+     * 删除
+     *
+     * @param empDimissionlog empDimissionlog
+     */
+    void deleteEmpDimissionLog(EmpDimissionLog empDimissionlog);
+
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date 2021-01-28 10:48
+     *
+     * @param ids 待删除Id
+     * @return void
+     * @author: luoyibo
+     */
+    void logicDelEmpDimissionLog(String ids);
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpJobChangeService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpJobChangeService.java
new file mode 100644
index 0000000..734183c
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IEmpJobChangeService.java
@@ -0,0 +1,69 @@
+package cc.mrbird.febs.server.hr.service;
+
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
+
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * name:EmpJobchange
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工调岗记录服务接口
+ *
+ * @author luoyibo
+ * @date 2021-02-18 17:57:36
+ * @since JDK1.8
+ */
+public interface IEmpJobChangeService extends IService<EmpJobChange> {
+    /**
+     * 查询(分页)
+     *
+     * @param request      QueryRequest
+     * @param empJobchange empJobchange
+     * @return IPage<EmpJobchange>
+     */
+    IPage<EmpJobChange> findEmpJobChanges(QueryRequest request, EmpJobChange empJobchange);
+
+    /**
+     * 查询(所有)
+     *
+     * @param empJobchange empJobchange
+     * @return List<EmpJobchange>
+     */
+    List<EmpJobChange> findEmpJobChanges(EmpJobChange empJobchange);
+
+    /**
+     * 新增
+     *
+     * @param empJobchange empJobchange
+     */
+    void createEmpJobChange(EmpJobChange empJobchange);
+
+    /**
+     * 修改
+     *
+     * @param empJobchange empJobchange
+     */
+    void updateEmpJobChange(EmpJobChange empJobchange);
+
+    /**
+     * 删除
+     *
+     * @param empJobchange empJobchange
+     */
+    void deleteEmpJobChange(EmpJobChange empJobchange);
+
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date 2021-01-28 10:48
+     *
+     * @param ids 待删除Id
+     * @return void
+     * @author: luoyibo
+     */
+    void logicDelEmpJobChange(String ids);
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IFilesUploadService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IFilesUploadService.java
index d5bd381..fdfdfec 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IFilesUploadService.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/IFilesUploadService.java
@@ -57,4 +57,6 @@
     void deleteFilesUpload(String fileids);
 
     void download(String fileids, HttpServletRequest request, HttpServletResponse response);
+
+    void mvFiles(String fileids,Long folderid);
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/ILabelService.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/ILabelService.java
index 6d367d9..d88ec47 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/ILabelService.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/ILabelService.java
@@ -2,6 +2,7 @@
 
 
 import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.exception.FebsException;
 import cc.mrbird.febs.server.hr.entity.Label;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.IService;
@@ -37,7 +38,7 @@
      *
      * @param label label
      */
-    void createLabel(Label label);
+    void createLabel(Label label) throws FebsException;
 
     /**
      * 修改
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpAccessoryServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpAccessoryServiceImpl.java
index 6503635..7f21cca 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpAccessoryServiceImpl.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpAccessoryServiceImpl.java
@@ -1,11 +1,26 @@
 package cc.mrbird.febs.server.hr.service.impl;
 
-import cc.mrbird.febs.server.hr.entity.EmpAccessory;
+import cc.mrbird.febs.common.core.constant.ModuleCode;
+import cc.mrbird.febs.common.core.exception.FebsException;
+import cc.mrbird.febs.common.core.utils.FebsUtil;
+import cc.mrbird.febs.common.core.utils.MyUtil;
+import cc.mrbird.febs.common.core.utils.SequenceUtil;
+import cc.mrbird.febs.server.hr.entity.*;
 import cc.mrbird.febs.server.hr.mapper.EmpAccessoryMapper;
+import cc.mrbird.febs.server.hr.properties.FebsServerHrProperties;
 import cc.mrbird.febs.server.hr.service.IEmpAccessoryService;
+import cc.mrbird.febs.server.hr.service.IEmpBaseInfoService;
+import cc.mrbird.febs.server.hr.service.ILabelService;
 import cc.mrbird.febs.server.hr.vo.EmpAccessoryVO;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.Dict;
+import cn.hutool.core.lang.Snowflake;
+import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.ZipUtil;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.transaction.annotation.Propagation;
@@ -15,9 +30,13 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import cc.mrbird.febs.common.core.entity.QueryRequest;
+import org.springframework.web.multipart.MultipartFile;
 
-import java.util.List;
-import java.util.Map;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
 
 /**
  * 附件管理 Service实现
@@ -29,8 +48,17 @@
 @RequiredArgsConstructor
 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
 public class EmpAccessoryServiceImpl extends ServiceImpl<EmpAccessoryMapper, EmpAccessory> implements IEmpAccessoryService {
-
+    private final ILabelService labelService;
     private final EmpAccessoryMapper empAccessoryMapper;
+    private final FebsServerHrProperties properties;
+    private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser())
+            .map(u -> u.getUserId().toString())
+            .orElse("1");
+    private final IEmpBaseInfoService empBaseInfoService;
+    /**
+     * 参数2为数据中心ID 参数1为终端ID
+     */
+    private Snowflake snowflake = IdUtil.getSnowflake(ModuleCode.HR_FIlE, 1);
 
     @Override
     public IPage<Map<String,Object>> findEmpAccessorys(QueryRequest request, EmpAccessoryVO vo) {
@@ -99,14 +127,39 @@
     @Override
     public List<EmpAccessory> findEmpAccessorys(EmpAccessory empAccessory) {
         LambdaQueryWrapper<EmpAccessory> queryWrapper = new LambdaQueryWrapper<>();
-        // TODO 设置查询条件
+        queryWrapper.eq(EmpAccessory::getDelFlag,0);
+        if (null != empAccessory.getLabelid()) {
+            queryWrapper.eq(EmpAccessory::getLabelid, empAccessory.getLabelid());
+        }
+        if (StrUtil.isNotBlank(empAccessory.getFilesname())) {
+            queryWrapper.like(EmpAccessory::getFilesname, empAccessory.getFilesname());
+        }
+        if (null != empAccessory.getEmpid()) {
+            queryWrapper.eq(EmpAccessory::getEmpid, empAccessory.getEmpid());
+        }
         return this.baseMapper.selectList(queryWrapper);
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void createEmpAccessory(EmpAccessory empAccessory) {
-        this.save(empAccessory);
+    public void createEmpAccessory(Long labelid, MultipartFile file,Long empId) throws FebsException, IOException {
+        EmpBaseInfo empBaseInfo = empBaseInfoService.getById(empId);
+        String nameAndCertificateNumb = empBaseInfo.getEmpName()+"_"+empBaseInfo.getCertificateNumb()+"/";
+        Dict dict = MyUtil.filesUpload(file,properties.getUploadSinglePath()+nameAndCertificateNumb,snowflake.nextIdStr());
+        EmpAccessory accessory = new EmpAccessory();
+        accessory.setCreatetime(new Date());
+        accessory.setCreator(operatorId);
+        accessory.setDelFlag(0);
+        accessory.setEmpid(empId);
+        accessory.setFilesaddress(dict.getStr("newName"));
+        accessory.setFilesformat(StrUtil.isBlank(dict.getStr("suffix")) ? dict.getStr("suffix") : dict.getStr("suffix").substring(1));
+        accessory.setAccessoryid(SequenceUtil.generateId(0L, ModuleCode.HR_FIlE));
+        accessory.setFilesname(dict.getStr("fileName"));
+        accessory.setLabelid(labelid);
+        accessory.setModifier(operatorId);
+        accessory.setModifytime(new Date());
+        accessory.setVersion(0);
+        this.save(accessory);
     }
 
     @Override
@@ -117,9 +170,89 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void deleteEmpAccessory(EmpAccessory empAccessory) {
-        LambdaQueryWrapper<EmpAccessory> wapper = new LambdaQueryWrapper<>();
-        // TODO 设置删除条件
-        this.remove(wapper);
+    public void deleteEmpAccessory(String accessoryids) {
+        String[] arr = accessoryids.split(",");
+        LambdaUpdateWrapper<EmpAccessory> wapper = new LambdaUpdateWrapper<>();
+        wapper.in(EmpAccessory::getAccessoryid,arr);
+        EmpAccessory accessory = new EmpAccessory();
+        accessory.setModifier(operatorId);
+        accessory.setModifytime(new Date());
+        accessory.setDelFlag(1);
+        this.update(accessory,wapper);
+
+        LambdaQueryWrapper<EmpAccessory> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(EmpAccessory::getAccessoryid,arr);
+        List<EmpAccessory> list = this.list(queryWrapper);
+        list.parallelStream().forEach(i-> {
+            EmpBaseInfo empBaseInfo = empBaseInfoService.getById(i.getEmpid());
+            String nameAndCertificateNumb = empBaseInfo.getEmpName()+"_"+empBaseInfo.getCertificateNumb()+"/";
+            FileUtil.del(properties.getUploadSinglePath()+nameAndCertificateNumb+"/" + i.getFilesaddress());
+        });
+    }
+
+
+    @Override
+    public void download(String accessoryids, HttpServletRequest request, HttpServletResponse response) {
+        String[] arr = accessoryids.split(",");
+        List<File> files = new ArrayList<>();
+        List<String> fileName = new ArrayList<>();
+        Arrays.stream(arr).forEach(i -> {
+            EmpAccessory accessory = this.getById(i);
+            EmpBaseInfo empBaseInfo = empBaseInfoService.getById(accessory.getEmpid());
+            String nameAndCertificateNumb = empBaseInfo.getEmpName()+"_"+empBaseInfo.getCertificateNumb()+"/";
+            files.add(new File(properties.getUploadSinglePath() + nameAndCertificateNumb + accessory.getFilesaddress()));
+            fileName.add(accessory.getFilesname());
+        });
+        MyUtil.download(request, response, files, fileName);
+
+    }
+
+    @Override
+    public void mvFiles(String accessoryids,Long labelid,Long empId) {
+        String[] arr = accessoryids.split(",");
+
+        LambdaUpdateWrapper<EmpAccessory> wapper = new LambdaUpdateWrapper<>();
+        wapper.in(EmpAccessory::getAccessoryid, arr);
+        EmpAccessory empAccessory = new EmpAccessory();
+        empAccessory.setModifier(operatorId);
+        empAccessory.setModifytime(new Date());
+        empAccessory.setLabelid(labelid);
+        empAccessory.setEmpid(empId);
+        this.update(empAccessory,wapper);
+
+    }
+
+    @Override
+    public void singledownload(String empIds, Long labelid, HttpServletRequest request, HttpServletResponse response) throws IOException {
+        String[] arr = empIds.split(",");
+        //主文件夹
+        String mianFileStr = properties.getUploadSinglePath()+snowflake.nextIdStr()+"/";
+        FileUtil.mkdir(mianFileStr);
+        Arrays.stream(arr).forEach(i -> {
+            LambdaQueryWrapper<EmpAccessory> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+            lambdaQueryWrapper.eq(EmpAccessory::getEmpid,i);
+            lambdaQueryWrapper.eq(EmpAccessory::getDelFlag,0);
+            if (!labelid.equals(-1L)){
+                lambdaQueryWrapper.eq(EmpAccessory::getLabelid,labelid);
+            }
+            List<EmpAccessory> accessory = this.list(lambdaQueryWrapper);
+            EmpBaseInfo empBaseInfo = empBaseInfoService.getById(i);
+            String nameAndCertificateNumb = empBaseInfo.getEmpName()+"_"+empBaseInfo.getCertificateNumb()+"/";
+            //创建个人文件夹
+            String singlefileStr = mianFileStr+nameAndCertificateNumb;
+            FileUtil.mkdir(singlefileStr);
+            accessory.stream().forEach(a->{
+                Label label = labelService.getById(a.getLabelid());
+                FileUtil.copy(properties.getUploadSinglePath() + nameAndCertificateNumb + a.getFilesaddress(),singlefileStr+label.getLabelname()+"/"+a.getFilesname(),true);
+            });
+        });
+        ZipUtil.zip(mianFileStr);
+        try {
+            MyUtil.downloadFile(new File(new StringBuilder().append(mianFileStr, 0, mianFileStr.length() - 1).append(".zip").toString()),response);
+        } catch (IOException e) {
+            log.error("下载文件异常",e);
+        }
+        FileUtil.del(new StringBuilder().append(mianFileStr, 0, mianFileStr.length() - 1).append(".zip").toString());
+        FileUtil.del(mianFileStr);
     }
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java
index 1302118..669faf1 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpBaseInfoServiceImpl.java
@@ -2,6 +2,12 @@
 
 import java.util.*;
 
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
+import cc.mrbird.febs.server.hr.service.IEmpDimissionLogService;
+import cc.mrbird.febs.server.hr.service.IEmpJobChangeService;
+import cn.hutool.core.date.DateUnit;
+import cn.hutool.core.date.DateUtil;
 import cc.mrbird.febs.server.hr.entity.*;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.stereotype.Service;
@@ -23,6 +29,7 @@
 import cc.mrbird.febs.common.core.utils.FebsUtil;
 import cc.mrbird.febs.common.core.utils.SequenceUtil;
 import cc.mrbird.febs.common.redis.service.RedisService;
+import cc.mrbird.febs.server.hr.entity.EmpBaseInfo;
 import cc.mrbird.febs.server.hr.feign.IRemoteDeptService;
 import cc.mrbird.febs.server.hr.mapper.EmpBaseInfoMapper;
 import cc.mrbird.febs.server.hr.service.IEmpBaseInfoService;
@@ -44,6 +51,8 @@
     private final RedisService redisService;
     private final IRemoteDeptService remoteDeptService;
     private final EmpBaseInfoMapper empBaseInfoMapper;
+    private final IEmpDimissionLogService dimissionLogService;
+    private final IEmpJobChangeService jobChangeService;
 
     private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser())
             .map(u -> u.getUserId().toString())
@@ -159,7 +168,6 @@
         } else{
             empBaseInfo.setEmpId(dbInfo.getEmpId());
         }
-        empBaseInfo.setEmpStatus("0");
         empBaseInfo.setCreator(operatorId);
         empBaseInfo.setModifier(operatorId);
         this.saveOrUpdate(empBaseInfo);
@@ -250,6 +258,118 @@
         }
         return this.getOne(queryWrapper);
     }
+    /**
+     *
+     * 关闭员工档案
+     *
+     * date 2021-02-18 12:54
+     * @author: luoyibo
+     * @param empDimissionLog
+     * @return boolean
+     */
+    @Override
+    public boolean closeEmpArchives(EmpDimissionLog empDimissionLog) {
+        String[] str = empDimissionLog.getEmpIds().split(",");
+        List<String> list = new ArrayList<>(Arrays.asList(str));
+        String[] strDate = empDimissionLog.getEntryDates().split(",");
+        EmpDimissionLog dimissionLog = null;
+        for (int i = 0,k=str.length; i < k; i++) {
+            dimissionLog = new EmpDimissionLog();
+            dimissionLog.setCloseId(SequenceUtil.generateId(0L, ModuleCode.HR_EMPLOYEE));
+            dimissionLog.setEmpId(Long.parseLong(str[i]));
+            dimissionLog.setEntryDate(DateUtil.parse(strDate[i],"yyyy-MM-dd"));
+            dimissionLog.setDimissionDate(empDimissionLog.getDimissionDate());
+            dimissionLog.setDimissionType(empDimissionLog.getDimissionType());
+            dimissionLog.setRemark(empDimissionLog.getRemark());
+            dimissionLog.setSelfLeaveDay(empDimissionLog.getSelfLeaveDay());
+            dimissionLog.setReporter(empDimissionLog.getReporter());
+            dimissionLog.setCreator(operatorId);
+            dimissionLog.setModifier(operatorId);
+
+            dimissionLogService.save(dimissionLog);
+        }
+        return empBaseInfoMapper.closeEmpArchives(list, empDimissionLog.getDimissionType(), empDimissionLog.getDimissionDate(), empDimissionLog.getRemark(), operatorId)>0;
+    }
+    /**
+     *
+     * 员工岗位变更
+     *
+     * date 2021-02-18 20:32
+     * @author: luoyibo
+     * @param empJobChange 1
+     * @return boolean
+     */
+    @Override
+    public boolean changeEmpJob(EmpJobChange empJobChange) {
+        String[] str = empJobChange.getEmpIds().split(",");
+        List<String> list = new ArrayList<>(Arrays.asList(str));
+        String[] strName = empJobChange.getEmpNames().split(",");
+        String[] strDeptName = empJobChange.getOldDeptNames().split(",");
+        String[] strJobName = empJobChange.getOldJobNames().split(",");
+
+        EmpJobChange saveChange = null;
+
+        for (int i = 0,k=str.length; i <k ; i++) {
+            saveChange = new EmpJobChange();
+            saveChange.setJobChangeId(SequenceUtil.generateId(0L, ModuleCode.HR_EMPLOYEE));
+            saveChange.setEmpId(Long.parseLong(str[i]));
+            saveChange.setEmpName(strName[i]);
+            saveChange.setOldDeptName(strDeptName[i]);
+            saveChange.setOldJobName(strJobName[i]);
+            saveChange.setNewDeptName(empJobChange.getNewDeptName());
+            saveChange.setNewJobName(empJobChange.getNewJobName());
+            saveChange.setChangeType(empJobChange.getChangeType());
+            saveChange.setChangeDate(empJobChange.getChangeDate());
+            saveChange.setChangeReason(empJobChange.getChangeReason());
+            saveChange.setCreator(operatorId);
+            saveChange.setModifier(operatorId);
+
+            jobChangeService.save(saveChange);
+
+        }
+
+        Map<String, Object> mapParams = new HashMap<>();
+        mapParams.put("deptId", empJobChange.getDeptId());
+        mapParams.put("deptName", empJobChange.getNewDeptName());
+        mapParams.put("jobId", empJobChange.getJobId());
+        mapParams.put("jobName", empJobChange.getNewJobName());
+        mapParams.put("operatorId", operatorId);
+        return empBaseInfoMapper.changeEmpJob(list,mapParams)>0;
+    }
+
+    /**
+     * 导入员工
+     * @param listObject
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+	public void importEmpBaseInfo(List<List<Object>> listObject) {
+		for (List<Object> list : listObject) {
+			EmpBaseInfo empBaseInfo = new EmpBaseInfo();
+			empBaseInfo.setEmpId(SequenceUtil.generateId(0L, ModuleCode.HR_EMPLOYEE));
+			empBaseInfo.setEmpNumb(list.get(0).toString());
+			List<Dept> depts = CastUtil.castList(redisService.get("depts"), Dept.class);
+			empBaseInfo.setDeptName(list.get(1).toString());
+			Long deptId=depts.stream().filter(d -> d.getDeptName().equals(list.get(1).toString())).findFirst().get().getDeptId();
+			empBaseInfo.setDeptId(deptId);
+			empBaseInfo.setJobName(list.get(2).toString());
+			empBaseInfo.setEmpName(list.get(3).toString());
+			empBaseInfo.setCertificateNumb(list.get(4).toString());
+			empBaseInfo.setSex("男".equals(list.get(5).toString())?"1":"0");
+			if (StringUtils.isNotBlank(list.get(6).toString())) {
+				empBaseInfo.setAge(Integer.valueOf(list.get(6).toString()));
+			}
+			empBaseInfo.setEducation(list.get(7).toString());
+			empBaseInfo.setNativePlace(list.get(8).toString());
+			empBaseInfo.setTelePhone(list.get(9).toString());
+			if (StringUtils.isNotBlank(list.get(10).toString())) {
+				empBaseInfo.setEntryDate(DateUtil.parseDate(list.get(10).toString()));
+			}
+			empBaseInfo.setEmpStatus("0");
+			this.save(empBaseInfo);
+		}
+
+	}
 
 
     @Override
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpDimissionLogServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpDimissionLogServiceImpl.java
new file mode 100644
index 0000000..c8760fe
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpDimissionLogServiceImpl.java
@@ -0,0 +1,100 @@
+package cc.mrbird.febs.server.hr.service.impl;
+
+import cc.mrbird.febs.common.core.constant.ModuleCode;
+import cc.mrbird.febs.server.hr.entity.EmpDimissionLog;
+import cc.mrbird.febs.server.hr.mapper.EmpDimissionLogMapper;
+import cc.mrbird.febs.server.hr.service.IEmpDimissionLogService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.annotation.Propagation;
+import lombok.RequiredArgsConstructor;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.utils.FebsUtil;
+import cc.mrbird.febs.common.core.utils.SequenceUtil;
+
+import java.util.*;
+
+/**
+ * name:EmpDimissionlog
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工离职记录服务接口实现
+ *
+ * @author luoyibo
+ * @date 2021-02-18 16:04:42
+ * @since JDK1.8
+ */
+@Service
+@RequiredArgsConstructor
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
+class EmpDimissionLogServiceImpl extends ServiceImpl<EmpDimissionLogMapper, EmpDimissionLog> implements IEmpDimissionLogService {
+
+    private final EmpDimissionLogMapper empDimissionlogMapper;
+    private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser())
+            .map(u -> u.getUserId().toString())
+            .orElse("1");
+
+    @Override
+    public IPage<EmpDimissionLog> findEmpDimissionLogs(QueryRequest request, EmpDimissionLog empDimissionlog) {
+        LambdaQueryWrapper<EmpDimissionLog> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EmpDimissionLog::getDelFlag, 0);
+        Page<EmpDimissionLog> page = new Page<>(request.getPageNum(), request.getPageSize());
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public List<EmpDimissionLog> findEmpDimissionLogs(EmpDimissionLog empDimissionlog) {
+        LambdaQueryWrapper<EmpDimissionLog> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EmpDimissionLog::getDelFlag, 0);
+        return this.baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void createEmpDimissionLog(EmpDimissionLog empDimissionlog) {
+        empDimissionlog.setCloseId(SequenceUtil.generateId(0L, ModuleCode.HR_EMPLOYEE));
+        empDimissionlog.setCreator(operatorId);
+        empDimissionlog.setModifier(operatorId);
+        this.save(empDimissionlog);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateEmpDimissionLog(EmpDimissionLog empDimissionlog) {
+        EmpDimissionLog dbData = this.getById(empDimissionlog.getCloseId());
+        empDimissionlog.setCreateTime(dbData.getCreateTime());
+        empDimissionlog.setCreator(dbData.getCreator());
+        empDimissionlog.setDelFlag(dbData.getDelFlag());
+        empDimissionlog.setModifyTime(new Date());
+        empDimissionlog.setModifier(operatorId);
+        this.saveOrUpdate(empDimissionlog);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteEmpDimissionLog(EmpDimissionLog empDimissionlog) {
+        LambdaQueryWrapper<EmpDimissionLog> wrapper = new LambdaQueryWrapper<>();
+// TODO 设置删除条件
+        this.remove(wrapper);
+    }
+
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date 2021-01-28 10:48
+     *
+     * @param ids 待删除Id
+     * @return void
+     * @author: luoyibo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void logicDelEmpDimissionLog(String ids) {
+        String[] str = ids.split(",");
+        List<String> list = new ArrayList<>(Arrays.asList(str));
+        empDimissionlogMapper.logicDeleteByIds(list, operatorId);
+    }
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpJobChangeServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpJobChangeServiceImpl.java
new file mode 100644
index 0000000..bdffe36
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/EmpJobChangeServiceImpl.java
@@ -0,0 +1,100 @@
+package cc.mrbird.febs.server.hr.service.impl;
+
+import cc.mrbird.febs.common.core.constant.ModuleCode;
+import cc.mrbird.febs.server.hr.entity.EmpJobChange;
+import cc.mrbird.febs.server.hr.mapper.EmpJobChangeMapper;
+import cc.mrbird.febs.server.hr.service.IEmpJobChangeService;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.annotation.Propagation;
+import lombok.RequiredArgsConstructor;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import cc.mrbird.febs.common.core.entity.QueryRequest;
+import cc.mrbird.febs.common.core.utils.FebsUtil;
+import cc.mrbird.febs.common.core.utils.SequenceUtil;
+
+import java.util.*;
+
+/**
+ * name:EmpJobchange
+ * package:cc.mrbird.febs.server.hr.controller
+ * description:员工调岗记录服务接口实现
+ *
+ * @author luoyibo
+ * @date 2021-02-18 17:57:36
+ * @since JDK1.8
+ */
+@Service
+@RequiredArgsConstructor
+@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
+class EmpJobChangeServiceImpl extends ServiceImpl<EmpJobChangeMapper, EmpJobChange> implements IEmpJobChangeService {
+
+    private final EmpJobChangeMapper empJobchangeMapper;
+    private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser())
+            .map(u -> u.getUserId().toString())
+            .orElse("1");
+
+    @Override
+    public IPage<EmpJobChange> findEmpJobChanges(QueryRequest request, EmpJobChange empJobchange) {
+        LambdaQueryWrapper<EmpJobChange> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EmpJobChange::getDelFlag, 0);
+        Page<EmpJobChange> page = new Page<>(request.getPageNum(), request.getPageSize());
+        return this.page(page, queryWrapper);
+    }
+
+    @Override
+    public List<EmpJobChange> findEmpJobChanges(EmpJobChange empJobchange) {
+        LambdaQueryWrapper<EmpJobChange> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(EmpJobChange::getDelFlag, 0);
+        return this.baseMapper.selectList(queryWrapper);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void createEmpJobChange(EmpJobChange empJobchange) {
+        empJobchange.setJobChangeId(SequenceUtil.generateId(0L, ModuleCode.HR_EMPLOYEE));
+        empJobchange.setCreator(operatorId);
+        empJobchange.setModifier(operatorId);
+        this.save(empJobchange);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void updateEmpJobChange(EmpJobChange empJobchange) {
+        EmpJobChange dbData = this.getById(empJobchange.getJobChangeId());
+        empJobchange.setCreateTime(dbData.getCreateTime());
+        empJobchange.setCreator(dbData.getCreator());
+        empJobchange.setDelFlag(dbData.getDelFlag());
+        empJobchange.setModifyTime(new Date());
+        empJobchange.setModifier(operatorId);
+        this.saveOrUpdate(empJobchange);
+    }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void deleteEmpJobChange(EmpJobChange empJobchange) {
+        LambdaQueryWrapper<EmpJobChange> wrapper = new LambdaQueryWrapper<>();
+// TODO 设置删除条件
+        this.remove(wrapper);
+    }
+
+    /**
+     * 根据Id批量逻辑删除记录
+     * <p>
+     * date 2021-01-28 10:48
+     *
+     * @param ids 待删除Id
+     * @return void
+     * @author: luoyibo
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public void logicDelEmpJobChange(String ids) {
+        String[] str = ids.split(",");
+        List<String> list = new ArrayList<>(Arrays.asList(str));
+        empJobchangeMapper.logicDeleteByIds(list, operatorId);
+    }
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FilesUploadServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FilesUploadServiceImpl.java
index 7ca006a..53e37dd 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FilesUploadServiceImpl.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FilesUploadServiceImpl.java
@@ -6,15 +6,16 @@
 import cc.mrbird.febs.common.core.constant.ModuleCode;
 import cc.mrbird.febs.common.core.exception.FebsException;
 import cc.mrbird.febs.common.core.utils.FebsUtil;
+import cc.mrbird.febs.common.core.utils.MyUtil;
 import cc.mrbird.febs.common.core.utils.SequenceUtil;
 import cc.mrbird.febs.server.hr.entity.FilesUpload;
 import cc.mrbird.febs.server.hr.entity.Folder;
 import cc.mrbird.febs.server.hr.mapper.FilesUploadMapper;
 import cc.mrbird.febs.server.hr.properties.FebsServerHrProperties;
 import cc.mrbird.febs.server.hr.service.IFilesUploadService;
-import cn.hutool.core.date.DateUtil;
+import cc.mrbird.febs.server.hr.service.IFolderService;
 import cn.hutool.core.io.FileUtil;
-import cn.hutool.core.io.file.FileWriter;
+import cn.hutool.core.lang.Dict;
 import cn.hutool.core.lang.Snowflake;
 import cn.hutool.core.util.IdUtil;
 import cn.hutool.core.util.StrUtil;
@@ -32,8 +33,6 @@
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipOutputStream;
 
 /**
  * 文件上传 Service实现
@@ -46,7 +45,7 @@
 @Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
 public class FilesUploadServiceImpl extends ServiceImpl<FilesUploadMapper, FilesUpload> implements IFilesUploadService {
 
-    private final FilesUploadMapper filesUploadMapper;
+    private final IFolderService iFolderService;
     private final FebsServerHrProperties properties;
     private final String operatorId = Optional.ofNullable(FebsUtil.getCurrentUser())
             .map(u -> u.getUserId().toString())
@@ -66,7 +65,7 @@
     @Override
     public List<FilesUpload> findFilesUploads(FilesUpload filesUpload) {
         LambdaQueryWrapper<FilesUpload> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(FilesUpload::getDelFlag,0);
+        queryWrapper.eq(FilesUpload::getDelFlag, 0);
         if (null != filesUpload.getFolderid()) {
             queryWrapper.eq(FilesUpload::getFolderid, filesUpload.getFolderid());
         }
@@ -80,38 +79,16 @@
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void createFilesUpload(Long folderid, MultipartFile file) throws FebsException, IOException {
-        if (file.isEmpty()) {
-            throw new FebsException("上传的文件不能为空!请重新上传");
-        }
-        if (file.getSize() <= 0) {
-            throw new FebsException("上传的文件大小需要大于0kb");
-        }
-        if (file.getSize() > 50 * 1024* 1024) {
-            throw new FebsException("上传的文件大于50M");
-        }
-        if (!FileUtil.exist(properties.getUploadPpath())) {
-            FileUtil.mkdir(properties.getUploadPpath());
-        }
-        //原本名字
-        String fileName = file.getOriginalFilename();
-        String suffix = "";
-        if (fileName.indexOf(".") > 0) {
-            //后缀
-            suffix = fileName.substring(fileName.indexOf("."), fileName.length());
-        }
-        //生成新的名字
-        String newName = snowflake.nextIdStr() + suffix;
-        //上传
-        file.transferTo(new File(properties.getUploadPpath() + newName));
-
+        Folder folder = iFolderService.getById(folderid);
+        Dict dict = MyUtil.filesUpload(file, properties.getUploadCommonPath() + folder.getFoldername() + "/", snowflake.nextIdStr());
         FilesUpload filesUpload = new FilesUpload();
         filesUpload.setCreatetime(new Date());
         filesUpload.setCreator(operatorId);
         filesUpload.setDelFlag(0);
-        filesUpload.setFilesaddress(newName);
-        filesUpload.setFilesformat(StrUtil.isBlank(suffix) ? suffix : suffix.substring(1));
+        filesUpload.setFilesaddress(dict.getStr("newName"));
+        filesUpload.setFilesformat(StrUtil.isBlank(dict.getStr("suffix")) ? dict.getStr("suffix") : dict.getStr("suffix").substring(1));
         filesUpload.setFilesid(SequenceUtil.generateId(0L, ModuleCode.HR_FIlE));
-        filesUpload.setFilesname(fileName);
+        filesUpload.setFilesname(dict.getStr("fileName"));
         filesUpload.setFolderid(folderid);
         filesUpload.setModifier(operatorId);
         filesUpload.setModifytime(new Date());
@@ -130,13 +107,20 @@
     public void deleteFilesUpload(String fileids) {
         String[] arr = fileids.split(",");
         LambdaUpdateWrapper<FilesUpload> wapper = new LambdaUpdateWrapper<>();
-        wapper.in(FilesUpload::getFilesid,arr).setSql("delFlag = 1");
-        this.update(wapper);
+        wapper.in(FilesUpload::getFilesid, arr);
+        FilesUpload filesUpload = new FilesUpload();
+        filesUpload.setModifier(operatorId);
+        filesUpload.setModifytime(new Date());
+        filesUpload.setDelFlag(1);
+        this.update(filesUpload,wapper);
 
         LambdaQueryWrapper<FilesUpload> queryWrapper = new LambdaQueryWrapper<>();
-        wapper.in(FilesUpload::getFilesid,arr);
+        queryWrapper.in(FilesUpload::getFilesid, arr);
         List<FilesUpload> list = this.list(queryWrapper);
-        list.parallelStream().forEach(i-> FileUtil.del(properties.getUploadPpath() + i.getFilesaddress()));
+        list.parallelStream().forEach(i -> {
+            Folder folder = iFolderService.getById(i.getFolderid());
+            FileUtil.del(properties.getUploadCommonPath() + folder.getFoldername() + "/" + i.getFilesaddress());
+        });
 
     }
 
@@ -147,71 +131,38 @@
         List<String> fileName = new ArrayList<>();
         Arrays.stream(arr).forEach(i -> {
             FilesUpload filesUpload = this.getById(i);
-            files.add(new File(properties.getUploadPpath() + filesUpload.getFilesaddress()));
+            Folder folder = iFolderService.getById(filesUpload.getFolderid());
+            files.add(new File(properties.getUploadCommonPath() + folder.getFoldername() + "/" + filesUpload.getFilesaddress()));
             fileName.add(filesUpload.getFilesname());
         });
-        //设置压缩包的名字
-        //解决不同浏览器压缩包名字含有中文时乱码的问题
-        String downloadName ="PersonnelInformation-" + DateUtil.format(new Date(), "yyyyMMddhhmmsss") + ".zip";
-        String agent = request.getHeader("USER-AGENT");
-        try {
-            if (agent.contains("MSIE") || agent.contains("Trident")) {
-                downloadName = java.net.URLEncoder.encode(downloadName, "UTF-8");
-            } else {
-                downloadName = new String(downloadName.getBytes("UTF-8"), "ISO-8859-1");
-            }
-        } catch (Exception e) {
-            e.printStackTrace();
-        }
-        response.setHeader("Content-Disposition", "attachment;fileName=\"" + downloadName + "\"");
-
-
-        //设置压缩流:直接写入response,实现边压缩边下载
-        ZipOutputStream zipos = null;
-        try {
-            zipos = new ZipOutputStream(new BufferedOutputStream(response.getOutputStream()));
-            //设置压缩方法
-            zipos.setMethod(ZipOutputStream.DEFLATED);
-        } catch (Exception e) {
-            log.error("设置压缩流出现异常" + e.getMessage());
-            e.printStackTrace();
-        }
-
-        //循环将文件写入压缩流
-        DataOutputStream os = null;
-        for (int i = 0; i < files.size(); i++) {
-            File file = files.get(i);
-            try {
-                //添加ZipEntry,并ZipEntry中写入文件流
-                //这里,加上i是防止要下载的文件有重名的导致下载失败
-                zipos.putNextEntry(new ZipEntry(fileName.get(i)));
-                os = new DataOutputStream(zipos);
-                InputStream is = new FileInputStream(file);
-                byte[] b = new byte[100];
-                int length;
-                while ((length = is.read(b)) != -1) {
-                    os.write(b, 0, length);
-                }
-                is.close();
-                zipos.closeEntry();
-            } catch (IOException e) {
-                log.error("循环将文件写入压缩流出现异常" + e.getMessage());
-                e.printStackTrace();
-            }
-        }
-
-        //关闭流
-        try {
-            os.flush();
-            os.close();
-            zipos.close();
-        } catch (IOException e) {
-            log.error("关闭流现异常" + e.getMessage());
-            e.printStackTrace();
-        }
+        MyUtil.download(request, response, files, fileName);
 
     }
 
+    @Override
+    public void mvFiles(String fileids,Long folderid) {
+        String[] arr = fileids.split(",");
+
+        LambdaQueryWrapper<FilesUpload> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(FilesUpload::getFilesid, arr);
+        List<FilesUpload> list = this.list(queryWrapper);
+        list.parallelStream().forEach(i -> {
+            Folder folder = iFolderService.getById(i.getFolderid());
+            Folder newfolder = iFolderService.getById(folderid);
+            File oldfile = new File(properties.getUploadCommonPath() + folder.getFoldername() + "/" + i.getFilesaddress());
+            File newfile = new File(properties.getUploadCommonPath() + newfolder.getFoldername() + "/" + i.getFilesaddress());
+            FileUtil.move(oldfile,newfile,true);
+        });
+
+        LambdaUpdateWrapper<FilesUpload> wapper = new LambdaUpdateWrapper<>();
+        wapper.in(FilesUpload::getFilesid, arr);
+        FilesUpload filesUpload = new FilesUpload();
+        filesUpload.setModifier(operatorId);
+        filesUpload.setModifytime(new Date());
+        filesUpload.setFolderid(folderid);
+        this.update(filesUpload,wapper);
+
+    }
 
 
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FolderServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FolderServiceImpl.java
index cf984dc..82f908f 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FolderServiceImpl.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/FolderServiceImpl.java
@@ -73,7 +73,11 @@
     @Transactional(rollbackFor = Exception.class)
     public void deleteFolder(Folder folder) {
         LambdaUpdateWrapper<Folder> wapper = new LambdaUpdateWrapper<>();
-        wapper.eq(Folder::getFolderid,folder.getFolderid()).setSql("delFlag = 1");
-        this.update(wapper);
+        wapper.eq(Folder::getFolderid,folder.getFolderid());
+        Folder updatefolder = new Folder();
+        updatefolder.setModifier(operatorId);
+        updatefolder.setModifytime(new Date());
+        updatefolder.setDelFlag(1);
+        this.update(updatefolder,wapper);
     }
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/LabelServiceImpl.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/LabelServiceImpl.java
index 9fb814f..fdd526d 100644
--- a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/LabelServiceImpl.java
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/service/impl/LabelServiceImpl.java
@@ -1,12 +1,14 @@
 package cc.mrbird.febs.server.hr.service.impl;
 
 import cc.mrbird.febs.common.core.constant.ModuleCode;
+import cc.mrbird.febs.common.core.exception.FebsException;
 import cc.mrbird.febs.common.core.utils.FebsUtil;
 import cc.mrbird.febs.common.core.utils.SequenceUtil;
 import cc.mrbird.febs.server.hr.entity.Folder;
 import cc.mrbird.febs.server.hr.entity.Label;
 import cc.mrbird.febs.server.hr.mapper.LabelMapper;
 import cc.mrbird.febs.server.hr.service.ILabelService;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -55,7 +57,16 @@
 
     @Override
     @Transactional(rollbackFor = Exception.class)
-    public void createLabel(Label label) {
+    public void createLabel(Label label) throws FebsException {
+        LambdaQueryWrapper<Label> queryWrapper = new LambdaQueryWrapper();
+        queryWrapper.eq(Label::getLabelname,label.getLabelname()).or().eq(Label::getLabelcode,label.getLabelcode());
+        Label l = this.getOne(queryWrapper);
+        if(StrUtil.equals(label.getLabelname(),l.getLabelname())){
+             throw new FebsException("标签名字重复");
+        }else if(StrUtil.equals(label.getLabelcode(),l.getLabelcode())){
+            throw new FebsException("标签code重复");
+        }
+
         label.setLabelid(SequenceUtil.generateId(0L, ModuleCode.HR_FIlE));
         label.setCreator(operatorId);
         label.setModifier(operatorId);
@@ -75,7 +86,11 @@
     @Transactional(rollbackFor = Exception.class)
     public void deleteLabel(Label label) {
         LambdaUpdateWrapper<Label> wapper = new LambdaUpdateWrapper<>();
-        wapper.eq(Label::getLabelid,label.getLabelid()).setSql("delFlag = 1");
+        wapper.eq(Label::getLabelid,label.getLabelid());
+        Label updateLabel = new Label();
+        updateLabel.setModifier(operatorId);
+        updateLabel.setModifytime(new Date());
+        updateLabel.setDelFlag(1);
         this.update(wapper);
     }
 }
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/ModelUtil.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/ModelUtil.java
new file mode 100644
index 0000000..859c628
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/ModelUtil.java
@@ -0,0 +1,163 @@
+package cc.mrbird.febs.server.hr.util;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+
+/**
+ * 实体的工具类
+ * 
+ * @author zhangshuaipeng
+ *
+ */
+public class ModelUtil {
+    public static Map<String, Field[]> modelFields = new HashMap<String, Field[]>();
+
+    public static Map<String, String> modelJson = new HashMap<String, String>();
+
+    /**
+     * 判断实体不为空
+     * 
+     * @param obj
+     * @return
+     */
+    public static Boolean isNotNull(Object obj) {
+        if (obj != null) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * 获取实体对应的数据表名
+     * 
+     * @param clazz
+     *            要获取表名的实体类
+     * @param equalEntity
+     *            为true时返回实体的名称,否则返回注解的表名
+     * @return
+     */
+    public static String getTableName(Class<?> clazz, boolean equalEntity) {
+        String tableName = clazz.getSimpleName();
+
+        if (!equalEntity) {
+        	TableName annotation = (TableName)clazz.getAnnotation(TableName.class);
+            if (!StringUtils.isEmpty(annotation.value())) {
+                tableName = annotation.value();
+            }
+        }
+        return tableName;
+    }
+
+    /**
+     * 获取指定字段映射的数据表的列名
+     * 
+     * @param f
+     *            指定的字段
+     * @param isAnnotation
+     *            为true表示取字段使用@Column进行注解的名称,当没有注解时取字段名
+     * @return
+     */
+//    public static String getColumnName(Field f, boolean isAnnotation) {
+//        String columnName = f.getName();
+//        if (isAnnotation) {
+//            Annotation[] annotations = f.getAnnotations();
+//            for (int i = 0; i < annotations.length; i++) {
+//                if (annotations[i] instanceof Column) {
+//                    // 数据列
+//                    Column column = (Column) annotations[i];
+//                    if (StringUtils.isNotEmpty(column.name())) {
+//                        columnName = column.name();
+//                    }
+//                } else if (annotations[i] instanceof JoinColumn) {
+//                    // 关联列
+//                    JoinColumn joinColumn = (JoinColumn) annotations[i];
+//                    if (StringUtils.isNotEmpty(joinColumn.name())) {
+//                        columnName = joinColumn.name();
+//                    }
+//                }
+//
+//            }
+//        }
+
+//        return columnName;
+//    }
+
+    /**
+     * 得到类的属性集合
+     * 
+     * @param c
+     * @param itself
+     *            是否是自身的字段
+     * @return
+     */
+    public static Field[] getClassFields(Class<?> c, boolean itself) {
+        if (itself) {
+            if (modelFields.get(c.getName()) != null) {
+                return modelFields.get(c.getName());
+            } else {
+                Field[] fields = c.getDeclaredFields();
+                modelFields.put(c.getName(), fields);
+                return fields;
+            }
+        } else {
+            if (modelFields.get(c.getName()) != null) {
+                return modelFields.get(c.getName());
+            } else {
+                List<Field> fields = new ArrayList<Field>();
+                getAllDeclaredFields(c, fields);
+                Field[] fies = new Field[fields.size()];
+                fields.toArray(fies);
+                modelFields.put(c.getName(), fies);
+                return fies;
+            }
+        }
+    }
+
+    /**
+     * 从c类中取得全部字段,包括父类
+     * 
+     * @param c
+     * @param fields
+     */
+    public static void getAllDeclaredFields(Class<?> c, List<Field> fields) {
+        Field[] fies = c.getDeclaredFields();
+        Collections.addAll(fields, fies);
+        Class<?> parent = c.getSuperclass();
+        if (parent != Object.class) {
+            getAllDeclaredFields(parent, fields);
+        } else {
+            return;
+        }
+    }
+
+    /**
+     * 得到类的主键字段
+     * 
+     * @param clazz
+     * @return
+     */
+//    public static String getClassPkName(Class<?> clazz) {
+//        Field[] fields = getClassFields(clazz, false);
+//        String pkName = "";
+//        for (Field f : fields) {
+//            FieldInfo fieldInfo = f.getAnnotation(FieldInfo.class);
+//            if (isNotNull(fieldInfo)) {
+//                if ("ID".equals(fieldInfo.type())) {
+//                    pkName = f.getName();
+//                    break;
+//                }
+//            }
+//        }
+//        return pkName;
+//    }
+
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiExportExcel.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiExportExcel.java
new file mode 100644
index 0000000..80eb819
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiExportExcel.java
@@ -0,0 +1,1480 @@
+package cc.mrbird.febs.server.hr.util;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.poi.hssf.usermodel.HSSFFont;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.VerticalAlignment;
+import org.apache.poi.ss.util.CellRangeAddress;
+
+import cc.mrbird.febs.common.core.annotation.FieldInfo;
+import cn.hutool.core.date.DateUtil;
+
+public class PoiExportExcel {
+
+	/**
+	 * 导出EXCEL文件(单个sheet,可以多个表格)
+	 *
+	 * @param response
+	 * @param fileName    文件名称
+	 * @param sheetTitle  sheet中的大标题(第一行)
+	 * @param listContent sheet中的数据集(list中每个map数据中,存放一个表格的数据;在每个map中又细分为多个不同的Object数据)
+	 *                    如:(详见导出班级代码) List<Map<String, Object>> listContent = new
+	 *                    ArrayList<>(); //数据集
+	 *
+	 *                    Map<String, Object> roomAllMap = new LinkedHashMap<>();
+	 *                    //一个map中,代表一个表格 roomAllMap.put("data", roomList);
+	 *                    //此表格中的具体遍历数据 roomAllMap.put("title", "班级学员宿舍信息表");
+	 *                    //表格标题,若为null,且数据集中存在其他map,则下一个map不会空出3行(空出3行,用于划分各个表格)。
+	 *                    roomAllMap.put("head", new String[] { "姓名", "性别", "是否午休",
+	 *                    "是否晚宿" });
+	 *                    //若存在名字相同的,则名字相同且相邻的head合并(当head名字相同,并且某行中的对应的列值也相同,则合并它们)
+	 *                    roomAllMap.put("columnWidth", new Integer[] { 15, 15, 15,
+	 *                    20 }); //
+	 *                    20代表20个字节,10个字符(整个sheet中,只能存在一个columnWidth,因为列宽是针对整个sheet的)
+	 *                    roomAllMap.put("columnAlignment", new Integer[] { 0, 0, 0,
+	 *                    0 }); // 0代表居中,1代表居左,2代表居右
+	 *                    roomAllMap.put("mergeCondition", null); //
+	 *                    跨行合行列需要的条件,条件优先级按顺序决定,NULL表示不合并,空数组表示无条件
+	 *                    listContent.add(roomAllMap); //加入此map到数据集中
+	 *
+	 * @return
+	 * @throws IOException
+	 */
+	public final static boolean exportExcel(HttpServletResponse response, String fileName, String sheetTitle,
+			List<Map<String, Object>> listContent) throws IOException {
+		HSSFWorkbook workbook = new HSSFWorkbook();
+		boolean result = false;
+		OutputStream fileOutputStream = null;
+		response.reset();// 清空输出流
+		response.setHeader("Content-disposition",
+				"attachment; filename=" + new String((fileName + ".xls").getBytes("GB2312"), "ISO8859-1"));
+		response.setContentType("application/msexcel");
+
+		if (null != listContent && !listContent.isEmpty()) {
+
+			try {
+				Sheet sheet = workbook.createSheet(fileName);
+
+				// 创建基本的样式
+				CellStyle titleStyle = getCellStyle(workbook, "", (short) 26, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle headStyle = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleCenter = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleLeft = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.LEFT,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleRight = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, true);
+
+				int rowNum = 0; // 初始化第一行为0开始计数
+				int colCount = ((String[]) listContent.get(0).get("head")).length;// 表头的列数
+
+				// 第一行先创建一个大标题(当不为null的时候,设置这一行)
+				if (sheetTitle != null) {
+					Row sheetTitleRow = sheet.createRow(rowNum); // 创建标题行
+					sheetTitleRow.setHeight((short) 0x300); // 设置行高
+					Cell sheetTitleCell = sheetTitleRow.createCell(0); // 创建第一个单元格
+					sheetTitleCell.setCellStyle(titleStyle); // 设置标题的样式
+					sheetTitleCell.setCellValue(sheetTitle); // 给标题格设定值
+					sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+					rowNum++;
+				}
+
+				// 处理数据
+				for (Map<String, Object> dataList : listContent) {
+
+					// 获取数据
+					List<Map<String, String>> currentData = (List<Map<String, String>>) dataList.get("data");
+					String title = (String) dataList.get("title");
+					String[] headArray = (String[]) dataList.get("head");
+					Integer[] columnWidthArray = (Integer[]) dataList.get("columnWidth");
+					Integer[] columnWidthAlignment = (Integer[]) dataList.get("columnAlignment");
+					String[] columnMergeCondition = (String[]) dataList.get("mergeCondition");
+
+					// 设置标题栏内容(当不为null的时候,设置这一行)
+					if (title != null) {
+						if (rowNum > 1) { // 除了第一个表格的时候,后续表格和之前表格空三行
+							rowNum += 3;
+						}
+						Row titleRow = sheet.createRow(rowNum); // 标题行
+						titleRow.setHeight((short) 0x248); // 标题行高
+
+						for (int i = 0; i < headArray.length; i++) {
+							Cell titleCell = titleRow.createCell(i);
+							titleCell.setCellStyle(headStyle);
+							titleCell.setCellValue(title);
+						}
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+						rowNum++;
+					}
+
+					// 设置表头内容
+					Row headRow = sheet.createRow(rowNum); // 表头行
+					headRow.setHeight((short) 0x200); // 表头行高
+					Object[] headMergeObj = null; // (因为2个行或列合并了之后,就必须要先移除合并,才能重新合并更多的行)
+					for (int i = 0; i < headArray.length; i++) {
+						Cell cell = headRow.createCell(i);
+						cell.setCellValue(headArray[i]);
+						cell.setCellStyle(headStyle);
+						sheet.setColumnWidth(i, columnWidthArray[i] * 256);
+
+						// 如果当前列名和上一列的名字一致,则合并
+						if (i > 0 && headArray[i - 1].equals(headArray[i])) {
+							if (headMergeObj == null) {
+								int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+								headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。。
+							} else {
+								if (headMergeObj[1].equals(headArray[i])) {
+									sheet.removeMergedRegion((int) headMergeObj[0]);
+									int index = sheet.addMergedRegion(
+											new CellRangeAddress(rowNum, rowNum, (int) headMergeObj[2], i));
+									headMergeObj[0] = index;
+								} else {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+									headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。
+								}
+							}
+						}
+
+					}
+					rowNum++;
+
+					// 保存上一个map
+					Map<String, String> preMap = null;
+					// 保存某一列上一个合并的数据,并用来判断是否再合并(因为2个列合并了之后,就必须要先移除合并,才能合并)
+					Map<Integer, Object[]> recordMap = new HashMap<>();
+					// 保存某一行的上一个合并的数据,并用来判断是否再合并
+					Object[] rowMergeObj = null;
+					for (int i = 0; i < currentData.size(); i++) {
+						Row textRow = sheet.createRow(rowNum);
+						Map<String, String> map = currentData.get(i);
+
+						int j = 0, maxTextHeight = (short) 0X250; // 默认行高,可以放2行数据
+						String preVal = null; // 保存某一行中,上一列的值
+						for (String s : map.keySet()) {
+							Object val = map.get(s);
+							if (val == null) {
+								val = "";
+							}
+
+							Cell cell = textRow.createCell(j);
+							cell.setCellValue(String.valueOf(val));
+
+							if (columnWidthAlignment[j] == 0) {
+								cell.setCellStyle(textStyleCenter);
+							} else if (columnWidthAlignment[j] == 1) {
+								cell.setCellStyle(textStyleLeft);
+							} else if (columnWidthAlignment[j] == 2) {
+								cell.setCellStyle(textStyleRight);
+							} else {
+								cell.setCellStyle(textStyleCenter);
+							}
+
+							// 计算最大的高度值
+							int len = String.valueOf(val).getBytes().length;
+							if (len > columnWidthArray[j] + 1) {
+								int tempHeight = (len / (columnWidthArray[j] - 1) + 1) * 0X125; // 加入了边框,所以一行放入的字节数会少一个
+								if (tempHeight > maxTextHeight)
+									maxTextHeight = tempHeight;
+							}
+
+							// 判断是否需要进行列合并
+							// 如果当前列名和上一列的名字一致,并且行的值也一致,则合并
+							if (j > 0 && headArray[j - 1].equals(headArray[j]) && preVal != null
+									&& preVal.equals(val)) {
+								if (rowMergeObj == null) {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+									rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+								} else {
+									// 当上一个合并的数据值、表头值、行号 与
+									// 当前处理的单元格的数据一致时,才继续合并,否则单独合并两列
+									if (rowMergeObj[2].equals(val) && rowMergeObj[1].equals(headArray[j])
+											&& i == (int) rowMergeObj[3]) {
+										sheet.removeMergedRegion((int) rowMergeObj[0]);
+										int index = sheet.addMergedRegion(
+												new CellRangeAddress(rowNum, rowNum, (int) rowMergeObj[4], j));
+										rowMergeObj[0] = index;
+									} else {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+										rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+									}
+								}
+							}
+
+							// 判断是否需要进行行合并
+							if (i > 0 && preMap.get(s) != null && !preMap.get(s).equals("") && preMap.get(s).equals(val)
+									&& columnMergeCondition != null) { // 当前后的值都一致,才能满足最基本的合并条件
+
+								boolean isMerge = true;
+								String tempStr = "";
+								// 当需要合并的列,满足必要的合并条件后,才允许合并
+								for (int k = 0; k < columnMergeCondition.length; k++) {
+									tempStr = columnMergeCondition[k];
+
+									// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+									if (s.equals(tempStr)) {
+										isMerge = true;
+										break;
+									} else if (!preMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+										isMerge = false;
+										break;
+									}
+								}
+
+								if (isMerge == true) {
+									// 若不存在值,表明还未合并
+									Object[] recordObj = recordMap.get(j);
+									if (recordObj == null) {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+										recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 合并的index值,MAP,行号。
+										recordMap.put(j, recordObj);
+									}
+									// 若存在值,则判断,值是否一致,一致则合并,否则重新保存新的数据
+									else {
+										boolean isTempMerger = false;
+										Map<String, String> tempMap = (Map) recordObj[1];
+										// 当需要合并的列,满足必要的合并条件后,才允许合并
+										for (int k = 0; k < columnMergeCondition.length; k++) {
+											tempStr = columnMergeCondition[k];
+
+											// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+											if (s.equals(tempStr) && tempMap.get(s).equals(val)) {
+												isTempMerger = true;
+												break;
+											} else if (!tempMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+												isTempMerger = false;
+												break;
+											}
+										}
+										if (isTempMerger == true) {
+											sheet.removeMergedRegion((int) recordObj[0]); // 先移除
+											int index = sheet.addMergedRegion(
+													new CellRangeAddress((int) recordObj[2], rowNum, j, j)); // 再合并
+											recordObj[0] = index;
+											recordMap.put(j, recordObj);
+										} else { // 否则,重新保存此列的合并数据
+											int index = sheet
+													.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+											recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 保存新的合并的index值,列值,行号。
+											recordMap.put(j, recordObj);
+										}
+
+									}
+								}
+							}
+							preVal = (String) val;
+							j++;
+						}
+
+						// 设置行高
+						textRow.setHeight((short) maxTextHeight);
+						// 保存上一个map
+						preMap = currentData.get(i);
+						rowNum++;
+					}
+
+				}
+
+				fileOutputStream = response.getOutputStream();
+				workbook.write(fileOutputStream);
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				if (null != fileOutputStream) {
+					try {
+						fileOutputStream.close();
+					} catch (IOException e) {
+						System.out.println(e.getMessage());
+					}
+				}
+			}
+			result = true;
+		}
+		return result;
+	}
+
+	public final static boolean exportExcelFile(HttpServletResponse response, String fileName, String sheetTitle,
+			List<Map<String, Object>> listContent, String fileUrl) throws IOException {
+		HSSFWorkbook workbook = new HSSFWorkbook();
+		boolean result = false;
+		OutputStream fileOutputStream = null;
+		response.reset();// 清空输出流
+		// response.setHeader("Content-disposition",
+		// "attachment; filename=" + new String((fileName +
+		// ".xls").getBytes("GB2312"), "ISO8859-1"));
+		// response.setContentType("application/msexcel");
+
+		if (null != listContent && !listContent.isEmpty()) {
+
+			try {
+				Sheet sheet = workbook.createSheet(fileName);
+
+				// 创建基本的样式
+				CellStyle titleStyle = getCellStyle(workbook, "", (short) 26, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle headStyle = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleCenter = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleLeft = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.LEFT,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleRight = getCellStyle(workbook, "", (short) 11, false, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, true);
+
+				int rowNum = 0; // 初始化第一行为0开始计数
+				int colCount = ((String[]) listContent.get(0).get("head")).length;// 表头的列数
+
+				// 第一行先创建一个大标题(当不为null的时候,设置这一行)
+				if (sheetTitle != null) {
+					Row sheetTitleRow = sheet.createRow(rowNum); // 创建标题行
+					sheetTitleRow.setHeight((short) 0x300); // 设置行高
+					Cell sheetTitleCell = sheetTitleRow.createCell(0); // 创建第一个单元格
+					sheetTitleCell.setCellStyle(titleStyle); // 设置标题的样式
+					sheetTitleCell.setCellValue(sheetTitle); // 给标题格设定值
+					sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+					rowNum++;
+				}
+
+				// 处理数据
+				for (Map<String, Object> dataList : listContent) {
+
+					// 获取数据
+					List<Map<String, String>> currentData = (List<Map<String, String>>) dataList.get("data");
+					String title = (String) dataList.get("title");
+					String[] headArray = (String[]) dataList.get("head");
+					Integer[] columnWidthArray = (Integer[]) dataList.get("columnWidth");
+					Integer[] columnWidthAlignment = (Integer[]) dataList.get("columnAlignment");
+					String[] columnMergeCondition = (String[]) dataList.get("mergeCondition");
+
+					// 设置标题栏内容(当不为null的时候,设置这一行)
+					if (title != null) {
+						if (rowNum > 1) { // 除了第一个表格的时候,后续表格和之前表格空三行
+							rowNum += 3;
+						}
+						Row titleRow = sheet.createRow(rowNum); // 标题行
+						titleRow.setHeight((short) 0x248); // 标题行高
+
+						for (int i = 0; i < headArray.length; i++) {
+							Cell titleCell = titleRow.createCell(i);
+							titleCell.setCellStyle(headStyle);
+							titleCell.setCellValue(title);
+						}
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+						rowNum++;
+					}
+
+					// 设置表头内容
+					Row headRow = sheet.createRow(rowNum); // 表头行
+					headRow.setHeight((short) 0x200); // 表头行高
+					Object[] headMergeObj = null; // (因为2个行或列合并了之后,就必须要先移除合并,才能重新合并更多的行)
+					for (int i = 0; i < headArray.length; i++) {
+						Cell cell = headRow.createCell(i);
+						cell.setCellValue(headArray[i]);
+						cell.setCellStyle(headStyle);
+						sheet.setColumnWidth(i, columnWidthArray[i] * 256);
+
+						// 如果当前列名和上一列的名字一致,则合并
+						if (i > 0 && headArray[i - 1].equals(headArray[i])) {
+							if (headMergeObj == null) {
+								int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+								headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。。
+							} else {
+								if (headMergeObj[1].equals(headArray[i])) {
+									sheet.removeMergedRegion((int) headMergeObj[0]);
+									int index = sheet.addMergedRegion(
+											new CellRangeAddress(rowNum, rowNum, (int) headMergeObj[2], i));
+									headMergeObj[0] = index;
+								} else {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+									headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。
+								}
+							}
+						}
+
+					}
+					rowNum++;
+
+					// 保存上一个map
+					Map<String, String> preMap = null;
+					// 保存某一列上一个合并的数据,并用来判断是否再合并(因为2个列合并了之后,就必须要先移除合并,才能合并)
+					Map<Integer, Object[]> recordMap = new HashMap<>();
+					// 保存某一行的上一个合并的数据,并用来判断是否再合并
+					Object[] rowMergeObj = null;
+					for (int i = 0; i < currentData.size(); i++) {
+						Row textRow = sheet.createRow(rowNum);
+						Map<String, String> map = currentData.get(i);
+
+						int j = 0, maxTextHeight = (short) 0X250; // 默认行高,可以放2行数据
+						String preVal = null; // 保存某一行中,上一列的值
+						for (String s : map.keySet()) {
+							Object val = map.get(s);
+							if (val == null) {
+								val = "";
+							}
+
+							Cell cell = textRow.createCell(j);
+							cell.setCellValue(String.valueOf(val));
+
+							if (columnWidthAlignment[j] == 0) {
+								cell.setCellStyle(textStyleCenter);
+							} else if (columnWidthAlignment[j] == 1) {
+								cell.setCellStyle(textStyleLeft);
+							} else if (columnWidthAlignment[j] == 2) {
+								cell.setCellStyle(textStyleRight);
+							} else {
+								cell.setCellStyle(textStyleCenter);
+							}
+
+							// 计算最大的高度值
+							int len = String.valueOf(val).getBytes().length;
+							if (len > columnWidthArray[j] + 1) {
+								int tempHeight = (len / (columnWidthArray[j] - 1) + 1) * 0X125; // 加入了边框,所以一行放入的字节数会少一个
+								if (tempHeight > maxTextHeight)
+									maxTextHeight = tempHeight;
+							}
+
+							// 判断是否需要进行列合并
+							// 如果当前列名和上一列的名字一致,并且行的值也一致,则合并
+							if (j > 0 && headArray[j - 1].equals(headArray[j]) && preVal != null
+									&& preVal.equals(val)) {
+								if (rowMergeObj == null) {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+									rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+								} else {
+									// 当上一个合并的数据值、表头值、行号 与
+									// 当前处理的单元格的数据一致时,才继续合并,否则单独合并两列
+									if (rowMergeObj[2].equals(val) && rowMergeObj[1].equals(headArray[j])
+											&& i == (int) rowMergeObj[3]) {
+										sheet.removeMergedRegion((int) rowMergeObj[0]);
+										int index = sheet.addMergedRegion(
+												new CellRangeAddress(rowNum, rowNum, (int) rowMergeObj[4], j));
+										rowMergeObj[0] = index;
+									} else {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+										rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+									}
+								}
+							}
+
+							// 判断是否需要进行行合并
+							if (i > 0 && preMap.get(s) != null && !preMap.get(s).equals("") && preMap.get(s).equals(val)
+									&& columnMergeCondition != null) { // 当前后的值都一致,才能满足最基本的合并条件
+
+								boolean isMerge = true;
+								String tempStr = "";
+								// 当需要合并的列,满足必要的合并条件后,才允许合并
+								for (int k = 0; k < columnMergeCondition.length; k++) {
+									tempStr = columnMergeCondition[k];
+
+									// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+									if (s.equals(tempStr)) {
+										isMerge = true;
+										break;
+									} else if (!preMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+										isMerge = false;
+										break;
+									}
+								}
+
+								if (isMerge == true) {
+									// 若不存在值,表明还未合并
+									Object[] recordObj = recordMap.get(j);
+									if (recordObj == null) {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+										recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 合并的index值,MAP,行号。
+										recordMap.put(j, recordObj);
+									}
+									// 若存在值,则判断,值是否一致,一致则合并,否则重新保存新的数据
+									else {
+										boolean isTempMerger = false;
+										Map<String, String> tempMap = (Map) recordObj[1];
+										// 当需要合并的列,满足必要的合并条件后,才允许合并
+										for (int k = 0; k < columnMergeCondition.length; k++) {
+											tempStr = columnMergeCondition[k];
+
+											// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+											if (s.equals(tempStr) && tempMap.get(s).equals(val)) {
+												isTempMerger = true;
+												break;
+											} else if (!tempMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+												isTempMerger = false;
+												break;
+											}
+										}
+										if (isTempMerger == true) {
+											sheet.removeMergedRegion((int) recordObj[0]); // 先移除
+											int index = sheet.addMergedRegion(
+													new CellRangeAddress((int) recordObj[2], rowNum, j, j)); // 再合并
+											recordObj[0] = index;
+											recordMap.put(j, recordObj);
+										} else { // 否则,重新保存此列的合并数据
+											int index = sheet
+													.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+											recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 保存新的合并的index值,列值,行号。
+											recordMap.put(j, recordObj);
+										}
+
+									}
+								}
+							}
+							preVal = (String) val;
+							j++;
+						}
+
+						// 设置行高
+						textRow.setHeight((short) maxTextHeight);
+						// 保存上一个map
+						preMap = currentData.get(i);
+						rowNum++;
+					}
+
+				}
+
+				File localFile = new File(fileUrl);
+				if (!localFile.exists()) {
+					// 先得到文件的上级目录,并创建上级目录,在创建文件
+					localFile.getParentFile().mkdirs();
+					localFile.createNewFile();
+				}
+				fileOutputStream = new FileOutputStream(localFile);
+				fileOutputStream.flush();
+
+				workbook.write(fileOutputStream);
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				if (null != fileOutputStream) {
+					try {
+						fileOutputStream.close();
+					} catch (IOException e) {
+						System.out.println(e.getMessage());
+					}
+				}
+			}
+			result = true;
+		}
+		return result;
+	}
+
+	/*
+	 * 获取样式格式的方法
+	 *
+	 * @param workbook Excel文件
+	 *
+	 * @param fontName 字体名称
+	 *
+	 * @param fontSize 字体大小
+	 *
+	 * @param isBold 是否加粗
+	 *
+	 * @param horizontalAlignment (左,右,居中)对齐
+	 *
+	 * @param verticalAlignment (上,下,居中)对齐
+	 *
+	 * @param isWrapText 是否换行
+	 *
+	 */
+	public static CellStyle getCellStyle(HSSFWorkbook workbook, String fontName, Short fontSize, Boolean isBold,
+			HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, Boolean isWrapText) {
+
+		HSSFFont font = workbook.createFont();
+		// 默认方正黑体
+		if (StringUtils.isBlank(fontName)) {
+			font.setFontName("方正黑体简体");
+		} else {
+			font.setFontName(fontName);
+		}
+		font.setFontHeightInPoints(fontSize);// 字体大小
+		font.setBold(isBold); // 是否加粗
+
+		CellStyle style = workbook.createCellStyle();
+		style.setFont(font);
+		style.setAlignment(horizontalAlignment);// 左右对齐
+		style.setVerticalAlignment(verticalAlignment);// 上下对齐
+		style.setBorderBottom(BorderStyle.THIN);
+		style.setBorderLeft(BorderStyle.THIN);
+		style.setBorderTop(BorderStyle.THIN);
+		style.setBorderRight(BorderStyle.THIN);
+		style.setWrapText(isWrapText);
+
+		return style;
+	}
+
+	/*
+	 * 导出的数据是多个sheet表的
+	 */
+	public final static boolean exportSheetsExcel(HttpServletResponse response, String fileName,
+			List<String> sheetNames, String sheetTitle, List<Map<String, Object>> listContent) throws IOException {
+		HSSFWorkbook workbook = new HSSFWorkbook();
+		boolean result = false;
+		OutputStream fileOutputStream = null;
+		response.reset();// 清空输出流
+		response.setHeader("Content-disposition",
+				"attachment; filename=" + new String((fileName + ".xls").getBytes("GB2312"), "ISO8859-1"));
+		response.setContentType("application/msexcel");
+
+		if (null != listContent && !listContent.isEmpty()) {
+
+			try {
+				// 创建基本的样式
+				CellStyle headStyle = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleCenter = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleLeft = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.LEFT,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleRight = getCellStyle(workbook, "", (short) 11, true, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, true);
+
+				int rowNum = 0; // 初始化第一行为0开始计数
+				// 处理数据
+				for (Map<String, Object> dataList : listContent) {
+
+					int sheetNumber = 0;
+					// 获取数据
+					List<Map<String, String>> currentData = (List<Map<String, String>>) dataList.get("data");
+					String title = (String) dataList.get("title");
+					String[] headArray = (String[]) dataList.get("head");
+					Integer[] columnWidthArray = (Integer[]) dataList.get("columnWidth");
+					Integer[] columnWidthAlignment = (Integer[]) dataList.get("columnAlignment");
+					String[] columnMergeCondition = (String[]) dataList.get("mergeCondition");
+
+					Sheet sheet = workbook.createSheet(sheetNames.get(sheetNumber));
+					sheetNumber++;
+
+					// 设置标题栏内容(当不为null的时候,设置这一行)
+					if (title != null) {
+						Row titleRow = sheet.createRow(rowNum); // 标题行
+						titleRow.setHeight((short) 0x248); // 标题行高
+						for (int i = 0; i < headArray.length; i++) {
+							Cell titleCell = titleRow.createCell(i);
+							titleCell.setCellStyle(headStyle);
+							titleCell.setCellValue(title);
+						}
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+						rowNum++;
+					}
+
+					// 设置表头内容
+					Row headRow = sheet.createRow(rowNum); // 表头行
+					headRow.setHeight((short) 0x200); // 表头行高
+					Object[] headMergeObj = null; // (因为2个行或列合并了之后,就必须要先移除合并,才能重新合并更多的行)
+					for (int i = 0; i < headArray.length; i++) {
+						Cell cell = headRow.createCell(i);
+						cell.setCellValue(headArray[i]);
+						cell.setCellStyle(headStyle);
+						sheet.setColumnWidth(i, columnWidthArray[i] * 256);
+
+						// 如果当前列名和上一列的名字一致,则合并
+						if (i > 0 && headArray[i - 1].equals(headArray[i])) {
+							if (headMergeObj == null) {
+								int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+								headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。。
+							} else {
+								if (headMergeObj[1].equals(headArray[i])) {
+									sheet.removeMergedRegion((int) headMergeObj[0]);
+									int index = sheet.addMergedRegion(
+											new CellRangeAddress(rowNum, rowNum, (int) headMergeObj[2], i));
+									headMergeObj[0] = index;
+								} else {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, i - 1, i));
+									headMergeObj = new Object[] { index, headArray[i], i - 1 }; // 合并的index值,表头值,行号。
+								}
+							}
+						}
+
+					}
+					rowNum++;
+
+					// 保存上一个map
+					Map<String, String> preMap = null;
+					// 保存某一列上一个合并的数据,并用来判断是否再合并(因为2个列合并了之后,就必须要先移除合并,才能合并)
+					Map<Integer, Object[]> recordMap = new HashMap<>();
+					// 保存某一行的上一个合并的数据,并用来判断是否再合并
+					Object[] rowMergeObj = null;
+					for (int i = 0; i < currentData.size(); i++) {
+						Row textRow = sheet.createRow(rowNum);
+						Map<String, String> map = currentData.get(i);
+
+						int j = 0, maxTextHeight = (short) 0X250; // 默认行高,可以放2行数据
+						String preVal = null; // 保存某一行中,上一列的值
+						for (String s : map.keySet()) {
+							Object val = map.get(s);
+							if (val == null) {
+								val = "";
+							}
+
+							Cell cell = textRow.createCell(j);
+							cell.setCellValue(String.valueOf(val));
+
+							if (columnWidthAlignment[j] == 0) {
+								cell.setCellStyle(textStyleCenter);
+							} else if (columnWidthAlignment[j] == 1) {
+								cell.setCellStyle(textStyleLeft);
+							} else if (columnWidthAlignment[j] == 2) {
+								cell.setCellStyle(textStyleRight);
+							} else {
+								cell.setCellStyle(textStyleCenter);
+							}
+
+							// 计算最大的高度值
+							int len = String.valueOf(val).getBytes().length;
+							if (len > columnWidthArray[j] + 1) {
+								int tempHeight = (len / (columnWidthArray[j] - 1) + 1) * 0X125; // 加入了边框,所以一行放入的字节数会少一个
+								if (tempHeight > maxTextHeight)
+									maxTextHeight = tempHeight;
+							}
+
+							// 判断是否需要进行列合并
+							// 如果当前列名和上一列的名字一致,并且行的值也一致,则合并
+							if (j > 0 && headArray[j - 1].equals(headArray[j]) && preVal != null
+									&& preVal.equals(val)) {
+								if (rowMergeObj == null) {
+									int index = sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+									rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+								} else {
+									// 当上一个合并的数据值、表头值、行号 与
+									// 当前处理的单元格的数据一致时,才继续合并,否则单独合并两列
+									if (rowMergeObj[2].equals(val) && rowMergeObj[1].equals(headArray[j])
+											&& i == (int) rowMergeObj[3]) {
+										sheet.removeMergedRegion((int) rowMergeObj[0]);
+										int index = sheet.addMergedRegion(
+												new CellRangeAddress(rowNum, rowNum, (int) rowMergeObj[4], j));
+										rowMergeObj[0] = index;
+									} else {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum, rowNum, j - 1, j));
+										rowMergeObj = new Object[] { index, headArray[j - 1], preVal, i, j - 1 }; // 合并的index值,表头值,数据值,行号,列号。
+									}
+								}
+							}
+
+							// 判断是否需要进行行合并
+							if (i > 0 && preMap.get(s) != null && !preMap.get(s).equals("") && preMap.get(s).equals(val)
+									&& columnMergeCondition != null) { // 当前后的值都一致,才能满足最基本的合并条件
+
+								boolean isMerge = true;
+								String tempStr = "";
+								// 当需要合并的列,满足必要的合并条件后,才允许合并
+								for (int k = 0; k < columnMergeCondition.length; k++) {
+									tempStr = columnMergeCondition[k];
+
+									// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+									if (s.equals(tempStr)) {
+										isMerge = true;
+										break;
+									} else if (!preMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+										isMerge = false;
+										break;
+									}
+								}
+
+								if (isMerge == true) {
+									// 若不存在值,表明还未合并
+									Object[] recordObj = recordMap.get(j);
+									if (recordObj == null) {
+										int index = sheet
+												.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+										recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 合并的index值,MAP,行号。
+										recordMap.put(j, recordObj);
+									}
+									// 若存在值,则判断,值是否一致,一致则合并,否则重新保存新的数据
+									else {
+										boolean isTempMerger = false;
+										Map<String, String> tempMap = (Map) recordObj[1];
+										// 当需要合并的列,满足必要的合并条件后,才允许合并
+										for (int k = 0; k < columnMergeCondition.length; k++) {
+											tempStr = columnMergeCondition[k];
+
+											// 当前判断的列为条件中的列时,可以直接合并(因为列是有顺序的,所以当判断到当前列的时候,表明前面的列条件都判断完毕)
+											if (s.equals(tempStr) && tempMap.get(s).equals(val)) {
+												isTempMerger = true;
+												break;
+											} else if (!tempMap.get(tempStr).equals(map.get(tempStr))) { // 当其中一个条件不满足,则不允许合并
+												isTempMerger = false;
+												break;
+											}
+										}
+										if (isTempMerger == true) {
+											sheet.removeMergedRegion((int) recordObj[0]); // 先移除
+											int index = sheet.addMergedRegion(
+													new CellRangeAddress((int) recordObj[2], rowNum, j, j)); // 再合并
+											recordObj[0] = index;
+											recordMap.put(j, recordObj);
+										} else { // 否则,重新保存此列的合并数据
+											int index = sheet
+													.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum, j, j));
+											recordObj = new Object[] { index, currentData.get(i), rowNum - 1 }; // 保存新的合并的index值,列值,行号。
+											recordMap.put(j, recordObj);
+										}
+
+									}
+								}
+							}
+							preVal = (String) val;
+							j++;
+						}
+
+						// 设置行高
+						textRow.setHeight((short) maxTextHeight);
+						// 保存上一个map
+						preMap = currentData.get(i);
+						rowNum++;
+					}
+
+				}
+
+				fileOutputStream = response.getOutputStream();
+				workbook.write(fileOutputStream);
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				if (null != fileOutputStream) {
+					try {
+						fileOutputStream.close();
+					} catch (IOException e) {
+						System.out.println(e.getMessage());
+					}
+				}
+			}
+			result = true;
+		}
+		return result;
+	}
+
+	/**
+	 * 导出EXCEL文件(单个sheet,可以多个表格)
+	 *
+	 * @param response
+	 * @param fileName    文件名称
+	 * @param sheetTitle  sheet中的大标题(第一行)
+	 * @param listContent sheet中的数据集(list中每个map数据中,存放一个表格的数据;在每个map中又细分为多个不同的Object数据)
+	 *                    如:(详见导出班级代码) List<Map<String, Object>> listContent = new
+	 *                    ArrayList<>(); //数据集
+	 *
+	 *                    Map<String, Object> roomAllMap = new LinkedHashMap<>();
+	 *                    //一个map中,代表一个表格 roomAllMap.put("data", roomList);
+	 *                    //此表格中的具体遍历数据 roomAllMap.put("title", "班级学员宿舍信息表");
+	 *                    //表格标题,若为null,且数据集中存在其他map,则下一个map不会空出3行(空出3行,用于划分各个表格)。
+	 *                    roomAllMap.put("head", new String[] { "姓名", "性别", "是否午休",
+	 *                    "是否晚宿" });
+	 *                    //若存在名字相同的,则名字相同且相邻的head合并(当head名字相同,并且某行中的对应的列值也相同,则合并它们)
+	 *                    roomAllMap.put("columnWidth", new Integer[] { 15, 15, 15,
+	 *                    20 }); //
+	 *                    20代表20个字节,10个字符(整个sheet中,只能存在一个columnWidth,因为列宽是针对整个sheet的)
+	 *                    roomAllMap.put("columnAlignment", new Integer[] { 0, 0, 0,
+	 *                    0 }); // 0代表居中,1代表居左,2代表居右
+	 *                    roomAllMap.put("mergeCondition", null); //
+	 *                    跨行合行列需要的条件,条件优先级按顺序决定,NULL表示不合并,空数组表示无条件
+	 *                    listContent.add(roomAllMap); //加入此map到数据集中
+	 *
+	 * @return
+	 * @throws IOException
+	 */
+	public final static boolean exportCommonExcel(HttpServletResponse response, String fileName, String sheetTitle,
+			List<Map<String, Object>> listContent) throws IOException {
+		return exportCommonExcel(response, fileName, sheetTitle, listContent, null);
+	}
+
+	public final static boolean exportCommonExcel(HttpServletResponse response, String fileName, String sheetTitle,
+			List<Map<String, Object>> listContent, String fileUrl) throws IOException {
+		HSSFWorkbook workbook = new HSSFWorkbook();
+		boolean result = false;
+		OutputStream fileOutputStream = null;
+		response.reset();// 清空输出流
+		response.setHeader("Content-disposition",
+				"attachment; filename=" + new String((fileName + ".xls").getBytes("GB2312"), "ISO8859-1"));
+		response.setContentType("application/msexcel");
+
+		if (null != listContent && !listContent.isEmpty()) {
+
+			try {
+				Sheet sheet = workbook.createSheet(fileName);
+
+				// 创建基本的样式
+				CellStyle titleStyle = getCellStyle(workbook, "", (short) 20, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle headStyle = getCellStyle(workbook, "", (short) 9, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleCenter = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleLeft = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.LEFT,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleRight = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, true);
+
+				int rowNum = 0; // 初始化第一行为0开始计数
+				int colCount = ((String[]) listContent.get(0).get("head")).length;// 表头的列数
+
+				// 第一行先创建一个大标题(当不为null的时候,设置这一行)
+				if (sheetTitle != null) {
+					titleStyle.setBorderTop(BorderStyle.NONE);
+					titleStyle.setBorderBottom(BorderStyle.NONE);
+					titleStyle.setBorderLeft(BorderStyle.NONE);
+					titleStyle.setBorderRight(BorderStyle.NONE);
+
+					Row sheetTitleRow = sheet.createRow(rowNum); // 创建标题行
+					sheetTitleRow.setHeight((short) 0x300); // 设置行高
+					Cell sheetTitleCell = sheetTitleRow.createCell(0); // 创建第一个单元格
+					sheetTitleCell.setCellStyle(titleStyle); // 设置标题的样式
+					sheetTitleCell.setCellValue(sheetTitle); // 给标题格设定值
+					if (colCount != 1) {
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+					}
+					// sheet.addMergedRegion(new CellRangeAddress(rowNum,
+					// rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+					rowNum++;
+				}
+
+				// 处理数据
+				for (Map<String, Object> dataList : listContent) {
+
+					// 获取数据
+					List<Map<String, String>> currentData = (List<Map<String, String>>) dataList.get("data");
+					String title = (String) dataList.get("title");
+					String[] headArray = (String[]) dataList.get("head");
+					Map<String, Integer> columnWidthArray = (Map<String, Integer>) dataList.get("columnWidth");
+					String[] pageHeadArray = (String[]) dataList.get("pageHead");
+					String[] pageFooterArray = (String[]) dataList.get("pageFooter");
+
+					// 设置标题栏内容(当不为null的时候,设置这一行)
+					if (title != null) {
+						if (rowNum > 1) { // 除了第一个表格的时候,后续表格和之前表格空三行
+							rowNum += 3;
+						}
+						Row titleRow = sheet.createRow(rowNum); // 标题行
+						titleRow.setHeight((short) 0x248); // 标题行高
+
+						for (int i = 0; i < headArray.length; i++) {
+							Cell titleCell = titleRow.createCell(i);
+							titleCell.setCellStyle(headStyle);
+							titleCell.setCellValue(title);
+						}
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+						rowNum++;
+					}
+
+					// 设置页头内容(标题下面的一排小文字信息)
+					if (pageHeadArray != null && pageHeadArray.length > 0) {
+						CellStyle pageHeadStyle = getCellStyle(workbook, "", (short) 9, false, HorizontalAlignment.LEFT,
+								VerticalAlignment.CENTER, false);
+						pageHeadStyle.setBorderTop(BorderStyle.NONE);
+						pageHeadStyle.setBorderBottom(BorderStyle.NONE);
+						pageHeadStyle.setBorderLeft(BorderStyle.NONE);
+						pageHeadStyle.setBorderRight(BorderStyle.NONE);
+						for (int i = 0; i < pageHeadArray.length; i++) {
+							Row headRow = sheet.createRow(rowNum); // 表头行
+							headRow.setHeight((short) 0x150); // 表头行高
+							for (int j = 0; j < headArray.length; j++) {
+								Cell titleCell = headRow.createCell(j);
+								titleCell.setCellStyle(pageHeadStyle);
+								titleCell.setCellValue(pageHeadArray[i]);
+							}
+							sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+							rowNum++;
+						}
+					}
+
+					// 设置表头内容
+					Row headRow = sheet.createRow(rowNum); // 表头行
+					headRow.setHeight((short) 0x200); // 表头行高
+					for (int i = 0; i < headArray.length; i++) {
+						Cell cell = headRow.createCell(i);
+						cell.setCellValue(headArray[i]);
+						cell.setCellStyle(headStyle);
+						if (sheetTitle != null && headArray.length == 1) {// 只有一列
+							sheet.setColumnWidth(i, sheetTitle.getBytes().length * 3 * 256);
+						} else {
+							if (null == columnWidthArray) {
+								sheet.setColumnWidth(i, headArray[i].getBytes().length * 2 * 256);
+							} else {
+								sheet.setColumnWidth(i, columnWidthArray.get(headArray[i]) * 256);
+							}
+						}
+
+					}
+					rowNum++;
+
+					for (int i = 0; i < currentData.size(); i++) {
+						Row textRow = sheet.createRow(rowNum);
+						Map<String, String> map = currentData.get(i);
+						int j = 0, maxTextHeight = (short) 0X170;// 0X250; //
+																	// 默认行高,可以放2行数据
+						for (String s : map.keySet()) {
+							Object val = map.get(s);
+							if (val == null) {
+								val = "";
+							}
+
+							Cell cell = textRow.createCell(j);
+							cell.setCellValue(String.valueOf(val));
+							cell.setCellStyle(textStyleCenter);
+
+							// 计算最大的高度值
+							// int len = String.valueOf(val).getBytes().length;
+							// if (len > columnWidthArray[j] + 1) {
+							// int tempHeight = (len / (columnWidthArray[j] - 1)
+							// + 1) * 0X125; // 加入了边框,所以一行放入的字节数会少一个
+							// if (tempHeight > maxTextHeight)
+							// maxTextHeight = tempHeight;
+							// }
+							j++;
+						}
+						// 设置行高
+						textRow.setHeight((short) maxTextHeight);
+						rowNum++;
+					}
+
+					// 设置页脚内容
+					if (pageFooterArray != null && pageFooterArray.length > 0) {
+						CellStyle pageFooterStyle = getCellStyle(workbook, "", (short) 9, false,
+								HorizontalAlignment.CENTER, VerticalAlignment.CENTER, false);
+						pageFooterStyle.setBorderTop(BorderStyle.NONE);
+						for (int i = 0; i < pageFooterArray.length; i++) {
+							Row footerRow = sheet.createRow(rowNum); // 表头行
+							footerRow.setHeight((short) 0x180); // 表头行高
+							for (int j = 0; j < headArray.length; j++) {
+								Cell titleCell = footerRow.createCell(j);
+								titleCell.setCellStyle(pageFooterStyle);
+								titleCell.setCellValue(pageFooterArray[i]);
+							}
+							sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+							rowNum++;
+						}
+					}
+
+				}
+
+				if (fileUrl != null) {
+					File localFile = new File(fileUrl);
+					if (!localFile.exists()) {
+						// 先得到文件的上级目录,并创建上级目录,在创建文件
+						localFile.getParentFile().mkdirs();
+						localFile.createNewFile();
+					}
+					fileOutputStream = new FileOutputStream(localFile);
+					fileOutputStream.flush();
+				} else {
+					fileOutputStream = response.getOutputStream();
+				}
+
+				workbook.write(fileOutputStream);
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				if (null != fileOutputStream) {
+					try {
+						fileOutputStream.close();
+					} catch (IOException e) {
+						System.out.println(e.getMessage());
+					}
+				}
+			}
+			result = true;
+		}
+		return result;
+	}
+
+	/**
+	 * 导出EXCEL文件(多个sheet,单个表格)
+	 *
+	 * @param response
+	 * @param fileName   文件名称
+	 * @param sheetTitle sheet中的大标题(第一行)
+	 * @param dataMap    sheet中的数据集(每个map中细分为多个不同的Object数据) 如:(详见导出班级代码) Map<String,
+	 *                   Object> roomAllMap = new LinkedHashMap<>(); //一个map中,代表一个表格
+	 *                   roomAllMap.put("data", roomList); //此表格中的具体遍历数据
+	 *                   roomAllMap.put("title", "班级学员宿舍信息表");
+	 *                   //表格标题,若为null,且数据集中存在其他map,则下一个map不会空出3行(空出3行,用于划分各个表格)。
+	 *                   roomAllMap.put("head", new String[] { "姓名", "性别", "是否午休",
+	 *                   "是否晚宿" });
+	 *                   //若存在名字相同的,则名字相同且相邻的head合并(当head名字相同,并且某行中的对应的列值也相同,则合并它们)
+	 *                   roomAllMap.put("columnWidth", new Integer[] { 15, 15, 15,
+	 *                   20 }); //
+	 *                   20代表20个字节,10个字符(整个sheet中,只能存在一个columnWidth,因为列宽是针对整个sheet的)
+	 *                   roomAllMap.put("columnAlignment", new Integer[] { 0, 0, 0,
+	 *                   0 }); // 0代表居中,1代表居左,2代表居右 roomAllMap.put("mergeCondition",
+	 *                   null); // 跨行合行列需要的条件,条件优先级按顺序决定,NULL表示不合并,空数组表示无条件
+	 * @param pageSize   每个sheet页的数据量
+	 * @return
+	 * @throws IOException
+	 */
+	public final static boolean exportCommonExcelMultiSheet(HttpServletResponse response, String fileName,
+			String sheetTitle, Map<String, Object> dataMap, int pageSize) throws IOException {
+		HSSFWorkbook workbook = new HSSFWorkbook();
+		boolean result = false;
+		OutputStream fileOutputStream = null;
+		response.reset();// 清空输出流
+		response.setHeader("Content-disposition",
+				"attachment; filename=" + new String((fileName + ".xls").getBytes("GB2312"), "ISO8859-1"));
+		response.setContentType("application/msexcel");
+
+		if (null != dataMap) {
+
+			try {
+				// 计算总页数
+				List<Map<String, String>> currentData = (List<Map<String, String>>) dataMap.get("data");
+
+				// 创建基本的样式
+				CellStyle titleStyle = getCellStyle(workbook, "", (short) 20, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle headStyle = getCellStyle(workbook, "", (short) 9, true, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleCenter = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.CENTER,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleLeft = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.LEFT,
+						VerticalAlignment.CENTER, true);
+				CellStyle textStyleRight = getCellStyle(workbook, "", (short) 8, false, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, true);
+				CellStyle pageSizeStyle = getCellStyle(workbook, "", (short) 9, false, HorizontalAlignment.RIGHT,
+						VerticalAlignment.CENTER, false);
+				pageSizeStyle.setBorderLeft(BorderStyle.NONE);
+				pageSizeStyle.setBorderRight(BorderStyle.NONE);
+				pageSizeStyle.setBorderBottom(BorderStyle.NONE);
+				pageSizeStyle.setBorderTop(BorderStyle.NONE);
+
+				int page = (currentData.size() + pageSize - 1) / pageSize;
+				for (int pageI = 0; pageI < page; pageI++) {
+
+					Sheet sheet = workbook.createSheet("第" + (pageI + 1) + "页");
+
+					int rowNum = 0; // 初始化第一行为0开始计数
+					int colCount = ((String[]) dataMap.get("head")).length;// 表头的列数
+
+					// 第一行先创建一个大标题(当不为null的时候,设置这一行)
+					if (sheetTitle != null) {
+						titleStyle.setBorderTop(BorderStyle.NONE);
+						titleStyle.setBorderBottom(BorderStyle.NONE);
+						titleStyle.setBorderLeft(BorderStyle.NONE);
+						titleStyle.setBorderRight(BorderStyle.NONE);
+
+						Row sheetTitleRow = sheet.createRow(rowNum); // 创建标题行
+						sheetTitleRow.setHeight((short) 0x300); // 设置行高
+						Cell sheetTitleCell = sheetTitleRow.createCell(0); // 创建第一个单元格
+						sheetTitleCell.setCellStyle(titleStyle); // 设置标题的样式
+						sheetTitleCell.setCellValue(sheetTitle); // 给标题格设定值
+						if (colCount != 1) {
+							sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+						}
+						// sheet.addMergedRegion(new CellRangeAddress(rowNum,
+						// rowNum, 0, colCount - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+						rowNum++;
+					}
+
+					String title = (String) dataMap.get("title");
+					String[] headArray = (String[]) dataMap.get("head");
+					Map<String, Integer> columnWidthArray = (Map<String, Integer>) dataMap.get("columnWidth");
+					String[] pageHeadArray = (String[]) dataMap.get("pageHead");
+					String[] pageFooterArray = (String[]) dataMap.get("pageFooter");
+
+					// 设置标题栏内容(当不为null的时候,设置这一行)
+					if (title != null) {
+						if (rowNum > 1) { // 除了第一个表格的时候,后续表格和之前表格空三行
+							rowNum += 3;
+						}
+						Row titleRow = sheet.createRow(rowNum); // 标题行
+						titleRow.setHeight((short) 0x248); // 标题行高
+
+						for (int i = 0; i < headArray.length; i++) {
+							Cell titleCell = titleRow.createCell(i);
+							titleCell.setCellStyle(headStyle);
+							titleCell.setCellValue(title);
+						}
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+						rowNum++;
+					}
+
+					// 设置页头内容(标题下面的一排小文字信息)
+					if (pageHeadArray != null && pageHeadArray.length > 0) {
+						CellStyle pageHeadStyle = getCellStyle(workbook, "", (short) 9, false, HorizontalAlignment.LEFT,
+								VerticalAlignment.CENTER, false);
+						pageHeadStyle.setBorderTop(BorderStyle.NONE);
+						pageHeadStyle.setBorderBottom(BorderStyle.NONE);
+						pageHeadStyle.setBorderLeft(BorderStyle.NONE);
+						pageHeadStyle.setBorderRight(BorderStyle.NONE);
+						for (int i = 0; i < pageHeadArray.length; i++) {
+							Row headRow = sheet.createRow(rowNum); // 表头行
+							headRow.setHeight((short) 0x150); // 表头行高
+							for (int j = 0; j < headArray.length; j++) {
+								Cell titleCell = headRow.createCell(j);
+								titleCell.setCellStyle(pageHeadStyle);
+								titleCell.setCellValue(pageHeadArray[i]);
+							}
+							sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+							rowNum++;
+						}
+					}
+
+					// 设置表头内容
+					Row headRow = sheet.createRow(rowNum); // 表头行
+					headRow.setHeight((short) 0x200); // 表头行高
+					for (int i = 0; i < headArray.length; i++) {
+						Cell cell = headRow.createCell(i);
+						cell.setCellValue(headArray[i]);
+						cell.setCellStyle(headStyle);
+						if (sheetTitle != null && headArray.length == 1) {// 只有一列
+							sheet.setColumnWidth(i, sheetTitle.getBytes().length * 3 * 256);
+						} else {
+							if (null == columnWidthArray) {
+								sheet.setColumnWidth(i, headArray[i].getBytes().length * 2 * 256);
+							} else {
+								sheet.setColumnWidth(i, columnWidthArray.get(headArray[i]) * 256);
+							}
+						}
+
+					}
+					rowNum++;
+
+					// 处理数据
+					for (int pageJ = pageSize * pageI; pageJ < (pageI + 1) * pageSize
+							&& pageJ < currentData.size(); pageJ++) {
+
+						Row textRow = sheet.createRow(rowNum);
+						Map<String, String> map = currentData.get(pageJ);
+						int j = 0, maxTextHeight = (short) 0X170;// 0X250;//
+																	// 默认行高,可以放2行数据
+
+						for (String s : map.keySet()) {
+							Object val = map.get(s);
+							if (val == null) {
+								val = "";
+							}
+
+							Cell cell = textRow.createCell(j);
+							cell.setCellValue(String.valueOf(val));
+							cell.setCellStyle(textStyleCenter);
+
+							// 计算最大的高度值
+							// int len =
+							// String.valueOf(val).getBytes().length;
+							// if (len > columnWidthArray[j] + 1) {
+							// int tempHeight = (len / (columnWidthArray[j]
+							// - 1)
+							// + 1) * 0X125; // 加入了边框,所以一行放入的字节数会少一个
+							// if (tempHeight > maxTextHeight)
+							// maxTextHeight = tempHeight;
+							// }
+							j++;
+						}
+						// 设置行高
+						textRow.setHeight((short) maxTextHeight);
+						rowNum++;
+					}
+
+					// 设置页脚内容
+					if (pageFooterArray != null && pageFooterArray.length > 0) {
+
+						// 当最后一页时,才输出统计信息
+						if (pageI + 1 == page) {
+							CellStyle pageFooterStyle = getCellStyle(workbook, "", (short) 9, false,
+									HorizontalAlignment.LEFT, VerticalAlignment.CENTER, false);
+							pageFooterStyle.setBorderTop(BorderStyle.NONE);
+							for (int i = 0; i < pageFooterArray.length; i++) {
+								Row footerRow = sheet.createRow(rowNum); // 页脚行
+								footerRow.setHeight((short) 0x180); // 行高
+								for (int j = 0; j < headArray.length; j++) {
+									Cell titleCell = footerRow.createCell(j);
+									titleCell.setCellStyle(pageFooterStyle);
+									titleCell.setCellValue(pageFooterArray[i]);
+								}
+								// 合并统计列
+								sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1));
+								rowNum++;
+							}
+						}
+					}
+
+					// 显示页数
+					Row footerRow = sheet.createRow(rowNum); // 页脚行
+					footerRow.setHeight((short) 0x180); // 行高
+					Cell pageCell = footerRow.createCell(0); // 创建单元格
+					pageCell.setCellStyle(pageSizeStyle); // 样式
+					pageCell.setCellValue("第" + (pageI + 1) + "页 - 共" + page + "页 "); // 值
+					if (colCount != 1) {
+						sheet.addMergedRegion(new CellRangeAddress(rowNum, rowNum, 0, headArray.length - 1)); // 合并单元格(起始行,结束行,起始列,结束列)
+					}
+					rowNum++;
+				}
+
+				fileOutputStream = response.getOutputStream();
+				workbook.write(fileOutputStream);
+			} catch (IOException e) {
+				System.out.println(e.getMessage());
+				return false;
+			} catch (Exception e) {
+				System.out.println(e.getMessage());
+				return false;
+			} finally {
+				if (null != fileOutputStream) {
+					try {
+						fileOutputStream.close();
+					} catch (IOException e) {
+						System.out.println(e.getMessage());
+					}
+				}
+			}
+			result = true;
+		}
+		return result;
+	}
+	
+	/*
+	 * 获取导出数据的方法
+	 *
+	 * @param exportField 需要导出的字段
+	 *
+	 * @param exportList 查询的结果集
+	 *
+	 */
+	public static List<Map<String, Object>> getDataList(String exportField, List<?> exportList,
+			List<Map<String, Object>> listMapDicItem) {
+
+		// 最终导出的数据
+		List<Map<String, Object>> allList = new ArrayList<>();
+
+		String[] exportFields = exportField.split(",");
+
+		Map<Integer, String> filedTitleMap = new TreeMap<Integer, String>();// 存放字段
+		Map<Integer, String> titleMap = new TreeMap<Integer, String>();// 存放名字
+		Map<String, Integer> widthMap = new TreeMap<String, Integer>();// 存放列宽
+		for (int i = 0; i < exportFields.length; i++) {
+			filedTitleMap.put(i, exportFields[i]);
+		}
+		Collection<String> values = filedTitleMap.values();
+		String[] s = new String[values.size()];
+		values.toArray(s);
+
+		// 处理基本数据
+		Map<String, String> dataMap = null;
+		List<Map<String, String>> dataList = new ArrayList<>();
+		if (null != exportList && !exportList.isEmpty()) {
+			Object test = exportList.get(0);
+			Map<String, Field> fieldMap = new HashMap<String, Field>();
+			Map<String, String> titleNameMap = new HashMap<String, String>();
+			Map<String, Integer> widthNameMap = new TreeMap<String, Integer>();// 存放列宽
+			// Field[] fields = test.getClass().getDeclaredFields();
+			Field[] fields = ModelUtil.getClassFields(test.getClass(), false);
+			int k = 0;
+			for (Field field : fields) {
+				if (field.isAnnotationPresent(FieldInfo.class)) {
+					FieldInfo mapperCell = field.getAnnotation(FieldInfo.class);
+					fieldMap.put(field.getName(), field);
+					filedTitleMap.put(k, field.getName());
+					titleNameMap.put(field.getName(), mapperCell.explain());
+					// widthMap.put(mapperCell.cellName(),
+					// mapperCell.cellWidth());
+					widthNameMap.put(mapperCell.explain(), 10);
+					k++;
+				}
+			}
+
+			// 存放基础数据
+			for (int i = 0; i < exportList.size(); i++) {
+				dataMap = new LinkedHashMap<>();
+				for (int j = 0; j < s.length; j++) {
+					for (Map.Entry<String, Field> data : fieldMap.entrySet()) {
+						if (data.getKey().equals(s[j])) {
+							Field field = data.getValue();
+							field.setAccessible(true);
+							titleMap.put(j, titleNameMap.get(s[j]));
+							String str = titleNameMap.get(s[j]);
+							widthMap.put(titleNameMap.get(s[j]), widthNameMap.get(titleNameMap.get(s[j])));
+							String value = "";
+
+							try {
+								if (field.getGenericType().toString().equals("class java.util.Date")) {
+									Date time = (Date) field.get(exportList.get(i));
+									value = field.get(exportList.get(i)) != null
+											? DateUtil.formatDateTime(time).toString()
+											: "";
+								} else if (field.getGenericType().toString().equals("class java.lang.Boolean")) {
+									Boolean bool = (Boolean) field.get(exportList.get(i));
+									value = bool != null && bool == true ? "是" : "否";
+								} else {
+									value = field.get(exportList.get(i)) != null
+											? field.get(exportList.get(i)).toString()
+											: "";
+								}
+								//
+							} catch (IllegalArgumentException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							} catch (IllegalAccessException e) {
+								// TODO Auto-generated catch block
+								e.printStackTrace();
+							}
+							if (null != listMapDicItem) {
+								for (int ss = 0; ss < listMapDicItem.size(); ss++) {
+									if (null != listMapDicItem.get(ss).get(s[j])) {
+										Map<String, String> mapDicItem = (Map<String, String>) listMapDicItem.get(ss)
+												.get(s[j]);
+										value = mapDicItem.get(value);
+									}
+								}
+							}
+
+							dataMap.put(s[j], value);
+						}
+					}
+				}
+				dataList.add(dataMap);
+			}
+		}
+
+		values = titleMap.values();
+		s = new String[values.size()];
+		values.toArray(s);
+
+		Map<String, Object> dataAllMap = new LinkedHashMap<>();
+		dataAllMap.put("data", dataList);
+		dataAllMap.put("head", s);
+		dataAllMap.put("columnWidth", widthMap);
+		allList.add(dataAllMap);
+		return allList;
+	}
+
+	
+}
diff --git a/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiImportExcel.java b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiImportExcel.java
new file mode 100644
index 0000000..f73ff68
--- /dev/null
+++ b/febs-server/febs-server-hr/src/main/java/cc/mrbird/febs/server/hr/util/PoiImportExcel.java
@@ -0,0 +1,190 @@
+package cc.mrbird.febs.server.hr.util;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+import org.apache.poi.hssf.usermodel.HSSFDataFormat;
+import org.apache.poi.hssf.usermodel.HSSFDateUtil;
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+
+public class PoiImportExcel {
+
+	private final static String excel2003L = ".xls"; // 2003- 版本的excel
+	private final static String excel2007U = ".xlsx"; // 2007+ 版本的excel
+
+	/**
+	 * 描述:获取IO流中的数据,组装成List<List<Object>>对象
+	 * 
+	 * @param in,fileName
+	 * @return
+	 * @throws IOException
+	 */
+	public static List<List<Object>> getListByExcel(InputStream in, String fileName) throws Exception {
+		List<List<Object>> list = null;
+
+		// 创建Excel工作薄
+		Workbook work = getWorkbook(in, fileName);
+		if (null == work) {
+			throw new Exception("创建Excel工作薄为空!");
+		}
+		Sheet sheet = null;
+		Row row = null;
+		Cell cell = null;
+
+		list = new ArrayList<List<Object>>();
+		// 直接获取第一个sheet
+		sheet = work.getSheetAt(0);
+		if (sheet == null) {
+			return list;
+		}
+		// 取得Excel的总列数,总行数
+		int columns = 0;
+		Row firstRow = sheet.getRow((short) 0);
+		if (firstRow != null) {
+			columns = firstRow.getPhysicalNumberOfCells();
+		}
+
+		int rows = sheet.getPhysicalNumberOfRows();
+		List<Object> dataRow = null;
+
+		// 首行为定义标题的行,数据从第2行开始
+		for (int i = 1; i < rows; i++) {
+			dataRow = new ArrayList<Object>();
+			// 获取行
+			row = sheet.getRow(i);
+			if (row != null) {
+				// columns=row.getPhysicalNumberOfCells();//不在这里设置,通过firstRow来获取列数信息。
+				for (int j = 0; j < columns; j++) {
+					// 获取某行某列的某一个单元格
+					cell = row.getCell(j);
+					// 往dataRow存值
+					dataRow.add(getCellValue(cell));
+				}
+				list.add(dataRow);
+			} else {
+				list.add(new ArrayList<>());
+			}
+		}
+
+		// 遍历当前sheet中的所有行
+		/*
+		 * int countCellNum = 0; for (int j = sheet.getFirstRowNum(); j <=
+		 * sheet.getLastRowNum(); j++) { row = sheet.getRow(j); if (row == null
+		 * || row.getFirstCellNum() == j) { if (row != null) countCellNum =
+		 * row.getLastCellNum(); continue; }
+		 * 
+		 * // 遍历所有的列 List<Object> li = new ArrayList<Object>(); for (int y = row
+		 * .getFirstCellNum(); y <= countCellNum; y++) { cell = row.getCell(y);
+		 * li.add(this.getCellValue(cell));
+		 * 
+		 * } list.add(li); }
+		 */
+
+		work.close();
+		return list;
+	}
+
+	/**
+	 * 描述:根据文件后缀,自适应上传文件的版本
+	 * 
+	 * @param inStr,fileName
+	 * @return
+	 * @throws Exception
+	 */
+	public static Workbook getWorkbook(InputStream inStr, String fileName) throws Exception {
+		Workbook wb = null;
+		String fileType = fileName.substring(fileName.lastIndexOf("."));
+		if (excel2003L.equals(fileType)) {
+			wb = new HSSFWorkbook(inStr); // 2003-
+		} else if (excel2007U.equals(fileType)) {
+			wb = new XSSFWorkbook(inStr); // 2007+
+		} else {
+			throw new Exception("解析的文件格式有误!");
+		}
+		return wb;
+	}
+
+	/**
+	 * 描述:对表格中数值进行格式化
+	 * 
+	 * @param cell
+	 * @return
+	 */
+	@SuppressWarnings("deprecation")
+	public static Object getCellValue(Cell cell) {
+		try {
+			Object value = null;
+
+			if (cell == null) {
+				value = "";
+				return value;
+			}
+
+			DecimalFormat df = new DecimalFormat("0"); // 格式化number String字符
+			SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 日期格式化
+			DecimalFormat df2 = new DecimalFormat("0.00"); // 格式化数字
+
+			switch (cell.getCellType()) {
+			case Cell.CELL_TYPE_STRING:
+				value = cell.getRichStringCellValue().getString();
+				break;
+			case Cell.CELL_TYPE_NUMERIC:
+				if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
+
+					if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm")
+							|| cell.getCellStyle().getDataFormat() == 176) {
+						sdf = new SimpleDateFormat("HH:mm");
+					}
+					Date date = cell.getDateCellValue();
+					value = sdf.format(date);
+
+				} else if (cell.getCellStyle().getDataFormat() == 58) {
+					// 处理自定义日期格式:m月d日(通过判断单元格的格式id解决,id的值是58)
+					SimpleDateFormat sdf2 = new SimpleDateFormat("MM-dd");
+					double cellValue = cell.getNumericCellValue();
+					Date date = org.apache.poi.ss.usermodel.DateUtil.getJavaDate(cellValue);
+					value = sdf2.format(date);
+				} else if (cell.getCellStyle().getDataFormat() == 183 || cell.getCellStyle().getDataFormat() == 177
+						|| cell.getCellStyle().getDataFormat() == 181) {
+					// 处理自定义日期格式:y年m月d日(通过判断单元格的格式id解决,id的值是183)
+					SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd");
+					Date date = cell.getDateCellValue();
+					value = sdf2.format(date);
+				} else {
+					if ("General".equals(cell.getCellStyle().getDataFormatString())) {
+						value = df.format(cell.getNumericCellValue());
+					} else {
+						value = df2.format(cell.getNumericCellValue());
+					}
+				}
+
+				break;
+			case Cell.CELL_TYPE_BOOLEAN:
+				value = cell.getBooleanCellValue();
+				break;
+			case Cell.CELL_TYPE_BLANK:
+				value = "";
+				break;
+			default:
+				value = cell.getStringCellValue();
+				break;
+			}
+			return value;
+
+		} catch (Exception e) {
+			return null;
+		}
+
+	}
+
+}
\ No newline at end of file
diff --git a/febs-server/febs-server-hr/src/main/resources/febs-server-hr.properties b/febs-server/febs-server-hr/src/main/resources/febs-server-hr.properties
index 157fb3c..47377c8 100644
--- a/febs-server/febs-server-hr/src/main/resources/febs-server-hr.properties
+++ b/febs-server/febs-server-hr/src/main/resources/febs-server-hr.properties
@@ -1,2 +1,2 @@
-# 批量插入单次最大值,比如配置为1000,那么数据库插入1000条数据commit一次
-febs.server.hr.uploadPpath=C:/upload/hr/
+febs.server.hr.uploadCommonPath=C:/upload/hr/commonfile/
+febs.server.hr.uploadSinglePath=C:/upload/hr/singlefile/

--
Gitblit v1.8.0