소스 검색

工时导出修改

yusm 9 달 전
부모
커밋
e2d982800b
12개의 변경된 파일904개의 추가작업 그리고 0개의 파일을 삭제
  1. 13 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java
  2. 5 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java
  3. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java
  4. 22 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java
  5. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelExportService.java
  6. 3 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java
  7. 2 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java
  8. 77 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  9. 417 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  10. 71 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java
  11. 135 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java
  12. 157 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

+ 13 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectController.java

@@ -103,6 +103,14 @@ public class ProjectController {
         return projectService.getProjectList(forReport, request);
     }
 
+    /**
+     * 获取项目列表
+     */
+    @RequestMapping("/getProjectListByPage")
+    public HttpRespMsg getProjectListByPage(@RequestParam Integer pageIndex, @RequestParam Integer pageSize,@RequestParam(required = false)String infoString,@RequestParam(required = false) Integer id,@RequestParam(required = false, defaultValue = "0") Integer forReport) {
+        return projectService.getProjectListByPage(pageIndex,pageSize,infoString,id,forReport, request);
+    }
+
     /**
      * 分页获取项目列表
      * pageIndex 页数
@@ -269,6 +277,11 @@ public class ProjectController {
         return projectService.exportTimeCost(withMainProject, exportContent,startDate, endDate, projectId, userIds, projectSum,type,deptId,stateKey, withPercent,projectCategoryId, request);
     }
 
+    @RequestMapping("/exportTimeByProjectAndEmployee")
+    public HttpRespMsg exportTimeByProjectAndEmployee(@RequestParam String date, HttpServletRequest request) {
+        return projectService.exportTimeByProjectAndEmployee(date, request);
+    }
+
     /**
      * 导出查询者所在公司每个项目分类的工时成本
      */

+ 5 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserController.java

@@ -172,6 +172,11 @@ public class UserController {
         return userService.getSimpleActiveUserList(departmentId,request,keyword,cursor);
     }
 
+    @RequestMapping("/getSimpleActiveUserListPage")
+    public HttpRespMsg getSimpleActiveUserListPage(@RequestParam Integer pageIndex, @RequestParam Integer pageSize,Integer departmentId,String keyword,String cursor,@RequestParam(required = false) String userIds) throws Exception {
+        return userService.getSimpleActiveUserListPage(pageIndex,pageSize,departmentId,request,keyword,cursor,userIds);
+    }
+
     @RequestMapping("/getUserListByRole")
     public HttpRespMsg getUserListByRole(String tableName){
         return userService.getUserListByRole(request,tableName);

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java

@@ -10,6 +10,7 @@ import java.io.Serializable;
 import java.util.List;
 
 import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;

+ 22 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ProjectMapper.java

@@ -198,4 +198,26 @@ public interface ProjectMapper extends BaseMapper<Project> {
 
     @Update("update project set category=null,category_name=null where id=#{id}")
     void updateProjectCategoryToNull(@Param("id") Integer id);
+
+    List<Map<String, Object>> getOnlyJoinProjectsPage(String id, Integer companyId, Integer pageIndex, Integer pageSize, String infoString);
+
+    Integer getOnlyJoinProjectsTotal(String id, Integer companyId, Integer pageIndex, Integer pageSize, String infoString);
+
+    List<Map<String, Object>> getOnlyJoinProjectsById(String id, Integer companyId, Integer projectId);
+
+    List<Map<String, Object>> getParticipatedProjectPage(String id, Integer companyId, Integer pageIndex, Integer pageSize, String infoString);
+
+    Integer getParticipatedProjectTotal(String id, Integer companyId, Integer pageIndex, Integer pageSize, String infoString);
+
+    List<Map<String, Object>> getParticipatedProjectById(String id, Integer companyId, Integer projectId);
+
+    List<Map<String, Object>> getTimeCostGroupByProjectUserSumTime(Integer companyId, String startDate, String endDate);
+
+    List<Map<String, Object>> getTimeCostProjectUserWorkTime(Integer companyId, String startDate, String endDate);
+
+    List<Map<String, Object>> getCostTimeByUserSum(Integer companyId, String startDate, String endDate);
+
+    List<Map<String, Object>> getCostTimeByUserForDay(Integer companyId, String startDate, String endDate);
+
+    List<Map<String, Object>> getTotalProjectByTime(Integer companyId, String startDate, String endDate);
 }

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

@@ -12,6 +12,7 @@ public interface ExcelExportService {
     public HttpRespMsg exportGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>> list, String downloadPath) throws Exception;
     public HttpRespMsg exportGeneralExcelByTitleAndList2(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>> list, String downloadPath) throws Exception;
     public HttpRespMsg exportMultiSheetGeneralExcelByTitleAndList(WxCorpInfo wxCorpInfo, CompanyDingding dingding,String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) throws Exception;
+    public HttpRespMsg exportMultiSheetGeneralExcelByTitleAndListNew(WxCorpInfo wxCorpInfo, CompanyDingding dingding,String title, List<List<String>>[] multiSheetList, String downloadPath,String[] sheetsName) throws Exception;
     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;

+ 3 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ProjectService.java

@@ -310,4 +310,7 @@ public interface ProjectService extends IService<Project> {
 
     HttpRespMsg exportGroupExpendProcessListForUser(String startDate, String endDate, String projectIds, String groupNames,String titleStr, String deptIdStr) throws UnsupportedEncodingException;
 
+    HttpRespMsg getProjectListByPage(Integer pageIndex, Integer pageSize, String infoString, Integer id, Integer forReport, HttpServletRequest request);
+
+    HttpRespMsg exportTimeByProjectAndEmployee(String date, HttpServletRequest request);
 }

+ 2 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/UserService.java

@@ -104,4 +104,6 @@ public interface UserService extends IService<User> {
     HttpRespMsg setActiveByIds(String ids, int isActive);
 
     HttpRespMsg deleteUserSalaryById(String id);
+
+    HttpRespMsg getSimpleActiveUserListPage(Integer pageIndex, Integer pageSize, Integer departmentId, HttpServletRequest request, String keyword, String cursor, String userIds) throws Exception;
 }

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

@@ -405,6 +405,83 @@ public class ExcelExportServiceImpl implements ExcelExportService {
         return httpRespMsg;
     }
 
+    @Override
+    public HttpRespMsg exportMultiSheetGeneralExcelByTitleAndListNew(WxCorpInfo wxCorpInfo, CompanyDingding dingding, String title, List<List<String>>[] multiSheetList, String downloadPath, String[] sheetsName) throws Exception {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String resp = ExcelUtil.exportMultiSheetGeneralExcelByTitleAndListNew(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 exportTranForwx(WxCorpInfo wxCorpInfo, CompanyDingding dingding,String title) throws Exception {
         HttpRespMsg httpRespMsg = new HttpRespMsg();
         if (title.contains("/")) {

+ 417 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.google.common.collect.ImmutableMap;
 import com.management.platform.entity.*;
 import com.management.platform.entity.Task;
 import com.management.platform.entity.vo.*;
@@ -254,6 +255,422 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
     private String path;
     @Value("${configEnv.isDev}")
     public boolean isDev;
+
+    @Override
+    public HttpRespMsg getProjectListByPage(Integer pageIndex, Integer pageSize, String infoString, Integer id, Integer forReport, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        try {
+            User user = userMapper.selectById(request.getHeader("Token"));
+            if (forReport == 1) {
+                if (!sysFunctionService.hasPriviledge(user.getRoleId(), "可填报全部项目")) {
+                    //只能看本人参与的项目
+                    pageIndex=(pageIndex-1)*pageSize;
+                    List<Map<String, Object>> data = projectMapper.getOnlyJoinProjectsPage(user.getId(), user.getCompanyId(),pageIndex,pageSize,infoString);
+                    Integer total = projectMapper.getOnlyJoinProjectsTotal(user.getId(), user.getCompanyId(),pageIndex,pageSize,infoString);
+                    HashMap<String, Object> resultMap = new HashMap<>();
+                    resultMap.put("total", total);
+                    if (id!=null){
+                        List<Map<String, Object>> dataByID = projectMapper.getOnlyJoinProjectsById(user.getId(), user.getCompanyId(),id);
+                        data.addAll(0,dataByID);
+                    }
+                    resultMap.put("data", data);
+
+                    httpRespMsg.data = resultMap;
+
+                } else {
+                    //有权限的填报全部的进行中项目
+                    QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
+                    if (!StringUtils.isEmpty(infoString)){
+                        queryWrapper.eq("company_id", user.getCompanyId())
+                                .eq("status", 1)
+                                .and(i->i.like("project_name",infoString).or()
+                                        .like("project_code",infoString))
+                                .orderByDesc("is_public")
+                                .orderByAsc("id")
+                                .select("id", "project_code", "project_name");
+                    }else {
+                        queryWrapper.eq("company_id", user.getCompanyId())
+                                .eq("status", 1)
+                                .orderByDesc("is_public")
+                                .orderByAsc("id")
+                                .select("id", "project_code", "project_name");
+                    }
+
+
+                    Page<Project> projectPage = new Page<>(pageIndex, pageSize);
+                    IPage<Project> projectIPage = projectMapper.selectPage(projectPage, queryWrapper);
+
+                    HashMap<String, Object> resultMap = new HashMap<>();
+                    resultMap.put("total", projectIPage.getTotal());
+                    List<Project> projectList = projectIPage.getRecords();
+                    if (id!=null){
+                        Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()).eq("status", 1).eq("id", id).select("id", "project_code", "project_name"));
+                        if (project!=null){
+                            projectList.add(0,project);
+                        }
+                    }
+                    resultMap.put("data", projectList);
+                    httpRespMsg.data = resultMap;
+                }
+            } else {
+                if (!sysFunctionService.hasPriviledge(user.getRoleId(), "查看全部项目")) {
+                    //只能看本人相关的项目
+                    pageIndex=(pageIndex-1)*pageSize;
+                    List<Map<String, Object>> data = projectMapper.getParticipatedProjectPage(user.getId(), user.getCompanyId(),pageIndex,pageSize,infoString);
+                    Integer total = projectMapper.getParticipatedProjectTotal(user.getId(), user.getCompanyId(),pageIndex,pageSize,infoString);
+                    HashMap<String, Object> resultMap = new HashMap<>();
+                    resultMap.put("total", total);
+                    if (id!=null){
+                        List<Map<String, Object>> dataByID = projectMapper.getParticipatedProjectById(user.getId(), user.getCompanyId(),id);
+                        data.addAll(0,dataByID);
+                    }
+                    resultMap.put("data", data);
+                    httpRespMsg.data = resultMap;
+                } else {
+                    //有权限的看全部的
+                    httpRespMsg.data = projectMapper.selectList(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()).orderByDesc("is_public").orderByAsc("id"));
+                    QueryWrapper<Project> queryWrapper = new QueryWrapper<>();
+                    if (!StringUtils.isEmpty(infoString)){
+                        queryWrapper.eq("company_id", user.getCompanyId())
+                                .and(i->i.like("project_name",infoString).or().like("project_code",infoString))
+                                .orderByDesc("is_public").orderByAsc("id")
+                                .select("id", "project_code", "project_name");
+                    }else {
+                        queryWrapper.eq("company_id", user.getCompanyId())
+                                .orderByDesc("is_public").orderByAsc("id")
+                                .select("id", "project_code", "project_name");
+                    }
+                    Page<Project> projectPage =new Page<>(pageIndex, pageSize);
+                    IPage<Project> projectIPage = projectMapper.selectPage(projectPage, queryWrapper);
+                    HashMap<String, Object> resultMap = new HashMap<>();
+                    resultMap.put("total", projectIPage.getTotal());
+                    List<Project> projectList = projectIPage.getRecords();
+                    if (id!=null){
+                        Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("company_id", user.getCompanyId()).eq("id", id).select("id", "project_code", "project_name"));
+                        if (project!=null){
+                            projectList.add(0,project);
+                        }
+                    }
+                    resultMap.put("data", projectList);
+                    httpRespMsg.data = resultMap;
+                }
+            }
+        } catch (NullPointerException e) {
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("access.verificationError"));
+            return httpRespMsg;
+        }
+        return httpRespMsg;
+    }
+
+    @Override
+    public HttpRespMsg exportTimeByProjectAndEmployee(String date, HttpServletRequest request) {
+        HttpRespMsg httpRespMsg = new HttpRespMsg();
+        String[] strings = date.split("-");
+        int year = Integer.parseInt(strings[0]);
+        int month = Integer.parseInt(strings[1]);
+        YearMonth yearMonth = YearMonth.of((year), month);
+        int daysInMonth = yearMonth.lengthOfMonth();
+
+        // 获取该月份的第一天
+        String startDate = String.format("%04d-%02d-01", year, month);
+        // 获取下个月的第一天
+        LocalDate lastDate = LocalDate.of(year, month, 1).plusDays(LocalDate.of(year, month, 1).lengthOfMonth() - 1);
+        String endDate = String.format("%04d-%02d-%02d", year, month, lastDate.getDayOfMonth());
+        try {
+            User targetUser = userMapper.selectById(request.getHeader("Token"));
+            Integer companyId = targetUser.getCompanyId();
+            WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+            CompanyDingding dingding = companyDingdingMapper.selectOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, companyId));
+            Map<String, Object> resultMap = new HashMap<>();
+
+//当前用户管理部门
+            List<Integer> deptIds=null;
+            List<Department> departmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("manager_id", targetUser.getId()).eq("company_id", companyId));
+            List<Department> allDepartmentList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", targetUser.getCompanyId()));
+            Department[] deptArray = allDepartmentList.toArray(new Department[0]);
+
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+
+
+
+            List<Map<String, Object>> list = new ArrayList<>();
+            List<List<String>> allList = null;
+            List<String> sumRow = null;
+
+            List<String> headList = new ArrayList<String>();
+            //headList.add("项目编号");
+            headList.add(MessageUtils.message("entry.projectId"));
+            //headList.add("项目名称");
+            headList.add(MessageUtils.message("entry.projectName"));
+            //headList.add("项目分类");
+            headList.add(MessageUtils.message("entry.projectType"));
+            //headList.add("人员");
+            headList.add(MessageUtils.message("entry.personnel"));
+            //headList.add("部门");
+            headList.add(MessageUtils.message("excel.department"));
+            headList.add("月度总工时(h)");
+            for (int i = 1; i <= daysInMonth; i++) {
+                headList.add(i+"日");
+            }
+
+            allList = new ArrayList<>();
+            allList.add(headList);
+            double totalCostTime = 0;
+
+            //查询到的前六个字段
+            List<Map<String, Object>> dataList = projectMapper.getTimeCostGroupByProjectUserSumTime(companyId,startDate, endDate);
+            for (Map<String, Object> membMap : dataList) {
+                Department dept = null;
+                Department targetDept = new Department();
+                if (membMap.get("deptId") != null) {
+                    targetDept.setDepartmentId(Integer.valueOf(membMap.get("deptId").toString()));
+                    int index = Arrays.binarySearch(deptArray, targetDept, Comparator.comparing(Department::getDepartmentId));
+                    if (index >= 0) {
+                        dept = deptArray[index];
+                    }
+                }
+                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                    if(membMap.get("departmentName").equals("未分配")){
+                        membMap.put("departmentNameComplete","未分配");
+                    }else {
+                        membMap.put("departmentNameComplete",departmentService.exportWxDepartment(dept,allDepartmentList));
+                    }
+                }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
+                    if(membMap.get("departmentName").equals("未分配")){
+                        membMap.put("departmentNameComplete","未分配");
+                    }else {
+                        membMap.put("departmentNameComplete",departmentService.exportDdDepartment(dept,allDepartmentList));
+                    }
+                }else {
+                    membMap.put("departmentNameComplete",departmentService.getSupDepartment(dept,allDepartmentList));
+                }
+            }
+
+            //抽取出来项目编号,项目名称
+            List<Map<String, Object>> uniqueDataList = dataList.stream()
+                    .distinct() // 确保唯一性
+                    .map(item -> ImmutableMap.of(
+                            "id", item.get("id"),
+                            "projectCode", item.get("projectCode"),
+                            "departmentName", item.get("departmentName")
+                    ))
+                    .collect(Collectors.toList());
+
+            //查询项目对应人员填写的每次工时时长
+            List<Map<String, Object>> dataDetailList = projectMapper.getTimeCostProjectUserWorkTime(companyId,startDate, endDate);
+
+
+            for (Map<String, Object> map : uniqueDataList) {
+                //每个项目的统计
+                List<String> rowList = new ArrayList<String>();
+                rowList.add(map.get("projectCode")==null?"":map.get("projectCode").toString());
+                rowList.add(map.get("departmentName")==null?"":map.get("departmentName").toString());
+                rowList.add("");//项目分类
+                rowList.add("");//人员
+                rowList.add("");//部门
+                double sumCost = dataList.stream().filter(d -> d.get("id").toString().equals(map.get("id").toString()))
+                        .mapToDouble(d -> Double.parseDouble(d.get("cost").toString())) // 映射到 cost
+                        .sum();// 计算总和
+                rowList.add(sumCost+"");//月度总工时
+                for (int i = 1; i <= daysInMonth; i++) {
+                    int finalI = i;
+                    double sumDay=0;
+                    sumDay = dataDetailList.stream().filter(d -> d.get("id").toString().equals(map.get("id").toString())&&d.get("dayOnly")!=null && d.get("dayOnly").toString().equals("" + finalI))
+                            .mapToDouble(d -> Double.parseDouble(d.get("cost").toString())) // 映射到 cost
+                            .sum();
+                    if (sumDay==0){
+                        rowList.add("");//每天填报总工时
+                    }else {
+                        rowList.add(sumDay+"");//每天的该项目的填报总工时
+                    }
+
+                }
+                allList.add(rowList);
+
+                //项目下每个员工的记录
+                List<Map<String, Object>> userDataList = dataList.stream().filter(d -> d.get("id").toString().equals(map.get("id").toString())).collect(Collectors.toList());
+                for (Map<String, Object> objectMap : userDataList) {
+                    List<String> rowUserList = new ArrayList<String>();
+                    rowUserList.add("");//项目编号
+                    rowUserList.add("");//项目名称
+                    rowUserList.add(objectMap.get("categoryName")==null?"":objectMap.get("categoryName").toString());
+                    rowUserList.add(objectMap.get("name")==null?"":objectMap.get("name").toString());
+                    rowUserList.add(objectMap.get("departmentNameComplete")==null?"":objectMap.get("departmentNameComplete").toString());
+                    rowUserList.add(objectMap.get("cost")==null?"":objectMap.get("cost").toString());
+                    for (int i = 1; i <= daysInMonth; i++) {
+                        int finalI = i;
+                        double sumDay=0;
+                        sumDay = dataDetailList.stream().filter(
+                                d -> d.get("id").toString().equals(objectMap.get("id").toString())
+                                        &&d.get("dayOnly")!=null
+                                        && d.get("dayOnly").toString().equals("" + finalI)
+                                        && d.get("userId").toString().equals(objectMap.get("userId").toString())
+                                )
+                                .mapToDouble(d -> Double.parseDouble(d.get("cost").toString())) // 映射到 cost
+                                .sum();
+                        if (sumDay==0){
+                            rowUserList.add("");//每天填报总工时
+                        }else {
+                            rowUserList.add(sumDay+"");//每天的该项目的填报总工时
+                        }
+
+                    }
+                    allList.add(rowUserList);
+                }
+            }
+            List<String> rowEndList = new ArrayList<String>();
+            rowEndList.add("总计");
+            rowEndList.add("");
+            rowEndList.add("");
+            rowEndList.add("");
+            rowEndList.add("");
+            double totalCost = dataList.stream()
+                    .mapToDouble(d -> Double.parseDouble(d.get("cost").toString())) // 映射到 cost
+                    .sum();
+            rowEndList.add(""+totalCost);//月度总工时
+            for (int i = 1; i <= daysInMonth; i++) {
+                int finalI = i;
+                double sumDay=0;
+                sumDay = dataDetailList.stream().filter(
+                                d -> d.get("dayOnly")!=null&& d.get("dayOnly").toString().equals("" + finalI)
+                        )
+                        .mapToDouble(d -> Double.parseDouble(d.get("cost").toString())) // 映射到 cost
+                        .sum();
+                if (sumDay==0){
+                    rowEndList.add("");//每天填报总工时
+                }else {
+                    rowEndList.add(sumDay+"");//每天填报总工时
+                }
+
+            }
+            allList.add(rowEndList);
+
+
+            List<Map<String, Object>> costTimeByUser=projectMapper.getCostTimeByUserSum(companyId,startDate, endDate);
+            List<Map<String, Object>> costTimeByUserForDay=projectMapper.getCostTimeByUserForDay(companyId,startDate, endDate);
+            List<Map<String, Object>> allProjectNew=projectMapper.getTotalProjectByTime(companyId,startDate, endDate);
+            for (Map<String, Object> membMap : costTimeByUser) {
+                Department dept = null;
+                Department targetDept = new Department();
+                if (membMap.get("deptId") != null) {
+                    targetDept.setDepartmentId(Integer.valueOf(membMap.get("deptId").toString()));
+                    int index = Arrays.binarySearch(deptArray, targetDept, Comparator.comparing(Department::getDepartmentId));
+                    if (index >= 0) {
+                        dept = deptArray[index];
+                    }
+                }
+                if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                    if(membMap.get("departmentName").equals("未分配")){
+                        membMap.put("departmentNameComplete","未分配");
+                    }else {
+                        membMap.put("departmentNameComplete",departmentService.exportWxDepartment(dept,allDepartmentList));
+                    }
+                }else if(dingding!=null&&dingding.getContactNeedTranslate()==1){
+                    if(membMap.get("departmentName").equals("未分配")){
+                        membMap.put("departmentNameComplete","未分配");
+                    }else {
+                        membMap.put("departmentNameComplete",departmentService.exportDdDepartment(dept,allDepartmentList));
+                    }
+                }else {
+                    membMap.put("departmentNameComplete",departmentService.getSupDepartment(dept,allDepartmentList));
+                }
+            }
+
+            List<List<String>> secondList = new ArrayList<>();
+            List<String> headsecondList = new ArrayList<String>();
+            headsecondList.add("工号");
+            headsecondList.add("姓名");
+            headsecondList.add("部门");
+            headsecondList.add("月度总工时(h)");
+            headsecondList.add(month+"月");
+            for (int i = 2; i <= daysInMonth; i++) {
+                headsecondList.add("");
+            }
+            if (!allProjectNew.isEmpty()){
+                headsecondList.add("项目工时分配");
+                for (int i = 1; i < allProjectNew.size()-1; i++) {
+                    headsecondList.add("");
+                }
+            }
+            secondList.add(headsecondList);
+
+            List<String> headsecondList_new = new ArrayList<String>();
+            headsecondList_new.add("");
+            headsecondList_new.add("");
+            headsecondList_new.add("");
+            headsecondList_new.add("");
+            for (int i = 1; i <= daysInMonth; i++) {
+                headsecondList_new.add(i+"日");
+            }
+            if (!allProjectNew.isEmpty()){
+                for (Map<String, Object> map : allProjectNew) {
+                    headsecondList_new.add(map.get("projectName")==null?"":map.get("projectName").toString());
+                }
+            }
+            secondList.add(headsecondList_new);
+
+            if (!costTimeByUser.isEmpty()){
+                for (Map<String, Object> map : costTimeByUser) {
+                    List<String> row = new ArrayList<String>();
+                    row.add(map.get("jobNumber")==null?"":map.get("jobNumber").toString());
+                    row.add(map.get("name")==null?"":map.get("name").toString());
+                    row.add(map.get("departmentNameComplete")==null?"":map.get("departmentNameComplete").toString());
+                    row.add(map.get("cost")==null?"":map.get("cost").toString());
+                    for (int i = 1; i <=daysInMonth; i++) {
+                        double sum=0;
+                        int finalI = i;
+                        sum = costTimeByUserForDay.stream().filter(c -> c.get("userId").toString().equals(map.get("userId").toString())
+                                        && c.get("dayOnly") != null && c.get("dayOnly").toString().equals(finalI + ""))
+                                .mapToDouble(d -> Double.parseDouble(d.get("cost").toString()))
+                                .sum();
+                        if (sum==0){
+                            row.add("");
+                        }else {
+                            row.add(sum+"");
+                        }
+                    }
+                    for (Map<String, Object> objectMap : allProjectNew) {
+                        double sum=0;
+                        sum = costTimeByUserForDay.stream().filter(c -> c.get("projectId").toString().equals(objectMap.get("projectId").toString())
+                                        && c.get("userId").toString().equals(map.get("userId").toString()))
+                                .mapToDouble(d -> Double.parseDouble(d.get("cost").toString()))
+                                .sum();
+                        if (sum==0){
+                            row.add("");
+                        }else {
+                            row.add(sum+"");
+                        }
+                    }
+                    secondList.add(row);
+                }
+            }
+
+            List[] totalList = new ArrayList[2];
+            totalList[0] = allList;
+            totalList[1] = secondList;
+
+            String[] sheetNames = new String[2];
+            sheetNames[0] = "项目统计表";
+            sheetNames[1] = "人员统计表";
+
+
+
+//            return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo,dingding,"月度工时统计表" , allList, path);
+//            return excelExportService.exportMultiSheetGeneralExcelByTitleAndList(wxCorpInfo,dingding,"月度工时统计表" , totalList, path,sheetNames);
+            return excelExportService.exportMultiSheetGeneralExcelByTitleAndListNew(wxCorpInfo,dingding,"月度工时统计表" , totalList, path,sheetNames);
+        } catch (NullPointerException e) {
+            e.printStackTrace();
+            //httpRespMsg.setError("验证失败");
+            httpRespMsg.setError(MessageUtils.message("access.verificationError"));
+            return httpRespMsg;
+        } catch (Exception exception) {
+            exception.printStackTrace();
+            httpRespMsg.setError(exception.getMessage());
+        }
+        return httpRespMsg;
+    }
+
     //获取项目列表
     @Override
     public HttpRespMsg getProjectList(Integer forReport, HttpServletRequest request) {

+ 71 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/UserServiceImpl.java

@@ -6,6 +6,7 @@ import com.aliyun.dingtalkcontact_1_0.models.SearchUserResponse;
 import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.management.platform.constant.Constant;
@@ -2450,6 +2451,76 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements Us
         }
     }
 
+
+    @Override
+    public HttpRespMsg getSimpleActiveUserListPage(Integer pageIndex, Integer pageSize, Integer departmentId, HttpServletRequest request, String keyword, String cursor, String userIds) throws Exception {
+        HttpRespMsg msg = new HttpRespMsg();
+        String token = request.getHeader("TOKEN");
+        User user = userMapper.selectById(token);
+        String nextCursor = "";
+        //企业微信通讯录搜索功能
+        Integer WXCompanyId = user.getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", WXCompanyId));
+        //当企业开启了微信通讯录的情况下
+        if (org.apache.commons.lang3.StringUtils.isNotBlank(keyword) && wxCorpInfo!=null && wxCorpInfo.getSaasSyncContact()==1){
+            HashMap<String, List> result = wxCorpInfoService.getOpenId(wxCorpInfo.getCorpid(), keyword, cursor,1,200);
+            HashMap<String, Object> msgResult = new HashMap<>();
+            List users = result.get("user");
+            msg.data = msgResult;
+            QueryWrapper<User> wrapper = new QueryWrapper<User>().in("corpwx_userid", users).select("id", "name", "job_number");
+            Page<User> page = new Page<>(pageIndex, pageSize);
+            if (users.size()!=0){
+                IPage<User> userIPage = userMapper.selectPage(page, wrapper);
+                msgResult.put("total",userIPage.getTotal());
+                List<User> userList = userIPage.getRecords();
+                List<String> targetUids;
+                if (!StringUtils.isEmpty(userIds)) {
+                    targetUids = ListUtil.convertLongIdsArrayToList(userIds);
+
+                    QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+                    queryWrapper.select("id", "name",  "job_number").in("id", targetUids).eq("is_active", 1);
+                    List<User> userData = userMapper.selectList(queryWrapper);
+                    userList.addAll(0,userData);
+                }
+                msgResult.put("data",userList);
+                return msg;
+            }else {
+                msgResult.put("data",new ArrayList<User>());
+                msgResult.put("total",0);
+                return msg;
+            }
+        }else {
+            QueryWrapper<User> wrapper = new QueryWrapper<User>()
+                    .select("id", "name",  "job_number").eq("company_id", user.getCompanyId()).eq("is_active", 1);
+            if (departmentId != null) {
+                //获取全部子部门
+                List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", user.getCompanyId()));
+                List<Integer> deptIds = departmentService.getDeptIncludeSubDeptIds(departmentId, allDeptList);
+                wrapper.in("department_id", deptIds);
+            }
+//            List<User> userList = userMapper.selectList(wrapper);
+//            msg.data = userList;
+            Page<User> page = new Page<>(pageIndex, pageSize);
+            IPage<User> userIPage = userMapper.selectPage(page, wrapper);
+            HashMap<String, Object> resultMap = new HashMap<>();
+            resultMap.put("total", userIPage.getTotal());
+            List<User> userList = userIPage.getRecords();
+            List<String> targetUids;
+            if (!StringUtils.isEmpty(userIds)) {
+                targetUids = ListUtil.convertLongIdsArrayToList(userIds);
+
+                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
+                queryWrapper.select("id", "name",  "job_number").in("id", targetUids).eq("is_active", 1);
+                List<User> users = userMapper.selectList(queryWrapper);
+                userList.addAll(0,users);
+            }
+
+            resultMap.put("data", userList);
+            msg.data=resultMap;
+            return msg;
+        }
+    }
+
     @Override
     public HttpRespMsg getUserListByRole(HttpServletRequest request,String tableName) {
         HttpRespMsg httpRespMsg=new HttpRespMsg();

+ 135 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/ExcelUtil.java

@@ -765,4 +765,139 @@ public class ExcelUtil {
         }
         return true;
     }
+
+    public static String exportMultiSheetGeneralExcelByTitleAndListNew(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(List<String> rowList : multiSheetList[sheetIndex]) {
+                        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++;
+                    }
+                    if (sheetIndex==1){
+                        Row row0 = sheetOne.getRow(0);
+                        for (int i = 0; i < 4; i++) {
+                            sheetOne.addMergedRegion(new CellRangeAddress(0, 1, i,i));
+                        }
+                        int numberOfCells = row0.getPhysicalNumberOfCells();
+                        int index=-1;
+                        for (int i = 0; i < numberOfCells; i++) {
+                            if (row0.getCell(i).getStringCellValue().equals("项目工时分配")){
+                                index=i;
+                                break;
+                            }
+                        }
+                        if (index!=-1){
+                            sheetOne.addMergedRegion(new CellRangeAddress(0, 0, 4,index-1));
+                        }
+                        short lastCellNum = row0.getLastCellNum();
+                        sheetOne.addMergedRegion(new CellRangeAddress(0, 0, index,lastCellNum));
+
+
+                    }
+                }
+            }
+
+
+            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;
+    }
 }

+ 157 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -2375,5 +2375,162 @@
         order by d.department_id,u.id
         ) as total
     </select>
+    <select id="getOnlyJoinProjectsPage" resultType="java.util.Map">
+        SELECT id, project_code AS projectCode, project_name AS projectName
+        FROM project
+        WHERE status = 1 and (id IN (
+            SELECT project_id
+            FROM participation
+            WHERE user_id = #{userId}
+        )
+            or (is_public = 1 and company_id = #{companyId}))
+        <if test="infoString !=null and infoString!='' ">
+            and (project_name like CONCAT('%', #{infoString}, '%')  or project_code like CONCAT('%', #{infoString}, '%') )
+        </if>
+        ORDER BY is_public DESC, id ASC
+        limit #{pageIndex},#{pageSize}
+    </select>
+    <select id="getOnlyJoinProjectsTotal" resultType="java.lang.Integer">
+        SELECT count(*) total
+        FROM project
+        WHERE status = 1 and (id IN (
+        SELECT project_id
+        FROM participation
+        WHERE user_id = #{userId}
+        )
+        or (is_public = 1 and company_id = #{companyId}))
+        <if test="infoString !=null and infoString!='' ">
+            and (project_name like CONCAT('%', #{infoString}, '%')  or project_code like CONCAT('%', #{infoString}, '%') )
+        </if>
+    </select>
+    <select id="getOnlyJoinProjectsById" resultType="java.util.Map">
+        SELECT id, project_code AS projectCode, project_name AS projectName
+        FROM project
+        WHERE status = 1 and (id IN (
+        SELECT project_id
+        FROM participation
+        WHERE user_id = #{userId}
+        )
+        or (is_public = 1 and company_id = #{companyId}))
+        and id =#{projectId}
+    </select>
+    <select id="getParticipatedProjectPage" resultType="java.util.Map">
+        SELECT id, project_code AS projectCode, project_name AS projectName
+        FROM project
+        WHERE id IN (
+            SELECT project_id
+            FROM participation
+            WHERE user_id = #{userId}
+        ) or incharger_id = #{userId}
+           or creator_id = #{userId}
+           or (is_public = 1 and company_id = #{companyId})
+        <if test="infoString !=null and infoString!='' ">
+            and (project_name like CONCAT('%', #{infoString}, '%')  or project_code like CONCAT('%', #{infoString}, '%') )
+        </if>
+        ORDER BY is_public DESC, id DESC
+        limit #{pageIndex},#{pageSize}
+    </select>
+    <select id="getParticipatedProjectTotal" resultType="java.lang.Integer">
+        SELECT count(*) total
+        FROM project
+        WHERE id IN (
+        SELECT project_id
+        FROM participation
+        WHERE user_id = #{userId}
+        ) or incharger_id = #{userId}
+        or creator_id = #{userId}
+        or (is_public = 1 and company_id = #{companyId})
+        <if test="infoString !=null and infoString!='' ">
+            and (project_name like CONCAT('%', #{infoString}, '%')  or project_code like CONCAT('%', #{infoString}, '%') )
+        </if>
+    </select>
+    <select id="getParticipatedProjectById" resultType="java.util.Map">
+        SELECT count(*) total
+        FROM project
+        WHERE id IN (
+        SELECT project_id
+        FROM participation
+        WHERE user_id = #{userId}
+        ) or incharger_id = #{userId}
+        or creator_id = #{userId}
+        or (is_public = 1 and company_id = #{companyId})
+        and id =#{projectId}
+    </select>
+    <select id="getTimeCostGroupByProjectUserSumTime" resultType="java.util.Map">
+        SELECT a.id, a.project_code as projectCode, a.project_name AS projectName,a.category_name as categoryName,
+        c.name name,sum(b.working_time) AS cost,
+        b.dept_id as deptId,department.corpwx_deptid as corpwxDeptId,department.dd_deptid as corpDdDeptId, IFNULL(department.department_name, '未分配') as departmentName,
+        c.id userId
+        FROM project AS a
+        LEFT JOIN report AS b ON b.project_id = a.id
+        JOIN user AS c ON b.creator_id = c.id
+        left join department on department.department_id = b.dept_id
+        WHERE a.company_id = #{companyId}
+        <if test="startDate != null and endDate != null">
+            AND b.create_date between #{startDate} and #{endDate}
+        </if>
+        AND b.state = 1
+        group by id,projectCode,projectName,categoryName,name
+        ORDER BY a.id ASC
+    </select>
+    <select id="getTimeCostProjectUserWorkTime" resultType="java.util.Map">
+        SELECT a.id, a.project_code as projectCode,a.project_name AS projectName,a.category_name as categoryName,
+               c.name name,b.working_time cost,
+               b.dept_id as deptId,department.corpwx_deptid as corpwxDeptId,department.dd_deptid as corpDdDeptId, IFNULL(department.department_name, '未分配') as departmentName,
+               b.create_date createDate,DAY(b.create_date) dayOnly,c.id userId
+        FROM project AS a
+            LEFT JOIN report AS b ON b.project_id = a.id
+            JOIN user AS c ON b.creator_id = c.id
+            left join department on department.department_id = b.dept_id
+        WHERE a.company_id = #{companyId}
+        <if test="startDate != null and endDate != null">
+            AND b.create_date between #{startDate} and #{endDate}
+        </if>
+            AND b.state = 1
+        ORDER BY a.id ASC ,c.name asc
+
+    </select>
+    <select id="getCostTimeByUserSum" resultType="java.util.Map">
+        SELECT c.id userId, c.job_number jobNumber,c.name name,sum(b.working_time) AS cost,
+               b.dept_id as deptId,department.corpwx_deptid as corpwxDeptId,department.dd_deptid as corpDdDeptId, IFNULL(department.department_name, '未分配') as departmentName
+        FROM   project AS a
+                   LEFT JOIN report AS b ON b.project_id = a.id
+                   JOIN user AS c ON b.creator_id = c.id
+                   left join department on department.department_id = b.dept_id
+        WHERE c.company_id = #{companyId}
+        <if test="startDate != null and endDate != null">
+            AND b.create_date between #{startDate} and #{endDate}
+        </if>
+        AND b.state = 1
+        group by userId
+    </select>
+    <select id="getCostTimeByUserForDay" resultType="java.util.Map">
+        SELECT c.id userId, c.job_number jobNumber,c.name name,b.working_time AS cost, a.id projectId,a.project_name ,
+               b.dept_id as deptId,department.corpwx_deptid as corpwxDeptId,department.dd_deptid as corpDdDeptId, IFNULL(department.department_name, '未分配') as departmentName,
+            DAY(b.create_date) dayOnly
+        FROM   project AS a
+            LEFT JOIN report AS b ON b.project_id = a.id
+            JOIN user AS c ON b.creator_id = c.id
+            left join department on department.department_id = b.dept_id
+        WHERE c.company_id = #{companyId}
+        <if test="startDate != null and endDate != null">
+            AND b.create_date between #{startDate} and #{endDate}
+        </if>
+        AND b.state = 1
+    </select>
+    <select id="getTotalProjectByTime" resultType="java.util.Map">
+        SELECT
+            a.id projectId,a.project_name projectName
+        FROM   project AS a
+                   LEFT JOIN report AS b ON b.project_id = a.id
+                   JOIN user AS c ON b.creator_id = c.id
+                   left join department on department.department_id = b.dept_id
+        WHERE c.company_id = #{companyId}
+        <if test="startDate != null and endDate != null">
+            AND b.create_date between #{startDate} and #{endDate}
+        </if>
+        AND b.state = 1
+        GROUP BY projectId
+    </select>
 
 </mapper>