|
@@ -1,22 +1,45 @@
|
|
|
package com.jpsoft.smart.modules.business.controller;
|
|
|
|
|
|
import com.github.pagehelper.Page;
|
|
|
+import com.jpsoft.smart.modules.base.entity.AlarmConfig;
|
|
|
+import com.jpsoft.smart.modules.base.entity.CompanyInfo;
|
|
|
+import com.jpsoft.smart.modules.base.entity.PersonInfo;
|
|
|
+import com.jpsoft.smart.modules.base.service.AlarmConfigService;
|
|
|
+import com.jpsoft.smart.modules.base.service.CompanyInfoService;
|
|
|
+import com.jpsoft.smart.modules.base.service.PersonInfoService;
|
|
|
import com.jpsoft.smart.modules.common.utils.PojoUtils;
|
|
|
import com.jpsoft.smart.modules.common.dto.Sort;
|
|
|
import com.jpsoft.smart.modules.common.dto.MessageResult;
|
|
|
import com.jpsoft.smart.modules.business.entity.WorkAttendance;
|
|
|
import com.jpsoft.smart.modules.business.service.WorkAttendanceService;
|
|
|
+import com.sun.corba.se.spi.orbutil.threadpool.Work;
|
|
|
import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiImplicitParam;
|
|
|
+import io.swagger.annotations.ApiImplicitParams;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
+import org.apache.poi.ss.usermodel.WorkbookFactory;
|
|
|
+import org.joda.time.DateTime;
|
|
|
+import org.joda.time.Days;
|
|
|
+import org.joda.time.Months;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.core.io.ClassPathResource;
|
|
|
+import org.springframework.format.annotation.DateTimeFormat;
|
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
+import java.io.FileInputStream;
|
|
|
+import java.io.FileOutputStream;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
import java.text.SimpleDateFormat;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@RestController
|
|
|
@RequestMapping("/workAttendance")
|
|
@@ -27,6 +50,15 @@ public class WorkAttendanceController {
|
|
|
@Autowired
|
|
|
private WorkAttendanceService workAttendanceService;
|
|
|
|
|
|
+ @Autowired
|
|
|
+ private CompanyInfoService companyInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private PersonInfoService personInfoService;
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private AlarmConfigService alarmConfigService;
|
|
|
+
|
|
|
@ApiOperation(value="创建空记录")
|
|
|
@GetMapping("create")
|
|
|
public MessageResult<WorkAttendance> create(){
|
|
@@ -222,4 +254,263 @@ public class WorkAttendanceController {
|
|
|
|
|
|
return msgResult;
|
|
|
}
|
|
|
+
|
|
|
+ @ApiOperation(value="导出考勤记录")
|
|
|
+ @ApiImplicitParams({
|
|
|
+ @ApiImplicitParam(name="companyId",value = "单位编号",required = true,paramType = "form"),
|
|
|
+ @ApiImplicitParam(name = "startDate",value = "开始时间", required = true,paramType="form"),
|
|
|
+ @ApiImplicitParam(name = "endDate",value = "截止时间", required = true,paramType="form"),
|
|
|
+ @ApiImplicitParam(name = "subject",value = "subject", required = false,paramType="form")
|
|
|
+ })
|
|
|
+ @RequestMapping(value = "exportXls",method = RequestMethod.POST)
|
|
|
+ public MessageResult<List> exportXls(
|
|
|
+ String companyId,
|
|
|
+ @DateTimeFormat(pattern = "yyyy-MM-dd") Date startDate,
|
|
|
+ @DateTimeFormat(pattern = "yyyy-MM-dd") Date endDate,
|
|
|
+ @RequestAttribute String subject){
|
|
|
+
|
|
|
+ //当前用户ID
|
|
|
+ System.out.println(subject);
|
|
|
+
|
|
|
+ MessageResult<List> msgResult = new MessageResult<>();
|
|
|
+
|
|
|
+ try {
|
|
|
+ //todo 起始时间与结束时间间隔最大1个月
|
|
|
+ DateTime startTime = new DateTime(startDate);
|
|
|
+ DateTime endTime = new DateTime(endDate);
|
|
|
+
|
|
|
+ int months = Months.monthsBetween(startTime,endTime).getMonths();
|
|
|
+
|
|
|
+ if(months>1){
|
|
|
+ throw new Exception("最多只能查询一个月内的考勤记录!");
|
|
|
+ }
|
|
|
+
|
|
|
+ CompanyInfo companyInfo = companyInfoService.get(companyId);
|
|
|
+
|
|
|
+ //todo 查询考勤设置
|
|
|
+ List<AlarmConfig> alarmConfigList = alarmConfigService.findByCompanyId(companyId);
|
|
|
+
|
|
|
+ int dayOfWorkAttendanceNum = alarmConfigList.size();
|
|
|
+
|
|
|
+ //todo 查询单位人员
|
|
|
+ List<PersonInfo> personInfoList = personInfoService.findByCompanyCode(companyInfo.getCode() + "%");
|
|
|
+
|
|
|
+ int days = Days.daysBetween(startTime,endTime).getDays();
|
|
|
+
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
|
|
+
|
|
|
+ List<Map> personMapList = new ArrayList<>();
|
|
|
+
|
|
|
+ for (PersonInfo personInfo : personInfoList) {
|
|
|
+ //todo 每个人在指定时间段(出勤天数,休息天数,迟到次数,早退次数,上班缺卡次数,下班缺卡次数,旷工天数)
|
|
|
+ int workDays=0,restDays=0,lateNum=0,leaveNum=0,missCardOnWorkCount=0,missCardOffWorkCount=0,missCardAllDayCount=0;
|
|
|
+
|
|
|
+ Map<String,Object> personMap = new HashMap<>();
|
|
|
+ Map<String,List> workAttendanceMap = new HashMap<>();
|
|
|
+
|
|
|
+ for (int i=0;i<=days;i++){
|
|
|
+ List<WorkAttendance> list = new ArrayList<>();
|
|
|
+ DateTime dt = startTime.plusDays(i);
|
|
|
+ workAttendanceMap.put(dt.toString("yyyy-MM-dd"),list);
|
|
|
+ }
|
|
|
+
|
|
|
+ //todo 每个人在指定时间段内每天的考勤情况
|
|
|
+ List<WorkAttendance> workAttendanceList = workAttendanceService.findByPersonIdAndDate(personInfo.getId(),startDate,endDate);
|
|
|
+
|
|
|
+ for (WorkAttendance workAttendance : workAttendanceList) {
|
|
|
+ if(workAttendance.getRecordTime()!=null) {
|
|
|
+ String key = sdf.format(workAttendance.getRecordTime());
|
|
|
+ workAttendanceMap.get(key).add(workAttendance);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ for (int i=0;i<=days;i++){
|
|
|
+ DateTime dt = startTime.plusDays(i);
|
|
|
+ String key = dt.toString("yyyy-MM-dd");
|
|
|
+
|
|
|
+ List<WorkAttendance> workAttendances = workAttendanceMap.get(key);
|
|
|
+
|
|
|
+ if (workAttendances.size()==0){
|
|
|
+ //单天不需要考勤则不会有记录
|
|
|
+ restDays++;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ workDays++;
|
|
|
+
|
|
|
+ for (WorkAttendance workAttendance : workAttendances) {
|
|
|
+ String result = workAttendance.getResult();
|
|
|
+
|
|
|
+ if (result.equals(WorkAttendance.LATE)){
|
|
|
+ lateNum++; //迟到
|
|
|
+ }
|
|
|
+ else if(result.equals(WorkAttendance.LEAVE_EARLY)){
|
|
|
+ leaveNum++; //早退
|
|
|
+ }
|
|
|
+ else if(result.equals(WorkAttendance.MISSING)){
|
|
|
+ if (workAttendance.getClassifier().equals("1")){
|
|
|
+ //上班缺卡
|
|
|
+ missCardOffWorkCount++;
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ //下班缺卡
|
|
|
+ missCardOffWorkCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (dayOfWorkAttendanceNum == missCardOnWorkCount + missCardOffWorkCount){
|
|
|
+ //当天的考勤总数=上下班缺卡之和
|
|
|
+ missCardAllDayCount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ personMap.put("personInfo",personInfo);
|
|
|
+ personMap.put("company",personInfo.getPosition1());
|
|
|
+ personMap.put("department",personInfo.getPosition2());
|
|
|
+ personMap.put("jobNumber",personInfo.getPosition3());
|
|
|
+ personMap.put("workDays",workDays);
|
|
|
+ personMap.put("restDays",restDays);
|
|
|
+ personMap.put("lateNum",lateNum);
|
|
|
+ personMap.put("leaveNum",leaveNum);
|
|
|
+ personMap.put("missCardOnWorkCount",missCardOnWorkCount);
|
|
|
+ personMap.put("missCardOffWorkCount",missCardOffWorkCount);
|
|
|
+ personMap.put("missCardAllDayCount",missCardAllDayCount);
|
|
|
+ personMap.put("workAttendanceMap",workAttendanceMap);
|
|
|
+
|
|
|
+ personMapList.add(personMap);
|
|
|
+ }
|
|
|
+
|
|
|
+ //todo 生成报表
|
|
|
+// String tmplFilePath = "E:\\workAttendanceReport.xlsx";
|
|
|
+ createReport(startTime,endTime,personMapList);
|
|
|
+
|
|
|
+ msgResult.setData(personMapList);
|
|
|
+ msgResult.setResult(true);
|
|
|
+ }
|
|
|
+ catch (Exception ex){
|
|
|
+ msgResult.setResult(false);
|
|
|
+ msgResult.setMessage(ex.getMessage());
|
|
|
+ logger.error(ex.getMessage(),ex);
|
|
|
+ }
|
|
|
+
|
|
|
+ return msgResult;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void createReport(DateTime startTime,DateTime endTime,List<Map> personMapList) throws Exception {
|
|
|
+ int days = Days.daysBetween(startTime,endTime).getDays();
|
|
|
+ ClassPathResource resource = new ClassPathResource("static/workAttendanceReport.xlsx");
|
|
|
+
|
|
|
+ Workbook wb = WorkbookFactory.create(resource.getInputStream());
|
|
|
+
|
|
|
+ Sheet sheet = wb.getSheetAt(0);
|
|
|
+
|
|
|
+ Row row1 = sheet.getRow(0);
|
|
|
+ Row row2 = sheet.getRow(1);
|
|
|
+ Row row3 = sheet.getRow(2);
|
|
|
+
|
|
|
+ String title = row1.getCell(0).getStringCellValue();
|
|
|
+ String subTitle = row2.getCell(0).getStringCellValue();
|
|
|
+
|
|
|
+ row1.getCell(0).setCellValue(String.format(title,startTime.toString("yyyy-MM-dd"),endTime.toString("yyyy-MM-dd")));
|
|
|
+ row2.getCell(0).setCellValue(String.format(subTitle,DateTime.now().toString("yyyy-MM-dd HH:mm")));
|
|
|
+
|
|
|
+ int dayStartColIndex = 11;
|
|
|
+
|
|
|
+ for (int i=0;i<days;i++){
|
|
|
+ DateTime dt = startTime.plusDays(i);
|
|
|
+ row3.getCell(dayStartColIndex + i).setCellValue(dt.toString("MM-dd") + "\r\n" + dt.dayOfWeek().getAsShortText(Locale.CHINA));
|
|
|
+ }
|
|
|
+
|
|
|
+ //todo 写考勤记录
|
|
|
+ int startRowIndex = 3;
|
|
|
+
|
|
|
+ for (int i=0;i<personMapList.size();i++) {
|
|
|
+ Row row = sheet.createRow(startRowIndex + i);
|
|
|
+ Map personMap = personMapList.get(i);
|
|
|
+
|
|
|
+ PersonInfo personInfo = (PersonInfo)personMap.get("personInfo");
|
|
|
+ row.createCell(0).setCellValue(personInfo.getName());
|
|
|
+
|
|
|
+ String companyName = (String)personMap.get("company");
|
|
|
+ row.createCell(1).setCellValue(companyName);
|
|
|
+
|
|
|
+ String department = (String)personMap.get("department");
|
|
|
+ row.createCell(2).setCellValue(department);
|
|
|
+
|
|
|
+ String jobNumber = (String)personMap.get("jobNumber");
|
|
|
+ row.createCell(3).setCellValue(jobNumber);
|
|
|
+
|
|
|
+ Integer workDays = Integer.valueOf(personMap.get("workDays").toString());
|
|
|
+ row.createCell(4).setCellValue(workDays);
|
|
|
+
|
|
|
+ Integer restDays = Integer.valueOf(personMap.get("restDays").toString());
|
|
|
+ row.createCell(5).setCellValue(restDays);
|
|
|
+
|
|
|
+ Integer lateNum = Integer.valueOf(personMap.get("lateNum").toString());
|
|
|
+ row.createCell(6).setCellValue(lateNum);
|
|
|
+
|
|
|
+ Integer leaveNum = Integer.valueOf(personMap.get("leaveNum").toString());
|
|
|
+ row.createCell(7).setCellValue(leaveNum);
|
|
|
+
|
|
|
+ Integer missCardOnWorkCount = Integer.valueOf(personMap.get("missCardOnWorkCount").toString());
|
|
|
+ row.createCell(8).setCellValue(missCardOnWorkCount);
|
|
|
+
|
|
|
+ Integer missCardOffWorkCount = Integer.valueOf(personMap.get("missCardOffWorkCount").toString());
|
|
|
+ row.createCell(9).setCellValue(missCardOffWorkCount);
|
|
|
+
|
|
|
+ Integer missCardAllDayCount = Integer.valueOf(personMap.get("missCardAllDayCount").toString());
|
|
|
+ row.createCell(10).setCellValue(missCardAllDayCount);
|
|
|
+
|
|
|
+ Map<String,List> workAttendanceMap = (Map<String,List>)personMap.get("workAttendanceMap");
|
|
|
+
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
|
|
|
+
|
|
|
+ for(int j=0;j<days;j++){
|
|
|
+ String key = startTime.plusDays(j).toString("yyyy-MM-dd");
|
|
|
+
|
|
|
+ if (workAttendanceMap.containsKey(key)){
|
|
|
+ List<WorkAttendance> workAttendanceList = workAttendanceMap.get(key);
|
|
|
+
|
|
|
+ String value = workAttendanceList.stream().map((item)->{
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+
|
|
|
+ if(item.getClassifier().equals(1)){
|
|
|
+ sb.append("上班");
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ sb.append("下班");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (WorkAttendance.SUCCESS.equals(item.getResult())){
|
|
|
+ sb.append("正常打卡");
|
|
|
+ }
|
|
|
+ else if (WorkAttendance.LATE.equals(item.getResult())){
|
|
|
+ sb.append("迟到");
|
|
|
+ }
|
|
|
+ else if (WorkAttendance.LEAVE_EARLY.equals(item.getResult())){
|
|
|
+ sb.append("早退");
|
|
|
+ }
|
|
|
+ else{
|
|
|
+ sb.append("缺卡");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (item.getRecordTime()!=null) {
|
|
|
+ sb.append(" " + sdf.format(item.getRecordTime()));
|
|
|
+ }
|
|
|
+
|
|
|
+ return sb.toString();
|
|
|
+ }).collect(Collectors.joining("\r\n"));
|
|
|
+
|
|
|
+ row.createCell(dayStartColIndex + j).setCellValue(value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ FileOutputStream output = new FileOutputStream("E:\\output.xlsx");
|
|
|
+
|
|
|
+ wb.write(output);
|
|
|
+ wb.close();
|
|
|
+ output.close();
|
|
|
+ }
|
|
|
}
|