Browse Source

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

Lijy 2 years ago
parent
commit
87c55c16dc
22 changed files with 539 additions and 43 deletions
  1. 6 0
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  2. 1 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/aop/AopLogConfiguration.java
  3. 9 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CommonUploadController.java
  4. 8 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectDocumentController.java
  5. 10 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  6. 7 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskFilesController.java
  7. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/User.java
  8. 15 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/mapper/ReportMapper.java
  9. 0 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ExcelExportServiceImpl.java
  10. 11 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java
  11. 139 20
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  12. 32 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/SFTPAsyncUploader.java
  13. 19 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java
  14. 63 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/SFTPUploader.java
  15. 39 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/TestSample.java
  16. 9 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-prod.yml
  17. 9 3
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml
  18. 16 10
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml
  19. 115 1
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ReportMapper.xml
  20. 2 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application-dev.yml
  21. 3 1
      fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application-prod.yml
  22. 25 0
      fhKeeper/formulahousekeeper/restart.sh

+ 6 - 0
fhKeeper/formulahousekeeper/management-platform/pom.xml

@@ -179,6 +179,12 @@
             <version>3.3.0</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.jcraft</groupId>
+            <artifactId>jsch</artifactId>
+            <version>0.1.55</version>
+        </dependency>
+
         <dependency>
             <groupId>com.aliyun</groupId>
             <artifactId>dysmsapi20170525</artifactId>

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

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

+ 9 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/CommonUploadController.java

@@ -1,13 +1,16 @@
 package com.management.platform.controller;
 
+import com.management.platform.task.SFTPAsyncUploader;
 import com.management.platform.util.HttpRespMsg;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.annotation.Resource;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.InputStream;
@@ -21,6 +24,8 @@ public class CommonUploadController {
     Logger logger = LogManager.getLogger(org.apache.logging.log4j.LogManager.ROOT_LOGGER_NAME);
     @Value(value = "${upload.path}")
     private String path;
+    @Autowired
+    public SFTPAsyncUploader sftpAsyncUploader;
 
     @RequestMapping(value="uploadFile")
     public HttpRespMsg uploadFile(MultipartFile multipartFile) {
@@ -50,6 +55,10 @@ public class CommonUploadController {
             inputStream.close();
             outputStream.close();
             msg.data = serverName;
+
+            // 上传到SFTP服务器
+            sftpAsyncUploader.uploadFileAsync(file);
+
         } catch (Exception exception) {
             exception.printStackTrace();
             logger.error(exception.getMessage());

+ 8 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ProjectDocumentController.java

@@ -9,6 +9,7 @@ import com.management.platform.constant.Constant;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.ProjectDocumentService;
+import com.management.platform.task.SFTPAsyncUploader;
 import com.management.platform.util.*;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
@@ -63,6 +64,9 @@ public class ProjectDocumentController {
     @Value("${upload.path}")
     private String uploadPath;
 
+    @Autowired
+    public SFTPAsyncUploader sftpAsyncUploader;
+
     /**
      * 上传文件
      * @param projectId 项目id
@@ -114,10 +118,14 @@ public class ProjectDocumentController {
                     try {
                         saveFile.createNewFile();
                         file.transferTo(saveFile);
+                        //异步上传到备份服务器
+                        sftpAsyncUploader.uploadFileAsync(saveFile);
+
                         //计算文件大小
                         long fileSize = saveFile.length();
                         String fileLength = FileUtil.getReadableFileSize(fileSize);
                         record.setServerName(uploadPath + fileName);
+
                         record.setSize(fileLength);
                         String pathPrefix = "/upload/";
                         record.setUrl(pathPrefix + fileName);

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

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

+ 7 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/TaskFilesController.java

@@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.management.platform.entity.*;
 import com.management.platform.mapper.*;
 import com.management.platform.service.ProjectDocumentService;
+import com.management.platform.task.SFTPAsyncUploader;
 import com.management.platform.util.*;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.util.StringUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -48,6 +50,9 @@ public class TaskFilesController {
     @Value("${upload.path}")
     private String uploadPath;
 
+    @Autowired
+    private SFTPAsyncUploader sftpAsyncUploader;
+
     /**
      * 获取该项目下的所有有效的文件列表
      * @param keyword
@@ -139,6 +144,8 @@ public class TaskFilesController {
                     try {
                         saveFile.createNewFile();
                         file.transferTo(saveFile);
+                        //异步上传到备份服务器
+                        sftpAsyncUploader.uploadFileAsync(saveFile);
                         //计算文件大小
                         long fileSize = saveFile.length();
                         String fileLength = FileUtil.getReadableFileSize(fileSize);

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

@@ -65,6 +65,7 @@ public class User extends Model<User> {
      */
     @TableField("create_time")
     @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm")
     private LocalDateTime createTime;
 
     /**

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

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

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

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

+ 11 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ProjectServiceImpl.java

@@ -63,6 +63,7 @@ import java.time.format.DateTimeFormatter;
 import java.time.temporal.TemporalAdjusters;
 import java.util.*;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 
 /**
@@ -10032,7 +10033,6 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         int days = WorkDayCalculateUtils.getWorkDaysListInRange(startDate, endDate, 0).size();
         TimeType allDay = timeTypeMapper.selectOne(new QueryWrapper<TimeType>().eq("company_id", targetUser.getCompanyId()));
         Float monthTime = days * allDay.getAllday();
-
         if(pageIndex!=null&&pageSize!=null){
             Integer size=pageSize;
             Integer start=(pageIndex-1)*size;
@@ -10042,7 +10042,7 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
             resultList=projectMapper.getFTEData(targetUser.getCompanyId(),startDate,endDate,null,null,area,branchDepartment,deptIds);
         }
         for (Map<String, Object> map : resultList) {
-            map.put("FTE",Float.parseFloat(map.get("workTime").toString())/monthTime);
+            map.put("FTE",Float.parseFloat(map.get("workTime") == null?"0":map.get("workTime").toString())/monthTime);
         }
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", targetUser.getCompanyId()));
         if (wxCorpInfo != null && wxCorpInfo.getSaasSyncContact().equals(1)){
@@ -10100,6 +10100,15 @@ public class ProjectServiceImpl extends ServiceImpl<ProjectMapper, Project> impl
         Float aTimeSum = 0.0F;
         Float aFteSum = 0.0F;
         for (int i = 0; i < resultList.size(); i++) {
+            if(resultList.get(i).get("workTime") == null){
+                resultList.get(i).put("workTime",0);
+            }
+            if(resultList.get(i).get("projectName") == null){
+                resultList.get(i).put("projectName","");
+            }
+            if(resultList.get(i).get("projectCode") == null){
+                resultList.get(i).put("projectCode","");
+            }
             if (!resultList.get(i).containsKey("area")){
                 resultList.get(i).put("area","无");
             }else if(org.apache.commons.lang3.StringUtils.isBlank(resultList.get(i).get("area").toString())){

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

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

+ 32 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/SFTPAsyncUploader.java

@@ -0,0 +1,32 @@
+package com.management.platform.task;
+
+import com.management.platform.util.SFTPUploader;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Component;
+import java.io.File;
+import javax.annotation.PostConstruct;
+
+@Component
+public class SFTPAsyncUploader {
+
+    private final SFTPUploader sftpUploader;
+
+    public SFTPAsyncUploader(SFTPUploader sftpUploader) {
+        this.sftpUploader = sftpUploader;
+    }
+
+    @PostConstruct
+    public void init() {
+//        new File("uploads").mkdirs(); // 创建上传目录
+    }
+
+    @Async
+    public void uploadFileAsync(File file) {
+        try {
+            sftpUploader.uploadFile(file);
+            System.out.println("File " + file.getName() + " has been uploaded.");
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 19 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/TimingTask.java

@@ -30,6 +30,7 @@ import org.springframework.web.client.DefaultResponseErrorHandler;
 import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
+import java.io.File;
 import java.io.IOException;
 import java.math.BigDecimal;
 import java.security.SecureRandom;
@@ -141,6 +142,24 @@ public class TimingTask {
         /*IntStream.rangeClosed('!', '*').forEach(VALID_TOKEN_CHARS::add);    // !-**/
     }
 
+    //每天凌晨5点10删除导出的临时文件
+    @Scheduled(cron = "0 10 05 ? * *")
+    private void deleteExportFile() {
+        if (isDev) return;
+        System.out.println("删除导出的临时文件");
+        File pathRoot = new File(path);
+        File[] files = pathRoot.listFiles();
+        //遍历files,删除名称匹配规则为以任意开头以十三位数字加.xls或.xlsx结尾的文件
+        for (File file : files) {
+            if (file.getName().matches("^[\\s\\S]*\\d{13}\\.xls[x]?$")) {
+                //删除一天前的导出文件
+                if (file.lastModified() < System.currentTimeMillis() - 24 * 60 * 60 * 1000) {
+                    file.delete();
+                }
+            }
+        }
+    }
+
     //检查项目到期,距离到期时间3天内的,每天提醒
     @Scheduled(cron = "0 0 10 ? * *")
     private void projectDeadlineAlert() {

+ 63 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/util/SFTPUploader.java

@@ -0,0 +1,63 @@
+package com.management.platform.util;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.Session;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+@Component
+public class SFTPUploader {
+    @Value("${sftp.isEnabled}")
+    private boolean isEnabled;
+    @Value("${sftp.server}")
+    private String server;
+
+    @Value("${sftp.port}")
+    private int port;
+    @Value("${sftp.remoteDir}")
+    private String remoteDir;
+
+    @Value("${sftp.user}")
+    private String user;
+
+    @Value("${sftp.password}")
+    private String password;
+
+    public void uploadFile(File file) throws Exception {
+        if (!isEnabled) {
+            System.out.println("sftp is not enabled, please set sftp.isEnabled=true in application.properties");
+            return;
+        }
+        JSch jsch = new JSch();
+        Session session = null;
+        ChannelSftp sftpChannel = null;
+        FileInputStream inputStream = null;
+        try {
+            session = jsch.getSession(user, server, port);
+            session.setPassword(password);
+            session.setConfig("StrictHostKeyChecking", "no");
+            session.connect();
+
+            sftpChannel = (ChannelSftp) session.openChannel("sftp");
+            sftpChannel.connect();
+
+            String remoteFilePath = (remoteDir.endsWith("/")?remoteDir: (remoteDir + "/")) + file.getName();
+            inputStream = new FileInputStream(file);
+
+            sftpChannel.put(inputStream, remoteFilePath);
+        } finally {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+            if (sftpChannel != null) {
+                sftpChannel.disconnect();
+            }
+            if (session != null) {
+                session.disconnect();
+            }
+        }
+    }
+}

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

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

+ 9 - 1
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application-prod.yml

@@ -102,4 +102,12 @@ management:
       enabled: false
 
 configEnv:
-  isDev: false
+  isDev: false
+# SFTP上传配置
+sftp:
+  isEnabled: true
+  server: 101.132.166.205
+  port: 22022
+  remoteDir: /bkup/timesheet
+  user: root
+  password: Huoshi@2022

+ 9 - 3
fhKeeper/formulahousekeeper/management-platform/src/main/resources/application.yml

@@ -15,7 +15,7 @@ spring:
       location: C:/upload/
   datasource:
     driver-class-name: com.mysql.cj.jdbc.Driver
-    url: jdbc:mysql://47.101.180.183:3306/man_dev?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
+    url: jdbc:mysql://47.101.180.183:3306/man_hour_manager?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&rewriteBatchedStatements=true&useSSL=false
     username: root
     password: HuoshiDB@2022
     hikari:
@@ -150,6 +150,12 @@ privateDeployURL:
   pcUrl: http://dev.huoshishanxin.com/#/
   mobUrl: http://dev.huoshishanxin.com/#/
 
-
-
+# SFTP上传配置
+sftp:
+  isEnabled: false
+  server: 101.132.166.205
+  port: 22022
+  remoteDir: /bkup/timesheet
+  user: root
+  password: Huoshi@2022
 

+ 16 - 10
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectMapper.xml

@@ -1612,16 +1612,23 @@
     </select>
 
     <select id="getFTEData" resultType="java.util.Map">
-        SELECT u.id,u.name userName,u.corpwx_userid wxUserId,u.plate1 area,SUM(r.working_time) workTime,p.project_name projectName,p.project_code projectCode
+        SELECT u.id,u.name userName,u.corpwx_userid wxUserId,u.plate1 area,r.projectName,r.projectCode,r.workTime
         FROM `user` u
-        LEFT JOIN report r
+        LEFT JOIN (
+            SELECT p.project_name projectName,p.project_code projectCode,report.working_time,report.creator_id,SUM(working_time) workTime
+            FROM report
+            LEFT JOIN project p
+            ON report.project_id = p.id
+            LEFT JOIN `user`
+            ON user.id = report.creator_id
+            WHERE report.state = 1
+            AND p.is_public = 0
+            AND report.company_id=#{companyId}
+            AND report.create_date BETWEEN #{startDate} AND #{endDate}
+            GROUP BY user.id,p.id,user.plate1,p.project_name,p.project_code
+        ) r
         ON u.id = r.creator_id
-        LEFT JOIN project p
-        ON r.project_id = p.id
-        WHERE r.state = 1
-        AND p.is_public = 0
-        AND u.company_id=#{companyId}
-        AND r.create_date BETWEEN #{startDate} AND #{endDate}
+        WHERE u.company_id=#{companyId}
         <if test="area!=null and area != '' ">
             and u.plate1 = #{area}
         </if>
@@ -1637,8 +1644,7 @@
                 #{item}
             </foreach>
         </if>
-        GROUP BY u.id,p.id,u.plate1,p.project_name,u.name,u.corpwx_userid,p.project_code
-        order by area,id
+        order by area,workTime,id
         <if test="start!=null and size!=null">
             limit #{start},#{size}
         </if>

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

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

+ 2 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application-dev.yml

@@ -81,7 +81,8 @@ mybatis:
 #####配置图片上传路径####
 upload:
   path: /www/staticproject/timesheet/upload/
-
+logDownLoad:
+  path: /www/webapps/worktime/wt_print.log
 ##actuator健康检查配置
 management:
   security:

+ 3 - 1
fhKeeper/formulahousekeeper/ops-platform/src/main/resources/application-prod.yml

@@ -80,8 +80,10 @@ mybatis:
   mapper-locations: mappers/*Mapper.xml
 #####配置图片上传路径####
 upload:
-  path: /www/staticproject/timesheet/upload/
+  path: /www/staticproject/octopus_vue/upload/
 
+logDownLoad:
+  path: /www/webapps/worktime/wt_print.log
 ##actuator健康检查配置
 management:
   security:

+ 25 - 0
fhKeeper/formulahousekeeper/restart.sh

@@ -0,0 +1,25 @@
+#!/bin/bash
+
+# 进程名
+process="timesheet"
+
+# 获取进程ID
+PID=$(ps -ef | grep $process | grep -v grep | awk '{print $2}')
+
+if [ -n "$PID" ]; then
+    echo "$process is exist"
+    if ps -p $PID >/dev/null; then
+        echo "$process is runnig"
+    else
+        echo " $ process is not running"
+    fi
+else
+    echo "$process is not exist"
+fi
+echo $PID;
+# 暂停1秒
+sleep 1;
+kill -9 $PID;
+echo "$process is killed"
+./startWorkTime.sh
+echo "restart timesheet success"