Browse Source

Merge branch 'master' of http://47.100.37.243:10191/wutt/manHourHousekeeper into master

seyason 3 months ago
parent
commit
8e8781c904
14 changed files with 785 additions and 63 deletions
  1. 16 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  2. 11 8
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ReportBatch.java
  3. 17 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeekUserDaySummary.java
  4. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeekUserSummary.java
  5. 15 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyChargeReportData.java
  6. 27 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyDate.java
  7. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyProject.java
  8. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportBatchMapper.java
  9. 3 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java
  10. 339 18
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  11. 28 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportBatchMapper.xml
  12. 38 14
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  13. 3 3
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue
  14. 252 18
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/weeklyReportReview.vue

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

@@ -2230,6 +2230,22 @@ public class ReportController {
                 request);
     }
 
+    @RequestMapping("/listByStateNew")
+    public HttpRespMsg listByStateNew(@RequestParam Integer state,
+                                      Integer departmentId,
+                                      Integer projectId,
+                                      String date,
+                                      String startDate,
+                                      String endDate,
+                                      String userId,
+                                      String auditUserId,
+                                      HttpServletRequest request) {
+        return reportService.listByStateNew(state, departmentId,
+                projectId,
+                date, startDate, endDate, userId,auditUserId,
+                request);
+    }
+
     /**
      * 导出待审核日报列表
      * @param state

+ 11 - 8
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ReportBatch.java

@@ -1,21 +1,21 @@
 package com.management.platform.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.extension.activerecord.Model;
-import java.time.LocalDate;
-import com.baomidou.mybatisplus.annotation.TableId;
-import java.time.LocalDateTime;
 import com.baomidou.mybatisplus.annotation.TableField;
-import java.io.Serializable;
-import java.util.List;
-import java.util.Map;
-
+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 java.io.Serializable;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Map;
+
 /**
  * <p>
  * 
@@ -88,6 +88,9 @@ public class ReportBatch extends Model<ReportBatch> {
     @TableField(exist = false)
     private String name;
 
+    @TableField(exist = false)
+    private String departmentId;
+
     @TableField(exist = false)
     private String departmentName;
 

+ 17 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeekUserDaySummary.java

@@ -0,0 +1,17 @@
+package com.management.platform.entity;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+public class WeekUserDaySummary {
+    private LocalDate currentDate;
+    private String currentDateTxt;
+    private String weekDayTxt;
+//    private List<WeeklyProject> projectList;
+
+
+    private List<WeeklyChargeReportData> projectList;
+}

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeekUserSummary.java

@@ -0,0 +1,19 @@
+package com.management.platform.entity;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+public class WeekUserSummary {
+    private String userId;
+    private String userName;
+    private LocalDate weekStart;
+    private LocalDate weekEnd;
+    private String weekStartTxt;
+    private String weekEndTxt;
+    private String departmentId;
+    private String departmentName;
+    private List<WeekUserDaySummary> daySummaryList;
+}

+ 15 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyChargeReportData.java

@@ -14,6 +14,7 @@ public class WeeklyChargeReportData {
     private String customText;
     private String date;
     private Integer degree_id;
+    private String degreeName;
     private Integer departmentAuditState;
     private String departmentName;
     private Integer groupAuditState;
@@ -33,9 +34,22 @@ public class WeeklyChargeReportData {
     private Integer projectId;
     private Integer reportTimeType;
     private String stage;
+    private String picStr;
+    private String rejectReason;
+    private String rejectUsername;
+    private String rejectUserid;
+    private String deptAuditorName;
+//    private String batchId;
+    private String extraField1;
+    private String extraField2;
+    private String extraField3;
+    private String sapServiceId;
+    private String multiDegrId;
     private Integer state;
-    private Integer time;
+    private BigDecimal time;
     private Integer timeType;
     private String userId;
     private List<WeeklyChargeReportWorkTime> worktimeList;
+
+    private String weekDayTxt;
 }

+ 27 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyDate.java

@@ -0,0 +1,27 @@
+package com.management.platform.entity;
+
+import lombok.Data;
+
+import java.time.LocalDate;
+import java.util.List;
+
+@Data
+public class WeeklyDate {
+//    private String startDateText;
+//    private String endDateText;
+    private LocalDate startDate;
+    private LocalDate endDate;
+
+    /**仅为方便用*/
+    private LocalDate currentDate;
+    /**仅为方便用*/
+    private String currentDateText;
+    /**仅为方便用*/
+    private String weekDayTxt;
+    /**仅为方便用*/
+    private List<WeeklyDate> currentWeekDates;
+    /**仅为方便用*/
+    private List<WeeklyChargeReportData> currentDateProjectReports;
+    /**仅为方便用*/
+    private List<WeeklyProject> projects;
+}

+ 10 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/WeeklyProject.java

@@ -0,0 +1,10 @@
+package com.management.platform.entity;
+
+import lombok.Data;
+
+@Data
+public class WeeklyProject {
+    private Integer projectId;
+    private String projectName;
+    private String projectCode;
+}

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportBatchMapper.java

@@ -2,6 +2,10 @@ package com.management.platform.mapper;
 
 import com.management.platform.entity.ReportBatch;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.management.platform.entity.WeeklyDate;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
 
 /**
  * <p>
@@ -13,4 +17,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  */
 public interface ReportBatchMapper extends BaseMapper<ReportBatch> {
 
+    List<ReportBatch> getWeekData(@Param("startDate") String startDate,@Param("endDate") String endDate,@Param("companyId") Integer companyId);
+
+    List<WeeklyDate> getWeekDate(@Param("startDate") String startDate, @Param("endDate") String endDate, @Param("companyId") Integer companyId);
 }

+ 3 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ReportService.java

@@ -12,7 +12,6 @@ import org.springframework.web.multipart.MultipartFile;
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
 import java.time.LocalDate;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -173,4 +172,7 @@ public interface ReportService extends IService<Report> {
     HttpRespMsg getCurAuditNode(String date, String userId);
 
     HttpRespMsg getReportTimeLessThanCardTimeList(String date, Integer deptId, String userId);
+
+    HttpRespMsg listByStateNew(Integer state, Integer departmentId, Integer projectId, String date, String startDate, String endDate, String userId, String auditUserId, HttpServletRequest request);
+
 }

+ 339 - 18
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -19,6 +19,7 @@ import me.chanjar.weixin.mp.api.WxMpService;
 import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
 import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
@@ -1649,7 +1650,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
     //获取待审核项目报告列表
     @Override
-    public HttpRespMsg getListByState(Integer state, Integer departmentId,
+    public HttpRespMsg listByStateNew(Integer state, Integer departmentId,
                                       Integer projectId,
                                       String date,
                                       String startDate,
@@ -1657,6 +1658,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                                       String userId,String auditUserId,HttpServletRequest request) {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         try {
+            long beforeStart = System.currentTimeMillis();
             User curUser = userMapper.selectById(request.getHeader("Token"));
             Integer companyId = curUser.getCompanyId();
             TimeType timeType = timeTypeMapper.selectById(companyId);
@@ -1887,39 +1889,358 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }
                 }
             }
+            long beforeEnd = System.currentTimeMillis();
+
+            System.out.println("前置查询耗时:"+(beforeEnd-beforeStart)+"ms");
+
             if(1 == timeType.getWeeklyChargeFilter()){
-                Map<String,Object> resMap = new HashMap<>();
+//                Map<String,Object> resMap = new HashMap<>();
+                long afterStart = System.currentTimeMillis();
                 List<WeeklyChargeReports> weeklyChargeReports = JSONObject.parseArray(JSON.toJSON(nameList).toString(), WeeklyChargeReports.class);
-                System.out.println("weeklyChargeReports.size()== "+weeklyChargeReports.size());
-                List<Integer> finalProjectIdList = new ArrayList<>();
-                for (WeeklyChargeReports weeklyChargeReport : weeklyChargeReports) {
-                    List<Integer> projectIdList = weeklyChargeReport.getData().stream()
-                            .filter(t -> null != t.getProjectId())
-                            .map(WeeklyChargeReportData::getProjectId)
-                            .distinct()
-                            .collect(Collectors.toList());
-                    finalProjectIdList.addAll(projectIdList);
 
+                if(CollectionUtils.isNotEmpty(weeklyChargeReports)){
 
+                    // 人 周开始 周结束
+                    List<ReportBatch> weekData = reportBatchMapper.getWeekData(startDate, endDate, companyId);
 
-                }
-                finalProjectIdList = finalProjectIdList.stream().distinct().collect(Collectors.toList());
+                    List<WeeklyChargeReportData> allData = new ArrayList<>();
+                    for (WeeklyChargeReports weeklyChargeReport : weeklyChargeReports) {
+                        allData.addAll(weeklyChargeReport.getData());
+                    }
 
-                List<Project> projects = projectMapper.selectList(new LambdaQueryWrapper<Project>().eq(Project::getCompanyId, companyId)
-                        .in(Project::getId, finalProjectIdList)
-                );
-                resMap.put("projects",projects);
+                    //按照人分组
+                    Map<String, List<WeeklyChargeReportData>> collect = allData.stream().collect(Collectors.groupingBy(WeeklyChargeReportData::getUserId));
 
+                    //日期不传
+//                    if(startDate != null && endDate != null){
+//
+//                    }
 
 
+//                    LocalDate now = LocalDate.now();
+//                    LocalDate monday = now.with(DayOfWeek.MONDAY);
+//                    LocalDate sunday = now.with(DayOfWeek.SUNDAY);
+//                    int dayIndex = now.getDayOfWeek().getValue();//当前天所处周的第几天
+                    List<WeekUserSummary> resList = new ArrayList<>();
+                    if(CollectionUtils.isNotEmpty(weekData)){
+                        for (ReportBatch weekDatum : weekData) {// 人 周开始 周结束
+                            WeekUserSummary weekUserSummary = new WeekUserSummary();
+                            weekUserSummary.setUserId(weekDatum.getCreatorId());
+                            weekUserSummary.setUserName(weekDatum.getName());
+                            weekUserSummary.setWeekStart(weekDatum.getStartDate());
+                            weekUserSummary.setWeekEnd(weekDatum.getEndDate());
+                            weekUserSummary.setDepartmentId(weekDatum.getDepartmentId());
+                            weekUserSummary.setDepartmentName(weekDatum.getDepartmentName());
+                            weekUserSummary.setWeekStartTxt(weekDatum.getStartDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                            weekUserSummary.setWeekEndTxt(weekDatum.getEndDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                            List<WeekUserDaySummary> daySummaryList = new ArrayList<>();
+                            List<WeeklyChargeReportData> userReportData = collect.get(weekDatum.getCreatorId());
+                            //当前人的所有未审核日报
+                            if(CollectionUtils.isNotEmpty(userReportData)){
+                                //若当前时间段内未填报日报为空,则跳过
+                                long count = userReportData.stream().filter(t -> {
+                                    LocalDate tmpDate = LocalDate.parse(t.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                                    if ((tmpDate.isEqual(weekDatum.getStartDate()) || tmpDate.isAfter(weekDatum.getStartDate()))
+                                            && (tmpDate.isEqual(weekDatum.getEndDate()) || tmpDate.isBefore(weekDatum.getEndDate()))) {
+                                        //数据在指定时间段内
+                                        return true;
+                                    } else {
+                                        return false;
+                                    }
+                                }).count();
+                                if(count <=0){
+                                    continue;
+                                }
+                                //获取当前区间内的日报
+                                for (int i = 0; i < 7; i++) {
+                                    WeekUserDaySummary weekUserDaySummary = new WeekUserDaySummary();
+                                    weekUserDaySummary.setCurrentDate(weekDatum.getStartDate().plusDays(i));
+                                    weekUserDaySummary.setCurrentDateTxt(weekUserDaySummary.getCurrentDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
+                                    weekUserDaySummary.setWeekDayTxt(DateTimeUtil.getWeekDayTxt(i+1));
+                                    List<WeeklyChargeReportData> tmpDayData = userReportData.stream().filter(t -> {
+                                        LocalDate tmpDate = LocalDate.parse(t.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                                        if (tmpDate.isEqual(weekUserDaySummary.getCurrentDate())) {
+                                            //数据在指定天
+                                            return true;
+                                        } else {
+                                            return false;
+                                        }
+                                    }).collect(Collectors.toList());
+                                    weekUserDaySummary.setProjectList(tmpDayData);
+//                                    tmpDayData.forEach(t->{
+//
+//                                    });
+                                    daySummaryList.add(weekUserDaySummary);
+                                }
+                                weekUserSummary.setDaySummaryList(daySummaryList);
+                                resList.add(weekUserSummary);
+                            }
+
+                        }
+                    }
 
+                    long afterEnd = System.currentTimeMillis();
+                    System.out.println("后置拼接耗时:"+(afterEnd-afterStart)+"ms");
 
+                    httpRespMsg.data = resList;
+                }
 
-                httpRespMsg.data = resMap;
             }else{
                 httpRespMsg.data = nameList;
             }
 
+//            httpRespMsg.data = nameList;
+
+        } catch (NullPointerException e) {
+            //httpRespMsg.setError("验证失败");
+            e.printStackTrace();
+            httpRespMsg.setError(MessageUtils.message("access.verificationError"));
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    //获取待审核项目报告列表
+    @Override
+    public HttpRespMsg getListByState(Integer state, Integer departmentId,
+                                      Integer projectId,
+                                      String date,
+                                      String startDate,
+                                      String endDate,
+                                      String userId,String auditUserId,HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            User curUser = userMapper.selectById(request.getHeader("Token"));
+            Integer companyId = curUser.getCompanyId();
+            TimeType timeType = timeTypeMapper.selectById(companyId);
+            Integer isParallel = timeType.getReportAuditType() == 7? 1 : 0;
+            Integer isEngeering = companyMapper.selectById(companyId).getPackageEngineering();
+            String leaderId = null;
+            List<SysRichFunction> functionList = sysFunctionMapper.getRoleFunctions(curUser.getRoleId(), "审核全员日报");
+            if (functionList.size() == 0) {//没有全员审核的权限
+                leaderId = curUser.getId();
+            }
+            List<String> targetUids = null;
+            if (!StringUtils.isEmpty(userId)) {
+                targetUids = ListUtil.convertLongIdsArrayToList(userId);
+            }
+            List<Map<String, Object>> auditReportList = reportMapper.getAuditReportList(date, companyId, departmentId, projectId, leaderId, isEngeering, startDate, endDate, targetUids,auditUserId, isParallel);
+            //针对依斯贝增加服务名称显示
+            if (companyId == 3092) {
+                List<SapProjectService> serviceList = sapProjectServiceMapper.selectList(new QueryWrapper<SapProjectService>().eq("company_id", companyId));
+                for (Map<String, Object> mapItem : auditReportList) {
+                    Integer sapServiceId = (Integer)mapItem.get("sapServiceId");
+                    if (sapServiceId != null) {
+                        Optional<SapProjectService> first = serviceList.stream().filter(s -> s.getId().equals(sapServiceId)).findFirst();
+                        if (first.isPresent()) {
+                            mapItem.put("sapServiceName", first.get().getServiceName());
+                        }
+                    }
+                }
+            }
+            //抽取姓名,进行分组
+            List<Map<String, Object>> nameList = new ArrayList<Map<String, Object>>();
+            Map<String, Object> lastName = null;
+            //某个用户某天下的各个项目日报列表
+            List<Map<String, Object>> userDailyReportList = null;
+            for (Map a : auditReportList) {
+                String createDate = (String)a.get("date");
+                String name = (String)a.get("name");
+                String uid = (String)a.get("userId");
+                String corpwxUserid = (String)a.get("corpwxUserid");
+
+                if (lastName == null || !(lastName.get("name").equals(name) && lastName.get("dateStr").equals(createDate))) {
+                    lastName = new HashMap<String, Object>();
+                    lastName.put("dateStr", createDate);
+                    lastName.put("name", name);
+                    lastName.put("userId", uid);
+                    lastName.put("corpwxUserid", corpwxUserid);
+                    nameList.add(lastName);
+                    userDailyReportList = new ArrayList<>();
+                    lastName.put("data", userDailyReportList);
+                }
+                //每组日报数据都加上去
+                userDailyReportList.add(a);
+            }
+            List<Profession> professions = new ArrayList<>();
+            if (isEngeering == 1) {
+                professions = professionMapper.selectList(new QueryWrapper<Profession>().eq("company_id", curUser.getCompanyId()));
+            }
+            for (int index=0;index<nameList.size(); index++) {
+                Map<String, Object> map2 = nameList.get(index);
+                List<Map<String, Object>> list2 = (List)map2.get("data");
+                //项目专业进度
+                if (isEngeering == 1) {
+                    final List<Profession> fProfessList = professions;
+                    for (Map<String, Object> map : list2) {
+                        //获取当前项目的工程专业进度
+                        List<ReportProfessionProgress> progressList = reportProfessionProgressService.list(new QueryWrapper<ReportProfessionProgress>().eq("report_id", (int)map.get("id")));
+                        progressList.stream().forEach(p->{
+                            p.setProfessionName(fProfessList.stream().filter(m->m.getId().equals(p.getProfessionId())).findFirst().get().getName());
+                        });
+                        map.put("professionProgressList", progressList);
+                    }
+                }
+
+                double reportTime = 0;
+                BigDecimal total = new BigDecimal(0);
+                //计算每日汇总的工时成本
+                for (Map<String, Object> m : list2) {
+                    double t = (double) m.get("time");
+                    reportTime += t;
+                    total = total.add((BigDecimal)m.get("cost"));
+                }
+                DecimalFormat df = new DecimalFormat("0.00");
+                map2.put("reportTime", df.format(reportTime));
+                map2.put("cost", total);
+                map2.put("state", list2.get(0).get("state"));
+                map2.put("auditDeptName", list2.get(0).get("auditDeptName"));
+                map2.put("isDeptAudit", list2.get(0).get("isDeptAudit"));
+                map2.put("groupAuditState", list2.get(0).get("groupAuditState"));
+                map2.put("deptAuditorName", list2.get(0).get("deptAuditorName"));
+                //增加填报人所属部门
+                map2.put("departmentName", list2.get(0).get("departmentName"));
+            }
+            //设置照片显示
+            for (Map map : nameList) {
+                List<Map<String, Object>> reportList = (List<Map<String, Object>>)map.get("data");
+                for (Map<String, Object> report : reportList) {
+                    String picStr = (String)report.get("picStr");
+                    if (picStr != null && !"@".equals(picStr)) {
+                        JSONArray array = JSONArray.parseArray(picStr.replaceAll("@", ","));
+                        List<String> picList = new ArrayList<>();
+                        for (int i=0;i<array.size(); i++) {
+                            String picName = array.getString(i);
+                            if (!picName.contains(".")) {
+                                picName += ".jpg";
+                            }
+                            picList.add("/upload/" + picName);
+                        }
+                        report.put("pics", picList);
+                    }
+                    if (((Integer)report.get("multiWorktime")) == 1) {
+                        //设置多个工时情况下的报告列表
+                        String timeStr = (String)report.get("content");
+                        report.put("worktimeList", JSONArray.parse(timeStr));
+                    }
+                }
+            }
+            //针对昱众,设置职能分工显示
+            if (companyId == 3385) {
+                List<ProjectFunctionalDivision> allDivList = projectFunctionalDivisionMapper.selectList(new QueryWrapper<ProjectFunctionalDivision>().eq("company_id", companyId));
+                List<ProFunWorkContext> allWorkContextList = proFunWorkContextMapper.selectList(new QueryWrapper<>());
+                for (Map map : nameList) {
+                    List<Map<String, Object>> reportList = (List<Map<String, Object>>)map.get("data");
+                    for (Map<String, Object> report : reportList) {
+                        Integer extraField2 = (Integer)report.get("extraField2");
+                        Optional<ProjectFunctionalDivision> first = allDivList.stream().filter(d->d.getId().equals(extraField2)).findFirst();
+                        if (first.isPresent()) {
+                            ProjectFunctionalDivision divItem = first.get();
+                            report.put("extraField2Name", divItem.getJobRespon());
+                        }
+                        Integer extraField3 = (Integer)report.get("extraField3");
+                        Optional<ProFunWorkContext> first2 = allWorkContextList.stream().filter(d->d.getId().equals(extraField3)).findFirst();
+                        if (first2.isPresent()) {
+                            ProFunWorkContext workItem = first2.get();
+                            report.put("extraField3Name", workItem.getWorkContext());
+                        }
+                    }
+                }
+            }
+            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+            String minDate = null;
+            String maxDate = null;
+            if (nameList.size() > 0) {
+                List<String> dateList = nameList.stream().map(m->(String)m.get("dateStr")).collect(Collectors.toList());
+                //获取最大和最小日期
+                minDate = dateList.stream().min(Comparator.comparing(String::toString)).get();
+                maxDate = dateList.stream().max(Comparator.comparing(String::toString)).get();
+            }
+            //设置每人每日考勤打卡时长
+            if (timeType.getShowCorpwxCardtime() == 1) {
+                //企业微信的情况
+                QueryWrapper<UserCorpwxTime> userCorpwxTimeQueryWrapper = new QueryWrapper<>();
+                if (nameList.size() > 0) {
+                    //获取日期范围
+                    userCorpwxTimeQueryWrapper.between("create_date", minDate, maxDate).eq("company_id", companyId);
+                    List<UserCorpwxTime> timeList = userCorpwxTimeMapper.selectList(userCorpwxTimeQueryWrapper);
+                    //过滤匹配当前的数据
+                    for (Map map : nameList) {
+                        String corpwxUserid = (String)map.get("corpwxUserid");
+                        String name = (String)map.get("name");
+                        String dateStr = (String)map.get("dateStr");
+                        Optional<UserCorpwxTime> first = timeList.stream().filter(time -> ((time.getCorpwxUserid() != null && time.getCorpwxUserid().equals(corpwxUserid)) || (time.getCorpwxUserid() == null && name != null && name.equals(time.getName()))) && dtf.format(time.getCreateDate()).equals(dateStr)).findFirst();
+                        if (first.isPresent()) {
+                            double wh = first.get().getWorkHours();
+                            //赋值打卡时长
+                            map.put("cardHours", wh);
+                        }
+                    }
+                }
+            } else if (timeType.getShowDdCardtime() == 1) {
+                //钉钉的情况
+                QueryWrapper<UserDingdingTime> userDingdingTimeQueryWrapper = new QueryWrapper<>();
+                if (nameList.size() > 0) {
+                    userDingdingTimeQueryWrapper.between("work_date", minDate, maxDate).eq("company_id", companyId);
+                    List<UserDingdingTime> timeList = userDingdingTimeMapper.selectList(userDingdingTimeQueryWrapper);
+                    //过滤匹配当前的数据
+                    for (Map map : nameList) {
+                        String itemUid = (String)map.get("userId");
+                        String dateStr = (String)map.get("dateStr");
+                        Optional<UserDingdingTime> first = timeList.stream().filter(time -> time.getUserId().equals(itemUid) && dtf.format(time.getWorkDate()).equals(dateStr)).findFirst();
+                        if (first.isPresent()) {
+                            double wh = first.get().getWorkHours();
+                            //赋值打卡时长
+                            map.put("cardHours", wh);
+                        }
+                    }
+                }
+            } else if(timeType.getSyncFanwei()==1){
+                //泛微的情况
+                QueryWrapper<UserFvTime> userFvTimeQueryWrapper = new QueryWrapper<>();
+                if (nameList.size() > 0) {
+                    userFvTimeQueryWrapper.between("work_date", minDate, maxDate).eq("company_id", companyId);
+                    List<UserFvTime> timeList = userFvTimeMapper.selectList(userFvTimeQueryWrapper);
+                    //过滤匹配当前的数据
+                    for (Map map : nameList) {
+                        String itemUid = (String)map.get("userId");
+                        String dateStr = (String)map.get("dateStr");
+                        Optional<UserFvTime> first = timeList.stream().filter(time -> time.getUserId().equals(itemUid) && dtf.format(time.getWorkDate()).equals(dateStr)).findFirst();
+                        if (first.isPresent()) {
+                            double wh = first.get().getWorkHours();
+                            //赋值打卡时长
+                            map.put("cardHours", wh);
+                        }
+                    }
+                }
+            }
+            //解析自定义多选的
+            if (timeType.getCustomDegreeActive() == 1 && timeType.getCustomDegreeMultiple()) {
+                List<ReportExtraDegree> extraList = reportExtraDegreeMapper.selectList(new QueryWrapper<ReportExtraDegree>().eq("company_id", companyId));
+                for (Map map : nameList) {
+                    List<Map<String, Object>> reportList = (List<Map<String, Object>>)map.get("data");
+                    for (Map<String, Object> report : reportList) {
+                        String multiDegrId = (String)report.get("multiDegrId");
+                        if (multiDegrId != null) {
+                            multiDegrId = multiDegrId.replace("@", ",");
+                            JSONArray array = JSONArray.parseArray(multiDegrId);
+                            String s = "";
+                            for (int i=0;i<array.size(); i++) {
+                                int item = array.getInteger(i);
+                                Optional<ReportExtraDegree> find = extraList.stream().filter(ex->ex.getId().equals(item)).findFirst();
+                                if (find.isPresent()) {
+                                    s += find.get().getName() + ",";
+                                }
+                            }
+                            if (s.length() > 0) {
+                                s = s.substring(0, s.length()-1);
+                            }
+                            report.put("degreeName", s);
+                        }
+                    }
+                }
+            }
+            httpRespMsg.data = nameList;
         } catch (NullPointerException e) {
             //httpRespMsg.setError("验证失败");
             e.printStackTrace();

+ 28 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportBatchMapper.xml

@@ -20,5 +20,33 @@
     <sql id="Base_Column_List">
         id, creator_id, start_date, end_date, total_work_time, state, create_time, company_id, summary, attachment
     </sql>
+    <select id="getWeekData" resultType="com.management.platform.entity.ReportBatch">
+        select rb.creator_id,rb.start_date,rb.end_date,user.name,user.department_id,d.department_name
+        from report_batch rb
+        left join user on rb.creator_id = user.id
+        left join department d on user.department_id = d.department_id
+        <where>
+            rb.company_id = #{companyId}
+            and rb.state = 0
+            <if test="endDate != null and startDate != null and startDate!= '' and endDate != ''">
+                and  rb.start_date &lt; #{endDate} and rb.end_date &gt; #{startDate}
+            </if>
+        </where>
+        group by rb.creator_id,rb.start_date
+        order by rb.creator_id asc,rb.start_date desc
+    </select>
+    <select id="getWeekDate" resultType="com.management.platform.entity.WeeklyDate">
+        select start_date as startDate ,end_date as endDate
+        from report_batch
+        <where>
+            company_id = #{companyId}
+            and state = 0
+            <if test="endDate != null and startDate != null and startDate!= '' and endDate != ''">
+                and  start_date &lt; #{endDate} and end_date &gt; #{startDate}
+            </if>
+        </where>
+        group by start_date
+        order by start_date
+    </select>
 
 </mapper>

File diff suppressed because it is too large
+ 38 - 14
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue


+ 3 - 3
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/list.vue

@@ -1,11 +1,11 @@
 <template>
   <div class="projectReportReview">
-    <!-- <template v-if="user.timeType.weeklyChargeFilter != 1"> -->
+    <template v-if="user.timeType.weeklyChargeFilter != 1">
         <dailyReportReview />
-    <!-- </template>
+    </template>
     <template>
         <weeklyReportReview />
-    </template> -->
+    </template>
   </div>
 </template>
 

+ 252 - 18
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/weeklyReportReview.vue

@@ -43,7 +43,7 @@
                           </el-option>
                       </el-select>
                   </el-form-item>
-                      <el-form-item :label="$t('weekDay.date')">
+                      <el-form-item :label="$t('weekDay.date')" v-if="false">
                           <el-date-picker
                               v-model="dataTime"
                               type="daterange"
@@ -55,8 +55,8 @@
                       </el-form-item>
 
                       <el-form-item   style="margin-left:20px;">
-                          <el-button @click="batchApprove(true)" style="margin-left:10px;" :loading="batchApproveLoading" :disabled="multipleSelection.length==0" size="mini">{{ $t('Batchthrough') }}</el-button>
-                          <el-button @click="batchApprove(false)"   :disabled="multipleSelection.length==0" size="mini">{{ $t('Batchrejected') }}</el-button>
+                          <el-button @click="batchCallThrough()" style="margin-left:10px;" :loading="batchApproveLoading" :disabled="multipleSelection.length==0" size="mini">{{ $t('Batchthrough') }}</el-button>
+                          <el-button @click="batchRejection()"   :disabled="multipleSelection.length==0" size="mini">{{ $t('Batchrejected') }}</el-button>
                       </el-form-item>
                       <el-form-item style="margin-left:20px;">
                       <el-link type="primary" @click="recordList(),recordDialogVisible = true,pageIndexList = 1,pageSizeList = 20">{{ $t('Auditrecords') }}</el-link>
@@ -70,11 +70,12 @@
       
       <!--列表-->
       <div class="reviewTable" ref="reviewTable">
-        <el-table :data="list" style="width: 100%">
+        <el-table :data="list" style="width: 100%" @selection-change="weeklyReportRowSelect">
+          <el-table-column type="selection" width="55"></el-table-column>
           <el-table-column type="expand">
             <template slot-scope="props">
               <div style="padding: 10px 30px">
-                <el-table :data="props.row.dataList" style="width: 100%" border @selection-change="(e) => weeklyReportItemSelect(e, props.row)">
+                <el-table :data="props.row.dataList" style="width: 100%" border @selection-change="(e) => weeklyReportItemSelect(e, props.row)" :span-method="({rowIndex, columnIndex}) => mergeCellsRow({ rowIndex, columnIndex, dataLength: props.row.dataList.length, columnLength: props.row.projectNameList.length })">
                   <el-table-column type="selection" width="55"></el-table-column>
                   <el-table-column label="日期" prop="userName">
                     <template slot-scope="scope">
@@ -84,15 +85,15 @@
                   <template v-for="(item, index) in props.row.projectNameList">
                     <el-table-column :label="item" prop="item" align="center">
                       <template slot-scope="scope">
-                        <el-link type="primary">
+                        <el-link type="primary" @click="viewDetails(scope.row.projectList[item])">
                           {{ scope.row.projectList[item] && scope.row.projectList[item].time + 'h' }}
                         </el-link>
                       </template>
                     </el-table-column>
                   </template>
                   <el-table-column label="操作" fixed="right" width="220">
-                    <el-button type="success" size="small" :disabled="props.row.selectItem.length <= 0">通过</el-button>
-                    <el-button type="danger" size="small" :disabled="props.row.selectItem.length <= 0">驳回</el-button>
+                    <el-button type="success" size="small" :disabled="props.row.selectItem.length <= 0" @click="rowMeans(props.row)">通过</el-button>
+                    <el-button type="danger" size="small" :disabled="props.row.selectItem.length <= 0" @click="rowRejection(props.row)">驳回</el-button>
                   </el-table-column>
                 </el-table>
               </div>
@@ -303,6 +304,111 @@
               <el-button type="primary" @click="approveinfun()" v-else>{{ $t('btn.determine') }}</el-button>
           </div>
       </el-dialog>
+
+      <el-dialog title="查看详情" v-if="FilteredDataRowVisable" :visible.sync="FilteredDataRowVisable" :close-on-click-modal="false" customClass="customWidth" width="800px">
+          <div>
+            <el-card shadow="never">
+                <p>{{ $t('other.project') + ':' }}<b>{{FilteredDataRow.projectCode+'/'+FilteredDataRow.project}}<span v-if="FilteredDataRow.subProjectName != null"> / {{FilteredDataRow.subProjectName}}</span>
+                    <span style="margin-left:15px;color:#DAA520;" >[ 
+                        <span v-if="user.timeType.reportAuditType == 7">
+                            {{$t('other.reviewer')}}:<TranslationOpenData :configurationItems="{ openType: 'userName', openId: FilteredDataRow.projectAuditorName, renderIndex: 0 }" /><span v-if="FilteredDataRow.projectAuditState==1">√</span>
+                            <span v-if="FilteredDataRow.deptAuditorName">、</span>
+                            <TranslationOpenData :configurationItems="{ openType: 'userName', openId: FilteredDataRow.deptAuditorName, renderIndex: 0 }" /><span v-if="FilteredDataRow.departmentAuditState==1">√</span>
+                        </span>
+                        <span v-else>
+                            <span v-if="FilteredDataRow.isDeptAudit==0">
+                                <span v-if="FilteredDataRow.projectAuditState==0">
+                                    {{ user.companyId == 469?"待部门主管":$t('other.waitForTheProjectReviewer') }}<span v-if="FilteredDataRow.projectAuditorName != null">(
+                                        <!-- {{FilteredDataRow.projectAuditorName}} -->
+                                        <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='FilteredDataRow.projectAuditorName'></TranslationOpenDataText></span>
+                                        <span v-if="user.userNameNeedTranslate != '1'">{{FilteredDataRow.projectAuditorName}}</span>
+                                        )</span>{{ $t('other.audit') }}
+                                </span>
+                                <span style="color:#32CD32;" v-else-if="FilteredDataRow.projectAuditState==1">
+                                    {{ user.companyId == 469?"待部门主管":$t('other.projectAuditor') }}<span v-if="FilteredDataRow.projectAuditorName != null">(
+                                        <!-- {{FilteredDataRow.projectAuditorName}} -->
+                                        <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='FilteredDataRow.projectAuditorName'></TranslationOpenDataText></span>
+                                        <span v-if="user.userNameNeedTranslate != '1'">{{FilteredDataRow.projectAuditorName}}</span>
+                                    )</span>{{ $t('state.approved') }}
+                                </span>
+                            </span>
+                            <span v-else-if="FilteredDataRow.isDeptAudit==1">
+                                <!-- {{($t('other.await') +FilteredDataRow.auditDeptName+('('+FilteredDataRow.deptAuditorName+')')+ $t('other.audit'))}} -->
+                                ({{$t('other.await')}}
+                                <span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='departmentName' :openid='FilteredDataRow.auditDeptName'></TranslationOpenDataText></span>
+                                <span v-if="user.userNameNeedTranslate != '1'">{{FilteredDataRow.auditDeptName}}</span>
+                                (<span v-if="user.userNameNeedTranslate == '1'"><TranslationOpenDataText type='userName' :openid='FilteredDataRow.deptAuditorName'></TranslationOpenDataText></span>
+                                <span v-if="user.userNameNeedTranslate != '1'">{{FilteredDataRow.deptAuditorName}}</span>)
+                                {{$t('other.audit')}})
+                            </span>
+                        </span>]
+                    </span>
+                    </b>
+                </p>
+                <p v-if="user.timeType.reportAuditType == 6" >{{ $t('shenHeLiuCheng') }}<span v-if="FilteredDataRow.auditorList && FilteredDataRow.auditorList.length == 1">{{ $t('yiCengShenHe') }}(<span class="themeFontColor">{{ FilteredDataRow.auditorList[0].name }}</span>)</span>
+                <span v-if="FilteredDataRow.auditorList && FilteredDataRow.auditorList.length == 2">{{ $t('liangCengShenHe') }}(<span class="themeFontColor">{{ FilteredDataRow.auditorList[0].name }}->{{ FilteredDataRow.auditorList[1].name }}</span>)</span>
+                <el-button size="small" @click="viewOneReport(FilteredDataRow)" v-if="!FilteredDataRow.auditorList">{{ $t('cha-kan') }}</el-button>
+                </p>
+                <p v-if="user.timeType.customDegreeActive==1 && (FilteredDataRow.degree_id != null || FilteredDataRow.multiDegrId != '[]')">{{user.timeType.customDegreeName}}:{{FilteredDataRow.degreeName}}</p>
+                <p v-if="user.timeType.customDataActive==1">{{user.timeType.customDataName}}:{{FilteredDataRow.customData}}</p>
+                <p v-if="user.timeType.customTextActive==1">{{user.timeType.customTextName}}:{{FilteredDataRow.customText}}</p>
+                <p v-if="user.company.packageEngineering == 1">
+                    {{ $t('other.professionalProgress') +':'}} <span style="margin-right:10px;" v-for="progressItem in FilteredDataRow.professionProgressList" :key="progressItem.id">
+                        {{progressItem.professionName}}({{progressItem.progress}}%)
+                        <el-tooltip v-if="progressItem.auditState == 0"  :content="$t('state.WaitingAudit')" effect="light" placement="top">
+                        <i class="iconfont firerock-icondaibandengdaishenhe"></i>
+                        </el-tooltip>
+                        <el-tooltip v-if="progressItem.auditState == 1" :content="$t('state.alreadyPassed')" effect="light" placement="top">
+                        <i  class="iconfont firerock-iconshenhetongguo"></i>
+                        </el-tooltip>
+                        <el-tooltip v-if="progressItem.auditState == 2" :content="$t('state.notThrough')" effect="light" placement="top">
+                        <i  class="iconfont firerock-iconshenhebohui"></i>
+                        </el-tooltip>
+                        </span> 
+                </p>
+                <p v-if="user.companyId == yuzhongCompId">
+                                        <span>{{ $t('jiao-se') }}:{{FilteredDataRow.extraField1? roleList.filter(r=>r.value == FilteredDataRow.extraField1)[0].label:''}}</span>
+                                    <span style="margin-left:10px;">{{ $t('gongZuoZhiZe') }}:{{ FilteredDataRow.extraField2? FilteredDataRow.extraField2Name:''}}</span>
+                                    <span style="margin-left:10px;">{{ $t('gongZuoNeiRong') }}:{{ FilteredDataRow.extraField3? FilteredDataRow.extraField3Name:''}}</span></p>
+                <p v-if="FilteredDataRow.taskId != null">{{$t('other.task')}}:{{FilteredDataRow.taskName}}
+                    <span style="margin-left:10px;" v-if="user.companyId==3092">-- {{ $t('fuWu') }}:{{ FilteredDataRow.sapServiceName }}</span></p>
+                <p v-if="FilteredDataRow.groupId">
+                    <span>{{$t('other.taskGroup')}}:{{FilteredDataRow.groupName}}</span>
+                    <!-- 阶段 -->
+                    <span v-if="FilteredDataRow.stage != null && user.companyId != yuzhongCompId" style="margin-left:10px;"> {{$t('other.inputStage')}}:{{FilteredDataRow.stage}}</span>
+                </p>
+                <p v-if="user.company.companyName == '成都明夷电子科技有限公司'">
+                    <span>{{ $t('lable.percentageOfTime') }} :{{ FilteredDataRow.progress }}%</span>
+                </p>
+                <p v-else>
+                    <span v-if="FilteredDataRow.multiWorktime==1">{{ $t('other.project') }}</span>
+                    <span>{{$t('time.duration')}}:</span>
+                    <span v-if="FilteredDataRow.startTime">{{ FilteredDataRow.startTime + '-' + FilteredDataRow.endTime }}</span>
+                    <span>{{FilteredDataRow.time.toFixed(1)}}h </span>
+                    <span class="propsbtn" v-if="FilteredDataRow.isOvertime === 1">
+                    <el-tag type="danger" size="mini" style="margin-left: 65px">{{ $t('other.WorkOvertime') }}<span v-if="FilteredDataRow.overtimeHours">{{FilteredDataRow.overtimeHours.toFixed(1)}}{{$t('time.hour')}}</span></el-tag></span>
+                </p>
+
+                <div v-if="FilteredDataRow.multiWorktime==0">
+                <p>{{ $t('other.matters') }}:<span v-html="FilteredDataRow.content"></span></p>
+                </div>
+                <div v-if="FilteredDataRow.multiWorktime==1" >
+                    <div v-for="(timeItem, tIndex) in FilteredDataRow.worktimeList" :key="tIndex"
+                        style="border: 0.5px #ddd solid;margin:5px 0px;padding:5px; ">
+                        <p style="line-height:20px;margin:5px 0px;">{{$t('time.duration')}}:
+                            <span v-if="FilteredDataRow.reportTimeType == 2" style="margin-right:10px;">{{timeItem.startTime+'-'+timeItem.endTime}}</span>
+                        {{timeItem.time.toFixed(1)}}h  
+                        <span v-if="timeItem.detail" style="margin-left:10px;"> {{timeItem.detail}} </span>
+                        </p>
+                        <p style="line-height:20px;margin:5px 0px;">{{ $t('other.matters') }}:<span v-html="timeItem.content"></span></p>
+                    </div>
+                </div>
+            </el-card>
+          </div>
+          <div slot="footer" class="dialog-footer">
+              <el-button  @click="FilteredDataRowVisable = false" >{{ $t('btn.cancel') }}</el-button>
+          </div>
+      </el-dialog>
   </div>
 </template>
 
@@ -398,6 +504,9 @@
                   reason: ''
               },
               undoBathFormLoading: false,
+              tableSelectRow: [],
+              FilteredDataRow: {},
+              FilteredDataRowVisable: false
           };
       },
       filters: {
@@ -408,8 +517,11 @@
           }
       },
       methods: {
+        viewDetails(row) {
+            this.FilteredDataRow = row
+            this.FilteredDataRowVisable = true
+        },
           showBatchRevocationVisable(row, index) {
-              console.log(row, '<===== 点击当前撤销')
               this.batchRevocationList = row.membdateList || []
               this.batchRevocationListIndex = index
               this.batchRevocationVisable = true
@@ -768,8 +880,122 @@
               return tablePush;
           },
           weeklyReportItemSelect(val, row) {
-            console.log(val, row)
+            const { itemIndex } = row
+            const selectItemVal = val.map(item => item.weekDayTxt)
+            this.list[itemIndex].selectItem = selectItemVal
+          },
+          weeklyReportRowSelect(val) {
+            this.multipleSelection = val
+          },
+          rowMeans(val) {
+            const row = this.list[val.itemIndex]
+            const { daySummaryList, selectItem } = row
+            const newList = daySummaryList.filter(item => selectItem.includes(item.weekDayTxt))
+            const mergedProjectList = newList.map(item => item.projectList).reduce((acc, curr) => acc.concat(curr), []);
+            const idList = mergedProjectList.map(item => item.id)
+            this.callThrough(idList.join(','))
+          },
+          batchCallThrough() {
+            const val = this.multipleSelection
+            const dataList = val.flatMap(item => 
+                item.daySummaryList.flatMap(daySummary => 
+                    daySummary.projectList
+                )
+            );
+            const ids = dataList.map(item => item.id)
+            this.callThrough(ids.join(','))
           },
+          callThrough(ids) {
+            this.http.post(`/report/approve`, { reportIds: ids },
+            res => {
+                if (res.code == "ok") {
+                    this.$message({
+                        message: '操作成功',
+                        type: "success"
+                    });
+                    this.getList()
+                } else {
+                    this.$message({
+                        message: res.msg,
+                        type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+            });
+          },
+          rowRejection(val) {
+            const row = this.list[val.itemIndex]
+            const { daySummaryList, selectItem } = row
+            const newList = daySummaryList.filter(item => selectItem.includes(item.weekDayTxt))
+            console.log(newList, '<==== newList')
+            const mergedProjectList = newList.map(item => item.projectList).reduce((acc, curr) => acc.concat(curr), []);
+            const idList = mergedProjectList.map(item => item.id)
+            const text = newList.map(item => item.weekDayTxt)
+            this.$prompt(`确定驳回【${text.join(',')}】这些日报吗?`, '', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                inputPattern: /^(?!\s*$).+/,
+                inputErrorMessage: '请输入驳回原因',
+                inputPlaceholder: '请输入驳回原因'
+            }).then(({ value }) => {
+                this.rejectionReport(idList.join(','), value)
+            })
+          },
+          batchRejection() {
+            const val = this.multipleSelection
+            const dataList = val.flatMap(item => 
+                item.daySummaryList.flatMap(daySummary => 
+                    daySummary.projectList
+                )
+            );
+            const ids = dataList.map(item => item.id)
+            this.$prompt(`确定驳回选中的这些日报吗?`, '', {
+                confirmButtonText: '确定',
+                cancelButtonText: '取消',
+                inputPattern: /^(?!\s*$).+/,
+                inputErrorMessage: '请输入驳回原因',
+                inputPlaceholder: '请输入驳回原因'
+            }).then(({ value }) => {
+                this.rejectionReport(ids.join(','), value)
+            })
+          },
+          rejectionReport(ids, reason) {
+            this.http.post(`/report/batchDenyReport`, { ids, reason },
+            res => {
+                if (res.code == "ok") {
+                    this.$message({
+                        message: '操作成功',
+                        type: "success"
+                    });
+                    this.getList()
+                } else {
+                    this.$message({
+                        message: res.msg,
+                        type: "error"
+                    });
+                }
+            },
+            error => {
+                this.$message({
+                    message: error,
+                    type: "error"
+                });
+            });
+          },
+        mergeCellsRow({ rowIndex, columnIndex, dataLength, columnLength }) {
+            if (columnIndex === (+(columnLength || 0) + 2)) {
+                if (rowIndex === 0) {
+                    return [dataLength, 1];  // 合并最后一列的所有行
+                }
+                return [0, 0];  // 不显示其他行
+            }
+            return [1, 1]; // 其他列不合并
+        },
           //获取待审核的数据列表
           getList(e) {
               this.listLoading = true;
@@ -800,15 +1026,21 @@
               res => {
                   this.listLoading = false;
                   if (res.code == "ok") {
-                      // for (let entry of res.data) {
-                      //     let reviewerNames = (entry.data || []).map(item => item.projectAuditorName);
-                      //     let uniqueReviewerNames = [...new Set(reviewerNames)];
-                      //     entry.reviewerNames = uniqueReviewerNames;
-                      // }
-                      const newList = res.data.map(item => {
+                      if(!res.data) {
+                        this.listBackup = []
+                        this.list = []
+                        let total = 0
+                        this.reviewTableObj = {
+                          reviewTableTotal: total,
+                          reviewTableIndex: 1,
+                          reviewTableSize: this.reviewTableObj.reviewTableSize
+                        }
+                        return
+                      }
+                      const newList = (res.data || []).map((item, index) => {
                         const daySummaryList = (item.daySummaryList || []).filter(item => (item.projectList || []).length > 0)
                         const dataList = daySummaryList.map(item => {
-                          const projectList = item.projectList.reduce((acc, curr) => {
+                          const projectList = (item.projectList || []).reduce((acc, curr) => {
                             acc[curr.project] = curr;
                             return acc;
                           }, {});
@@ -820,13 +1052,15 @@
                         let projectNameList = []
                         for(let i in daySummaryList) {
                           const projectList = (daySummaryList[i].projectList || [])
-                          projectNameList = projectNameList.concat(projectList.map(item => item.project))
+                          const projectNames = projectList.map(item => item.project)
+                          projectNameList = [...new Set([...projectNameList, ...projectNames])]
                         }
                         return {
                           ...item,
                           daySummaryList,
                           projectNameList,
                           dataList,
+                          itemIndex:index,
                           selectItem: []
                         }
                       })