浏览代码

优化导出日报性能

seyason 2 年之前
父节点
当前提交
43e4d70fe5

+ 1 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/aop/AopLogConfiguration.java

@@ -24,7 +24,7 @@ import java.util.stream.Stream;
 @Aspect
 @Configuration
 public class AopLogConfiguration {
-    public static String[] methods = {"importData", "editReport", "approve", "deny", "cancel", "batchApproveReport", "batchDenyReport"
+    public static String[] methods = {"importData", "exportReport", "editReport", "approve", "deny", "cancel", "batchApproveReport", "batchDenyReport"
             , "loginByUserId", "getUserByCode"};
     public static List<String> printMethods = new ArrayList<String>();
     static {

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java

@@ -188,6 +188,16 @@ public class ReportController {
      */
     @RequestMapping("/exportReport")
     public HttpRespMsg exportReport(String startDate, String endDate, Integer projectId,@RequestParam(defaultValue = "0") Integer stateKey,Integer departmentId) {
+        //startDate和endDate间隔不得超过1年
+        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+        LocalDate start = LocalDate.parse(startDate, dateTimeFormatter);
+        LocalDate end = LocalDate.parse(endDate, dateTimeFormatter);
+        if (start.until(end, ChronoUnit.DAYS) > 365) {
+            HttpRespMsg httpRespMsg = new HttpRespMsg();
+            httpRespMsg.setError("导出日报时间间隔不得超过1年");
+            return httpRespMsg;
+        }
+
         return reportService.exportReport(startDate, endDate, projectId,stateKey,departmentId, request);
     }
 

+ 15 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java

@@ -28,7 +28,14 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                      @Param("stateKey") Integer stateKey,
                                                      @Param("branchDepartment")List<Integer> branchDepartment
                                                  );
-
+    List<HashMap<String, Object>> getAllReportByDateWithReportLog(@Param("startDate") String startDate,
+                                                     @Param("companyId") Integer companyId,
+                                                     @Param("userId") String userId,
+                                                     @Param("endDate") String endDate,
+                                                     @Param("projectId") Integer projectId,
+                                                     @Param("stateKey") Integer stateKey,
+                                                     @Param("branchDepartment")List<Integer> branchDepartment
+    );
     List<HashMap<String, Object>> getProjectMembReportByDate(@Param("startDate") String startDate,
                                                      @Param("companyId") Integer companyId,
                                                      @Param("leaderId") String leaderId,
@@ -36,7 +43,13 @@ public interface ReportMapper extends BaseMapper<Report> {
                                                      @Param("projectId") Integer projectId,
                                                      @Param("stateKey") Integer stateKey,
                                                      @Param("branchDepartment")List<Integer> branchDepartment);
-
+    List<HashMap<String, Object>> getProjectMembReportByDateWithReportLog(@Param("startDate") String startDate,
+                                                             @Param("companyId") Integer companyId,
+                                                             @Param("leaderId") String leaderId,
+                                                             @Param("endDate") String endDate,
+                                                             @Param("projectId") Integer projectId,
+                                                             @Param("stateKey") Integer stateKey,
+                                                             @Param("branchDepartment")List<Integer> branchDepartment);
     //获取部门下的人员的日报
     List<HashMap<String, Object>> getDeptMembReportByDate(@Param("startDate") String startDate,
                                                              @Param("companyId") Integer companyId,

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

@@ -61,7 +61,6 @@ public class ExcelExportServiceImpl implements ExcelExportService {
 
     public HttpRespMsg exportGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, String title, List<List<String>> list, String downloadPath) throws Exception {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
-        System.out.println(File.separator);
         if (title.contains("/")) {
             //文件名不能含有路径,得替换掉
             title = title.replace("/", "@");

+ 139 - 20
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -4209,7 +4209,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 titles.add(MessageUtils.message("excel.inputStage"));
             }
             //每个日报的审批流程记录
-            List<ReportLogDetail> logDetails = new ArrayList<>();
+//            List<ReportLogDetail> logDetails = new ArrayList<>();
             if (timeType.getShowFillauditTime() == 1) {
 //                titles.add("填写时间");
 //                titles.add("项目审核人");
@@ -4219,7 +4219,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 titles.add(MessageUtils.message("excel.proReviewer"));
                 titles.add(MessageUtils.message("excel.auditTime"));
                 titles.add(MessageUtils.message("excel.auditProcess"));
-                logDetails = reportLogDetailMapper.selectList(new QueryWrapper<ReportLogDetail>().eq("company_id", company.getId()).between("work_date", startDate, endDate));
+//                logDetails = reportLogDetailMapper.selectList(new QueryWrapper<ReportLogDetail>().select("report_id, msg, operator_id, operate_date").eq("company_id", company.getId()).between("work_date", startDate, endDate));
             }
 
             //titles.add("工作事项");
@@ -4238,6 +4238,8 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
             //新增数据行 并且装填数据
             int rowNum = 1;
             List<HashMap<String, Object>> allReportByDate = null;
+
+            System.out.println("开始查询"+LocalDateTime.now().toString());
             List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(user.getRoleId(), "查看全公司工时");
             //获取部门的所有子部门
             List<Department> departments = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id",companyId));
@@ -4256,10 +4258,20 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 //检查是否是项目负责人
                 int cnt = projectMapper.selectCount(new QueryWrapper<Project>().eq("incharger_id", user.getId()));
                 if (cnt > 0) {
-                    reportsFromProjects = reportMapper.getProjectMembReportByDate(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    if (timeType.getShowFillauditTime() == 1) {
+                        reportsFromProjects = reportMapper.getProjectMembReportByDateWithReportLog(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    } else{
+                        reportsFromProjects = reportMapper.getProjectMembReportByDate(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    }
+
                 } else {
                     //普通员工只能看自己的
-                    reportsFromProjects = reportMapper.getAllReportByDate(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    if (timeType.getShowFillauditTime() == 1) {
+                        reportsFromProjects = reportMapper.getAllReportByDateWithReportLog(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    } else {
+                        reportsFromProjects = reportMapper.getAllReportByDate(startDate, null, user.getId(), endDate, projectId,stateKey,branchDepartment);
+                    }
+
                 }
                 if (allReportByDate == null) {
                     allReportByDate = reportsFromProjects;
@@ -4279,10 +4291,20 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 //            }
             else {
                 //看公司所有人的
-                allReportByDate = reportMapper.getAllReportByDate(startDate, user.getCompanyId(), null, endDate, projectId,stateKey,branchDepartment);
+                allReportByDate = null;
+                if (timeType.getShowFillauditTime() == 1) {
+                    allReportByDate = reportMapper.getAllReportByDateWithReportLog(startDate, user.getCompanyId(), null, endDate, projectId,stateKey,branchDepartment);
+                } else {
+                    allReportByDate = reportMapper.getAllReportByDate(startDate, user.getCompanyId(), null, endDate, projectId,stateKey,branchDepartment);
+                }
             }
+            System.out.println("进度1"+LocalDateTime.now().toString());
             //获取企业微信考勤数据
-            List<UserCorpwxTime> userCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("company_id", user.getCompanyId()).between("create_date", startDate, endDate));
+            List<UserCorpwxTime> userCorpwxTimeList = new ArrayList<>();
+            if(timeType.getSyncCorpwxTime()==1) {
+                userCorpwxTimeList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("company_id", user.getCompanyId()).between("create_date", startDate, endDate));
+            }
+            System.out.println("进度2"+LocalDateTime.now().toString());
             if (timeType.getMultiWorktime() == 1) {
                 java.text.DecimalFormat df = new java.text.DecimalFormat("#0.00");
                 //重新处理一下数据,把工作时间和工作事项移出来
@@ -4325,14 +4347,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
                 allReportByDate = dealDataList;
             }
-            //HSSFRow条数范围限制0..65535
-            if (allReportByDate.size() > 60000) {
+            //07Excel HSSFRow条数范围限制0..1048576
+            if (allReportByDate.size() > 1048576) {
                 HttpRespMsg msg = new HttpRespMsg();
                 //msg.setError("数据量过大,请分时间段导出");
                 msg.setError(MessageUtils.message("data.OversizeError"));
                 return msg;
             }
-            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             DecimalFormat df = new DecimalFormat("#0.0");
             int offsetSeconds = 0;
             if (company.getIsInternational() == 1) {
@@ -4358,6 +4380,9 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
             List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+            System.out.println("进度3"+LocalDateTime.now().toString());
+            long t1 = System.currentTimeMillis();
+            DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             for (Map<String, Object> map : allReportByDate) {
                 List<String> item=new ArrayList<>();
                 item.add(String.valueOf(rowNum));
@@ -4392,6 +4417,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     item.add((String) map.get("name"));
                     item.add(departmentService.getSupDepartment(dept,departments));
                 }
+
                 item.add((String) map.get("projectCode"));
                 item.add((String) map.get("project"));
                 item.add((String) map.get("categoryName"));
@@ -4449,13 +4475,22 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     } else {
                         item.add(sdf.format((Date)map.get("projectAuditTime")));
                     }
-                    //审核流程显示
-                    List<ReportLogDetail> detailList = logDetails.stream().filter(log -> log.getReportId().equals((Integer) map.get("id"))).collect(Collectors.toList());
-                    if (detailList.size() > 0) {
-                        StringBuilder sb = new StringBuilder();
-                        boolean isFirst = true;
-                        for (ReportLogDetail audit:detailList) {
-                            LocalDateTime operateDate = audit.getOperateDate();
+
+                    StringBuilder sb = new StringBuilder();
+                    boolean isFirst = true;
+                    String logMsg = (String)map.get("logMsg");
+                    if (logMsg != null) {
+                        String[] logMsgs = logMsg.split("❤");
+                        for (String msgItem : logMsgs) {
+                            String[] splitItems = msgItem.split("@");
+                            //operator_id@operate_date@msg
+                            String operateDateStr = splitItems[1];
+                            LocalDateTime operateDate = LocalDateTime.parse(operateDateStr, dtf);
+                            ReportLogDetail audit = new ReportLogDetail();
+                            audit.setOperatorId(splitItems[0]);
+                            audit.setOperateDate(operateDate);
+                            audit.setMsg(splitItems[2]);
+
                             if (company.getIsInternational() == 1) {
                                 operateDate = operateDate.plusSeconds(offsetSeconds);
                             }
@@ -4488,10 +4523,90 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             }
                             sb.append(msg);
                         }
-                        item.add(sb.toString());
-                    } else {
-                        item.add("");
                     }
+                    //审核流程显示;//stream性能较差,换成for循环
+//                    for (int m=0; m <logDetails.size(); m++) {
+//                        ReportLogDetail audit = logDetails.get(m);
+//                        //仅处理当前日报的审核流程
+//                        if (audit.getReportId().intValue() == ((Integer)map.get("id")).intValue()) {
+//                            LocalDateTime operateDate = audit.getOperateDate();
+//                            if (company.getIsInternational() == 1) {
+//                                operateDate = operateDate.plusSeconds(offsetSeconds);
+//                            }
+//                            String time = dtf.format(operateDate);
+//                            String msg= "";
+//                            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+//                                Optional<User> first = userList.stream().filter(ul -> ul.getId().equals(audit.getOperatorId())).findFirst();
+//                                if(first.isPresent()){
+//                                    if(audit.getMsg().contains("提交了")){
+//                                        int i = audit.getMsg().indexOf("提");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }else if(audit.getMsg().contains("审核通过了")){
+//                                        int i = audit.getMsg().indexOf("审");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }else if(audit.getMsg().contains("驳回了")) {
+//                                        int i = audit.getMsg().indexOf("驳");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }
+//                                }
+//                            }else {
+//                                msg = time+" " + audit.getMsg();
+//                            }
+//                            if (!isFirst) {
+//                                sb.append("->");
+//                            } else {
+//                                isFirst = false;
+//                            }
+//                            sb.append(msg);
+//                            //去掉这条记录,减少下次循环的次数
+//                            logDetails.remove(m);
+//                            m--;//因为删除了一条记录,所以要减少一次循环
+//                        }
+//                    }
+                    item.add(sb.toString());
+//                    List<ReportLogDetail> detailList = logDetails.parallelStream().filter(log -> log.getReportId().equals((Integer) map.get("id"))).collect(Collectors.toList());
+//                    if (detailList.size() > 0) {
+//                        for (ReportLogDetail audit:detailList) {
+//                            LocalDateTime operateDate = audit.getOperateDate();
+//                            if (company.getIsInternational() == 1) {
+//                                operateDate = operateDate.plusSeconds(offsetSeconds);
+//                            }
+//                            String time = dtf.format(operateDate);
+//                            String msg= "";
+//                            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+//                                Optional<User> first = userList.stream().filter(ul -> ul.getId().equals(audit.getOperatorId())).findFirst();
+//                                if(first.isPresent()){
+//                                    if(audit.getMsg().contains("提交了")){
+//                                        int i = audit.getMsg().indexOf("提");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }else if(audit.getMsg().contains("审核通过了")){
+//                                        int i = audit.getMsg().indexOf("审");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }else if(audit.getMsg().contains("驳回了")) {
+//                                        int i = audit.getMsg().indexOf("驳");
+//                                        String substring = audit.getMsg().substring(0, i);
+//                                        msg = time+" " + audit.getMsg().replaceAll(substring,"\\$userName="+first.get().getCorpwxUserid()+"\\$");
+//                                    }
+//                                }
+//                            }else {
+//                                msg = time+" " + audit.getMsg();
+//                            }
+//                            if (!isFirst) {
+//                                sb.append("->");
+//                            } else {
+//                                isFirst = false;
+//                            }
+//                            sb.append(msg);
+//                        }
+//                        item.add(sb.toString());
+//                    } else {
+//                        item.add("");
+//                    }
                 }
                 item.add((String) map.get("content"));
                 if(stateKey==1){
@@ -4580,10 +4695,14 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 dataList.add(item);
                 rowNum++;
             }
+            System.out.println("进度4"+LocalDateTime.now().toString());
+            long t2 = System.currentTimeMillis();
+            System.out.println("计算耗时:"+(t2-t1)+", 共"+rowNum+"条数据");
             //生成Excel文件
             //String fileUrlSuffix = (startDate==null?"":(startDate+"至"+endDate))+"工作日报" + System.currentTimeMillis() + ".xls";
-            String fileUrlSuffix = (startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate))+MessageUtils.message("excel.workReport") + System.currentTimeMillis() + ".xls";
+            String fileUrlSuffix = (startDate==null?"":(startDate+MessageUtils.message("leave.to")+endDate))+MessageUtils.message("excel.workReport") + System.currentTimeMillis();
             httpRespMsg = excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,fileUrlSuffix,dataList,path);
+            System.out.println("进度5, 导出结束"+LocalDateTime.now().toString());
         } catch (NullPointerException e) {
             //httpRespMsg.setError("验证失败或缺少数据");
             httpRespMsg.setError(MessageUtils.message("access.verErrorOrDataLack"));

+ 39 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/TestSample.java

@@ -0,0 +1,39 @@
+package com.management.platform.util;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ForkJoinPool;
+
+public class TestSample {
+    public static void main(String[] args) {
+        /* 创建数组,用来构建不同大小的List */
+        Integer[] intArr = new Integer[200];
+        List<Integer> intList = Arrays.asList(intArr);
+
+        List<Integer> forList = new ArrayList<>();
+        List<Integer> streamForList = new ArrayList<>();
+        List<Integer> parallelStreamForList = new ArrayList<>();
+
+
+        intList.forEach(l -> forList.add(l));
+        intList.stream().forEach(l -> streamForList.add(l));
+        ForkJoinPool forkJoinPool1 = new ForkJoinPool(Runtime.getRuntime().availableProcessors());
+        CountDownLatch countDownLatch = new CountDownLatch(2);
+        forkJoinPool1.submit(() -> {
+            intList.parallelStream().forEach(l -> parallelStreamForList.add(l));
+            countDownLatch.countDown();
+        });
+//        intList.parallelStream().forEach(l -> parallelStreamForList.add(l));
+//        try {
+//            countDownLatch.await();
+//        } catch (InterruptedException e) {
+//            throw new RuntimeException(e);
+//        }
+
+        System.out.println(forList.size() + "---普通for循环数组");
+        System.out.println(streamForList.size() + "---stream流for循环数组");
+        System.out.println(parallelStreamForList.size() + "---parallelStream流for循环数组");
+    }
+}

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

@@ -108,6 +108,61 @@
         ORDER BY a.creator_id, a.create_date desc
     </select>
 
+    <select id="getAllReportByDateWithReportLog" resultType="java.util.Map">
+        SELECT a.id, c.name,c.job_number as jobNumber,c.corpwx_userid as corpwxUserId,c.corpwx_deptid as corpwxDeptId, b.project_name AS project,b.project_code as projectCode,b.category_name as categoryName, a.working_time AS duration, a.content, a.create_time   AS time,a.create_date as createDate,
+        a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType,a.start_time as startTime,u.job_number as jobNumber,
+        a.end_time  as endTime, d.name as subProjectName,d.code as subProjectCode,a.task_id as taskId, task.name as taskName, a.is_overtime as isOvertime,a.progress as progress,
+        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime,a.is_dept_audit as isDeptAudit,a.group_audit_state as groupAuditState,task_group.incharger_id as inchargerId,a.project_audit_state as projectAuditState,a.audit_dept_managerid as deptAuditorName
+        ,c.plate1 as plate1,c.plate2 as plate2,c.plate3 as plate3,c.plate4 as plate4,c.plate5 as plate5
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId,a.custom_data as customData
+        ,u.name as projectAuditorName,u.corpwx_userid as projectAuditorCorpwxUserId, a.project_auditor_id as projectAuditorId, department.department_name as departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText,a.project_audit_time  as projectAuditTime,project_main.name as projectMainName,
+        GROUP_CONCAT(rlog.operator_id,'@', rlog.operate_date,'@', rlog.msg SEPARATOR '❤') AS logMsg
+        FROM report AS a
+        JOIN project AS b ON a.project_id=b.id
+        LEFT JOIN user AS c ON a.creator_id=c.id
+        left join sub_project as d on d.id = a.sub_project_id
+        left join task on task.id = a.task_id
+        left join report_extra_degree on report_extra_degree.id = a.degree_id
+        left join task_group on task_group.id = a.group_id
+        left join user u on u.id = a.project_auditor_id
+        left join department on department.department_id = c.department_id
+        left join department dp2 on dp2.department_id = b.bu_id
+        left join project_main on b.project_main_id=project_main.id
+        left join report_log_detail rlog on rlog.report_id = a.id
+        WHERE (<if test="stateKey == null or stateKey == 0">
+        a.state = 1
+    </if>
+        <if test="stateKey!=null">
+            <if test="stateKey==1">
+                (a.state = 1 or a.state = 0 or a.state = -1)
+            </if>
+            <if test="stateKey==2">
+                (a.state=0 or a.state = -1)
+            </if>
+        </if>)
+        <if test="startDate != null and startDate != ''">
+            AND a.create_date between #{startDate} and #{endDate}
+        </if>
+        <if test="projectId != null">
+            AND a.project_id = #{projectId}
+        </if>
+        <if test="companyId != null">
+            AND c.company_id = #{companyId}
+        </if>
+        <if test="userId != null">
+            AND a.creator_id = #{userId}
+        </if>
+        <if test="branchDepartment != null">
+            AND department.department_id in
+            <foreach collection="branchDepartment" item="deptId" separator="," close=")" open="(" index="index">
+                #{deptId}
+            </foreach>
+        </if>
+        group by a.id
+        ORDER BY a.creator_id, a.create_date desc
+    </select>
+
+
     <select id="geReportByProject" resultType="java.util.Map">
         SELECT project_main.name as projectMainName,project_main.code as projectMainCode,
         b.project_name as project,b.project_code as projectCode,
@@ -212,7 +267,66 @@
         </if>
         ORDER BY a.creator_id, a.create_date desc
     </select>
-
+    <select id="getProjectMembReportByDateWithReportLog" resultType="java.util.Map">
+        SELECT a.id, c.name,c.job_number as jobNumber,c.corpwx_userid as corpwxUserId,c.corpwx_deptid as corpwxDeptId, b.project_name AS project, b.project_code as projectCode, b.category_name as categoryName,a.working_time AS duration,
+        a.content, a.create_time AS time, a.create_date as createDate,
+        a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,
+        a.end_time as endTime, d.name as subProjectName,a.task_id as taskId, task.name as taskName, a.is_overtime as
+        isOvertime,a.progress as progress,
+        a.department_audit_state as departmentAuditState, a.stage, a.pic_str as picStr, multi_worktime as multiWorktime,a.is_dept_audit as isDeptAudit,a.group_audit_state as groupAuditState,task_group.incharger_id as inchargerId,a.project_audit_state as projectAuditState,a.audit_dept_managerid as deptAuditorName
+        , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as
+        degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId,
+        a.custom_data as customData
+        ,c.plate1 as plate1,c.plate2 as plate2,c.plate3 as plate3,c.plate4 as plate4,c.plate5 as plate5
+        ,u.name as projectAuditorName,u.corpwx_userid as projectAuditorCorpwxUserId, a.project_auditor_id as projectAuditorId, department.department_name as
+        departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText, a.project_audit_time as
+        projectAuditTime,project_main.name as projectMainName,
+        GROUP_CONCAT(rlog.operator_id,'@', rlog.operate_date,'@', rlog.msg SEPARATOR '❤') AS logMsg
+        FROM report AS a
+        JOIN project AS b ON a.project_id=b.id
+        LEFT JOIN user AS c ON a.creator_id=c.id
+        left join sub_project as d on d.id = a.sub_project_id
+        left join task on task.id = a.task_id
+        left join report_extra_degree on report_extra_degree.id = a.degree_id
+        left join task_group on task_group.id = a.group_id
+        left join user u on u.id = a.project_auditor_id
+        left join department on department.department_id = c.department_id
+        left join department dp2 on dp2.department_id = b.bu_id
+        left join project_main on project_main.id=b.project_main_id
+        left join report_log_detail rlog on rlog.report_id = a.id
+        WHERE
+        (<if test="stateKey == null or stateKey == 0">
+        a.state = 1
+    </if>
+        <if test="stateKey!=null">
+            <if test="stateKey==1">
+                (a.state = 1 or a.state=0 or a.state = -1)
+            </if>
+            <if test="stateKey==2">
+                (a.state=0 or a.state = -1)
+            </if>
+        </if>)
+        <if test="startDate != null and startDate != ''">
+            AND a.create_date between #{startDate} and #{endDate}
+        </if>
+        <if test="companyId != null">
+            AND c.company_id = #{companyId}
+        </if>
+        <if test="projectId != null">
+            AND a.project_id = #{projectId}
+        </if>
+        <if test="leaderId != null">
+            AND (b.incharger_id = #{leaderId} or a.creator_id=#{leaderId})
+        </if>
+        <if test="branchDepartment != null">
+            AND department.department_id in
+            <foreach collection="branchDepartment" item="deptId" separator="," close=")" open="(" index="index">
+                #{deptId}
+            </foreach>
+        </if>
+        group by a.id
+        ORDER BY a.creator_id, a.create_date desc
+    </select>
     <select id="getDeptMembReportByDate" resultType="java.util.Map">
         SELECT a.id, c.name,c.job_number as jobNumber,c.corpwx_userid as corpwxUserId,c.corpwx_deptid as corpwxDeptId, b.project_name AS project, b.project_code as projectCode,b.category_name as categoryName, a.working_time AS duration, a.content, a.create_time AS time,a.create_date as createDate,
         a.state, a.time_type as timeType, a.cost, a.report_time_type as reportTimeType, a.start_time as startTime,