xiongzhu 5 лет назад
Родитель
Сommit
cecb6e2cd7

+ 20 - 8
src/main/java/com/x1ongzhu/wisFactory/service/AttendanceService.java

@@ -79,13 +79,16 @@ public class AttendanceService {
         }
     }
 
-    public List<StaffAttendanceBrief> departmentReport(String departmentName, LocalDate start, LocalDate end) {
-        Department department = departmentRepo.findByName(departmentName);
-        return staffInfoRepo.findByDepartment(departmentName)
-                .stream()
-                .parallel()
-                .map(staffInfo -> staffAttendance1(staffInfo, start, end, department))
-                .collect(Collectors.toList());
+    public List<StaffAttendanceBrief> departmentReport(List<String> departmentNames, LocalDate start, LocalDate end) {
+        List<StaffAttendanceBrief> list = new ArrayList<>();
+        for (String departmentName : departmentNames) {
+            Department department = departmentRepo.findByName(departmentName);
+            list.addAll(staffInfoRepo.findByDepartment(departmentName)
+                    .stream()
+                    .map(staffInfo -> staffAttendance1(staffInfo, start, end, department))
+                    .collect(Collectors.toList()));
+        }
+        return list;
     }
 
     public StaffAttendanceBrief staffReport(Long id, LocalDate start, LocalDate end) {
@@ -327,6 +330,9 @@ public class AttendanceService {
     }
 
     public StaffAttendanceBrief staffAttendance1(StaffInfo staffInfo, LocalDate start, LocalDate end, Department department) {
+        if (department == null) {
+            log.error("department null: staffid {}", staffInfo.getId());
+        }
         department = departmentRepo.findById(department.getId()).orElseThrow(new BusinessException("部门不存在"));
         List<StaffAccess> accessList = staffAccessRepo
                 .findByEmployNoAndAccessTimeBetweenOrderByAccessTimeAsc(staffInfo.getEmployNo(),
@@ -357,7 +363,7 @@ public class AttendanceService {
                 staffAttendanceDetailList.add(detail);
                 brief.setHours(brief.getHours() + detail.getHours());
                 if (detail.isAbsent()) {
-                    brief.setAbsentDays(brief.getAttendDays() + 1);
+                    brief.setAbsentDays(brief.getAbsentDays() + 1);
                     brief.addAbsentDetail(DateTimeUtils.format(date, "yyyy-MM-dd"));
                 } else {
                     brief.setAttendDays(brief.getAttendDays() + 1);
@@ -392,6 +398,12 @@ public class AttendanceService {
         TimeBucket timeBucket = null;
         Shift shift = null;
         List<Shift> shifts = department.getShifts();
+        shifts.sort((o1, o2) -> {
+            if (o1.getAttendanceType() == AttendanceType.FIX && o2.getAttendanceType() == AttendanceType.FIX) {
+                return o1.getStart().compareTo(o2.getStart());
+            }
+            return 0;
+        });
         for (Shift s : shifts) {
             TimeBucket t = null;
             t = calcTimeBucket(allList, s, date);

+ 8 - 0
src/main/java/com/x1ongzhu/wisFactory/service/DepartmentService.java

@@ -3,12 +3,14 @@ package com.x1ongzhu.wisFactory.service;
 import com.x1ongzhu.wisFactory.domain.Department;
 import com.x1ongzhu.wisFactory.domain.Shift;
 import com.x1ongzhu.wisFactory.enums.AttendanceType;
+import com.x1ongzhu.wisFactory.enums.PrecisionUnit;
 import com.x1ongzhu.wisFactory.repo.DepartmentRepo;
 import lombok.AllArgsConstructor;
 import org.springframework.stereotype.Service;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
 
+import java.math.RoundingMode;
 import java.time.LocalTime;
 import java.util.ArrayList;
 import java.util.List;
@@ -31,8 +33,14 @@ public class DepartmentService {
                         .workDay("1,2,3,4,5")
                         .shifts(new ArrayList<Shift>() {{
                             add(Shift.builder()
+                                    .attendanceType(AttendanceType.FIX)
                                     .start(LocalTime.of(8, 30))
                                     .end(LocalTime.of(17, 30))
+                                    .overtimeStart(LocalTime.of(18, 0))
+                                    .maxOvertime(3)
+                                    .prc(0.5)
+                                    .prcUnit(PrecisionUnit.HOUR)
+                                    .roundingMode(RoundingMode.CEILING)
                                     .build());
                         }})
                         .build();

+ 4 - 3
src/main/java/com/x1ongzhu/wisFactory/service/StaffInfoService.java

@@ -41,8 +41,9 @@ public class StaffInfoService {
         List<StaffInfoImportModel> list = EasyExcel.read(file.getInputStream()).head(StaffInfoImportModel.class)
                 .sheet().doReadSync();
         list.stream().parallel().forEach(model -> {
+            String employNo = model.getEmployNo().replaceFirst("^0+(?!$)", "");
             model.setDepartment(model.getDepartment().replace("'", ""));
-            StaffInfo staffInfo = staffInfoRepo.findFirstByEmployNo(model.getEmployNo()).orElse(null);
+            StaffInfo staffInfo = staffInfoRepo.findFirstByEmployNo(employNo).orElse(null);
             List<String> cards = new ArrayList<>();
             if (StringUtils.isNotBlank(model.getCardNo())) {
                 cards = Arrays.stream(model.getCardNo().split(";"))
@@ -55,7 +56,7 @@ public class StaffInfoService {
                         .name(model.getName())
                         .sex(model.getSex().equals("1") ? "男" : (model.getSex().equals("2") ? "女" : null))
                         .department(model.getDepartment())
-                        .employNo(model.getEmployNo().replaceFirst("^0+(?!$)", ""))
+                        .employNo(employNo)
                         .phone(model.getPhone())
                         .build();
             } else {
@@ -63,7 +64,7 @@ public class StaffInfoService {
                 staffInfo.setName(model.getName());
                 staffInfo.setSex(model.getSex().equals("1") ? "男" : (model.getSex().equals("2") ? "女" : null));
                 staffInfo.setDepartment(model.getDepartment());
-                staffInfo.setEmployNo(model.getEmployNo().replaceFirst("^0+(?!$)", ""));
+                staffInfo.setEmployNo(employNo);
                 staffInfo.setPhone(model.getPhone());
             }
             staffInfoRepo.save(staffInfo);

+ 2 - 2
src/main/java/com/x1ongzhu/wisFactory/web/AttendanceController.java

@@ -76,14 +76,14 @@ public class AttendanceController extends BaseController {
 
     @GetMapping("/departmentReport")
     @ResponseBody
-    public List<StaffAttendanceBrief> departmentReport(@RequestParam String department,
+    public List<StaffAttendanceBrief> departmentReport(@RequestParam List<String> department,
                                                        @RequestParam LocalDate start, @RequestParam LocalDate end) {
         return attendanceService.departmentReport(department, start, end);
     }
 
     @GetMapping("/departmentReportExcel")
     @ResponseBody
-    public void departmentReportExcel(HttpServletResponse response, @RequestParam String department,
+    public void departmentReportExcel(HttpServletResponse response, List<String> department,
                                       @RequestParam LocalDate start, @RequestParam LocalDate end) throws IOException {
         List<StaffAttendanceBrief> reports = attendanceService.departmentReport(department, start, end);
         ExcelUtils.export(response, reports, "部门考勤报表");

+ 28 - 16
src/main/vue/src/views/DepartmentAttendanceReport.vue

@@ -7,7 +7,16 @@
                 clearable
                 class="filter-item"
             ></el-input> -->
-            <el-select v-model="department" clearable filterable placeholder="选择部门" class="filter-item">
+            <el-select
+                v-model="department"
+                clearable
+                filterable
+                placeholder="选择部门"
+                class="filter-item"
+                multiple
+                collapse-tags
+                style="width:300px"
+            >
                 <el-option v-for="item in departments" :label="item" :value="item" :key="item"></el-option>
             </el-select>
             <el-date-picker
@@ -40,17 +49,20 @@
             :height="tableHeight"
             v-loading="loading"
         >
-            <el-table-column prop="name" label="姓名"> </el-table-column>
-            <el-table-column prop="department" label="部门"> </el-table-column>
-            <el-table-column prop="start" label="开始时间"> </el-table-column>
-            <el-table-column prop="end" label="结束时间"> </el-table-column>
-            <el-table-column prop="totalDays" label="总天数"></el-table-column>
-            <el-table-column prop="workDays" label="工作日"></el-table-column>
-            <el-table-column prop="attendDays" label="到勤天数"></el-table-column>
-            <el-table-column prop="absentDays" label="缺勤天数"></el-table-column>
-            <el-table-column prop="fullDays" label="满勤天数"></el-table-column>
-            <el-table-column prop="late" label="迟到天数"></el-table-column>
-            <el-table-column prop="early" label="早退天数"></el-table-column>
+            <el-table-column prop="name" label="姓名" width="100"> </el-table-column>
+            <el-table-column prop="department" label="部门" min-width="150" show-overflow-tooltip> </el-table-column>
+            <el-table-column prop="start" label="开始时间" min-width="150"> </el-table-column>
+            <el-table-column prop="end" label="结束时间" min-width="150"> </el-table-column>
+            <el-table-column prop="totalDays" label="总天数" width="100"></el-table-column>
+            <el-table-column prop="workDays" label="工作日" width="100"></el-table-column>
+            <el-table-column prop="attendDays" label="到勤天数" width="100"></el-table-column>
+            <el-table-column prop="absentDays" label="缺勤天数" width="100"></el-table-column>
+            <el-table-column prop="absentDetail" label="缺勤详情" width="100" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="fullDays" label="满勤天数" width="100"></el-table-column>
+            <el-table-column prop="late" label="迟到天数" width="100"></el-table-column>
+            <el-table-column prop="lateDetail" label="迟到详情" width="100" show-overflow-tooltip></el-table-column>
+            <el-table-column prop="early" label="早退天数" width="100"></el-table-column>
+            <el-table-column prop="earlyDetail" label="早退详情" width="100" show-overflow-tooltip></el-table-column>
         </el-table>
     </div>
 </template>
@@ -69,7 +81,7 @@ export default {
             downloading: false,
             date: null,
             departments: [],
-            department: null,
+            department: [],
             loading: false,
             pickerOptions: {
                 shortcuts: [
@@ -107,7 +119,7 @@ export default {
     },
     methods: {
         beforeOnCreate() {
-            this.department = this.$store.state.userInfo.department;
+            this.department = [this.$store.state.userInfo.department];
             let d = addMonths(new Date(), -1);
             this.date = [format(startOfMonth(d), 'yyyy-MM-dd'), format(endOfMonth(d), 'yyyy-MM-dd')];
         },
@@ -118,7 +130,7 @@ export default {
             this.loading = true;
             this.$http
                 .get('/attendance/departmentReport', {
-                    department: this.department,
+                    department: this.department.join(),
                     start: this.date[0],
                     end: this.date[1]
                 })
@@ -140,7 +152,7 @@ export default {
             this.$axios
                 .get('/attendance/departmentReportExcel', {
                     responseType: 'blob',
-                    params: { department: this.department, start: this.date[0], end: this.date[1] }
+                    params: { department: this.department.join(), start: this.date[0], end: this.date[1] }
                 })
                 .then(res => {
                     console.log(res);

+ 5 - 5
src/main/vue/src/views/StaffAttendanceReport.vue

@@ -39,7 +39,6 @@
             header-row-class-name="table-header-row"
             header-cell-class-name="table-header-cell"
             row-class-name="table-row"
-            cell-class-name="table-cell"
             :height="tableHeight"
             v-loading="loading"
             :cell-class-name="cellClassName"
@@ -47,6 +46,7 @@
             <el-table-column prop="name" label="姓名" width="100"> </el-table-column>
             <el-table-column prop="department" label="部门" min-width="150" show-overflow-tooltip> </el-table-column>
             <el-table-column prop="date" label="日期" min-width="100"> </el-table-column>
+            <el-table-column prop="weekDay" label="星期" min-width="100"> </el-table-column>
             <el-table-column prop="start" label="签到" min-width="150"> </el-table-column>
             <el-table-column prop="end" label="签退" min-width="150"> </el-table-column>
             <el-table-column prop="hours" label="工时" width="100"></el-table-column>
@@ -180,13 +180,13 @@ export default {
         },
         cellClassName({ row, column, rowIndex, columnIndex }) {
             if (column.property === 'absent') {
-                return row[column.property] ? 'cell-error' : '';
+                return row[column.property] ? 'cell-error' : 'table-cell';
             } else if (column.property === 'late' || column.property === 'early') {
-                return row[column.property] > 0 ? 'cell-error' : '';
+                return row[column.property] > 0 ? 'cell-error' : 'table-cell';
             } else if (column.property === 'overtime') {
-                return row[column.property] > 0 ? 'cell-success' : '';
+                return row[column.property] > 0 ? 'cell-success' : 'table-cell';
             }
-            return '';
+            return 'table-cell';
         }
     },
     watch: {