Browse Source

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

seyason 1 year ago
parent
commit
2b40254ab7

+ 71 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ExpenseItemController.java

@@ -1,16 +1,26 @@
 package com.management.platform.controller;
 
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.ExpenseItem;
+import com.management.platform.entity.WxCorpInfo;
 import com.management.platform.entity.vo.ExpenseItemVO;
 import com.management.platform.mapper.ExpenseItemMapper;
+import com.management.platform.mapper.UserMapper;
+import com.management.platform.mapper.WxCorpInfoMapper;
+import com.management.platform.service.ExcelExportService;
 import com.management.platform.util.HttpRespMsg;
+import com.management.platform.util.MessageUtils;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestMapping;
 
 import org.springframework.web.bind.annotation.RestController;
 
 import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -27,6 +37,16 @@ public class ExpenseItemController {
 
     @Resource
     private ExpenseItemMapper expenseItemMapper;
+    @Resource
+    private UserMapper userMapper;
+    @Resource
+    private HttpServletRequest request;
+    @Resource
+    private WxCorpInfoMapper wxCorpInfoMapper;
+    @Resource
+    private ExcelExportService excelExportService;
+    @Value(value = "${upload.path}")
+    private String path;
 
     @RequestMapping("/list")
     public HttpRespMsg list(Integer projectId) {
@@ -35,5 +55,56 @@ public class ExpenseItemController {
         msg.data = userExpenseDetail;
         return msg;
     }
+
+    @RequestMapping("/exportData")
+    public HttpRespMsg exportData(Integer projectId) {
+        HttpRespMsg msg = new HttpRespMsg();
+        Integer companyId = userMapper.selectById(request.getHeader("token")).getCompanyId();
+        WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new LambdaQueryWrapper<WxCorpInfo>().eq(WxCorpInfo::getCompanyId,companyId));
+        HttpRespMsg data = list(projectId);
+        List<ExpenseItemVO> itemVOS = (List<ExpenseItemVO>) data.getData();
+        List<List<String>> dataList=new ArrayList<>();
+        List<String> titleList=new ArrayList<>();
+        titleList.add("员工姓名");
+        titleList.add("所在部门");
+        titleList.add("费用日期");
+        titleList.add("费用类型");
+        titleList.add("票据类型");
+        titleList.add("金额(含税)");
+        titleList.add("税额");
+        titleList.add("金额(不含税)");
+        titleList.add("备注");
+        dataList.add(titleList);
+        for (ExpenseItemVO itemVO : itemVOS) {
+            List<String> item=new ArrayList<>();
+            if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                String userName ="$userName="+String.valueOf(itemVO.getCorpwxUserId())+"$";
+                String deptName ="$departmentName="+String.valueOf(itemVO.getCorpwxDeptId())+"$";
+                item.add(userName);
+                item.add(deptName);
+            }else {
+                item.add(itemVO.getUsername());
+                item.add(itemVO.getDepartmentName());
+            }
+            item.add(itemVO.getHappenDate());
+            item.add(itemVO.getExpenseType());
+            item.add(itemVO.getInvoiceType()==null?"":(itemVO.getInvoiceType()==0?"增值税专用发票":"增值税普通发票"));
+            BigDecimal decimal = new BigDecimal(itemVO.getAmount()==null?0:itemVO.getAmount());
+            item.add(String.valueOf(itemVO.getAmount()==null?"0":itemVO.getAmount()));
+            item.add(String.valueOf(itemVO.getTaxValue()==null?"0":itemVO.getTaxValue()));
+            decimal=decimal.subtract(new BigDecimal(itemVO.getTaxValue()==null?0:itemVO.getTaxValue())).setScale(2,BigDecimal.ROUND_HALF_UP);
+            item.add(String.valueOf(decimal.doubleValue()));
+            item.add(itemVO.getRemark()==null?"":itemVO.getRemark());
+            dataList.add(item);
+        }
+        String fileUrlSuffix = "费用报销明细表_" + System.currentTimeMillis();
+        try {
+           return excelExportService.exportGeneralExcelByTitleAndList(wxCorpInfo, fileUrlSuffix, dataList, path);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return msg;
+    }
 }
 
+

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

@@ -2333,8 +2333,8 @@ public class ReportController {
 
     //todo:推送工时管家工时考勤数据到SAP
     @RequestMapping("/pushProjectReportToSap")
-    public HttpRespMsg pushProjectReportToSap(String yearMonth){
-        return reportService.pushProjectReportToSap(yearMonth);
+    public HttpRespMsg pushProjectReportToSap(String pushDate){
+        return reportService.pushProjectReportToSap(pushDate);
     }
 
     //todo: 提供接口(威派格) 获取项目工时数据

+ 4 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserWithBeisenController.java

@@ -62,6 +62,10 @@ public class UserWithBeisenController {
                 if(first.isPresent()){
                     userWithBeisen.setId(first.get().getId());
                 }
+                boolean anyMatch = userWithBeisenList.stream().anyMatch(u -> u.getUserId().equals(userWithBeisen.getUserId()));
+                if(anyMatch){
+                    continue;
+                }
                 userWithBeisenList.add(userWithBeisen);
             }
         }

+ 2 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/vo/ExpenseItemVO.java

@@ -11,5 +11,6 @@ import lombok.experimental.Accessors;
 public class ExpenseItemVO extends ExpenseItem {
     public String username;
     public String departmentName;
-
+    public String corpwxUserId;
+    public String corpwxDeptId;
 }

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

@@ -188,7 +188,7 @@ public interface ReportMapper extends BaseMapper<Report> {
 
     Double getReallWorkingTimeByProjectAndGroup(Integer projectId, Integer taskGroupId);
 
-    List<Map<String, Object>> getProjectPlanData(Integer companyId, String startDate, String endDate);
+    List<Map<String, Object>> getProjectPlanData(Integer companyId,@Param("list") List<Integer> projectIds, String startDate, String endDate);
 
     List<String> getUserIds(ArrayList<Integer> deptIds, String startDate, String endDate);
 

+ 135 - 104
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -54,6 +54,7 @@ import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.stream.Collectors;
 
@@ -5146,6 +5147,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 //                titles.add("审核流程");
                 titles.add(MessageUtils.message("excel.fillTime"));
                 titles.add(MessageUtils.message("excel.proReviewer"));
+                titles.add("项目经理");
                 titles.add(MessageUtils.message("excel.auditTime"));
                 titles.add(MessageUtils.message("excel.auditProcess"));
 //                logDetails = reportLogDetailMapper.selectList(new QueryWrapper<ReportLogDetail>().select("report_id, msg, operator_id, operate_date").eq("company_id", company.getId()).between("work_date", startDate, endDate));
@@ -5416,6 +5418,12 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                     }else {
                         item.add((String)map.get("projectAuditorName"));
                     }
+                    if(wxCorpInfo!=null&&wxCorpInfo.getSaasSyncContact()==1){
+                        String projectManagerName ="$userName="+String.valueOf(map.get("projectManagerCorpwxUserId"))+"$";
+                        item.add(projectManagerName);
+                    }else {
+                        item.add((String)map.get("projectManagerName"));
+                    }
                     //分组审核通过或者项目审核通过都显示
                     if (map.get("projectAuditTime") != null && ((Integer)map.get("projectAuditState") == 1 || (Integer)map.get("groupAuditState") == 1)) {
                         item.add(sdf.format((Date)map.get("projectAuditTime")));
@@ -7465,21 +7473,23 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
     }
 
     @Override
-    public HttpRespMsg pushProjectReportToSap(String yearMonth) {
+    public HttpRespMsg pushProjectReportToSap(String pushDate) {
         HttpRespMsg httpRespMsg =new HttpRespMsg();
-        String dateStr = yearMonth+"-01";
-        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
-        LocalDate start = LocalDate.parse(dateStr,df);
-        LocalDate end =start.plusMonths(1).minusDays(1);
-        List<SapSyncLog> sapSyncLogs=new ArrayList<>();
         LocalDateTime localDateTime=LocalDateTime.now();
         User user = userMapper.selectById(request.getHeader("token"));
         Integer companyId = user.getCompanyId();
-        List<Map<String,Object>> resultList=reportMapper.getPushProjectReportToSap(companyId,df.format(start),df.format(end),null);
+        List<Map<String,Object>> resultList=reportMapper.getPushProjectReportToSap(companyId,pushDate,pushDate,null);
+        //过滤服务code为空的数据
+        resultList=resultList.stream().filter(r->r.get("ProjectElementID")!=null && !StringUtils.isEmpty(String.valueOf(r.get("ProjectElementID")))).collect(Collectors.toList());
+        List<Integer> projectIds = resultList.stream().map(r -> Integer.valueOf(String.valueOf(r.get("ProjectId")))).distinct().collect(Collectors.toList());
+        projectIds.add(-1);
         //提前推送项目工时(工时管家相关项目任务分组阶段下任务作为SAP服务 预算工时数据推送到SAP)
-        List<Map<String, Object>> pushProjectPlanHour = reportMapper.getProjectPlanData(companyId,null,null);
+        //只推送需要推送日报参与的部分就可以了
+        List<Map<String, Object>> pushProjectPlanHour = reportMapper.getProjectPlanData(companyId,projectIds,null,null);
         List<SapSyncLog> projectPlanSyncLogs = SyncSapUtils.pushProjectPlanToSap(pushProjectPlanHour, user.getCompanyId(), user.getJobNumber());
-        sapSyncLogs.addAll(projectPlanSyncLogs);
+        if(projectPlanSyncLogs.size()>0){
+            sapSyncLogService.saveBatch(projectPlanSyncLogs);
+        }
         //配置xml请求参数
         XmlRequestData xmlRequestData=new XmlRequestData();
         xmlRequestData.setBasicMessageHeader("");
@@ -7488,102 +7498,123 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         workDescriptionText.setLanguageCode("ZH");
         SapPeriod datePeriod=new SapPeriod();
         SapPeriod timePeriod=new SapPeriod();
-        List<ReportPushLog> addList=new ArrayList<>();
-        long sTime = System.currentTimeMillis();
-        for (Map<String, Object> map : resultList) {
-            ReportPushLog one = reportPushLogService.getOne(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getCompanyId, companyId).eq(ReportPushLog::getReportId, map.get("ReportId")).eq(ReportPushLog::getTargetSystem,"SAP"));
-            if(one!=null){
-                continue;
-            }
-            employeeTime.setEmployeeID(String.valueOf(map.get("EmployeeID")));
-            employeeTime.setActionCode("01");
-            if(map.get("StartDate")!=null){
-                datePeriod.setStartDate(String.valueOf(map.get("StartDate")));
-            }
-            if(map.get("EndDate")!=null){
-                datePeriod.setEndDate(String.valueOf(map.get("EndDate")));
-            }
-            if(map.get("StartTime")!=null){
-                timePeriod.setStartTime(String.valueOf(map.get("StartTime"))+":00");
-            }
-            if(map.get("EndTime")!=null){
-                timePeriod.setEndTime(String.valueOf(map.get("EndTime"))+":00");
-            }
-            employeeTime.setDatePeriod(datePeriod);
-            employeeTime.setTimePeriod(timePeriod);
-            employeeTime.setItemTypeCode("CN0001");
-            String duration=map.get("Duration")==null?"0":String.valueOf(map.get("Duration"))+"";
-            String hour = duration.substring(0, duration.indexOf("."));
-            String min = "0"+duration.substring(duration.indexOf("."));
-            BigDecimal minBigDecimal = new BigDecimal(min);
-            minBigDecimal=minBigDecimal.multiply(new BigDecimal(60)).setScale(0,BigDecimal.ROUND_HALF_UP);
-            employeeTime.setDuration("PT"+hour+"H"+minBigDecimal.intValue()+"M");
-            if(map.get("ProjectElementID")==null||map.get("ServiceProductInternalID")==null){
-                continue;
-            }
-            employeeTime.setProjectElementID(String.valueOf(map.get("ProjectElementID")));
-            employeeTime.setServiceProductInternalID(String.valueOf(map.get("ServiceProductInternalID")));
-            if(map.get("WorkDescriptionText")!=null){
-                workDescriptionText.setWorkDescriptionText(String.valueOf(map.get("WorkDescriptionText")));
-                employeeTime.setWorkDescriptionText(workDescriptionText);
-            }
-            xmlRequestData.setEmployeeTime(employeeTime);
-            String xml = CommonUtils.convertToXml(xmlRequestData);
-            System.out.println(xml);
-            xml=xml.substring(xml.indexOf("<XMLDATA>")+9,xml.lastIndexOf("</XMLDATA>"));
-            StringBuffer sb = new StringBuffer();
-            sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">\n" +
-                    "   <soapenv:Header/>\n" +
-                    "   <soapenv:Body>\n" +
-                    "      <glob:EmployeeTimeAsBundleMaintainRequest_sync>\n");
-            sb.append(xml);
-            sb.append("      </glob:EmployeeTimeAsBundleMaintainRequest_sync>\n" +
-                    "   </soapenv:Body>\n" +
-                    "</soapenv:Envelope>");
-            System.out.println(sb.toString());
-            String result = "";
-            try {
-                result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/manageemployeetimein?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
-            } catch (Exception e) {
-                e.printStackTrace();
-            }
-            if(!StringUtils.isEmpty(result)) {
-                result = result.substring(result.indexOf("<soap-env:Body>")+15, result.lastIndexOf("</soap-env:Body>"));
-                result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:EmployeeTimeAsBundleMaintainConfirmation_sync>"));
-                result="<XMLDATA>"+result+"</XMLDATA>";
-            }
-            System.out.println(result);
-            XmlResponseData xmlResponseData = (XmlResponseData) CommonUtils.convertXmlStrToObject(XmlResponseData.class, result);
-            SapSyncLog sapSyncLog=new SapSyncLog();
-            sapSyncLog.setOperator(user.getJobNumber());
-            sapSyncLog.setCompanyId(companyId);
-            sapSyncLog.setRemark("日报数据推送");
-            sapSyncLog.setSyncType("手动推送");
-            sapSyncLog.setSyncTime(localDateTime);
-            if(StringUtils.isEmpty(xmlResponseData.getEmployeeTime())){
-                log.error("推送失败===》工号:"+employeeTime.getEmployeeID());
-                sapSyncLog.setResult("员工工号["+employeeTime.getEmployeeID()+"]"+datePeriod.getStartDate()+"日报推送失败");
-                sapSyncLog.setResultRemark(xmlResponseData.getLog()!=null?xmlResponseData.getLog().getItem()!=null?xmlResponseData.getLog().getItem().getNote():"":"");
-            }else {
-                sapSyncLog.setResult("工号["+employeeTime.getEmployeeID()+"]"+datePeriod.getStartDate()+"日报推送成功");
-                //推送成功 日报数据打上标记
-                ReportPushLog reportPushLog=new ReportPushLog();
-                reportPushLog.setCompanyId(companyId);
-                reportPushLog.setReportId(Integer.valueOf(String.valueOf(map.get("ReportId"))));
-                reportPushLog.setTargetSystem("SAP");
-                reportPushLog.setUuid(xmlResponseData.getEmployeeTime().getUUID());
-                addList.add(reportPushLog);
-            }
-            sapSyncLogs.add(sapSyncLog);
-        }
-        if(addList.size()>0){
-            reportPushLogService.saveBatch(addList);
-        }
-        if(sapSyncLogs.size()>0){
-            sapSyncLogService.saveBatch(sapSyncLogs);
+        List<Map<String, Object>> finalResultList = resultList;
+        //创建多个个线程来处理 每个线程处理10条数据
+        int size = finalResultList.size();
+        //需要创建的线程数量 防止有小数 获取整数+1
+        BigDecimal divide = new BigDecimal(size).divide(new BigDecimal(10));
+        int thredNum = divide.intValue() + 1;
+        ExecutorService executor = Executors.newFixedThreadPool(10);
+        //创建锁对象
+        Object o = new Object();
+        /*execute()让线程池中的线程来执行业务,每次调用都会将一个线程加入到就绪队列*/
+        for (int i = 0; i <thredNum ; i++) {
+            //目标数据进行分组
+            int start=i*10;
+            int end=(i+1)*10;
+            if(end>finalResultList.size()){
+                end=finalResultList.size();
+            }
+            List<Map<String, Object>> mapList = finalResultList.subList(start, end);
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    synchronized (o) {//同步代码块解决的是重卖的问题
+                        /*本方法的参数就是你要执行的业务,也就是目标业务类对象*/
+                        //3.定义成员变量,保存票数
+                        for (Map<String, Object> map : mapList) {
+                            ReportPushLog one = reportPushLogService.getOne(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getCompanyId, companyId).eq(ReportPushLog::getReportId, map.get("ReportId")).eq(ReportPushLog::getTargetSystem,"SAP"));
+                            if(one!=null){
+                                continue;
+                            }
+                            employeeTime.setEmployeeID(String.valueOf(map.get("EmployeeID")));
+                            employeeTime.setActionCode("01");
+                            if(map.get("StartDate")!=null){
+                                datePeriod.setStartDate(String.valueOf(map.get("StartDate")));
+                            }
+                            if(map.get("EndDate")!=null){
+                                datePeriod.setEndDate(String.valueOf(map.get("EndDate")));
+                            }
+                            if(map.get("StartTime")!=null){
+                                timePeriod.setStartTime(String.valueOf(map.get("StartTime"))+":00");
+                            }
+                            if(map.get("EndTime")!=null){
+                                timePeriod.setEndTime(String.valueOf(map.get("EndTime"))+":00");
+                            }
+                            employeeTime.setDatePeriod(datePeriod);
+                            employeeTime.setTimePeriod(timePeriod);
+                            employeeTime.setItemTypeCode("CN0001");
+                            String duration=map.get("Duration")==null?"0":String.valueOf(map.get("Duration"))+"";
+                            String hour = duration.substring(0, duration.indexOf("."));
+                            String min = "0"+duration.substring(duration.indexOf("."));
+                            BigDecimal minBigDecimal = new BigDecimal(min);
+                            minBigDecimal=minBigDecimal.multiply(new BigDecimal(60)).setScale(0,BigDecimal.ROUND_HALF_UP);
+                            employeeTime.setDuration("PT"+hour+"H"+minBigDecimal.intValue()+"M");
+                            if(map.get("ProjectElementID")==null||map.get("ServiceProductInternalID")==null){
+                                continue;
+                            }
+                            employeeTime.setProjectElementID(String.valueOf(map.get("ProjectElementID")));
+                            employeeTime.setServiceProductInternalID(String.valueOf(map.get("ServiceProductInternalID")));
+                            if(map.get("WorkDescriptionText")!=null){
+                                workDescriptionText.setWorkDescriptionText(String.valueOf(map.get("WorkDescriptionText")));
+                                employeeTime.setWorkDescriptionText(workDescriptionText);
+                            }
+                            xmlRequestData.setEmployeeTime(employeeTime);
+                            String xml = CommonUtils.convertToXml(xmlRequestData);
+                            System.out.println(xml);
+                            xml=xml.substring(xml.indexOf("<XMLDATA>")+9,xml.lastIndexOf("</XMLDATA>"));
+                            StringBuffer sb = new StringBuffer();
+                            sb.append("<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:glob=\"http://sap.com/xi/SAPGlobal20/Global\">\n" +
+                                    "   <soapenv:Header/>\n" +
+                                    "   <soapenv:Body>\n" +
+                                    "      <glob:EmployeeTimeAsBundleMaintainRequest_sync>\n");
+                            sb.append(xml);
+                            sb.append("      </glob:EmployeeTimeAsBundleMaintainRequest_sync>\n" +
+                                    "   </soapenv:Body>\n" +
+                                    "</soapenv:Envelope>");
+                            System.out.println(sb.toString());
+                            String result = "";
+                            try {
+                                result = WebServiceUtils.requestByXml("https://my601432.sapbyd.cn/sap/bc/srt/scs/sap/manageemployeetimein?sap-vhost=my601432.sapbyd.cn", sb.toString(), 0, "_BYDHOST", "Welcome1");
+                            } catch (Exception e) {
+                                e.printStackTrace();
+                            }
+                            if(!StringUtils.isEmpty(result)) {
+                                result = result.substring(result.indexOf("<soap-env:Body>")+15, result.lastIndexOf("</soap-env:Body>"));
+                                result = result.substring(result.indexOf(">")+1, result.lastIndexOf("</n0:EmployeeTimeAsBundleMaintainConfirmation_sync>"));
+                                result="<XMLDATA>"+result+"</XMLDATA>";
+                            }
+                            System.out.println(result);
+                            XmlResponseData xmlResponseData = (XmlResponseData) CommonUtils.convertXmlStrToObject(XmlResponseData.class, result);
+                            SapSyncLog sapSyncLog=new SapSyncLog();
+                            sapSyncLog.setOperator(user.getJobNumber());
+                            sapSyncLog.setCompanyId(companyId);
+                            sapSyncLog.setRemark("日报数据推送");
+                            sapSyncLog.setSyncType("手动推送");
+                            sapSyncLog.setSyncTime(localDateTime);
+                            if(StringUtils.isEmpty(xmlResponseData.getEmployeeTime())){
+                                log.error("推送失败===》员工工号:"+employeeTime.getEmployeeID());
+                                sapSyncLog.setResult("员工工号["+employeeTime.getEmployeeID()+"]"+datePeriod.getStartDate()+"日报推送失败");
+                                sapSyncLog.setResultRemark(xmlResponseData.getLog()!=null?xmlResponseData.getLog().getItem()!=null?xmlResponseData.getLog().getItem().getNote():"":"");
+                            }else {
+                                sapSyncLog.setResult("员工工号["+employeeTime.getEmployeeID()+"]"+datePeriod.getStartDate()+"日报推送成功");
+                                //推送成功 日报数据打上标记
+                                ReportPushLog reportPushLog=new ReportPushLog();
+                                reportPushLog.setCompanyId(companyId);
+                                reportPushLog.setReportId(Integer.valueOf(String.valueOf(map.get("ReportId"))));
+                                reportPushLog.setTargetSystem("SAP");
+                                reportPushLog.setUuid(xmlResponseData.getEmployeeTime().getUUID());
+                                reportPushLogService.save(reportPushLog);
+                            }
+                            sapSyncLogService.save(sapSyncLog);
+                            System.out.println("线程:"+Thread.currentThread().getName()+"正在操作"+map.get("ReportId"));
+                        }
+                    }
+                }
+            });
         }
-        long eTime = System.currentTimeMillis();
-        httpRespMsg.setData("推送完成 耗时:"+(eTime-sTime)+"ms");
+        httpRespMsg.setData("推送正在进行...待推送完成可查看工时日志");
+        executor.shutdown();
         return httpRespMsg;
     }
 

+ 63 - 39
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -49,9 +49,7 @@ import java.time.temporal.TemporalAccessor;
 import java.time.temporal.TemporalAdjusters;
 import java.time.temporal.WeekFields;
 import java.util.*;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
+import java.util.concurrent.*;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
 
@@ -1702,45 +1700,71 @@ public class TimingTask {
         LocalDateTime localDateTime=LocalDateTime.now();
         for (TimeType timeType : timeTypeList) {
             Integer companyId = timeType.getCompanyId();
-            List<SapSyncLog> sapSyncLogs=new ArrayList<>();
             //提前推送项目工时(工时管家相关项目任务分组阶段下任务作为SAP服务 预算工时数据推送到SAP)
-            List<Map<String, Object>> pushProjectPlanHour = reportMapper.getProjectPlanData(companyId,null,null);
-            List<SapSyncLog> projectPlanSapSyncLogs = SyncSapUtils.pushProjectPlanToSap(pushProjectPlanHour, companyId, "");
-            sapSyncLogs.addAll(projectPlanSapSyncLogs);
             List<Map<String, Object>> mapList = reportMapper.getPushProjectReportToSap(companyId,df.format(date.minusDays(1)),df.format(date.minusDays(1)), null);
-            List<ReportPushLog> addList=new ArrayList<>();
-            for (Map<String, Object> map : mapList) {
-                ReportPushLog one = reportPushLogService.getOne(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getCompanyId, companyId).eq(ReportPushLog::getReportId, map.get("ReportId")).eq(ReportPushLog::getTargetSystem,"SAP"));
-                if(one!=null){
-                    continue;
-                }
-                XmlResponseData xmlResponseData = SyncSapUtils.pushReportToSap(map);
-                SapSyncLog sapSyncLog=new SapSyncLog();
-                sapSyncLog.setCompanyId(companyId);
-                sapSyncLog.setRemark("日报数据推送");
-                sapSyncLog.setSyncType("定时任务推送");
-                sapSyncLog.setSyncTime(localDateTime);
-                if(StringUtils.isEmpty(xmlResponseData.getEmployeeTime())){
-                    log.error("推送失败===》工号:"+map.get("EmployeeID"));
-                    sapSyncLog.setResult("员工工号["+map.get("EmployeeID")+"]"+map.get("StartDate")+"日报推送失败");
-                    sapSyncLog.setResultRemark(xmlResponseData.getLog()!=null?xmlResponseData.getLog().getItem()!=null?xmlResponseData.getLog().getItem().getNote():"":"");
-                }else {
-                    sapSyncLog.setResult("工号["+map.get("EmployeeID")+"]"+map.get("StartDate")+"日报推送成功");
-                    //推送成功 日报数据打上标记
-                    ReportPushLog reportPushLog=new ReportPushLog();
-                    reportPushLog.setCompanyId(companyId);
-                    reportPushLog.setReportId(Integer.valueOf(String.valueOf(map.get("ReportId"))));
-                    reportPushLog.setTargetSystem("SAP");
-                    reportPushLog.setUuid(xmlResponseData.getEmployeeTime().getUUID());
-                    addList.add(reportPushLog);
-                }
-                sapSyncLogs.add(sapSyncLog);
-            }
-            if(addList.size()>0){
-                reportPushLogService.saveBatch(addList);
+            //过滤服务code为空的数据
+            mapList=mapList.stream().filter(r->r.get("ProjectElementID")!=null && !StringUtils.isEmpty(String.valueOf(r.get("ProjectElementID")))).collect(Collectors.toList());
+            List<Integer> projectIds = mapList.stream().map(r -> Integer.valueOf(String.valueOf(r.get("ProjectId")))).distinct().collect(Collectors.toList());
+            projectIds.add(-1);
+            List<Map<String, Object>> pushProjectPlanHour = reportMapper.getProjectPlanData(companyId,projectIds,null,null);
+            List<SapSyncLog> projectPlanSapSyncLogs = SyncSapUtils.pushProjectPlanToSap(pushProjectPlanHour, companyId, "");
+            if(projectPlanSapSyncLogs.size()>0){
+                sapSyncLogService.saveBatch(projectPlanSapSyncLogs);
             }
-            if(sapSyncLogs.size()>0){
-                sapSyncLogService.saveBatch(sapSyncLogs);
+            List<Map<String, Object>> finalResultList = mapList;
+            //创建多个个线程来处理 每个线程处理10条数据
+            int size = finalResultList.size();
+            //需要创建的线程数量 防止有小数 获取整数+1
+            BigDecimal divide = new BigDecimal(size).divide(new BigDecimal(10));
+            int thredNum = divide.intValue() + 1;
+            ExecutorService executor = Executors.newFixedThreadPool(10);
+            //创建锁对象
+            Object o = new Object();
+            /*execute()让线程池中的线程来执行业务,每次调用都会将一个线程加入到就绪队列*/
+            for (int i = 0; i <thredNum ; i++) {
+                //目标数据进行分组
+                int start=i*10;
+                int end=(i+1)*10;
+                if(end>finalResultList.size()){
+                    end=finalResultList.size();
+                }
+                List<Map<String, Object>> targetList = finalResultList.subList(start, end);
+                executor.execute(new Runnable() {
+                    @Override
+                    public void run() {
+                        synchronized (o) {//同步代码块解决的是重卖的问题
+                            /*本方法的参数就是你要执行的业务,也就是目标业务类对象*/
+                            //3.定义成员变量,保存票数
+                            for (Map<String, Object> map : targetList) {
+                                ReportPushLog one = reportPushLogService.getOne(new LambdaQueryWrapper<ReportPushLog>().eq(ReportPushLog::getCompanyId, companyId).eq(ReportPushLog::getReportId, map.get("ReportId")).eq(ReportPushLog::getTargetSystem,"SAP"));
+                                if(one!=null){
+                                    continue;
+                                }
+                                XmlResponseData xmlResponseData = SyncSapUtils.pushReportToSap(map);
+                                SapSyncLog sapSyncLog=new SapSyncLog();
+                                sapSyncLog.setCompanyId(companyId);
+                                sapSyncLog.setRemark("日报数据推送");
+                                sapSyncLog.setSyncType("定时任务推送");
+                                sapSyncLog.setSyncTime(localDateTime);
+                                if(StringUtils.isEmpty(xmlResponseData.getEmployeeTime())){
+                                    log.error("推送失败===》工号:"+map.get("EmployeeID"));
+                                    sapSyncLog.setResult("员工工号["+map.get("EmployeeID")+"]"+map.get("StartDate")+"日报推送失败");
+                                    sapSyncLog.setResultRemark(xmlResponseData.getLog()!=null?xmlResponseData.getLog().getItem()!=null?xmlResponseData.getLog().getItem().getNote():"":"");
+                                }else {
+                                    sapSyncLog.setResult("员工工号["+map.get("EmployeeID")+"]"+map.get("StartDate")+"日报推送成功");
+                                    //推送成功 日报数据打上标记
+                                    ReportPushLog reportPushLog=new ReportPushLog();
+                                    reportPushLog.setCompanyId(companyId);
+                                    reportPushLog.setReportId(Integer.valueOf(String.valueOf(map.get("ReportId"))));
+                                    reportPushLog.setTargetSystem("SAP");
+                                    reportPushLog.setUuid(xmlResponseData.getEmployeeTime().getUUID());
+                                    reportPushLogService.save(reportPushLog);
+                                }
+                                sapSyncLogService.save(sapSyncLog);
+                            }
+                        }
+                    }
+                });
             }
         }
     }

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/SyncSapUtils.java

@@ -107,6 +107,7 @@ public class SyncSapUtils {
             if(StringUtils.isEmpty(xmlResponseData.getZManageProjectTaskWork())){
                 log.error("推送失败===》项目编号:"+zManageProjectTaskWork.getProjectID());
                 sapSyncLog.setResult("项目编号["+zManageProjectTaskWork.getProjectID()+"]预算工时推送失败");
+                sapSyncLog.setResultRemark(xmlResponseData.getLog()!=null?xmlResponseData.getLog().getItem()!=null?xmlResponseData.getLog().getItem().getNote():"":"");
             }else {
                 sapSyncLog.setResult("项目编号["+zManageProjectTaskWork.getProjectID()+"]预算工时推送成功");
             }

+ 7 - 4
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ExpenseItemMapper.xml

@@ -34,6 +34,8 @@
         <result column="status" property="status" />
         <result column="username" property="username" />
         <result column="department_name" property="departmentName" />
+        <result column="corpwxUserId" property="corpwxUserId" />
+        <result column="corpwxDeptId" property="corpwxDeptId" />
     </resultMap>
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
@@ -41,10 +43,11 @@
     </sql>
     <select id="getUserExpenseDetail" resultMap="UserBaseResultMap">
         select a.id, a.expense_id, a.project_id, a.happen_date, a.invoice_type, a.tax_percent, a.tax_value, a.amount, a.remark, a.expense_type, a.pic,a.status,
-               user.name as username, department.department_name
-        from expense_item a left join expense_sheet b on a.expense_id = b.id
-                            left join user on user.id = b.owner_id
-                            left join department on department.department_id = user.department_id
+        user.name as username,user.corpwx_userid as corpwxUserId, department.department_name,department.corpwx_deptid as corpwxDeptId
+        from expense_item a
+        left join expense_sheet b on a.expense_id = b.id
+        left join user on user.id = b.owner_id
+        left join department on department.department_id = user.department_id
         where a.project_id = #{projectId} order by a.happen_date desc
     </select>
 

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

@@ -69,6 +69,7 @@
         , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId,a.custom_data as customData
         ,u.name as projectAuditorName,u.corpwx_userid as projectAuditorCorpwxUserId, a.project_auditor_id as projectAuditorId, department.department_name as departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText,a.project_audit_time  as projectAuditTime,project_main.name as projectMainName,
         a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId,b.status as projectStatus,DATE_FORMAT(b.finish_date,'%Y-%m-%d') as finishDate,ps.project_category_sub as projectCategorySub
+        ,u2.name as projectManagerName,u2.corpwx_userid as projectManagerCorpwxUserId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
         LEFT JOIN project_separate AS ps on b.id=ps.id
@@ -78,6 +79,7 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
+        left join user u2 on u2.id = b.incharger_id
         left join department on department.department_id = c.department_id
         left join department dp2 on dp2.department_id = b.bu_id
         left join project_main on b.project_main_id=project_main.id
@@ -123,6 +125,7 @@
         , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId,a.custom_data as customData
         ,u.name as projectAuditorName,u.corpwx_userid as projectAuditorCorpwxUserId, a.project_auditor_id as projectAuditorId, department.department_name as departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText,a.project_audit_time  as projectAuditTime,project_main.name as projectMainName,
         GROUP_CONCAT(rlog.operator_id,'@', rlog.operate_date,'@', rlog.msg SEPARATOR '❤') AS logMsg,a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3,b.status as projectStatus,DATE_FORMAT(b.finish_date,'%Y-%m-%d') as finishDate,ps.project_category_sub as projectCategorySub
+        ,u2.name as projectManagerName,u2.corpwx_userid as projectManagerCorpwxUserId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
         LEFT JOIN project_separate AS ps on b.id=ps.id
@@ -132,6 +135,7 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
+        left join user u2 on u2.id = b.incharger_id
         left join department on department.department_id = c.department_id
         left join department dp2 on dp2.department_id = b.bu_id
         left join project_main on b.project_main_id=project_main.id
@@ -204,6 +208,7 @@
         departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText, a.project_audit_time as
         projectAuditTime,project_main.name as projectMainName,a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId,b.status as projectStatus,
         DATE_FORMAT(b.finish_date,'%Y-%m-%d') as finishDate,ps.project_category_sub as projectCategorySub
+        ,u2.name as projectManagerName,u2.corpwx_userid as projectManagerCorpwxUserId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
         LEFT JOIN project_separate AS ps on b.id=ps.id
@@ -213,6 +218,7 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
+        left join user u2 on u2.id = b.incharger_id
         left join department on department.department_id = c.department_id
         left join department dp2 on dp2.department_id = b.bu_id
         left join project_main on project_main.id=b.project_main_id
@@ -270,6 +276,7 @@
         departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText, a.project_audit_time as
         projectAuditTime,project_main.name as projectMainName,b.status as projectStatus,DATE_FORMAT(b.finish_date,'%Y-%m-%d') as finishDate,ps.project_category_sub as projectCategorySub,
         GROUP_CONCAT(rlog.operator_id,'@', rlog.operate_date,'@', rlog.msg SEPARATOR '❤') AS logMsg,a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3
+        ,u2.name as projectManagerName,u2.corpwx_userid as projectManagerCorpwxUserId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
         LEFT JOIN project_separate AS ps on b.id=ps.id
@@ -279,6 +286,7 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
+        left join user u2 on u2.id = b.incharger_id
         left join department on department.department_id = c.department_id
         left join department dp2 on dp2.department_id = b.bu_id
         left join project_main on project_main.id=b.project_main_id
@@ -331,6 +339,7 @@
         , reject_reason as rejectReason, reject_username as rejectUsername, reject_userid as rejectUserid, degree_id as degree_id,report_extra_degree.name as degreeName,task_group.name as groupName,a.group_id as groupId, a.custom_data as customData
         ,u.name as projectAuditorName,u.corpwx_userid as projectAuditorCorpwxUserId, a.project_auditor_id as projectAuditorId, department.department_name as departmentName,dp2.department_name as buDepartmentName,department.department_id as departmentId, a.overtime_hours as overtimeHours, a.custom_text as customText, a.project_audit_time as projectAuditTime,project_main.name as projectMainName
         ,a.extra_field1 as extraField1,a.extra_field2 as extraField2,a.extra_field3 as extraField3, a.batch_id as batchId,a.sap_service_id as sapServiceId,b.status as projectStatus,DATE_FORMAT(b.finish_date,'%Y-%m-%d') as finishDate,ps.project_category_sub as projectCategorySub
+        ,u2.name as projectManagerName,u2.corpwx_userid as projectManagerCorpwxUserId
         FROM report AS a
         JOIN project AS b ON a.project_id=b.id
         LEFT JOIN project_separate AS ps on b.id=ps.id
@@ -340,6 +349,7 @@
         left join report_extra_degree on report_extra_degree.id = a.degree_id
         left join task_group on task_group.id = a.group_id
         left join user u on u.id = a.project_auditor_id
+        left join user u2 on u2.id = b.incharger_id
         left join department on department.department_id = c.department_id
         left join department dp2 on dp2.department_id = b.bu_id
         left join project_main on project_main.id=b.project_main_id
@@ -961,7 +971,7 @@
     <select id="getPushProjectReportToSap" resultType="java.util.Map">
         select r.id as ReportId, u.job_number as EmployeeID,r.create_date as StartDate,r.create_date as EndDate,r.start_time as StartTime,r.end_time as EndTime,
         r.working_time as Duration,t.sap_task_code as ProjectElementID,
-        sps.service_code as ServiceProductInternalID,r.content as WorkDescriptionText
+        sps.service_code as ServiceProductInternalID,r.content as WorkDescriptionText,p.id as ProjectId
         from report r
         left join user u on u.id=r.creator_id
         left join department d on u.department_id=d.department_id
@@ -1012,9 +1022,14 @@
         left join user u on te.executor_id=u.id
         where t.company_id=#{companyId}
         and t.start_date is not null
+        and t.end_date is not null
         and t.plan_hours is not null
         and te.service_id is not null
         and u.job_number is not null
+        and p.id in
+        <foreach collection="list" open="(" separator="," close=")" item="item">
+            #{item}
+        </foreach>
         <if test="startDate!=null and startDate!='' and endDate!=null and endDate!=''">
             and t.create_date between #{startDate} and #{endDate}
         </if>

+ 28 - 0
fhKeeper/formulahousekeeper/timesheet/src/views/corpreport/list.vue

@@ -1132,6 +1132,7 @@
             </div>
         </el-dialog>
         <el-dialog :title="curProject.projectName+'-'+$t('detailsofreimbursementexpenses')" show-summary=true v-if="detailVisible" :summary-method="getSummaries" :visible.sync="detailVisible" :close-on-click-modal="false" customClass="customWidth" width="1000px">
+        <div><el-button size="mini" @click="exportExpenseDetail" style="float:right" type="primary">导出</el-button></div>
         <el-table  :key="ins" border :data="detailList" highlight-current-row v-loading="detailListLoading" :height="500" style="width: 100%;">
                 <el-table-column  prop="username" :label="$t('screening.employeename')"  >
                   <template slot-scope="scope" >
@@ -1490,6 +1491,8 @@ export default {
 
       projectTaskgroupList: [], // 选择项目的任务分组
       projectGroupId: '', // 选择项目的任务分组id
+
+      detailProjectId:null,//报销费用详情项目id
     };
   },
   computed: {},
@@ -1757,6 +1760,7 @@ export default {
       this.curProject = row;
       this.detailListLoading = true;
       this.detailVisible = true;
+      this.detailProjectId=row.id;
       this.http.post('/expense-item/list', {projectId: row.id},
             res => {
               this.detailListLoading = false;
@@ -1776,6 +1780,30 @@ export default {
                 });
             });
     },
+    exportExpenseDetail(){
+      this.http.post("/expense-item/exportData", {projectId:this.detailProjectId},
+        res => {
+            if (res.code == "ok") {
+                var filePath = res.data;
+                const a = document.createElement('a'); // 创建a标签
+                a.setAttribute('download', '费用报销明细表.xlsx');// download属性
+                a.setAttribute('href', filePath);// href链接
+                a.click(); //自执行点击事件
+                a.remove();
+            } else {
+                this.$message({
+                message: res.msg,
+                type: "error"
+                });
+            }
+        },
+        error => {
+            this.$message({
+                message: error,
+                type: "error"
+            });
+        });
+    },
     expandRow(row, index) {
       this.title = this.$t('ke-hu')+':'+row.customerName;
         this.childrenList = row.children;

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

@@ -144,7 +144,7 @@
                                     <!--部门负责人给个导出工时的功能 -->
                                     <el-link type="primary" v-if="user.manageDeptId != 0" style="margin-right:10px;" :underline="false" @click="showExportTimeDialog">{{$t('textLink.exportingTimeStatistics')}}</el-link>
                                     <el-link type="primary" v-if="user.timeType.pushReportData == 1 && permissions.reportPush" :underline="false" @click="pushWorkTime">推送工时</el-link>
-                                    <el-link type="primary" v-if="user.timeType.pushReportData == 1 && permissions.reportPush" :underline="false" @click="pushWorkTimeLogDig=true,getPushWorkLogData()">工时推送日志</el-link>
+                                    <el-link type="primary" v-if="user.timeType.pushReportData == 1 && user.companyId==3092 && permissions.reportPush" :underline="false" @click="pushWorkTimeLogDig=true,getPushWorkLogData()">工时推送日志</el-link>
                                     <!-- <el-button v-if="user.timeType.pushReportData == 1 && permissions.reportPush" style="margin-left:10px;" icon="iconfont firerock-icontuisong" size="mini" @click="pushWorkTime"></el-button> -->
 
                                 </span>
@@ -3528,10 +3528,47 @@
         let url=''
         if(this.user.timeType.syncSap == 1){
             url='/report/pushProjectReportToSap'
+            let day = (this.choseDay+1) > 9 ? "-" + (this.choseDay + 1) : "-0" + (this.choseDay + 1);
+            var pushDate = this.date + day;
+            this.$confirm('确认推送'+pushDate+'的工时?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'info'
+        }).then(() => {
+            const loading = this.$loading({
+                lock: true,
+                text: '正在推送中,请耐心等待。',
+                spinner: 'el-icon-loading',
+                background: 'rgba(0, 0, 0, 0.7)'
+            });
+            this.http.post(url,{
+                pushDate: pushDate
+            },res => {
+                loading.close();
+                if(res.code == 'ok'){
+                    this.$message({
+                        type: 'success',
+                        message: res.data
+                    });
+                }else{
+                    this.$message({
+                        type: 'error',
+                        message: res.msg
+                    })
+                }
+            },err => {
+                loading.close();
+                this.$message({
+                    type: 'error',
+                    message: err
+                })
+            })
+          
+        }).catch(() => {
+        });
         }else{
             url='/report/pushReportDataToThird'
-        }
-        this.$confirm('确认推送'+this.date+'月的工时?', '提示', {
+            this.$confirm('确认推送'+this.date+'月的工时?', '提示', {
           confirmButtonText: '确定',
           cancelButtonText: '取消',
           type: 'info'
@@ -3567,6 +3604,7 @@
           
         }).catch(() => {
         });
+        }
     },
 
     showWorkTime(){