Browse Source

苏州正北7703定制考勤导入

QuYueTing 12 hours ago
parent
commit
fc4bce6fa4

+ 54 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/controller/UserCorpwxTimeController.java

@@ -54,6 +54,9 @@ public class UserCorpwxTimeController {
 
     @Value(value = "${upload.path}")
     private String path;
+    @Resource
+    private ExcelParserService excelParserService;
+
     @Resource
     UserCorpwxTimeMapper userCorpwxTimeMapper;
     @Resource
@@ -831,5 +834,56 @@ public class UserCorpwxTimeController {
         }
         return msg;
     }
+
+
+    @RequestMapping("/importZhengBeiAttendance")
+    public HttpRespMsg importZhengBeiAttendance(Integer companyId, @RequestParam("multipartFile") MultipartFile file) throws IOException {
+        WxCorpInfo wxCorpInfo = wxCorpInfoService.getOne(new QueryWrapper<WxCorpInfo>().eq("company_id", companyId));
+        HttpRespMsg msg = new HttpRespMsg();
+        List<UserCorpwxTime> list = excelParserService.parseAttendanceExcel(file);
+        list.forEach(l->{
+            l.setCompanyId(companyId);
+            l.setWxCorpid(wxCorpInfo.getCorpid());
+            //工作时长四舍五入
+            l.setWorkHours(DateTimeUtil.getHalfHoursFromDouble(l.getWorkHours()));
+            l.setWeekDay(l.getCreateDate().getDayOfWeek().getValue());
+            l.setWeekDayTxt(DateTimeUtil.getWeekDayTxt(l.getWeekDay()));
+        });
+        //处理人员,调用企业微信的通讯录搜索接口
+        List<String> userNameList = list.stream().map(UserCorpwxTime::getName).distinct().collect(Collectors.toList());
+        try {
+            HttpRespMsg respMsg = wxCorpInfoService.getBatchSearchUserInfo(wxCorpInfo, userNameList,null);
+            if(respMsg.code.equals("0")){
+                msg.setError("姓名为["+String.valueOf(respMsg.data)+"]的人员存在重复,请使用工号!");
+                return msg;
+            }
+            List<User> targetUserList= (List<User>) respMsg.data;
+            for (User user : targetUserList) {
+                list.forEach(l->{
+                    if (l.getName().equals(user.getName())) {
+                        l.setCorpwxUserid(user.getCorpwxUserid());
+                    }
+                });
+            }
+            LocalDate min = list.stream().map(UserCorpwxTime::getCreateDate).min(LocalDate::compareTo).get();
+            LocalDate max = list.stream().map(UserCorpwxTime::getCreateDate).max(LocalDate::compareTo).get();
+            //保存或更新
+            List<UserCorpwxTime> oldList = userCorpwxTimeMapper.selectList(new QueryWrapper<UserCorpwxTime>().eq("company_id", companyId).between("create_date", min, max));
+            if (oldList.size() > 0) {
+                list.forEach(l->{
+                    for (UserCorpwxTime old : oldList) {
+                        if (old.getName().equals(l.getName()) && old.getCreateDate().equals(l.getCreateDate())) {
+                            l.setId(old.getId());
+                        }
+                    }
+                });
+            }
+            userCorpwxTimeService.saveOrUpdateBatch(list);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+
+        return msg;
+    }
 }
 

+ 155 - 0
fhKeeper/formulahousekeeper/management-platform/src/main/java/com/management/platform/service/ExcelParserService.java

@@ -0,0 +1,155 @@
+package com.management.platform.service;
+
+import com.management.platform.entity.UserCorpwxTime;
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class ExcelParserService {
+
+    public List<UserCorpwxTime> parseAttendanceExcel(MultipartFile file) throws IOException {
+        List<UserCorpwxTime> attendanceList = new ArrayList<>();
+
+        try (Workbook workbook = new XSSFWorkbook(file.getInputStream())) {
+            Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表
+
+            // 获取表头行
+            Row headerRow = sheet.getRow(0);
+
+            // 从第二行开始解析数据(假设第一行是表头)
+            for (int i = 2; i <= sheet.getLastRowNum(); i++) {
+                Row row = sheet.getRow(i);
+                if (row == null) continue;
+
+                // 获取姓名和部门
+                String name = getCellValue(row.getCell(0));
+                String department = getCellValue(row.getCell(2));
+
+                // 从第4列开始是日期列
+                for (int col = 3; col < row.getLastCellNum(); col++) {
+                    Cell dateCell = headerRow.getCell(col);
+                    Cell timeCell = row.getCell(col);
+
+                    if (dateCell == null || timeCell == null) continue;
+
+                    // 解析日期(格式如:03-01\n周六)
+                    String dateStr = getCellValue(dateCell);
+                    String[] dateParts = dateStr.split("\n");
+                    if (dateParts.length < 1) continue;
+
+                    // 假设年份是当前年(可能需要根据实际情况调整)
+                    String monthDay = dateParts[0];
+                    int year = LocalDate.now().getYear();
+                    LocalDate date = LocalDate.parse(year + "-" + monthDay, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+
+                    // 解析时间记录
+                    String timeRecord = getCellValue(timeCell);
+                    if (timeRecord == null || timeRecord.isEmpty() || "-".equals(timeRecord)) {
+                        continue;
+                    }
+
+                    // 分割时间记录(可能有多个打卡时间)
+                    String[] times = timeRecord.split("\n");
+                    if (times.length < 2) continue;
+
+                    // 取第一个和最后一个时间作为上班和下班时间
+                    String startTime = times[0];
+                    String endTime = times[times.length - 1];
+
+                    // 创建考勤记录对象
+                    UserCorpwxTime attendance = new UserCorpwxTime();
+                    attendance.setName(name);
+                    attendance.setCreateDate(date);
+                    attendance.setStartTime(startTime);
+                    attendance.setEndTime(endTime);
+
+                    // 计算工作时长(这里简化处理,实际需要更精确的计算)
+                    if (startTime != null && endTime != null) {
+                        try {
+                            double workHours = calculateWorkHours(startTime, endTime);
+                            attendance.setWorkHours(workHours);
+                        } catch (Exception e) {
+                            // 时间格式不正确时忽略
+                        }
+                    }
+
+                    // 设置星期几
+                    if (dateParts.length > 1) {
+                        attendance.setWeekDayTxt(dateParts[1]);
+                        // 可以根据星期文字设置星期数字
+                        attendance.setWeekDay(convertWeekDay(dateParts[1]));
+                    }
+
+                    attendanceList.add(attendance);
+                }
+            }
+        }
+
+        return attendanceList;
+    }
+
+    private String getCellValue(Cell cell) {
+        if (cell == null) {
+            return null;
+        }
+
+        switch (cell.getCellTypeEnum()) {
+            case STRING:
+                return cell.getStringCellValue().trim();
+            case NUMERIC:
+                if (DateUtil.isCellDateFormatted(cell)) {
+                    return cell.getDateCellValue().toString();
+                } else {
+                    return String.valueOf(cell.getNumericCellValue());
+                }
+            case BOOLEAN:
+                return String.valueOf(cell.getBooleanCellValue());
+            case FORMULA:
+                return cell.getCellFormula();
+            default:
+                return "";
+        }
+    }
+
+    private double calculateWorkHours(String startTime, String endTime) {
+        // 简单计算工作时长(小时)
+        // 实际应用中需要更精确的计算,考虑午休时间等
+        String[] startParts = startTime.split(":");
+        String[] endParts = endTime.split(":");
+
+        int startHour = Integer.parseInt(startParts[0]);
+        int startMinute = Integer.parseInt(startParts[1]);
+        int endHour = Integer.parseInt(endParts[0]);
+        int endMinute = Integer.parseInt(endParts[1]);
+
+        double hours = (endHour - startHour) + (endMinute - startMinute) / 60.0;
+
+        // 减去午休时间(假设12:00-13:00为午休)
+        if (startHour <= 12 && endHour >= 13) {
+            hours -= 1;
+        }
+
+        return hours;
+    }
+
+    private int convertWeekDay(String weekDayTxt) {
+        switch (weekDayTxt) {
+            case "周一": return 1;
+            case "周二": return 2;
+            case "周三": return 3;
+            case "周四": return 4;
+            case "周五": return 5;
+            case "周六": return 6;
+            case "周日": return 7;
+            default: return 0;
+        }
+    }
+}

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

@@ -903,10 +903,13 @@ public class WxCorpInfoServiceImpl extends ServiceImpl<WxCorpInfoMapper, WxCorpI
                 }
             }
             if(targetUserNameList.size()>0){
+                System.out.println("=====================批量查询企业微信人员");
                 HttpRespMsg respMsg = getBatchSearchUserInfo(wxCorpInfo, targetUserNameList,nextCursor);
                 if(!respMsg.code.equals("0")){
                     List<User> targetUserList= (List<User>) respMsg.data;
                     userList.addAll(targetUserList);
+                } else {
+                    System.out.println("异常返回="+respMsg.code+":"+respMsg.msg);
                 }
             }
 

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

@@ -3752,7 +3752,7 @@
                     let formData = new FormData();
                     formData.append("multipartFile", item.file);
                     formData.append("companyId", this.user.companyId);
-                    this.http.uploadFile('/user-corpwx-time/importCardTime', formData,
+                    this.http.uploadFile(this.user.companyId == 7703?'/user-corpwx-time/importZhengBeiAttendance':'/user-corpwx-time/importCardTime', formData,
                     res => {
                         this.$refs.uploadCardTime.clearFiles();
                         this.importingData = false;