Bläddra i källkod

Merge remote-tracking branch 'origin/master'

yusm 1 vecka sedan
förälder
incheckning
07b6f3ade7
19 ändrade filer med 492 tillägg och 168 borttagningar
  1. 11 12
      fhKeeper/formulahousekeeper/collectdata/src/main/java/com/management/collectdata/controller/DataCollectController.java
  2. 23 10
      fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/taskCalendar.vue
  3. 6 6
      fhKeeper/formulahousekeeper/management-platform/pom.xml
  4. 81 52
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/QRCodeController.java
  5. 20 1
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/ReportController.java
  6. 26 0
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java
  7. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BusinessTrip.java
  8. 46 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ErpOrderInfo.java
  9. 29 9
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java
  10. 10 5
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java
  11. 172 39
      fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java
  12. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages.properties
  13. 1 0
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages_en_US.properties
  14. 26 9
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ErpOrderInfoMapper.xml
  15. 2 2
      fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectRequirementMapper.xml
  16. 1 0
      fhKeeper/formulahousekeeper/pom.xml
  17. 11 1
      fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue
  18. 9 5
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue
  19. 15 6
      fhKeeper/formulahousekeeper/timesheet_h5/src/views/error/index.vue

+ 11 - 12
fhKeeper/formulahousekeeper/collectdata/src/main/java/com/management/collectdata/controller/DataCollectController.java

@@ -258,11 +258,11 @@ public class DataCollectController {
 //        String sqlCount = "select count(*) from mom_orderdetail where status in (3,4) ";
         String sqlCount = "select count(*) " +
                 "from ( " +
-                "    select mo.cbSysBarCode,SUBSTRING(mo.cbSysBarCode, 8, 14) as orderId,mo.Define24,mo.Define25 " +
-                "     ,RIGHT(mo.cbSysBarCode,1) as line,mo.Status,cb.cDeptID,cb.cDepName,mo.MoDId " +
+                "    select mo.cbSysBarCode,substring(cbSysBarCode,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)+1,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1) + 1)-CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)-1) as orderId,mo.Define24,mo.Define25 " +
+                "     ,RIGHT(mo.cbSysBarCode,1) as line,mo.Status,mo.MDeptCode,mo.MoDId " +
                 " " +
                 "from mom_orderdetail mo " +
-                " left join ca_batchmap cb on SUBSTRING(mo.cbSysBarCode, 8, 14) = cb.cMOCode and RIGHT(mo.cbSysBarCode,1) = cb.iMOSubSN " +
+//                " left join ca_batchmap cb on substring(cbSysBarCode,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)+1,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1) + 1)-CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)-1)= cb.cMOCode and RIGHT(mo.cbSysBarCode,1) = cb.iMOSubSN " +
                 " where mo.Status = 3 " +
                 "         )tmp ";
         int totalCount = 0;
@@ -285,10 +285,10 @@ public class DataCollectController {
 //                " from mom_orderdetail " +
 //                " where status in (3,4) "
 //                +" ORDER BY MoDId OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
-        String sqlQuery = "select mo.MoDId,SUBSTRING(mo.cbSysBarCode, 8, 14) as orderId,mo.Define24  as projectId,mo.Define25  as projectName,mo.relsdate" +
-                "     ,RIGHT(mo.cbSysBarCode,1) as line,mo.Status,cb.cDeptID,cb.cDepName " +
+        String sqlQuery = "select mo.MoDId,substring(cbSysBarCode,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)+1,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1) + 1)-CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)-1) as orderId,mo.Define24  as projectId,mo.Define25  as projectName,mo.relsdate" +
+                "     ,RIGHT(mo.cbSysBarCode,1) as line,mo.Status,mo.MDeptCode " +
                 " from mom_orderdetail mo " +
-                " left join ca_batchmap cb on SUBSTRING(mo.cbSysBarCode, 8, 14) = cb.cMOCode and RIGHT(mo.cbSysBarCode,1) = cb.iMOSubSN " +
+//                " left join ca_batchmap cb on substring(cbSysBarCode,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)+1,CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1) + 1)-CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode, CHARINDEX('|', cbSysBarCode) + 1) + 1)-1) = cb.cMOCode and RIGHT(mo.cbSysBarCode,1) = cb.iMOSubSN " +
                 " where mo.Status = 3 " +
                 " ORDER BY mo.MoDId OFFSET ? ROWS FETCH NEXT ? ROWS ONLY ";
         List<ErpOrderInfo> resList = new ArrayList<>();
@@ -309,8 +309,8 @@ public class DataCollectController {
                     erpOrderInfo.setLine(resultSet.getInt("line"));
                     erpOrderInfo.setStatus(resultSet.getInt("Status"));
                     erpOrderInfo.setRelsDate(resultSet.getDate("relsdate"));
-                    erpOrderInfo.setDeptId(resultSet.getString("cDeptID"));
-                    erpOrderInfo.setDeptName(resultSet.getString("cDepName"));
+                    erpOrderInfo.setDeptId(resultSet.getString("MDeptCode"));
+//                    erpOrderInfo.setDeptName(resultSet.getString("cDepName"));
                     resList.add(erpOrderInfo);
                 }
             }
@@ -478,11 +478,10 @@ public class DataCollectController {
     @RequestMapping("/getBusinessTripDataList")
     public List<BusinessTrip> getBusinessTripDataList(@RequestBody PageBO pageBO) {
         String sqlQuery = "select id,emp_no,emp_name,reason,begin_date,end_date,c_departure_place_city " +
-                " ,c_destination_place_city,trip_day,c_ccxm_no " +
+                " ,c_destination_place_city,trip_day,c_ccxm_name " +
                 " from att_business_trip_order abto " +
                 " where abto.audit_status = 3 and abto.is_delete = 0 and abto.create_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY) order by id limit ?,? ";
 
-        SimpleDateFormat sdfAll = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         SimpleDateFormat sdfYmd = new SimpleDateFormat("yyyy-MM-dd");
         List<BusinessTrip> resList = new ArrayList<>();
         try (Connection connection = mysqlDataSource.getConnection()) {
@@ -494,7 +493,7 @@ public class DataCollectController {
             try (ResultSet resultSet = queryStmt.executeQuery()) {
                 while (resultSet.next()) {
                     BusinessTrip businessTrip = new BusinessTrip();
-                    businessTrip.setCCcxmNo(resultSet.getString("c_ccxm_no"));
+                    businessTrip.setCCcxmNo(resultSet.getString("c_ccxm_name"));
                     businessTrip.setCompanyId(companyId);
                     businessTrip.setWay(4);
                     businessTrip.setOwnerId(resultSet.getString("emp_no"));
@@ -506,7 +505,7 @@ public class DataCollectController {
                     businessTrip.setCityFrom(resultSet.getString("c_departure_place_city"));
                     businessTrip.setCityTo(resultSet.getString("c_destination_place_city"));
                     businessTrip.setDayCount(null==resultSet.getBigDecimal("trip_day")?null:resultSet.getBigDecimal("trip_day").setScale(0,RoundingMode.HALF_UP).intValue());
-                    businessTrip.setIndate(LocalDateTime.now());
+//                    businessTrip.setIndate(LocalDateTime.now());
                     businessTrip.setProcinstId(resultSet.getString("id"));
 
                     resList.add(businessTrip);

+ 23 - 10
fhKeeper/formulahousekeeper/customerBuler-crm/src/pages/tasks/taskCalendar.vue

@@ -41,21 +41,21 @@ const calendarOptions = ref<any>({
   plugins: [dayGridPlugin, timeGridPlugin, interactionPlugin],
   locale: zhCnLocale,
   initialView: currentView.value,
-  slotMinTime: '06:00:00',  // 最早显示时间
-  slotMaxTime: '22:00:00',  // 最晚显示时间
-  slotDuration: '01:00:00', // 一个小时一格(timeGrid生效)
+  slotMinTime: '06:00:00',
+  slotMaxTime: '22:00:00',
+  slotDuration: '01:00:00',
   events: [],
-  headerToolbar: {  // 自定义头部
-    left: 'today,prev,next',  // 左侧按钮:上一页,下一页,今天
+  headerToolbar: {  
+    left: 'today,prev,next',
     center: 'title',
-    right: 'dayGridMonth,timeGridWeek,timeGridDay'  // 右侧显示视图切换按钮
+    right: 'dayGridMonth,timeGridWeek,timeGridDay'
   },
   slotLabelContent: (arg: any) => {
     const hour = arg.date.getHours()
     const meridiem = hour < 12 ? '上午' : '下午'
     return `${meridiem} ${hour} 时`
   },
-  datesSet: (arg: any) => { // 📌 每次切换视图或日期都会触发
+  datesSet: (arg: any) => {
     const { startStr = '', endStr = '' } = arg
     if (startStr && endStr) {
       dateForm.value = {
@@ -64,7 +64,7 @@ const calendarOptions = ref<any>({
       }
       getTaskCalendar()
     }
-  }
+  },
 })
 
 // 重新渲染表格数据
@@ -77,10 +77,13 @@ function renderTableData() {
         start: item.startDate,
         end: item.endDate,
         title: item.taskName,
+        backgroundColor: item.status == 1 ? item.color : ['#909399', '#075985', '#67C23A', '#F56C6C'][item.status],
+        borderColor:  item.status == 1 ? item.color : ['#909399', '#075985', '#67C23A', '#F56C6C'][item.status],
         // backgroundColor: ['#909399', '#075985', '#67C23A', '#F56C6C'][item.status],
         // borderColor: ['#909399', '#075985', '#67C23A', '#F56C6C'][item.status]
-        backgroundColor: ['#a6a9b0', '#3a7fc1', '#7fbf72', '#e28c8c'][item.status],
-        borderColor: ['#a6a9b0', '#3a7fc1', '#7fbf72', '#e28c8c'][item.status],
+
+        // backgroundColor: ['#a6a9b0', '#3a7fc1', '#7fbf72', '#e28c8c'][item.status],
+        // borderColor: ['#a6a9b0', '#3a7fc1', '#7fbf72', '#e28c8c'][item.status],
       }
     })
   }
@@ -130,5 +133,15 @@ defineExpose({
     white-space: normal !important;
     word-break: break-word;
   }
+
+  :deep(.fc-event-main) {
+    font-size: 20px;
+    text-align: center;
+  }
+
+  :deep(.fc-daygrid-day-events) {
+    font-size: 20px;
+    text-align: center;
+  }
 }
 </style> 

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

@@ -145,15 +145,15 @@
             <scope>system</scope>
             <systemPath>${basedir}/src/main/resources/lib/taobao-sdk-java-auto_1479188381469-20210623.jar</systemPath>
         </dependency>
+<!--        <dependency>-->
+<!--            <groupId>com.aliyun</groupId>-->
+<!--            <artifactId>dingtalk</artifactId>-->
+<!--            <version>1.1.50</version>-->
+<!--        </dependency>-->
         <dependency>
             <groupId>com.aliyun</groupId>
             <artifactId>dingtalk</artifactId>
-            <version>1.1.50</version>
-        </dependency>
-        <dependency>
-            <groupId>com.aliyun</groupId>
-            <artifactId>dingtalk</artifactId>
-            <version>2.1.14</version>
+            <version>2.2.15</version>
         </dependency>
         <dependency>
             <groupId>org.springframework.boot</groupId>

+ 81 - 52
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/QRCodeController.java

@@ -20,6 +20,7 @@ import javax.imageio.ImageIO;
 import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -36,6 +37,33 @@ public class QRCodeController {
 
     private static final int specialCompanyId = 7536;
 
+    private static final List<String> SPECIAL_CHARS = new ArrayList<>();
+    static {
+        SPECIAL_CHARS.add("\\");
+        SPECIAL_CHARS.add("/");
+        SPECIAL_CHARS.add(":");
+        SPECIAL_CHARS.add(":");
+        SPECIAL_CHARS.add("*");
+        SPECIAL_CHARS.add("?");
+        SPECIAL_CHARS.add("\"");
+        SPECIAL_CHARS.add("<");
+        SPECIAL_CHARS.add(">");
+        SPECIAL_CHARS.add("|");
+    }
+
+    private String replaceChar(String str){
+        String res = str;
+        if(StringUtils.isBlank(res)){
+            return "";
+        }
+        for (String specialChar : SPECIAL_CHARS) {
+            if(res.contains(specialChar)){
+                res = res.replace(specialChar,"-");
+            }
+        }
+        return res;
+    }
+
     @RequestMapping("/generateQRCodeByErpIds")
     public HttpRespMsg generateQRCodeByErpIds(@RequestParam("erpIds")String erpIds){
         HttpRespMsg msg = new HttpRespMsg();
@@ -60,35 +88,35 @@ public class QRCodeController {
             String footerLine1 = String.format("工单号: %s",null == erpOrderInfo.getOrderId()?"":erpOrderInfo.getOrderId());
             String footerLine2 = String.format("行号: %s",null == erpOrderInfo.getLine()?"":erpOrderInfo.getLine());
 
-            String s = null != erpOrderInfo.getMoDId() ? erpOrderInfo.getMoDId() : "";
-            String finalProjectName = erpOrderInfo.getProjectName();
-            if(finalProjectName.contains("/") || finalProjectName.contains("\\")){
-                finalProjectName = finalProjectName.replace("/","-");
-                finalProjectName = finalProjectName.replace("\\","-");
-            }
-            String fileName = finalProjectName+erpOrderInfo.getOrderId()+erpOrderInfo.getLine()+".png";
-
-            try {
-                BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
-                // 创建带标题和两行底部文字的完整图片
-                BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
-                        qrImage,
-                        titleText,
-                        new String[]{footerLine1, footerLine2},
-                        new Color(70, 130, 180),  // 标题背景色(钢蓝色)
-                        new Color(220, 220, 220)   // 底部背景色(浅灰色)
-                );
-
-                // 保存最终图片
-                File outputFile = new File(uploadPath+fileName);
-                ImageIO.write(combinedImage, "png", outputFile);
-            } catch (Exception e) {
-                e.printStackTrace();
-                msg.setError("二维码生成失败,请联系管理员");
-                return msg;
+//            String s = null != erpOrderInfo.getMoDId() ? erpOrderInfo.getMoDId() : "";
+
+            String fileName = erpOrderInfo.getProjectName()+erpOrderInfo.getOrderId()+erpOrderInfo.getLine()+".png";
+            fileName = replaceChar(fileName);
+            if(StringUtils.isBlank(fileName)){
+                System.out.println("文件参数有空,projectName== "+erpOrderInfo.getProjectName()+",orderID== "+erpOrderInfo.getOrderId()+",line:"+ erpOrderInfo.getLine());
+            }else{
+                try {
+                    BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
+                    // 创建带标题和两行底部文字的完整图片
+                    BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
+                            qrImage,
+                            titleText,
+                            new String[]{footerLine1, footerLine2},
+                            new Color(70, 130, 180),  // 标题背景色(钢蓝色)
+                            new Color(220, 220, 220)   // 底部背景色(浅灰色)
+                    );
+
+                    // 保存最终图片
+                    File outputFile = new File(uploadPath+fileName);
+                    ImageIO.write(combinedImage, "png", outputFile);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    msg.setError("二维码生成失败,请联系管理员");
+                    return msg;
+                }
+                filesToZip[index] = uploadPath+fileName;
+                index++;
             }
-            filesToZip[index] = uploadPath+fileName;
-            index++;
 
         }
         String zipFileName = System.currentTimeMillis()+".zip";
@@ -137,31 +165,32 @@ public class QRCodeController {
 
         int width = 300; // 二维码宽度
         int height = 300; // 二维码高度
-        String finalProjectName = erpOrderInfo.getProjectName();
-        if(finalProjectName.contains("/") || finalProjectName.contains("\\")){
-            finalProjectName = finalProjectName.replace("/","-");
-            finalProjectName = finalProjectName.replace("\\","-");
-        }
-        String fileName = finalProjectName+erpOrderInfo.getOrderId()+erpOrderInfo.getLine()+".png";
-        try {
-            BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
-            // 创建带标题和两行底部文字的完整图片
-            BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
-                    qrImage,
-                    titleText,
-                    new String[]{footerLine1, footerLine2},
-                    new Color(70, 130, 180),  // 标题背景色(钢蓝色)
-                    new Color(220, 220, 220)   // 底部背景色(浅灰色)
-            );
-
-            // 保存最终图片
-            File outputFile = new File(uploadPath+fileName);
-            ImageIO.write(combinedImage, "png", outputFile);
-        } catch (Exception e) {
-            e.printStackTrace();
-            msg.setError("二维码生成失败,请联系管理员");
-            return msg;
+        String fileName = erpOrderInfo.getProjectName()+erpOrderInfo.getOrderId()+erpOrderInfo.getLine()+".png";
+        fileName = replaceChar(fileName);
+        if(StringUtils.isBlank(fileName)){
+            System.out.println("文件参数有空,projectName== "+erpOrderInfo.getProjectName()+",orderID== "+erpOrderInfo.getOrderId()+",line:"+ erpOrderInfo.getLine());
+        }else{
+            try {
+                BufferedImage qrImage = QRCodeUtil.generateQRCodeImage(data, width, height);
+                // 创建带标题和两行底部文字的完整图片
+                BufferedImage combinedImage = QRCodeUtil.createCompleteImage(
+                        qrImage,
+                        titleText,
+                        new String[]{footerLine1, footerLine2},
+                        new Color(70, 130, 180),  // 标题背景色(钢蓝色)
+                        new Color(220, 220, 220)   // 底部背景色(浅灰色)
+                );
+
+                // 保存最终图片
+                File outputFile = new File(uploadPath+fileName);
+                ImageIO.write(combinedImage, "png", outputFile);
+            } catch (Exception e) {
+                e.printStackTrace();
+                msg.setError("二维码生成失败,请联系管理员");
+                return msg;
+            }
         }
+
         msg.setData("/upload/"+fileName);
         return msg;
     }

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

@@ -498,6 +498,13 @@ public class ReportController {
                 //自动扩充数组大小
                 projectAuditorId = Arrays.copyOf(projectAuditorId, projectId.length);
             }
+        } else {
+            //检查是否有为-的,表示没有审核人,需要手动转为null
+            for (int i = 0; i < projectAuditorId.length; i++) {
+                if (projectAuditorId[i].equals("-")) {
+                    projectAuditorId[i] = null;
+                }
+            }
         }
 
         if (overtimeHours == null) {
@@ -1554,6 +1561,18 @@ public class ReportController {
         }
         //针对泓浒(苏州),需要按照工单号的部门来设置工时所属部门,同时设置是否是协作工时
         if (Constant.HONG_HU_COMPANY_ID == company.getId()) {
+            for (Report report : reportList) {
+                //校验分组为车间的分组时,工单号是否必填
+                if (report.getGroupId() != null) {
+                    String groupName = taskGroupService.getById(report.getGroupId()).getName();
+                    if (groupName.contains("车间") && StringUtils.isEmpty(report.getExtraField4())) {
+                        HttpRespMsg httpRespMsg = new HttpRespMsg();
+                        httpRespMsg.setError("当前选择了带车间的工时分组,对应的工单号必填");
+                        return httpRespMsg;
+                    }
+                }
+            }
+
             List<String> collect = reportList.stream().filter(r -> !StringUtils.isEmpty(r.getExtraField4())).map(Report::getExtraField4).collect(Collectors.toList());
             if (collect.size() > 0) {
                 List<ErpOrderInfo> orderList = erpOrderInfoMapper.selectList(new QueryWrapper<ErpOrderInfo>().in("order_id", collect));
@@ -1571,7 +1590,7 @@ public class ReportController {
                                     report.setIsAssist(true);
                                 }
                             } else {
-                                errorMsg = "工时系统中尚未给部门:"+first.get().getDeptName()+"设置部门编号";
+                                errorMsg = "工时系统中尚未设置部门编号:"+first.get().getDeptId();
                             }
                         }
                     } else {

+ 26 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/WeiXinCorpController.java

@@ -1107,6 +1107,20 @@ public class WeiXinCorpController {
                             contactSyncLogMapper.insert(contactSyncLog);
                         }else {
                             userMapper.insert(user);
+                            //处理项目参与人
+                            if (user.getDepartmentId() != null && user.getDepartmentId() != 0) {
+                                List<Participation> toAddList = new ArrayList<>();
+                                projectDeptRelateMapper.selectList(new QueryWrapper<ProjectDeptRelate>().eq("department_id", user.getDepartmentId()).eq("company_id", companyId))
+                                        .forEach(projectDeptRelate -> {
+                                            Participation participation = new Participation();
+                                            participation.setProjectId(projectDeptRelate.getProjectId());
+                                            participation.setUserId(user.getId());
+                                            toAddList.add(participation);
+                                        });
+                                if (toAddList.size() > 0) {
+                                    participationMapper.insertBatch(toAddList);
+                                }
+                            }
                             wxCorpInfoService.getUserByCompanyIdAndTransferLicense(companyId,user.getCorpwxUserid());
                             contactSyncLog.setResult(1);
                             //contactSyncLog.setMsg("同步成功");
@@ -1208,6 +1222,18 @@ public class WeiXinCorpController {
                                         List<Department> allDeptList = departmentMapper.selectList(new QueryWrapper<Department>().eq("company_id", companyId));
                                         changeUser.setDepartmentCascade(convertDepartmentIdToCascade(changeUser.getDepartmentId(), allDeptList));
                                         userMapper.updateById(changeUser);
+                                        //处理项目参与人
+                                        List<Participation> toAddList = new ArrayList<>();
+                                        projectDeptRelateMapper.selectList(new QueryWrapper<ProjectDeptRelate>().eq("department_id", changeUser.getDepartmentId()).eq("company_id", companyId))
+                                                .forEach(projectDeptRelate -> {
+                                                    Participation participation = new Participation();
+                                                    participation.setProjectId(projectDeptRelate.getProjectId());
+                                                    participation.setUserId(changeUser.getId());
+                                                    toAddList.add(participation);
+                                                });
+                                        if (toAddList.size() > 0) {
+                                            participationMapper.insertBatch(toAddList);
+                                        }
                                     }
                                 }
                             }

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/BusinessTrip.java

@@ -127,8 +127,8 @@ public class BusinessTrip extends Model<BusinessTrip> {
      * 申请时间
      */
     @TableField("indate")
-    @DateTimeFormat(pattern = "yyyy-MM-dd")
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime indate;
 
     /**

+ 46 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/entity/ErpOrderInfo.java

@@ -1,44 +1,80 @@
 package com.management.platform.entity;
 
 import com.baomidou.mybatisplus.annotation.IdType;
-import com.baomidou.mybatisplus.annotation.TableField;
-import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.extension.activerecord.Model;
+import java.time.LocalDate;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import lombok.experimental.Accessors;
 
-import java.util.Date;
-
+/**
+ * <p>
+ * 工时申请单
+ * </p>
+ *
+ * @author Seyason
+ * @since 2025-05-03
+ */
 @Data
 @EqualsAndHashCode(callSuper = false)
 @Accessors(chain = true)
 public class ErpOrderInfo extends Model<ErpOrderInfo> {
+
     private static final long serialVersionUID=1L;
 
     @TableId(value = "id", type = IdType.AUTO)
     private Integer id;
 
+    /**
+     * 工单编号
+     */
     @TableField("order_id")
     private String orderId;
 
+    /**
+     * 项目编号
+     */
     @TableField("project_id")
     private String projectId;
 
+    /**
+     * 项目名称
+     */
     @TableField("project_name")
     private String projectName;
 
+    /**
+     * 行号
+     */
     @TableField("line")
     private Integer line;
 
+    /**
+     * 工单状态 NA-开立/FM-锁定/OP-审核/CL-关闭
+     */
     @TableField("status")
     private Integer status;
 
+    /**
+     * 同步主键id
+     */
     @TableField("moDId")
     private String moDId;
 
+    /**
+     * 生产工单日期
+     */
     @TableField("rels_date")
-    private Date relsDate;
+    private LocalDate relsDate;
+
+    /**
+     * 外部系统部门id,也是code
+     */
+    @TableField("dept_id")
+    private String deptId;
 
     @TableField(exist = false)
     private Integer pageIndex;
@@ -49,9 +85,10 @@ public class ErpOrderInfo extends Model<ErpOrderInfo> {
     @TableField(exist = false)
     private String trueProjectId;
 
-    @TableField("dept_id")
-    private String deptId;
 
-    @TableField("dept_name")
-    private String deptName;
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
 }

+ 29 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/ReportServiceImpl.java

@@ -1354,7 +1354,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 if (wxCorpInfo != null) {
                     List<String> auditorCorpwxUserids = new ArrayList<>();
                     for (Report report : reportList) {
-                        String corpwxUserid = userMapper.selectById(report.getProjectAuditorId()).getCorpwxUserid();
+                        String corpwxUserid = userMapper.selectById((report.getIsDeptAudit() == null || report.getIsDeptAudit() == 0)?report.getProjectAuditorId():report.getAuditDeptManagerid()).getCorpwxUserid();
                         //推送到企业微信
                         JSONObject json=new JSONObject();
                         JSONArray dataJson=new JSONArray();
@@ -5333,7 +5333,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                             if (WorkDayCalculateUtils.isWorkDay(workDate)) {
                                 Map<String, Object> leaveMap = new HashMap<>();
                                 leaveMap.put("createDate", leaveDateStr);
-                                leaveMap.put("workingTime", MessageUtils.message("leave.leave")+leave.getTimeHours()+"h");
+                                if(leave.getTimeHours() >= timeType.getAllday()){
+                                    leaveMap.put("workingTime", MessageUtils.message("leave.leaveOfDay"));
+                                } else {
+                                    leaveMap.put("workingTime", MessageUtils.message("leave.leave")+leave.getTimeHours()+"h");
+                                }
                                 worktimeList.add(leaveMap);
                             }
                         }
@@ -5469,6 +5473,7 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", user.getCompanyId()));
         CompanyDingding dingding = companyDingdingService.getOne(new LambdaQueryWrapper<CompanyDingding>().eq(CompanyDingding::getCompanyId, companyId));
         TimeType timeType = timeTypeMapper.selectById(user.getCompanyId());
+        Integer notAllowedOnNonWorkday = timeType.getNotAllowedOnNonWorkday();
         //对于存在预算成本的公司,暂不支持导入工时
         Company company = companyMapper.selectById(companyId);
         if (company.getPackageProject() == 1) {
@@ -5757,6 +5762,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
 
                                 report.setCreateDate(LocalDate.parse(reportDate, dtf));
                                 report.setCost(reportCreator.getCost()==null?new BigDecimal(0) : reportCreator.getCost().multiply(new BigDecimal(time)));
+                                if (notAllowedOnNonWorkday == 1 && WorkDayCalculateUtils.isWorkDay(report.getCreateDate()) == false) {
+                                    //msg.setError("第"+dataCount+"行日期为非工作日,无法导入");
+                                    msg.setError(MessageUtils.message("report.nonWorkDay",dataCount+1, reportDate));
+                                    return msg;
+                                }
                                 reportList.add(report);
                                 curRowTotalTime += time;
                             } else if (time < 0) {
@@ -10866,15 +10876,11 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
         List<Map<String, Object>> data = getReportTimeLessThanCardTimeList(startDate, endDate, null,null, companyId, true);
         if (data.size() > 0) {
             //发送企业微信消息提醒,给员工和系统管理员
-            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId));
+            List<User> userList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).in("id", data.stream().map(m -> String.valueOf(m.get("userId"))).collect(Collectors.toList())));
             WxCorpInfo wxCorpInfo = wxCorpInfoMapper.selectOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
             String wxUserIds = userList.stream().map(User::getCorpwxUserid).collect(Collectors.joining("|"));
             wxCorpInfoService.sendWXCorpMsg(wxCorpInfo, wxUserIds,  "您最近一周内考勤工时填报存在异常,请及时修正!", null, WxCorpInfoServiceImpl.TEXT_CARD_MSG_REPORT_ABNOEMAL);
 
-//            for (Map<String, Object> map : data) {
-//                String userId = String.valueOf(map.get("userId"));
-//                String userName = String.valueOf(map.get("userName"));
-//                }
             //给管理员发送
             List<User> adminList = userMapper.selectList(new QueryWrapper<User>().eq("company_id", companyId).eq("role_name", "系统管理员"));
             String adminIds = adminList.stream().map(User::getCorpwxUserid).collect(Collectors.joining("|"));
@@ -11019,8 +11025,22 @@ public class ReportServiceImpl extends ServiceImpl<ReportMapper, Report> impleme
                 }
             }
         }
-
-
+        //去掉不提醒的人员
+        for (int i=0;i<manageUserList.size();i++) {
+            User item = manageUserList.get(i);
+            //不需要填报的用户,需要去掉
+            if (item.getReportStatus() == 1) {
+                manageUserList.remove(item);
+                i--;
+                if (timeType.getSyncCorpwxTime() == 1) {
+                    //从userCorpwxTimeList中去掉
+                    userCorpwxTimeList.removeIf(userCorpwxTime -> userCorpwxTime.getCorpwxUserid() != null && userCorpwxTime.getCorpwxUserid().equals(item.getCorpwxUserid()));
+                } else if (timeType.getSyncFanwei() == 1) {
+                    //从userFvTimeList中去掉
+                    userFvTimeList.removeIf(userFvTime -> userFvTime.getUserId() != null && userFvTime.getUserId().equals(item.getId()));
+                }
+            }
+        }
 
         //获取填报工时记录表
         List<Report> reportList = new ArrayList<>();

+ 10 - 5
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/impl/WxCorpInfoServiceImpl.java

@@ -1696,8 +1696,8 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                                     //检查请假时间段是否在打卡的时间范围内
                                     if (baseMorningStart.equals(leaveStart) && baseMorningEnd.equals(leaveEnd)) {
                                         morningLeave = true;
-                                    } else if ((baseAfternoonStart.equals(leaveStart) || "14:00".equals(leaveStart)) && baseAfternoonEnd.equals(leaveEnd)) {
-                                        //补充14:00是因为企业微信传递的数据不规则,有时候下午请假正常是13:00-18:00,有时候是14:00-18:00
+                                    } else if ((baseAfternoonStart.equals(leaveStart) || (corpInfo.getCompanyId() != 469 && "14:00".equals(leaveStart))) && baseAfternoonEnd.equals(leaveEnd)) {
+                                        //补充14:00是因为企业微信传递的数据不规则(赛元微电子除外),有时候下午请假正常是13:00-18:00,有时候是14:00-18:00
                                         afternoonLeave = true;
                                     }
 
@@ -1745,6 +1745,10 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             timeDelta += ct.getOutdoorTime();
                         }
                         double workHours = 0;
+                        if (corpInfo.getCompanyId() == 469) {
+                            timeDelta = DateTimeUtil.getHoursFromDouble(timeDelta);
+                        }
+                        System.out.println("上下班间隔时长======="+timeDelta);
                         if (needRecaculate) {
                             workHours = timeDelta - ct.getAskLeaveTime();
                         } else {
@@ -1760,13 +1764,14 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                             ct.setStartTime(baseMorningStart);
                             ct.setEndTime(baseAfternoonEnd);
                         }
-                        if (showLog) System.out.println("工作时长==" + workHours);
-
                         if (corpInfo.getCompanyId() == 481) {
                             //给盛立安元0.5单位进位
                             ct.setWorkHours(DateTimeUtil.getHalfHoursFromDouble(workHours));
+                        } else if (corpInfo.getCompanyId() == 469) {
+                            //赛元微电子之前计算完间隔后,已经四舍五入过了,此处不需要再处理了
+                            ct.setWorkHours(workHours);
                         } else {
-                            ct.setWorkHours(DateTimeUtil.getHoursFromDouble(workHours));
+                            ct.setWorkHours(DateTimeUtil.getHalfHoursFromDouble(workHours));
                         }
 //                        if (showLog) System.out.println("ct.getStartTime()==" + ct.getStartTime()+", ct.getEndTime()="+ct.getEndTime());
 

+ 172 - 39
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/task/DataCollectTask.java

@@ -2,11 +2,11 @@ package com.management.platform.task;
 
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.management.platform.controller.ReportController;
 import com.management.platform.entity.*;
 import com.management.platform.entity.vo.TisTimeVO;
 import com.management.platform.mapper.*;
-import com.management.platform.service.StagesService;
-import com.management.platform.service.TaskService;
+import com.management.platform.service.*;
 import com.management.platform.util.MessageUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -21,6 +21,7 @@ import org.springframework.util.CollectionUtils;
 import org.springframework.web.client.RestTemplate;
 
 import javax.annotation.Resource;
+import java.math.BigDecimal;
 import java.text.SimpleDateFormat;
 import java.time.LocalDate;
 import java.time.format.DateTimeFormatter;
@@ -43,9 +44,13 @@ public class DataCollectTask {
 
     @Resource
     private ErpOrderInfoMapper erpOrderInfoMapper;
+    @Resource
+    private ErpOrderInfoService erpOrderInfoService;
 
     @Resource
     private ProjectMapper projectMapper;
+    @Resource
+    private UserSalaryService userSalaryService;
 
     @Resource
     private ProjectCategoryMapper projectCategoryMapper;
@@ -64,10 +69,12 @@ public class DataCollectTask {
 
     @Resource
     private FmwDetailMapper fmwDetailMapper;
-    @Autowired
+    @Resource
     private FinanceMonthlyWorktimeMapper financeMonthlyWorktimeMapper;
-    @Autowired
+    @Resource
     private CompanyMapper companyMapper;
+    @Autowired
+    private LeaveSheetService leaveSheetService;
 
 
 //    private static HikariDataSource sqlServerDataSource;
@@ -195,7 +202,7 @@ public class DataCollectTask {
 
 
     @Scheduled(cron = "0 0 1 * * ?")
-//    @Scheduled(cron = "0 05 16 * * ?")
+//    @Scheduled(cron = "0 46 7 * * ?")
     @Async
     public void sqlServerTask() {
         if(isDev){return;}
@@ -239,20 +246,21 @@ public class DataCollectTask {
                         List<ErpOrderInfo> dataList = listResponse.getBody();
                         if(org.apache.commons.collections.CollectionUtils.isNotEmpty(dataList)){
                             List<String> collect = dataList.stream().map(ErpOrderInfo::getMoDId).distinct().collect(Collectors.toList());
-                            List<String> existIds = erpOrderInfoMapper.getExistIds(collect);
-                            if(!CollectionUtils.isEmpty(existIds)){
-                                toUpdateList.addAll(dataList.stream().filter(t -> existIds.contains(t.getMoDId())).collect(Collectors.toList()));
-                                toAddList.addAll(dataList.stream().filter(t -> !existIds.contains(t.getMoDId())).collect(Collectors.toList()));
-                            }else{
-                                toAddList.addAll(dataList);
+                            List<ErpOrderInfo> erpOrderInfos = erpOrderInfoMapper.selectList(new LambdaQueryWrapper<ErpOrderInfo>().in(ErpOrderInfo::getMoDId, collect));
+                            for (ErpOrderInfo item : dataList) {
+                                Optional<ErpOrderInfo> first = erpOrderInfos.stream().filter(t -> t.getMoDId().equals(item.getMoDId())).findFirst();
+                                if(first.isPresent()){
+                                    item.setId(first.get().getId());
+                                    toUpdateList.add(item);
+                                } else {
+                                    toAddList.add(item);
+                                }
                             }
                             if(!CollectionUtils.isEmpty(toAddList)){
                                 erpOrderInfoMapper.batchInsert(toAddList);
                             }
                             if(!CollectionUtils.isEmpty(toUpdateList)){
-                                for (ErpOrderInfo orderInfo : toUpdateList) {
-                                    erpOrderInfoMapper.updateById(orderInfo);
-                                }
+                                erpOrderInfoService.updateBatchById(toUpdateList);
                             }
                             toUpdateList.clear();
                             toAddList.clear();
@@ -357,7 +365,7 @@ public class DataCollectTask {
     }
 
     @Scheduled(cron = "0 0 2 * * ?")
-//@Scheduled(cron = "0 43 16 * * ?")
+//@Scheduled(cron = "0 35 8 * * ?")
     @Async
     public void leaveSheetTask(){
         if(isDev){return;}
@@ -415,19 +423,103 @@ public class DataCollectTask {
                             List<LeaveSheet> realDataList = dataList.stream().filter(t -> StringUtils.isNotBlank(t.getOwnerId())).collect(Collectors.toList());
                             if(!CollectionUtils.isEmpty(realDataList)){
                                 List<String> collect = realDataList.stream().map(LeaveSheet::getProcinstId).distinct().collect(Collectors.toList());
-                                List<String> existIds = leaveSheetMapper.getExistIds(collect,specialCompanyId);
-                                if(!CollectionUtils.isEmpty(existIds)){
-                                    toUpdateList.addAll(realDataList.stream().filter(t -> existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-                                    toAddList.addAll(realDataList.stream().filter(t -> !existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-                                }else{
-                                    toAddList.addAll(realDataList);
+                                List<LeaveSheet> existLeaveSheetList = leaveSheetMapper.selectList(new LambdaQueryWrapper<LeaveSheet>().in(LeaveSheet::getProcinstId, collect).eq(LeaveSheet::getCompanyId, specialCompanyId));
+                                List<String> existIds = existLeaveSheetList.stream().map(LeaveSheet::getProcinstId).collect(Collectors.toList());
+//                                List<String> existIds = leaveSheetMapper.getExistIds(collect,specialCompanyId);
+                                for (LeaveSheet tmp : realDataList) {
+                                    Optional<LeaveSheet> first = existLeaveSheetList.stream().filter(t -> t.getProcinstId().equals(tmp.getProcinstId())).findFirst();
+                                    if (first.isPresent()) {
+                                        tmp.setId(first.get().getId());
+                                        toUpdateList.add(tmp);
+                                    } else {
+                                        toAddList.add(tmp);
+                                    }
                                 }
                                 if(!CollectionUtils.isEmpty(toAddList)){
                                     leaveSheetMapper.batchInsert(toAddList);
                                 }
                                 if(!CollectionUtils.isEmpty(toUpdateList)){
-                                    for (LeaveSheet tmp : toUpdateList) {
-                                        leaveSheetMapper.updateById(tmp);
+                                    leaveSheetService.updateBatchById(toUpdateList);
+                                }
+                                //自动生成审核通过的请假工时日报
+                                for (LeaveSheet tmp : realDataList) {
+                                    //获取某人每天请假的时长合计
+                                    String ownerId = tmp.getOwnerId();
+                                    User owner = userMapper.selectById(ownerId);
+                                    //停用的用户不生成日报
+                                    if (owner.getIsActive() == 0) {
+                                        continue;
+                                    }
+                                    Project project = projectMapper.selectOne(new QueryWrapper<Project>().eq("project_code", "HH-GG-0000001").eq("company_id", specialCompanyId));
+                                    TaskGroup leaveGroup = taskGroupMapper.selectOne(new LambdaQueryWrapper<TaskGroup>().eq(TaskGroup::getProjectId, project.getId()).eq(TaskGroup::getName, "请假工时"));
+                                    for (LocalDate date = tmp.getStartDate(); date.compareTo(tmp.getEndDate()) <= 0; date = date.plusDays(1)) {
+                                        //先计算每一天的请假工时数合计
+                                        List<LeaveSheet> leaveSheetList = leaveSheetMapper.selectList(new LambdaQueryWrapper<LeaveSheet>()
+                                                .eq(LeaveSheet::getOwnerId, ownerId)
+                                                .eq(LeaveSheet::getCompanyId, specialCompanyId)
+                                                .le(LeaveSheet::getStartDate, date).gt(LeaveSheet::getEndDate, date));
+                                        if (!CollectionUtils.isEmpty(leaveSheetList)) {
+                                            double leaveHours = leaveSheetList.stream().mapToDouble(LeaveSheet::getTimeHours).sum();
+                                            if (leaveHours > 0) {
+                                                //跨天请假的
+                                                if (leaveHours > 8.0) {
+                                                    leaveHours = 8.0;
+                                                }
+                                                //检查当天是否已经生成了请假工时的日报
+                                                List<Report> reportList = reportMapper.selectList(new QueryWrapper<Report>().eq("company_id", specialCompanyId).eq("project_id", project.getId()).eq("create_date", date).eq("creator_id", ownerId));
+                                                //取第一条
+                                                Report oneReport = reportList.size() > 0?reportList.get(0):new Report();
+
+                                                if (oneReport.getId() != null) {
+                                                    if (!oneReport.getWorkingTime().equals(leaveHours)) {
+                                                        //更新时长
+                                                        reportMapper.updateById(new Report().setId(oneReport.getId()).setWorkingTime(leaveHours));
+                                                    }
+                                                } else {
+                                                    //生成请假工时的日报
+                                                    Report report = new Report();
+                                                    report.setProjectId(project.getId());
+                                                    report.setGroupId(leaveGroup.getId());
+                                                    report.setReportTimeType(1);
+                                                    report.setMultiWorktime(0);
+                                                    report.setContent("请假");
+                                                    report.setState(1);//自动生成的审核通过
+                                                    report.setCompanyId(specialCompanyId);
+                                                    report.setStage("-");
+                                                    report.setCreateDate(date);
+                                                    report.setCreatorId(ownerId);
+                                                    report.setDeptId(owner.getDepartmentId());
+                                                    report.setProjectAuditState(0);
+
+                                                    LocalDate now = LocalDate.now();
+                                                    DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
+                                                    BigDecimal hourCost = null;
+                                                    if (owner.getCostApplyDate() != null) {
+                                                        //检查有效期
+                                                        if (owner.getCostApplyDate().compareTo(dtf.format(now)) > 0) {
+                                                            //取上一个历史成本
+                                                            List<UserSalary> list = userSalaryService.list(new QueryWrapper<UserSalary>().eq("user_id", owner.getId()).orderByDesc("indate").last("limit 2"));
+                                                            if (list.size() > 1) {
+                                                                hourCost = list.get(1).getCost();
+                                                            } else {
+                                                                //没有记录,又没有达到预设的起效时间,则默认为0
+                                                                hourCost = new BigDecimal(0);
+                                                            }
+                                                        } else {
+                                                            hourCost = owner.getCost();
+                                                        }
+                                                    } else {
+                                                        hourCost = owner.getCost();
+                                                    }
+                                                    if (hourCost == null) {
+                                                        hourCost = new BigDecimal(0);
+                                                    }
+                                                    //计算工时和成本
+                                                    report.setCost(hourCost.multiply(new BigDecimal(leaveHours)));
+                                                    reportMapper.insert(report);
+                                                }
+                                            }
+                                        }
                                     }
                                 }
                             }
@@ -446,9 +538,9 @@ public class DataCollectTask {
         }
     }
 
-    @Scheduled(cron = "0 30 2 * * ?")
+//    @Scheduled(cron = "0 30 2 * * ?")
 //@Scheduled(cron = "0 46 15 * * ?")
-    @Async
+//    @Async
     public void sqlServerProjectTypeTask() {
         if(isDev){return;}
         RestTemplate restTemplate = new RestTemplate();
@@ -584,6 +676,9 @@ public class DataCollectTask {
                             }
                             if(!CollectionUtils.isEmpty(toAddList)){
                                 for (Project project : toAddList) {
+                                    //以项目编码前五为作为分类名称
+                                    String categoryName = project.getProjectCode().substring(0,5);
+                                    project.setCategoryName(categoryName);
                                     ProjectCategory category = projectCategoryMapper.selectOne(new LambdaQueryWrapper<ProjectCategory>()
                                             .eq(ProjectCategory::getCompanyId, specialCompanyId)
                                             .eq(ProjectCategory::getName, project.getCategoryName())
@@ -703,7 +798,7 @@ public class DataCollectTask {
     }
 
     @Scheduled(cron = "0 0 3 * * ?")
-//@Scheduled(cron = "0 20 17 * * ?")
+//@Scheduled(cron = "0 57 9 * * ?")
     @Async
     public void businessTripTask(){
         if(isDev){return;}
@@ -724,6 +819,7 @@ public class DataCollectTask {
             } else {
                 System.out.println("请求失败,状态码: " + sumResponse.getStatusCode());
             }
+            System.out.println("出差数据:"+totalNum);
             if(totalNum > 0){
                 int pageSize = 1000;
                 int offset = 0;
@@ -757,35 +853,72 @@ public class DataCollectTask {
                             List<BusinessTrip> realDataList = dataList.stream().filter(t -> StringUtils.isNotBlank(t.getOwnerId())).collect(Collectors.toList());
                             if(!CollectionUtils.isEmpty(realDataList)){
                                 List<String> collect = realDataList.stream().map(BusinessTrip::getProcinstId).distinct().collect(Collectors.toList());
-                                List<String> existIds = businessTripMapper.getExistIds(collect,specialCompanyId);
-                                if(!CollectionUtils.isEmpty(existIds)){
-                                    toUpdateList.addAll(realDataList.stream().filter(t -> existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-                                    toAddList.addAll(realDataList.stream().filter(t -> !existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
-                                }else{
-                                    toAddList.addAll(realDataList);
+                                List<BusinessTrip> existBTripList = businessTripMapper.selectList(new QueryWrapper<BusinessTrip>().in("procinst_id", collect));
+                                for (BusinessTrip businessTrip : realDataList) {
+                                    if (existBTripList.stream().anyMatch(t -> t.getProcinstId().equals(businessTrip.getProcinstId()))) {
+                                        businessTrip.setId(existBTripList.stream().filter(t -> t.getProcinstId().equals(businessTrip.getProcinstId())).findFirst().get().getId());
+                                        toUpdateList.add(businessTrip);
+                                    } else {
+                                        toAddList.add(businessTrip);
+                                    }
                                 }
+//                                if(existBTripList.size() > 0){
+//                                    toUpdateList.addAll(realDataList.stream().filter(t -> existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
+//                                    toAddList.addAll(realDataList.stream().filter(t -> !existIds.contains(t.getProcinstId())).collect(Collectors.toList()));
+//                                }else{
+//                                    toAddList.addAll(realDataList);
+//                                }
                                 if(!CollectionUtils.isEmpty(toAddList)){
 //                                businessTripMapper.batchInsert(toAddList);
                                     for (BusinessTrip businessTrip : toAddList) {
                                         businessTripMapper.insert(businessTrip);
-                                        BustripProject bustripProject = new BustripProject();
-                                        bustripProject.setBustripId(businessTrip.getId());
-                                        Project project = projectCodeMap.get(businessTrip.getCCcxmNo());
-                                        bustripProject.setProjectId(null == project?null:project.getId());
-                                        bustripProject.setStartDate(businessTrip.getStartDate());
-                                        bustripProject.setEndDate(businessTrip.getEndDate());
-                                        bustripProjectMapper.insert(bustripProject);
+                                        if (!StringUtils.isEmpty(businessTrip.getCCcxmNo())) {
+                                            String[] split = businessTrip.getCCcxmNo().split(",");
+                                            for (String s : split) {
+                                                Project project = projectCodeMap.get(s);
+                                                if (project != null) {
+                                                    BustripProject bustripProject = new BustripProject();
+                                                    bustripProject.setBustripId(businessTrip.getId());
+                                                    bustripProject.setProjectId(project.getId());
+                                                    bustripProject.setStartDate(businessTrip.getStartDate());
+                                                    bustripProject.setEndDate(businessTrip.getEndDate());
+                                                    bustripProjectMapper.insert(bustripProject);
+                                                }
+                                            }
+                                        }
                                     }
                                 }
                                 if(!CollectionUtils.isEmpty(toUpdateList)){
                                     for (BusinessTrip tmp : toUpdateList) {
                                         businessTripMapper.updateById(tmp);
+                                        //检查出差项目
+                                        if (!StringUtils.isEmpty(tmp.getCCcxmNo())) {
+                                            String[] split = tmp.getCCcxmNo().split(",");
+                                            for (String s : split) {
+                                                Project project = projectCodeMap.get(s);
+                                                if (project != null) {
+                                                    //查找是否已经存在
+                                                    BustripProject existBustripProject = bustripProjectMapper.selectOne(
+                                                            new LambdaQueryWrapper<BustripProject>().eq(BustripProject::getBustripId, tmp.getId()).eq(BustripProject::getProjectId, project.getId()).between(BustripProject::getStartDate, tmp.getStartDate(), tmp.getEndDate()));
+                                                    if (existBustripProject == null) {
+                                                        BustripProject bustripProject = new BustripProject();
+                                                        bustripProject.setBustripId(tmp.getId());
+                                                        bustripProject.setProjectId(project.getId());
+                                                        bustripProject.setStartDate(tmp.getStartDate());
+                                                        bustripProject.setEndDate(tmp.getEndDate());
+                                                        bustripProjectMapper.insert(bustripProject);
+                                                    }
+                                                }
+                                            }
+                                        }
                                     }
                                 }
                             }
 
                             toUpdateList.clear();
                             toAddList.clear();
+                        } else {
+                            System.out.println("出差数据为空");
                         }
 
                     }

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages.properties

@@ -338,6 +338,7 @@ report.hourReportNoFilled=您{0}的工时报告还未填写
 report.lackCardTime=缺少考勤时长: {0}
 report.timeReachLimitError=填报工时不可超过考勤时长: {0}
 report.financial_report=财务已完成对{0}月日报的审核,无法提交。
+report.nonWorkDay=表格中第{0}行日期{1}为非工作日,无法导入
 #模板相关
 Template.subProject=子项目
 Template.AlreadyExists=该模板名称已存在

+ 1 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/resources/i18n/messages_en_US.properties

@@ -338,6 +338,7 @@ report.hourReportNoFilled=Your work hour report for {0} has not been completed.
 report.lackCardTime=Lack attendance record: {0}
 report.timeReachLimitError=Report working time cannot be larger than attendance time: {0}
 report.financial_report=The financial department has completed the review of reports in {0}, it cannot be submitted.
+report.nonWorkDay=Line:{0},date[{1}] is not a workday, please check.
 #模板相关
 Template.subProject=subproject
 Template.AlreadyExists=The template name already exists.

+ 26 - 9
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ErpOrderInfoMapper.xml

@@ -1,14 +1,31 @@
-<?xml version="1.0" encoding="utf-8" ?>
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
-        "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.management.platform.mapper.ErpOrderInfoMapper">
 
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.management.platform.entity.ErpOrderInfo">
+        <id column="id" property="id" />
+        <result column="order_id" property="orderId" />
+        <result column="project_id" property="projectId" />
+        <result column="project_name" property="projectName" />
+        <result column="line" property="line" />
+        <result column="status" property="status" />
+        <result column="moDId" property="moDId" />
+        <result column="rels_date" property="relsDate" />
+        <result column="dept_id" property="deptId" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, order_id, project_id, project_name, line, status, moDId, rels_date, dept_id
+    </sql>
     <insert id="batchInsert">
-        insert into erp_order_info(order_id, project_id, project_name, line, status,rels_date,moDId,dept_id,dept_name)
+        insert into erp_order_info(order_id, project_id, project_name, line, status,rels_date,moDId,dept_id)
         VALUES
-            <foreach collection="resList" separator="," item="res">
-                (#{res.orderId},#{res.projectId},#{res.projectName},#{res.line},#{res.status},#{res.relsDate},#{res.moDId},#{res.deptId},#{res.deptName})
-            </foreach>
+
+        <foreach collection="resList" separator="," item="res">
+            (#{res.orderId},#{res.projectId},#{res.projectName},#{res.line},#{res.status},#{res.relsDate},#{res.moDId},#{res.deptId})
+        </foreach>
     </insert>
     <select id="getExistIds" resultType="java.lang.String">
         select moDId
@@ -37,9 +54,9 @@
     </select>
     <select id="getWithProject" resultType="com.management.platform.entity.ErpOrderInfo">
         select eoi.id,eoi.order_id,eoi.project_id,eoi.project_name,eoi.line,eoi.status,eoi.moDId,
-               p.id as trueProjectId
+        p.id as trueProjectId
         from erp_order_info eoi
-                 left join project p on eoi.project_id = p.project_code
+        left join project p on eoi.project_id = p.project_code
         where p.company_id = #{specialCompanyId}
         and eoi.id in <foreach collection="erpIds" item="erpId" open="(" close=")" separator=",">#{erpId}</foreach>
     </select>

+ 2 - 2
fhKeeper/formulahousekeeper/management-platform/src/main/resources/mapper/ProjectRequirementMapper.xml

@@ -57,11 +57,11 @@
                  #{item}
              </foreach>
          </if>
-        <if test="reStartDate != null and reEndDate !=null">
+        <if test="reStartDate != null and reEndDate != null">
             and project_requirement.start_date>=#{reStartDate} and project_requirement.end_date&lt;=#{reEndDate}
         </if>
         order by project.id asc
-        <if test="startIndex!=null and startIndex!='' and pageSize!=null and pageSize!=''">
+        <if test="startIndex != null and pageSize != null">
             limit #{startIndex}, #{pageSize}
         </if>
     </select>

+ 1 - 0
fhKeeper/formulahousekeeper/pom.xml

@@ -40,6 +40,7 @@
         <fastjson.version>1.2.7</fastjson.version>
         <baidu.api.sdk.version>4.2.0</baidu.api.sdk.version>
         <tess4j-version>4.4.1</tess4j-version>
+		<kotlin.version>1.6.21</kotlin.version>
     </properties>
 
     <repositories>

+ 11 - 1
fhKeeper/formulahousekeeper/timesheet/src/views/workReport/daily.vue

@@ -1040,7 +1040,7 @@
                             <div v-if="scope.row.canFill == 1">
                                 <template v-if="user.company.packageProject == 0 && user.timeType.type == 1">
                                     <div v-if="reportTimeType.multiWorktime == 0" slot="reference">
-                                        <el-input-number v-model="scope.row[item.projectName].workingTime" size="small" :step="0.5" controls-position="right" step-strictly :min="0" :max="20" :disabled="[0, 1, '0', '1'].includes(scope.row[item.projectName].state)" @change="fillInThePedometerOnAWeeklyBasis(scope.$index)"></el-input-number>
+                                        <el-input-number v-model="scope.row[item.projectName].workingTime" size="small" :step="0.5" controls-position="right" step-strictly :min="0" :max="20" :disabled="[0, 1, '0', '1'].includes(scope.row[item.projectName].state)" @change="fillInThePedometerOnAWeeklyBasis(scope.$index)" @input="onInputWorkTime(scope.$index)"></el-input-number>
                                         <span v-if="scope.row[item.projectName].state != 3 && workReportStateString[scope.row[item.projectName].state]" :class="statusStyle[scope.row[item.projectName].state]">({{workReportStateString[scope.row[item.projectName].state]}})</span>
                                         <el-link type="primary" style="margin-left: 10px" @click="showWeekItemEdit(scope.row[item.projectName], scope.$index, item.id, item.projectName, workForm.domains)">编辑</el-link>
                                     </div>
@@ -6737,6 +6737,10 @@
                 const totalNum = collectionArray.reduce((accumulator, currentValue) => accumulator + currentValue, 0)
                 this.zhoData[index].he = totalNum
             },
+            //输入工时触发
+            onInputWorkTime(index) {
+                const weeklyItem = this.zhoData[index] || {}
+            },
 
             // 按周填报里内容的填写
             showWeekItemEdit(item, i, projectId,names, row) {
@@ -7762,6 +7766,9 @@
                                         formData.append("createDate",zhoD.zhoDataTime)
                                         if (zhoD[j].projectAuditorId) {
                                             formData.append("projectAuditorId",zhoD[j].projectAuditorId)
+                                        } else {
+                                            //对齐数据
+                                            formData.append("projectAuditorId",'-');
                                         }
                                         if(zhoD[j].basecostId) {
                                             formData.append("basecostId", zhoD[j].basecostId);
@@ -7859,6 +7866,9 @@
                                         formData.append("createDate",zhoD.zhoDataTime)
                                         if (zhoD[j].projectAuditorId) {
                                             formData.append("projectAuditorId",zhoD[j].projectAuditorId)
+                                        } else {
+                                            //对齐数据
+                                            formData.append("projectAuditorId",'-')
                                         }
                                         if(zhoD[j].basecostId) {
                                             formData.append("basecostId", zhoD[j].basecostId);

+ 9 - 5
fhKeeper/formulahousekeeper/timesheet_h5/src/views/edit/index.vue

@@ -20,7 +20,7 @@
                     </van-field>
                     <template #right-icon>
                         <!--先开放几家,试一下-->
-                        <span style="color:#20a0ff;" @click="getAIReport()" v-if="!substitute && !hasWrittenReport && (user.companyId==10||user.companyId==7||user.companyId==7030)">智能填报</span>
+                        <span style="color:#20a0ff;" @click="getAIReport()" v-if="!substitute && !hasWrittenReport && (user.companyId==10||user.companyId==7||user.companyId==7030||user.companyId==7536)">智能填报</span>
                     </template>
                 </van-cell>
                 
@@ -676,7 +676,7 @@ export default {
                     id: null,
                     projectId: "",
                     projectName: "",
-                    workingTime: "",
+                    workingTime: "0",
                     content: "",
                     state: 2,
                     multiWorktime: 0,
@@ -799,12 +799,16 @@ export default {
             }
 
             const projectList = this.projectss || []
+            console.log(projectList, '<==== projectList')
+            console.log(trueProjectId, '<==== trueProjectId')
             const rows = projectList.filter(item => item.id == trueProjectId)
             if(rows.length <= 0) {
                 this.$toast.fail(`暂未参与该项目`);
                 return
             }
 
+            this.closeQrcode()
+
             this.form.domains[this.clickIndex] = {
                 ...this.form.domains[this.clickIndex],
                 extraField4: orderId,
@@ -1935,10 +1939,8 @@ export default {
                                 }
                             }
                             this.form.domains = array;
-                            // console.log('执行One')
                             this.setTotalReportHours()
                         } else {
-                            // console.log('执行TWO')
                             this.totalReportHours = 0
                             this.canCancel = false;
                             this.canEdit = true;
@@ -3089,7 +3091,9 @@ export default {
             this.initFormData();
         } else {
             //个人自己填报
-            this.getReport();
+            setTimeout(() => { 
+                this.getReport();
+            }, 1000);
         }
         
         this.getAllUsersList()

+ 15 - 6
fhKeeper/formulahousekeeper/timesheet_h5/src/views/error/index.vue

@@ -1,12 +1,21 @@
 <template>
     <div>
         <div class="login_form">
-            <p style="color:red;font-size:16px;">{{errorMsg}}</p>
-            <p style="color:#666;">欢迎添加客服微信,咨询使用</p>
-            <p><img src="../../assets/img/kf.jpg" style="width:100%;" /></p>
-            <p>QQ:3052894409</p>
-            <p>电话:<a href="tel://15895914665">15895914665</a></p>
-            <p v-if="errorMsg == '账号不存在'" style="text-align:center;"><van-button @click="clearAccount" type="info">清空重试</van-button></p>
+            
+            <template v-if="user.companyId==7536">
+                <p style="color:red;font-size:16px;">{{errorMsg}}</p>
+                <p style="color:#666;">联系信息部  -张煜桦</p>
+                <p>电话:<a href="tel://18625227707">18625227707</a></p>
+                <p v-if="errorMsg == '账号不存在'" style="text-align:center;"><van-button @click="clearAccount" type="info">清空重试</van-button></p>
+            </template>
+            <template v-else>
+                <p style="color:red;font-size:16px;">{{errorMsg}}</p>
+                <p style="color:#666;">欢迎添加客服微信,咨询使用</p>
+                <p><img src="../../assets/img/kf.jpg" style="width:100%;" /></p>
+                <p>QQ:3052894409</p>
+                <p>电话:<a href="tel://15895914665">15895914665</a></p>
+                <p v-if="errorMsg == '账号不存在'" style="text-align:center;"><van-button @click="clearAccount" type="info">清空重试</van-button></p>
+            </template>
         </div>
     </div>
 </template>