Переглянути джерело

修改分摊数据和成本核算

zhouyy 5 місяців тому
батько
коміт
8830ea51d1
18 змінених файлів з 884 додано та 32 видалено
  1. 6 3
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceController.java
  2. 43 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceExcludeProjectController.java
  3. 61 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/FinanceExcludeProject.java
  4. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/AddOrUpdateFinanceExcludeProjectBO.java
  5. 11 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceExcludeProjectMapper.java
  6. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceMapper.java
  7. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceProjectsMapper.java
  8. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  9. 4 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelExportService.java
  10. 15 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceExcludeProjectService.java
  11. 2 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceService.java
  12. 203 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  13. 133 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceExcludeProjectServiceImpl.java
  14. 47 10
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java
  15. 282 12
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java
  16. 13 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceExcludeProjectMapper.xml
  17. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceProjectsMapper.xml
  18. 29 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

+ 6 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceController.java

@@ -2,7 +2,10 @@ package com.management.platform.controller;
 
 
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.management.platform.entity.*;
+import com.management.platform.entity.Company;
+import com.management.platform.entity.FinanceFixedcolname;
+import com.management.platform.entity.FinanceTblcuscol;
+import com.management.platform.entity.TimeType;
 import com.management.platform.mapper.CompanyMapper;
 import com.management.platform.mapper.FinanceTblcuscolMapper;
 import com.management.platform.mapper.TimeTypeMapper;
@@ -10,7 +13,6 @@ import com.management.platform.mapper.WxCorpInfoMapper;
 import com.management.platform.service.ExcelExportService;
 import com.management.platform.service.FinanceFixedcolnameService;
 import com.management.platform.service.FinanceService;
-import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
 import com.management.platform.util.UserNotFoundException;
@@ -100,8 +102,9 @@ public class FinanceController {
     //导出分摊数据
     @RequestMapping("/exportData")
     public HttpRespMsg exportData(@RequestParam(required = false, defaultValue = "0") Integer groupByCategory,
+                                  @RequestParam(defaultValue = "0")Integer onlyTotal,
                                   @RequestParam String date, Boolean assignNoProUser,HttpServletRequest request) {
-        return financeService.exportData(groupByCategory, date, assignNoProUser, request);
+        return financeService.exportData(groupByCategory,onlyTotal, date, assignNoProUser, request);
     }
 
     /**

+ 43 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/FinanceExcludeProjectController.java

@@ -0,0 +1,43 @@
+package com.management.platform.controller;
+
+import com.management.platform.entity.bo.AddOrUpdateFinanceExcludeProjectBO;
+import com.management.platform.service.FinanceExcludeProjectService;
+import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+
+@RestController
+@RequestMapping("/financeExcludeProject")
+public class FinanceExcludeProjectController {
+
+    @Resource
+    private FinanceExcludeProjectService financeExcludeProjectService;
+
+    @GetMapping("/getProjects")
+    public HttpRespMsg getProjects(@RequestParam(value = "useYM")String useYM, HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = financeExcludeProjectService.getProjects(useYM,request);
+        } catch (Exception e) {e.printStackTrace();
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+        return msg;
+    }
+
+    @PostMapping("/addOrUpdateProjects")
+    public HttpRespMsg addProjects(AddOrUpdateFinanceExcludeProjectBO addBO, HttpServletRequest request){
+        HttpRespMsg msg = new HttpRespMsg();
+        try {
+            msg = financeExcludeProjectService.addOrUpdateProjects(addBO,request);
+        } catch (Exception e) {e.printStackTrace();
+            msg.setError(MessageUtils.message("other.error"));
+            return msg;
+        }
+        return msg;
+    }
+
+}

+ 61 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/FinanceExcludeProject.java

@@ -0,0 +1,61 @@
+package com.management.platform.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.Pattern;
+import java.time.LocalDateTime;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+public class FinanceExcludeProject extends Model<FinanceExcludeProject> {
+    private static final long serialVersionUID=1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    /**项目id*/
+    @TableField("project_id")
+    private Integer projectId;
+
+    /**
+     * 公司表外键
+     */
+    @TableField("company_id")
+    private Integer companyId;
+
+    /**
+     * 创建人id
+     */
+    @TableField("create_by")
+    private String createBy;
+
+
+    /**
+     * 创建日期
+     */
+    @TableField("create_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;
+
+    /**
+     * 年月
+     * */
+    @TableField("use_ym")
+    @NotBlank(message = "年月不能为空")
+    @Pattern(regexp = "^[0-9]{4}-[0-9]{2}$",message = "年月格式错误")
+    private String useYM;
+}

+ 16 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/bo/AddOrUpdateFinanceExcludeProjectBO.java

@@ -0,0 +1,16 @@
+package com.management.platform.entity.bo;
+
+import lombok.Data;
+
+@Data
+public class AddOrUpdateFinanceExcludeProjectBO {
+//    @NotEmpty(message = "项目不能为空")
+    private String[] projects;
+
+//    @NotBlank(message = "年月不能为空")
+//    @Pattern(regexp = "^[0-9]{4}-[0-9]{2}$",message = "年月格式错误")
+    private String useYM;
+
+    /**0非全部 1是全部*/
+    private int isAll;
+}

+ 11 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceExcludeProjectMapper.java

@@ -0,0 +1,11 @@
+package com.management.platform.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.FinanceExcludeProject;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+public interface FinanceExcludeProjectMapper extends BaseMapper<FinanceExcludeProject> {
+    void batchInsert(@Param("projects") List<FinanceExcludeProject> projects);
+}

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceMapper.java

@@ -1,7 +1,7 @@
 package com.management.platform.mapper;
 
-import com.management.platform.entity.Finance;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.Finance;
 
 /**
  * <p>

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/FinanceProjectsMapper.java

@@ -2,6 +2,9 @@ package com.management.platform.mapper;
 
 import com.management.platform.entity.FinanceProjects;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +16,5 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface FinanceProjectsMapper extends BaseMapper<FinanceProjects> {
 
+    List<FinanceProjects> getExcludeFinanceProjects(@Param("companyId") Integer companyId, @Param("yearMonth") String yearMonth);
 }

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -124,6 +124,8 @@ public interface ReportMapper extends BaseMapper<Report> {
 
     List<Map<String, Object>> getRealProjectTime(@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate, Integer companyId);
 
+    List<Map<String, Object>> getRealProjectTimeNew(@Param("ym")String ym,@Param("startDate") LocalDate startDate, @Param("endDate") LocalDate endDate, Integer companyId);
+
     List<Map<String, Object>> getReportFillStatus(String startDate, String endDate, String userId);
 
     List<Map<String, Object>> getDepartmentDetailByState(@Param("departmentIds") List<Integer> departmentIds,
@@ -133,6 +135,8 @@ public interface ReportMapper extends BaseMapper<Report> {
 
     List<Map<String, Object>> getUserWorkingTimeByRange(Integer companyId, String startDate, String endDate);
 
+    List<Map<String, Object>> getUserWorkingTimeByRangeWithExclude(Integer companyId,String yearMonth, String startDate, String endDate);
+
     List<Report> selectSimpleTime(Integer companyId, String startDate, String endDate);
 
     List<Map<String, Object>> getDeptImportAuditList(@Param("companyId") Integer companyId,

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelExportService.java

@@ -16,4 +16,8 @@ public interface ExcelExportService {
     public HttpRespMsg exportTranForwx(WxCorpInfo wxCorpInfo, CompanyDingding dingding,String title) throws Exception;
     void testAdd(String jobId);
     HttpRespMsg exportGeneralExcelForExpense(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String fileName, List<List<String>> allList, List<Map> mapList, String path) throws Exception;
+
+    HttpRespMsg exportMultiSheetGeneralExcelTotal(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>>[] multiSheetList, String downloadPath, String[] sheetsName) throws Exception;
+
+    HttpRespMsg exportGeneralExcelTotal(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String fileName, List<List<String>> allList, String path) throws Exception ;
 }

+ 15 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceExcludeProjectService.java

@@ -0,0 +1,15 @@
+package com.management.platform.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.FinanceExcludeProject;
+import com.management.platform.entity.bo.AddOrUpdateFinanceExcludeProjectBO;
+import com.management.platform.util.HttpRespMsg;
+
+import javax.servlet.http.HttpServletRequest;
+
+public interface FinanceExcludeProjectService extends IService<FinanceExcludeProject> {
+    HttpRespMsg getProjects(String useYM, HttpServletRequest request);
+
+    HttpRespMsg addOrUpdateProjects(AddOrUpdateFinanceExcludeProjectBO addBO, HttpServletRequest request);
+
+}

+ 2 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/FinanceService.java

@@ -1,14 +1,11 @@
 package com.management.platform.service;
 
-import com.management.platform.entity.Finance;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.management.platform.entity.Finance;
 import com.management.platform.util.HttpRespMsg;
-import com.management.platform.util.UserNotFoundException;
-import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
-import java.io.IOException;
 
 /**
  * <p>
@@ -24,7 +21,7 @@ public interface FinanceService extends IService<Finance> {
 
     HttpRespMsg importData(Integer companyId, String yearMonth, Boolean syncUserCost, Boolean syncHistoryReport, MultipartFile multipartFile, HttpServletRequest request) throws Exception;
 
-    HttpRespMsg exportData(Integer groupByCategory, String date, Boolean assignNoProUser, HttpServletRequest request);
+    HttpRespMsg exportData(Integer groupByCategory,Integer onlyTotal, String date, Boolean assignNoProUser, HttpServletRequest request);
 
     HttpRespMsg getTimeCost(String yearMonth, Boolean assignNoProUser, HttpServletRequest request);
 

+ 203 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java

@@ -70,6 +70,132 @@ public class ExcelExportServiceImpl implements ExcelExportService {
         }
     }
 
+    @Override
+    public HttpRespMsg exportGeneralExcelTotal(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>> list, String downloadPath) throws Exception {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        if (title.contains("/")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("/", "@");
+        }
+        if (title.contains("\\")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("\\", "@");
+        }
+        String resp = ExcelUtil.exportGeneralExcelTotal(title, list, downloadPath);
+        String fileUrlSuffix = title + ".xlsx";
+        if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
+            FileSystemResource fileSystemResource = new FileSystemResource(path+fileUrlSuffix);
+//            String md5 = DigestUtils.md5Hex(FileUtil.readBytes(fileSystemResource.getFile()));
+
+            Long checkSize = 20L*1024*1024;
+            if(fileSystemResource.getFile().length() >= checkSize){
+                httpRespMsg.setError("文件过大,请缩短查询日期范围");
+                return httpRespMsg;
+            }
+            String jobId = "";
+            String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
+            jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+//            if(fileSystemResource.getFile().length() >= checkSize){
+//                String tmpFileJobId = wxCorpInfoService.getTranslationJobId(fileUrlSuffix,md5,wxCorpInfo);
+//                if(!StringUtils.isEmpty(tmpFileJobId)){
+//                    String mediaId = wxCorpInfoService.getAsyncJobResult(tmpFileJobId,wxCorpInfo);
+//                    jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+//                }
+//            }else{
+//                String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
+//                jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+//            }
+
+            System.out.println("上传待转译文件到企业微信, jobId==" + jobId);
+//            if(StringUtils.isEmpty(jobId)){
+//                httpRespMsg.setError("转义jobId为空,请联系管理员");
+//                return httpRespMsg;
+//            }
+            int i = 0;
+            String syncTranslationResult = null;
+            /**
+             * 异步上传转译文件的任务完成时会触发回调,在WeiXinCorpController中的commonDevCallbackPost实现了对回调的处理,存储到corpwxJobResult表中
+             * 此处轮询查询本地数据库,检测到有任务的回调数据时继续执行查询操作
+             */
+            long t = System.currentTimeMillis();
+            while (i < 40) {
+                if (i < 10) {
+                    Thread.sleep(300);
+                } else if (i < 20){
+                    Thread.sleep(1000);
+                } else {
+                    Thread.sleep(3000);
+                }
+                System.out.println("i=="+i+", "+LocalDateTime.now());
+                CorpwxJobResult corpwxJobResult = corpwxJobCenter.get(jobId);
+                if (corpwxJobResult != null) {
+                    if (corpwxJobResult.getErrCode() == 0) {
+                        syncTranslationResult = wxCorpInfoService.getSyncTranslationResult(jobId);
+                        corpwxJobCenter.remove(jobId);
+                    } else {
+                        long t2 = System.currentTimeMillis();
+                        System.out.println("222企业微信转译报错:"+corpwxJobResult.getErrMsg()+",耗时:" + (t2 - t) + "ms");
+                        httpRespMsg.setError(corpwxJobResult.getErrMsg());
+                        return httpRespMsg;
+                    }
+                    break;
+                }
+                i++;
+            }
+            if (syncTranslationResult != null) {
+                long t2 = System.currentTimeMillis();
+                System.out.println("企业微信转译文件后地址是:"+syncTranslationResult+",耗时:" + (t2 - t) + "ms");
+                httpRespMsg.data = syncTranslationResult;
+            } else {
+                //httpRespMsg.setError("处理超时...");
+                httpRespMsg.setError(MessageUtils.message("request.outTime"));
+            }
+        }else if(dingding != null && dingding.getContactNeedTranslate() == 1){
+            User user = userMapper.selectById(request.getHeader("token"));
+            String mediaId = dingDingService.getTranslationMediaId(fileUrlSuffix,dingding);
+            String jobId = dingDingService.syncTranslation(mediaId,fileUrlSuffix, user.getDingdingUnionid(),dingding);
+            System.out.println("上传待转译文件到钉钉, jobId==" + jobId);
+            int i = 0;
+            String syncTranslationResult = null;
+            /**
+             * 异步上传转译文件的任务完成时会触发回调,在DingDingController中的callback实现了对回调的处理,存储到corpddJobCenter缓存中
+             * 此处轮询查询本地数据库,检测到有任务的回调数据时继续执行查询操作
+             */
+            long t = System.currentTimeMillis();
+            while (i < 30) {
+                if (i < 10) {
+                    Thread.sleep(300);
+                } else if (i < 20){
+                    Thread.sleep(1000);
+                } else {
+                    Thread.sleep(3000);
+                }
+                System.out.println("i=="+i+", "+LocalDateTime.now());
+                Integer status = corpddJobCenter.get(jobId);
+                if (status != null) {
+                    if (status == 1) {
+                        syncTranslationResult = dingDingService.getSyncTranslationResult(jobId,dingding);
+                        corpddJobCenter.remove(jobId);
+                    }
+                    break;
+                }
+                i++;
+            }
+            if (syncTranslationResult != null) {
+                long t2 = System.currentTimeMillis();
+                System.out.println("钉钉转译文件后地址是:"+syncTranslationResult+",耗时:" + (t2 - t) + "ms");
+                httpRespMsg.data = syncTranslationResult;
+            } else {
+                //httpRespMsg.setError("处理超时...");
+                httpRespMsg.setError(MessageUtils.message("request.outTime"));
+            }
+        }else {
+            httpRespMsg.data = resp;
+        }
+        return httpRespMsg;
+    }
+
+
     public HttpRespMsg exportGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>> list, String downloadPath) throws Exception {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         if (title.contains("/")) {
@@ -448,6 +574,83 @@ public class ExcelExportServiceImpl implements ExcelExportService {
         return httpRespMsg;
     }
 
+    @Override
+    public  HttpRespMsg exportMultiSheetGeneralExcelTotal(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>>[] multiSheetList, String downloadPath, String[] sheetsName) throws Exception {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String resp = ExcelUtil.exportMultiSheetGeneralExcelTotal(title,multiSheetList, downloadPath,sheetsName);
+        if (title.contains("/")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("/", "@");
+        }
+        if (title.contains("\\")) {
+            //文件名不能含有路径,得替换掉
+            title = title.replace("\\", "@");
+        }
+        String fileUrlSuffix = title + ".xlsx";
+        if(wxCorpInfo != null && wxCorpInfo.getSaasSyncContact() == 1){
+            String mediaId = wxCorpInfoService.getTranslationMediaId(fileUrlSuffix);
+            String jobId = wxCorpInfoService.syncTranslation(wxCorpInfo.getCorpid(),mediaId,fileUrlSuffix, null);
+            int i = 0;
+            String syncTranslationResult = null;
+            /**
+             * 异步上传转译文件的任务完成时会触发回调,在WeiXinCorpController中的commonDevCallbackPost实现了对回调的处理,存储到corpwxJobResult表中
+             * 此处轮询查询本地数据库,检测到有任务的回调数据时继续执行查询操作
+             */
+            while (i < 10) {
+                Thread.sleep(300);
+                CorpwxJobResult corpwxJobResult = corpwxJobCenter.get(jobId);
+                if (corpwxJobResult != null) {
+                    if (corpwxJobResult.getErrCode() == 0) {
+                        syncTranslationResult = wxCorpInfoService.getSyncTranslationResult(jobId);
+                        corpwxJobCenter.remove(jobId);
+                    } else {
+                        httpRespMsg.setError(corpwxJobResult.getErrMsg());
+                        return httpRespMsg;
+                    }
+                    break;
+                }
+                i++;
+            }
+            if (syncTranslationResult != null) {
+                httpRespMsg.data = syncTranslationResult;
+            } else {
+                //httpRespMsg.setError("处理超时...");
+                httpRespMsg.setError(MessageUtils.message("request.outTime"));
+            }
+        }else if(dingding != null && dingding.getContactNeedTranslate() == 1){
+            User user = userMapper.selectById(request.getHeader("token"));
+            String mediaId = dingDingService.getTranslationMediaId(fileUrlSuffix,dingding);
+            String jobId = dingDingService.syncTranslation(mediaId,fileUrlSuffix,user.getDingdingUnionid(), dingding);
+            int i = 0;
+            String syncTranslationResult = null;
+            /**
+             * 异步上传转译文件的任务完成时会触发回调,在DingDingController中的callback实现了对回调的处理,存储到corpddJobCenter缓存中
+             * 此处轮询查询本地数据库,检测到有任务的回调数据时继续执行查询操作
+             */
+            while (i < 10) {
+                Thread.sleep(300);
+                Integer status = corpddJobCenter.get(jobId);
+                if (status != null) {
+                    if (status == 1) {
+                        syncTranslationResult = dingDingService.getSyncTranslationResult(jobId,dingding);
+                        corpddJobCenter.remove(jobId);
+                    }
+                    break;
+                }
+                i++;
+            }
+            if (syncTranslationResult != null) {
+                httpRespMsg.data = syncTranslationResult;
+            } else {
+                //httpRespMsg.setError("处理超时...");
+                httpRespMsg.setError(MessageUtils.message("request.outTime"));
+            }
+        }else {
+            httpRespMsg.data = resp;
+        }
+        return httpRespMsg;
+    }
+
 
     public  HttpRespMsg exportMultiSheetGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, CompanyDingding dingding,String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) throws Exception {
         HttpRespMsg httpRespMsg = new HttpRespMsg();

+ 133 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceExcludeProjectServiceImpl.java

@@ -0,0 +1,133 @@
+package com.management.platform.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.management.platform.entity.FinanceExcludeProject;
+import com.management.platform.entity.Project;
+import com.management.platform.entity.User;
+import com.management.platform.entity.bo.AddOrUpdateFinanceExcludeProjectBO;
+import com.management.platform.mapper.FinanceExcludeProjectMapper;
+import com.management.platform.mapper.ProjectMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.service.FinanceExcludeProjectService;
+import com.management.platform.util.HttpRespMsg;
+import org.apache.commons.collections.CollectionUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+
+@Service
+public class FinanceExcludeProjectServiceImpl extends ServiceImpl<FinanceExcludeProjectMapper, FinanceExcludeProject> implements FinanceExcludeProjectService {
+
+    @Resource
+    private FinanceExcludeProjectMapper financeExcludeProjectMapper;
+
+    @Resource
+    private UserMapper userMapper;
+
+    @Resource
+    private ProjectMapper projectMapper;
+
+
+    public static final String DATE_TIME_FORMAT = "^[0-9]{4}-[0-9]{2}$";
+
+    public static final Pattern DATE_TIME_CHECK = Pattern.compile(DATE_TIME_FORMAT);
+
+    @Override
+    public HttpRespMsg getProjects(String useYM, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        Map<String,Object> map = new HashMap<>();
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            httpRespMsg.setError("登录凭证有误,请联系管理员");
+            return httpRespMsg;
+        }
+        Matcher matcher = DATE_TIME_CHECK.matcher(useYM);
+        boolean res = matcher.find();
+        if(!res){
+            httpRespMsg.setError("年月格式错误");
+            return httpRespMsg;
+        }
+        Integer projectCount = projectMapper.selectCount(new LambdaQueryWrapper<Project>()
+                .eq(Project::getCompanyId, user.getCompanyId()));
+
+        List<FinanceExcludeProject> resList = financeExcludeProjectMapper
+                .selectList(new LambdaQueryWrapper<FinanceExcludeProject>().eq(FinanceExcludeProject::getUseYM,useYM));
+        if(projectCount == resList.size()){
+            map.put("isAll",1);
+        }else{
+            map.put("isAll",0);
+        }
+        map.put("projectList",resList);
+        httpRespMsg.setData(map);
+        return httpRespMsg;
+    }
+
+    @Override
+    @Transactional
+    public HttpRespMsg addOrUpdateProjects(AddOrUpdateFinanceExcludeProjectBO addBO, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        User user = userMapper.selectById(request.getHeader("TOKEN"));
+        if(null ==user){
+            httpRespMsg.setError("登录凭证有误,请联系管理员");
+            return httpRespMsg;
+        }
+        if(null == addBO.getUseYM()){
+            httpRespMsg.setError("年月不能为空");
+            return httpRespMsg;
+        }
+        Matcher matcher = DATE_TIME_CHECK.matcher(addBO.getUseYM());
+        boolean res = matcher.find();
+        if(!res){
+            httpRespMsg.setError("年月格式错误");
+            return httpRespMsg;
+        }
+        List<FinanceExcludeProject> resList = new ArrayList<>();
+        if(1==addBO.getIsAll()){
+            List<Project> allProjects = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()));
+            List<FinanceExcludeProject> collect = allProjects.stream().map(t -> {
+                FinanceExcludeProject excludeProject = new FinanceExcludeProject();
+                excludeProject.setProjectId(t.getId());
+                excludeProject.setCompanyId(user.getCompanyId());
+                excludeProject.setCreateBy(user.getId());
+                excludeProject.setUseYM(addBO.getUseYM());
+                return excludeProject;
+            }).collect(Collectors.toList());
+            resList = collect;
+        }else{
+//            if(null == addBO.getProjects() || addBO.getProjects().length <=0){
+//                httpRespMsg.setError("项目不能为空");
+//                return httpRespMsg;
+//            }
+            if(null != addBO.getProjects()){
+                for (int i = 0; i < addBO.getProjects().length; i++) {
+                    FinanceExcludeProject excludeProject = new FinanceExcludeProject();
+                    excludeProject.setProjectId(Integer.parseInt(addBO.getProjects()[i]));
+                    excludeProject.setCompanyId(user.getCompanyId());
+                    excludeProject.setCreateBy(user.getId());
+                    excludeProject.setUseYM(addBO.getUseYM());
+                    resList.add(excludeProject);
+                }
+            }
+
+        }
+
+        financeExcludeProjectMapper.delete(new LambdaQueryWrapper<FinanceExcludeProject>()
+                .eq(FinanceExcludeProject::getCompanyId,user.getCompanyId()));
+        if(CollectionUtils.isNotEmpty(resList)){
+            financeExcludeProjectMapper.batchInsert(resList);
+        }
+        return httpRespMsg;
+    }
+
+}

+ 47 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/FinanceServiceImpl.java

@@ -2,6 +2,7 @@ package com.management.platform.service.impl;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.entity.*;
@@ -10,8 +11,8 @@ import com.management.platform.service.*;
 import com.management.platform.util.ExcelUtil;
 import com.management.platform.util.HttpRespMsg;
 import com.management.platform.util.MessageUtils;
-import com.management.platform.util.UserNotFoundException;
 import com.taobao.api.internal.util.StringUtils;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
@@ -89,6 +90,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     @Resource
     private CompanyDingdingMapper companyDingdingMapper;
 
+    @Resource
+    private FinanceExcludeProjectMapper financeExcludeProjectMapper;
+
     @Resource
     private ProjectMapper projectMapper;
     @Value(value = "${upload.path}")
@@ -180,7 +184,8 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             //获取人员该月份填写的日报的总时长
             List<Map<String, Object>> userTimeList = null;
             if (syncUserCost || syncHistoryReport) {
-                userTimeList = reportMapper.getUserWorkingTimeByRange(companyId, startStr, endStr);
+//                userTimeList = reportMapper.getUserWorkingTimeByRange(companyId, startStr, endStr);
+                userTimeList = reportMapper.getUserWorkingTimeByRangeWithExclude(companyId, yearMonth,startStr, endStr);
             }
 
             //设置财务核算薪资模板配置
@@ -554,6 +559,17 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                 }
                 userService.updateBatchById(dbUpUserList);
             }
+            /**添加分摊成本置零*/
+            List<FinanceExcludeProject> financeExcludeProjects = financeExcludeProjectMapper
+                    .selectList(new LambdaQueryWrapper<FinanceExcludeProject>()
+                    .eq(FinanceExcludeProject::getCompanyId, companyId)
+                    .eq(FinanceExcludeProject::getUseYM, yearMonth));
+            List<Integer> projectIds = new ArrayList<>();
+            if(CollectionUtils.isNotEmpty(financeExcludeProjects)){
+                projectIds = financeExcludeProjects.stream()
+                        .map(FinanceExcludeProject::getProjectId).collect(Collectors.toList());
+            }
+
             //如果有必要,更新该月份的日报相关的成本
             if (syncHistoryReport) {
                 List<Report> reportList = reportMapper.selectSimpleTime(companyId, startStr, endStr);
@@ -564,6 +580,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         if (first.isPresent()) {
                             BigDecimal hourCost = first.get().getCost();
                             r.setCost(hourCost.multiply(new BigDecimal(r.getWorkingTime())));
+                            if(projectIds.contains(r.getProjectId())){
+                                r.setCost(new BigDecimal(0));
+                            }
                             r.setCreatorId(null);
                             r.setWorkingTime(null);
                             updateReportList.add(r);
@@ -622,7 +641,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
     }
 
     @Override
-    public HttpRespMsg exportData(Integer groupByCategory, String yearMonth, Boolean assignNoProUser, HttpServletRequest request) {
+    public HttpRespMsg exportData(Integer groupByCategory,Integer onlyTotal, String yearMonth, Boolean assignNoProUser, HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
             Integer companyId = userMapper.selectById(request.getHeader("Token")).getCompanyId();
@@ -711,7 +730,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             LocalDate endDate = LocalDate.parse(dateStr,df);
             endDate = endDate.plusMonths(1);
 
-            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTime(startDate, endDate, companyId);
+//            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTime(startDate, endDate, companyId);
+            /**添加非分摊项目过滤*/
+            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTimeNew(yearMonth,startDate, endDate, companyId);
             //如果定义了可分摊项目的过滤,按照数据处理一下
             CostProjectSetting setting = costProjectSettingMapper.selectOne(new QueryWrapper<CostProjectSetting>().eq("company_id", companyId));
             if (setting != null && setting.getSettingType() > 0) {
@@ -742,7 +763,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             HashMap<String, UserWorkTime> userTime = new HashMap<String, UserWorkTime>();
             for (Map<String, Object> map : projectTimeList) {
                 String creatorId = (String) map.get("creatorId");
-                totalCostTime += (Double)map.get("workingTime");
+//                totalCostTime += (Double)map.get("workingTime");
                 if (userTime.get(creatorId) == null) {
                     UserWorkTime user = new UserWorkTime();
                     user.workingTime = new BigDecimal((Double)map.get("workingTime"));
@@ -770,7 +791,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             }
 
             ProjectPercentage percentage = null;
-            List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+//            List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+            /**添加非分摊项目筛选*/
+            List<FinanceProjects> financeProjects = financeProjectsMapper.getExcludeFinanceProjects(companyId,yearMonth);
             //填充项目分类
             financeProjects.forEach(f->{
                 Optional<Project> curP = allProjects.stream().filter(p->p.getId().equals(f.getProjectId())).findFirst();
@@ -932,6 +955,7 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                         item.field6 = field6Item;
                         item.field7 = field7Item;
                     }
+                    totalCostTime += workingTime;
                     totalMoneyCost = totalMoneyCost.add(cost);
                     totalSalary = totalSalary.add(salary);
                     totalBonus = totalBonus.add(bonus);
@@ -1541,9 +1565,18 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
                             multiSheetDataList[i].add(newRow);
                         }
                     }
-                    return excelExportService.exportMultiSheetGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , multiSheetDataList, path, sheetNameList.toArray(new String[0]));
+                    if(0 == onlyTotal){
+                        return excelExportService.exportMultiSheetGeneralExcelTotal(wxCorpInfo,dingding,fileName , multiSheetDataList, path, sheetNameList.toArray(new String[0]));
+
+                    }else{
+                        return excelExportService.exportMultiSheetGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , multiSheetDataList, path, sheetNameList.toArray(new String[0]));
+                    }
                 } else {
-                    return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
+                    if(0 == onlyTotal){
+                        return excelExportService.exportGeneralExcelTotal(wxCorpInfo,dingding,fileName , allList, path);
+                    }else{
+                        return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,fileName , allList, path);
+                    }
                 }
             } catch (Exception e) {
                 e.printStackTrace();
@@ -1570,7 +1603,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             LocalDate endDate = LocalDate.parse(dateStr,df);
             endDate = endDate.plusMonths(1);
 
-            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTime(startDate, endDate, companyId);
+//            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTime(startDate, endDate, companyId);
+            /**添加非分摊项目过滤*/
+            List<Map<String, Object>> projectTimeList = reportMapper.getRealProjectTimeNew(yearMonth,startDate, endDate, companyId);
             //如果定义了可分摊项目的过滤,按照数据处理一下
             CostProjectSetting setting = costProjectSettingMapper.selectOne(new QueryWrapper<CostProjectSetting>().eq("company_id", companyId));
             if (setting != null && setting.getSettingType() > 0) {
@@ -1687,7 +1722,9 @@ public class FinanceServiceImpl extends ServiceImpl<FinanceMapper, Finance> impl
             BigDecimal percentTotal = new BigDecimal(0);
             //加上待分摊的无工时项目,如果当前项目列表没有的话
             if (assignNoProUser != null && assignNoProUser && noProjectItem.project != null) {
-                List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+//                List<FinanceProjects> financeProjects = financeProjectsMapper.selectList(new QueryWrapper<FinanceProjects>().eq("company_id", companyId).eq("ymonth", yearMonth));
+                /**添加非分摊项目筛选*/
+                List<FinanceProjects> financeProjects = financeProjectsMapper.getExcludeFinanceProjects(companyId,yearMonth);
                 if (financeProjects.size() == 0) {
                     //httpRespMsg.setError("缺少待分摊项目,请重新设置并保存分摊比例设置");
                     httpRespMsg.setError(MessageUtils.message("project.lackApportion"));

+ 282 - 12
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java

@@ -1,22 +1,12 @@
 package com.management.platform.util;
 
-import com.management.platform.entity.CorpwxJobResult;
-import com.management.platform.entity.ExpenseSheet;
-import com.management.platform.entity.WxCorpInfo;
-import com.management.platform.mapper.CorpwxJobResultMapper;
-import com.management.platform.service.CorpwxJobResultService;
-import com.management.platform.service.WxCorpInfoService;
-import org.apache.poi.hssf.usermodel.*;
 import org.apache.poi.ss.usermodel.*;
 import org.apache.poi.ss.util.CellRangeAddress;
-import org.apache.poi.ss.util.RegionUtil;
-import org.apache.poi.xssf.streaming.SXSSFRow;
 import org.apache.poi.xssf.streaming.SXSSFWorkbook;
-import org.apache.poi.xssf.usermodel.*;
-import org.springframework.beans.factory.annotation.Autowired;
+import org.apache.poi.xssf.usermodel.XSSFCellStyle;
+import org.apache.poi.xssf.usermodel.XSSFColor;
 import org.springframework.stereotype.Component;
 
-import javax.annotation.PostConstruct;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.util.List;
@@ -179,6 +169,171 @@ public class ExcelUtil {
 //        return "";
     }
 
+    public static String exportGeneralExcelTotal(String title, List<List<String>> list, String downloadPath) {
+        String result="系统提示:Excel文件导出成功!";
+        String fileName= title+".xlsx";
+        try {
+//            response.reset();
+//            response.setHeader("Content-disposition",
+//                "attachment;filename="+ URLEncoder.encode(fileName, "UTF-8"));
+//            //设置文件头编码格式
+//            response.setContentType("APPLICATION/OCTET-STREAM;charset=UTF-8");//设置类型
+//            response.setHeader("Cache-Control","no-cache");//设置头
+//            response.setDateHeader("Expires", 0);//设置日期头
+            // 创建工作簿, 换成XSSSF 来支持万以上的数据
+            SXSSFWorkbook workBook = new SXSSFWorkbook();
+//            HSSFWorkbook workBook = new HSSFWorkbook();
+            // 创建工作类
+            Sheet sheet = workBook.createSheet();
+            //设置首行冻结
+            sheet.createFreezePane(0, 1);
+            sheet.setDefaultColumnWidth(16);
+            //设置字体样式
+            Font headFont = workBook.createFont();
+            headFont.setBold(true);
+            headFont.setFontHeightInPoints((short) 10);
+            headFont.setFontName("黑体");
+
+            Font titleFont = workBook.createFont();
+            titleFont.setBold(true);
+            titleFont.setFontHeightInPoints((short) 10);
+            titleFont.setFontName("黑体");
+
+            Font font = workBook.createFont();
+            font.setFontHeightInPoints((short) 10);
+            font.setFontName("宋体");
+
+            //设置单元格样式
+            XSSFCellStyle  headStyle = (XSSFCellStyle) workBook.createCellStyle();
+            headStyle.setFont(headFont);
+            headStyle.setAlignment(HorizontalAlignment.CENTER);
+            headStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+            headStyle.setWrapText(true);
+            headStyle.setBorderBottom(BorderStyle.THIN); //下边框
+            headStyle.setBorderLeft(BorderStyle.THIN);//左边框
+            headStyle.setBorderTop(BorderStyle.THIN);//上边框
+            headStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+            String color = "c0c0c0";    //此处得到的color为16进制的字符串
+            //转为RGB码
+            int r = Integer.parseInt((color.substring(0,2)),16);   //转为16进制
+            int g = Integer.parseInt((color.substring(2,4)),16);
+            int b = Integer.parseInt((color.substring(4,6)),16);
+
+            //自定义cell颜色
+//            HSSFPalette palette = workBook.getCustomPalette();
+            //这里的9是索引
+//            palette.setColorAtIndex((short)9, (byte) r, (byte) g, (byte) b);
+
+            //设置自定义颜色
+            XSSFColor xssfColor = new XSSFColor();
+            byte[] colorRgb = { (short)9, (byte) r, (byte) g, (byte) b };
+            xssfColor.setRGB(colorRgb);
+
+            headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
+            headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 填充模式(和背景颜色成对使用)
+            /*headStyle.setFillForegroundColor(IndexedColors.AQUA.getIndex());*/ //设置自带的颜色
+
+            CellStyle titleStyle = workBook.createCellStyle();
+            titleStyle.setFont(titleFont);
+            titleStyle.setAlignment(HorizontalAlignment.CENTER);
+            titleStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+            titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);  //填充单元格
+            titleStyle.setFillForegroundColor((short)9);    //填色
+            titleStyle.setWrapText(true);
+            titleStyle.setBorderBottom(BorderStyle.THIN); //下边框
+            titleStyle.setBorderLeft(BorderStyle.THIN);//左边框
+            titleStyle.setBorderTop(BorderStyle.THIN);//上边框
+            titleStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+            CellStyle cellStyle = workBook.createCellStyle();
+            cellStyle.setFont(font);
+            cellStyle.setAlignment(HorizontalAlignment.CENTER);
+            cellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+            cellStyle.setWrapText(true);
+            cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
+            cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
+            cellStyle.setBorderTop(BorderStyle.THIN);//上边框
+            cellStyle.setBorderRight(BorderStyle.THIN);//右边框
+            DataFormat dataFormat = workBook.createDataFormat();
+            cellStyle.setDataFormat(dataFormat.getFormat("@"));
+
+            if(list.size() > 0) {
+                //标题(如果需要在EXCEL内容最上面加标题,请打开下面的注释,修改start)
+                /*
+                HSSFRow titleRow = sheet.createRow(0);
+                titleRow.setHeightInPoints(30);
+                HSSFCell titleCell = titleRow.createCell(0);
+                titleCell.setCellStyle(headStyle);
+                titleCell.setCellValue(title);
+                //合并单元格
+                CellRangeAddress cellRangeAddress = new CellRangeAddress(0,0,0, list.get(0).size() - 1);
+                //加入合并单元格对象
+                sheet.addMergedRegion(cellRangeAddress);
+                //使用RegionUtil类为合并后的单元格添加边框
+			    RegionUtil.setBorderBottom(BorderStyle.THIN, cellRangeAddress, sheet); // 下边框
+                RegionUtil.setBorderLeft(BorderStyle.THIN, cellRangeAddress, sheet); // 左边框
+                RegionUtil.setBorderRight(BorderStyle.THIN, cellRangeAddress, sheet); // 有边框
+                RegionUtil.setBorderTop(BorderStyle.THIN, cellRangeAddress, sheet); // 上边框
+                */
+                int start = 0;
+                for (int j = 0; j < list.size(); j++) {
+                    List<String> rowList = list.get(j);
+                    Row row = sheet.createRow(start);
+                    row.setHeightInPoints(24);
+                    for(int i = 0; i < rowList.size(); i++) {
+                        Cell cell = row.createCell(i);
+                        if(start == 0) {
+                            cell.setCellStyle(headStyle);
+                        }else {
+                            cell.setCellStyle(cellStyle);
+                        }
+                        cell.setCellValue(rowList.get(i));
+                    }
+                    start++;
+                }
+//                for(List<String> rowList : list) {
+//                    Row row = sheet.createRow(start);
+//                    row.setHeightInPoints(24);
+//
+//                    for(int i = 0; i < rowList.size(); i++) {
+//                        Cell cell = row.createCell(i);
+//                        if(start == 0) {
+//                            cell.setCellStyle(headStyle);
+//                        }else {
+//                            cell.setCellStyle(cellStyle);
+//                        }
+//                        cell.setCellValue(rowList.get(i));
+//                    }
+//                    start++;
+//                }
+            }
+            //用于非传统ajax;
+//            String headStr = "attachment; filename=\"" + fileName + "\"";
+//            response.setContentType("APPLICATION/OCTET-STREAM");//返回格式为流
+//            response.setHeader("Content-Disposition", headStr);
+//            //普通下载不需要以上三行,注掉即可
+//            OutputStream os = response.getOutputStream();//在线下载
+            File dir = null;
+            dir = new File(downloadPath);
+            // D://cloud/upload 文件上传后所存储的位置,部署到服务器上时配置服务器地址即可
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            FileOutputStream os = new FileOutputStream(downloadPath+fileName);//保存到本地
+            workBook.write(os);
+            os.flush();
+            os.close();
+        }catch(Exception e) {
+            System.out.println(result);
+            e.printStackTrace();
+        }
+        return "/upload/"+fileName;
+//        return "";
+    }
+
+
+
     public static String exportGeneralExcelByTitleAndList2(String title, List<List<String>> list, String downloadPath) {
         String result="系统提示:Excel文件导出成功!";
         String fileName= title+".xlsx";
@@ -473,6 +628,121 @@ public class ExcelUtil {
         return "/upload/"+fileName;
     }
 
+    public static String exportMultiSheetGeneralExcelTotal(String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) {
+        String result="系统提示:Excel文件导出成功!";
+        String fileName= title+".xlsx";
+        try {
+            // 创建工作簿
+            SXSSFWorkbook workBook = new SXSSFWorkbook();
+            // 创建工作类
+            for (int sheetIndex=0;sheetIndex< multiSheetList.length; sheetIndex++) {
+                Sheet sheetOne = workBook.createSheet();
+                workBook.setSheetName(sheetIndex,sheetsName[sheetIndex]);
+                sheetOne.setDefaultColumnWidth(16);
+
+                //设置字体样式
+                Font headFont = workBook.createFont();
+                headFont.setBold(true);
+                headFont.setFontHeightInPoints((short) 10);
+                headFont.setFontName("黑体");
+
+                Font titleFont = workBook.createFont();
+                titleFont.setBold(true);
+                titleFont.setFontHeightInPoints((short) 10);
+                titleFont.setFontName("黑体");
+
+                Font font = workBook.createFont();
+                font.setFontHeightInPoints((short) 10);
+                font.setFontName("宋体");
+
+                //设置单元格样式
+                XSSFCellStyle  headStyle = (XSSFCellStyle) workBook.createCellStyle();
+                headStyle.setFont(headFont);
+                headStyle.setAlignment(HorizontalAlignment.CENTER);
+                headStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+                headStyle.setWrapText(true);
+                headStyle.setBorderBottom(BorderStyle.THIN); //下边框
+                headStyle.setBorderLeft(BorderStyle.THIN);//左边框
+                headStyle.setBorderTop(BorderStyle.THIN);//上边框
+                headStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+                String color = "c0c0c0";    //此处得到的color为16进制的字符串
+                //转为RGB码
+                int r = Integer.parseInt((color.substring(0,2)),16);   //转为16进制
+                int g = Integer.parseInt((color.substring(2,4)),16);
+                int b = Integer.parseInt((color.substring(4,6)),16);
+
+                //自定义cell颜色
+//            HSSFPalette palette = workBook.getCustomPalette();
+                //这里的9是索引
+//            palette.setColorAtIndex((short)9, (byte) r, (byte) g, (byte) b);
+
+                //设置自定义颜色
+                XSSFColor xssfColor = new XSSFColor();
+                byte[] colorRgb = { (byte)118, (byte)147, (byte)60 };
+                xssfColor.setRGB(colorRgb);
+                headStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.index);
+                headStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);// 填充模式(和背景颜色成对使用)
+                //cs.setFillForegroundColor(IndexedColors.AQUA.getIndex()); //设置自带的颜色
+
+                CellStyle titleStyle = workBook.createCellStyle();
+                titleStyle.setFont(titleFont);
+                titleStyle.setAlignment(HorizontalAlignment.CENTER);
+                titleStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+                titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);  //填充单元格
+                titleStyle.setFillForegroundColor((short)9);    //填色
+                titleStyle.setWrapText(true);
+                titleStyle.setBorderBottom(BorderStyle.THIN); //下边框
+                titleStyle.setBorderLeft(BorderStyle.THIN);//左边框
+                titleStyle.setBorderTop(BorderStyle.THIN);//上边框
+                titleStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+                CellStyle cellStyle = workBook.createCellStyle();
+                cellStyle.setFont(font);
+                cellStyle.setAlignment(HorizontalAlignment.CENTER);
+                cellStyle.setVerticalAlignment(org.apache.poi.ss.usermodel.VerticalAlignment.CENTER);
+                cellStyle.setWrapText(true);
+                cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
+                cellStyle.setBorderLeft(BorderStyle.THIN);//左边框
+                cellStyle.setBorderTop(BorderStyle.THIN);//上边框
+                cellStyle.setBorderRight(BorderStyle.THIN);//右边框
+
+                if(multiSheetList[sheetIndex].size() > 0) {
+                    int start = 0;
+                    for (int j = 0; j <=1; j++) {
+                        List<String> rowList = multiSheetList[sheetIndex].get(j);
+                        Row row = sheetOne.createRow(start);
+                        row.setHeightInPoints(24);
+                        for(int i = 0; i < rowList.size(); i++) {
+                            Cell cell = row.createCell(i);
+                            if(start == 0) {
+                                cell.setCellStyle(headStyle);
+                            }else {
+                                cell.setCellStyle(cellStyle);
+                            }
+                            cell.setCellValue(rowList.get(i));
+                        }
+                        start++;
+                    }
+                }
+            }
+
+
+            File dir = new File(downloadPath);
+            if (!dir.exists()) {
+                dir.mkdirs();
+            }
+            FileOutputStream os = new FileOutputStream(downloadPath+fileName);//保存到本地
+            workBook.write(os);
+            os.flush();
+            os.close();
+        }catch(Exception e) {
+            System.out.println(result);
+            e.printStackTrace();
+        }
+        return "/upload/"+fileName;
+    }
+
     public static String exportMultiSheetGeneralExcelByTitleAndList(String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) {
         String result="系统提示:Excel文件导出成功!";
         String fileName= title+".xlsx";

+ 13 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceExcludeProjectMapper.xml

@@ -0,0 +1,13 @@
+<?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="com.management.platform.mapper.FinanceExcludeProjectMapper">
+
+    <insert id="batchInsert">
+        insert into finance_exclude_project (project_id, company_id, create_by, use_ym)
+        values
+            <foreach collection="projects" item="project" separator=",">
+                (#{project.projectId},#{project.companyId},#{project.createBy},#{project.useYM})
+            </foreach>
+    </insert>
+</mapper>

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/FinanceProjectsMapper.xml

@@ -16,5 +16,15 @@
     <sql id="Base_Column_List">
         id, company_id, ymonth, project_id, project_name, project_code
     </sql>
+    <select id="getExcludeFinanceProjects" resultType="com.management.platform.entity.FinanceProjects">
+        select fp.id, fp.company_id, fp.ymonth, fp.project_id, fp.project_name, fp.project_code
+        from finance_projects fp
+        where company_id = #{companyId}
+          and ymonth = #{yearMonth}
+          and not exists(
+            select 1 from finance_exclude_project fep where fep.company_id = fp.company_id and fep.use_ym = #{yearMonth}
+                                                        and fp.project_id = fep.project_id
+        )
+    </select>
 
 </mapper>

+ 29 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml

@@ -988,6 +988,25 @@
         GROUP BY project_id, report.creator_id;
     </select>
 
+    <select id="getRealProjectTimeNew" resultType="java.util.Map">
+        SELECT ifnull(project.id, 0) as projectId, project.project_code as projectCode, IFNULL(project.category_name,'其他') as categoryName,
+        IFNULL(project.project_name,'其他') as project,report.creator_id AS creatorId,sum(working_time) as workingTime, SUM(cost) as cost
+        FROM report
+        left join project on project.id = report.project_id
+        WHERE report.company_id = #{companyId}
+        and state = 1
+        <if test="startDate != null">
+            AND report.create_date &gt;= #{startDate}
+        </if>
+        <if test="endDate != null">
+            AND report.create_date &lt; #{endDate}
+        </if>
+        AND not exists(
+        select 1 from finance_exclude_project fep where fep.company_id = report.company_id and fep.use_ym = #{ym} and fep.project_id = report.project_id
+        )
+        GROUP BY project_id, report.creator_id;
+    </select>
+
     <select id="getUploadThirdReportData" resultType="java.util.Map">
         select IFNULL(p.project_code,'其他') as projectCode,IFNULL(tg.wbs_code,'其他')as wbsCode,DATE_FORMAT(r.create_date, '%Y') as ofyear,
                DATE_FORMAT(r.create_date, '%m') as ofmonth,u.name as userName,u.job_number as jobNumber,d.department_name as departmentName,SUM(r.cost) as cost
@@ -1036,8 +1055,17 @@
                                                                                        AND create_date BETWEEN #{startDate} and #{endDate}
         GROUP BY creator_id
     </select>
+    <select id="getUserWorkingTimeByRangeWithExclude" resultType="java.util.Map">
+        SELECT creator_id as creatorId, SUM(working_time) AS workingTime FROM report r
+        WHERE state = 1 AND creator_id IN(SELECT id FROM user WHERE company_id = #{companyId})
+        AND create_date BETWEEN #{startDate} and #{endDate}
+        AND not exists(
+            select 1 from finance_exclude_project fep where fep.company_id = r.company_id and fep.use_ym = #{yearMonth} and fep.project_id = r.project_id
+        )
+        GROUP BY creator_id
+    </select>
     <select id="selectSimpleTime" resultMap="BaseResultMap">
-        SELECT id,creator_id, working_time, cost FROM report WHERE state = 1 AND creator_id IN(SELECT id FROM user WHERE company_id = #{companyId})
+        SELECT id,creator_id, working_time, cost,project_id FROM report WHERE state = 1 AND creator_id IN(SELECT id FROM user WHERE company_id = #{companyId})
                                                                AND create_date BETWEEN #{startDate} and #{endDate}
     </select>