|
|
@ -5,15 +5,16 @@ import cn.hutool.core.date.DateUtil; |
|
|
import cn.hutool.core.lang.Snowflake; |
|
|
import cn.hutool.core.lang.Snowflake; |
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
import cn.hutool.core.util.ObjectUtil; |
|
|
import com.ccsens.common.bean.po.ProMember; |
|
|
import com.ccsens.common.bean.po.ProMember; |
|
|
|
|
|
import com.ccsens.common.bean.po.SysHolidays; |
|
|
|
|
|
import com.ccsens.common.bean.po.SysHolidaysExample; |
|
|
import com.ccsens.common.persist.dao.ProMemberDao; |
|
|
import com.ccsens.common.persist.dao.ProMemberDao; |
|
|
|
|
|
import com.ccsens.common.persist.mapper.SysHolidaysMapper; |
|
|
import com.ccsens.common.service.IPowerService; |
|
|
import com.ccsens.common.service.IPowerService; |
|
|
import com.ccsens.common.util.CommonCodeError; |
|
|
import com.ccsens.common.util.CommonCodeError; |
|
|
import com.ccsens.defaultwbs.bean.dto.ClockingInDto; |
|
|
import com.ccsens.defaultwbs.bean.dto.ClockingInDto; |
|
|
import com.ccsens.defaultwbs.bean.po.ProClockingIn; |
|
|
import com.ccsens.defaultwbs.bean.po.ProClockingIn; |
|
|
|
|
|
|
|
|
import com.ccsens.defaultwbs.bean.vo.ClockingInVo; |
|
|
import com.ccsens.defaultwbs.bean.vo.ClockingInVo; |
|
|
import com.ccsens.defaultwbs.persist.dao.ProClockingInDao; |
|
|
import com.ccsens.defaultwbs.persist.dao.ProClockingInDao; |
|
|
|
|
|
|
|
|
import com.ccsens.defaultwbs.util.DefaultCodeError; |
|
|
import com.ccsens.defaultwbs.util.DefaultCodeError; |
|
|
import com.ccsens.util.PoiUtil; |
|
|
import com.ccsens.util.PoiUtil; |
|
|
import com.ccsens.util.PropUtil; |
|
|
import com.ccsens.util.PropUtil; |
|
|
@ -21,15 +22,14 @@ import com.ccsens.util.exception.BaseException; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import org.apache.poi.ss.usermodel.Workbook; |
|
|
import org.apache.poi.ss.usermodel.Workbook; |
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
|
|
|
|
|
import org.springframework.core.io.DefaultResourceLoader; |
|
|
|
|
|
import org.springframework.core.io.ResourceLoader; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.stereotype.Service; |
|
|
import org.springframework.transaction.annotation.Propagation; |
|
|
import org.springframework.transaction.annotation.Propagation; |
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
import javax.annotation.Resource; |
|
|
import java.io.File; |
|
|
import java.io.*; |
|
|
import java.io.FileOutputStream; |
|
|
|
|
|
import java.io.IOException; |
|
|
|
|
|
import java.io.OutputStream; |
|
|
|
|
|
import java.text.DateFormat; |
|
|
import java.text.DateFormat; |
|
|
import java.text.SimpleDateFormat; |
|
|
import java.text.SimpleDateFormat; |
|
|
import java.util.*; |
|
|
import java.util.*; |
|
|
@ -48,6 +48,8 @@ public class ClockingInService implements IClockingInService { |
|
|
private Snowflake snowflake; |
|
|
private Snowflake snowflake; |
|
|
@Resource |
|
|
@Resource |
|
|
private IPowerService powerService; |
|
|
private IPowerService powerService; |
|
|
|
|
|
@Resource |
|
|
|
|
|
private SysHolidaysMapper holidaysMapper; |
|
|
|
|
|
|
|
|
@Override |
|
|
@Override |
|
|
public List<ClockingInVo.ClockingInInfo> queryClockingIn(ClockingInDto.QueryClockingIn params, Long userId) { |
|
|
public List<ClockingInVo.ClockingInInfo> queryClockingIn(ClockingInDto.QueryClockingIn params, Long userId) { |
|
|
@ -76,7 +78,6 @@ public class ClockingInService implements IClockingInService { |
|
|
|
|
|
|
|
|
//添加成员信息
|
|
|
//添加成员信息
|
|
|
//1.查询全部
|
|
|
//1.查询全部
|
|
|
|
|
|
|
|
|
List<Long> memberIdList = new ArrayList<>(); |
|
|
List<Long> memberIdList = new ArrayList<>(); |
|
|
Long userOfMemberId = memberDao.findUserOfMemberId(params.getProjectId(), userId); |
|
|
Long userOfMemberId = memberDao.findUserOfMemberId(params.getProjectId(), userId); |
|
|
memberIdList.add(userOfMemberId); |
|
|
memberIdList.add(userOfMemberId); |
|
|
@ -427,23 +428,182 @@ public class ClockingInService implements IClockingInService { |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
//写入数据
|
|
|
|
|
|
Workbook wbs = PoiUtil.exportWB("Sheet1", list, workbook); |
|
|
|
|
|
|
|
|
|
|
|
return excelReport(wbs); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
|
|
public ClockingInVo.ExcelUrl exportRecord1(ClockingInDto.QueryClockingIn params, Long userId) throws Exception { |
|
|
|
|
|
//根据时间生成日期列表(工作日)
|
|
|
|
|
|
List<String> dateList = getDateList(params.getStartTime(), params.getEndTime()); |
|
|
|
|
|
//查询需要的成员的记录
|
|
|
|
|
|
List<ClockingInVo.ClockMember> clockMembers = clockingInDao.queryMemberClockingIn(params.getMemberIdList(), params.getRoleId(), params.getStartTime(), params.getEndTime()); |
|
|
|
|
|
|
|
|
|
|
|
//生成导入数据
|
|
|
|
|
|
List<List<PoiUtil.PoiUtilCell>> list = createCell(dateList, clockMembers); |
|
|
|
|
|
|
|
|
|
|
|
//获取模板
|
|
|
|
|
|
ResourceLoader resourceLoader = new DefaultResourceLoader(); |
|
|
|
|
|
InputStream is = resourceLoader.getResource("classpath:templates/ClcokingIn.xlsx").getInputStream(); |
|
|
|
|
|
Workbook workbook = new XSSFWorkbook(is); |
|
|
|
|
|
//写入数据
|
|
|
|
|
|
Workbook wbs = PoiUtil.exportWB("考勤统计", list, workbook); |
|
|
|
|
|
|
|
|
|
|
|
return excelReport(wbs); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//导出操作
|
|
|
private ClockingInVo.ExcelUrl excelReport(Workbook wbs) throws IOException { |
|
|
|
|
|
//生成导出文件
|
|
|
String fileName = DateUtil.today() + "/" + System.currentTimeMillis() + ".xlsx"; |
|
|
String fileName = DateUtil.today() + "/" + System.currentTimeMillis() + ".xlsx"; |
|
|
String path = PropUtil.path + fileName; |
|
|
String path = PropUtil.path + fileName; |
|
|
File tmpFile = new File(path); |
|
|
File tmpFile = new File(path); |
|
|
if (!tmpFile.getParentFile().exists()) { |
|
|
if (!tmpFile.getParentFile().exists()) { |
|
|
tmpFile.getParentFile().mkdirs(); |
|
|
tmpFile.getParentFile().mkdirs(); |
|
|
} |
|
|
} |
|
|
|
|
|
//将workBook写入文件
|
|
|
Workbook wbs = PoiUtil.exportWB("Sheet1", list, workbook); |
|
|
|
|
|
OutputStream stream = new FileOutputStream(tmpFile); |
|
|
OutputStream stream = new FileOutputStream(tmpFile); |
|
|
wbs.write(stream); |
|
|
wbs.write(stream); |
|
|
stream.close(); |
|
|
stream.close(); |
|
|
|
|
|
//返回文件路径
|
|
|
ClockingInVo.ExcelUrl excelUrl = new ClockingInVo.ExcelUrl(); |
|
|
ClockingInVo.ExcelUrl excelUrl = new ClockingInVo.ExcelUrl(); |
|
|
String url = PropUtil.imgDomain+fileName; |
|
|
String url = PropUtil.imgDomain+fileName; |
|
|
excelUrl.setUrl(url); |
|
|
excelUrl.setUrl(url); |
|
|
return excelUrl; |
|
|
return excelUrl; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<List<PoiUtil.PoiUtilCell>> createCell(List<String> dateList, List<ClockingInVo.ClockMember> clockMembers) { |
|
|
|
|
|
//整体数据
|
|
|
|
|
|
List<List<PoiUtil.PoiUtilCell>> list = new ArrayList<>(); |
|
|
|
|
|
//第一行(标题)
|
|
|
|
|
|
list.add(new ArrayList<>()); |
|
|
|
|
|
//第二三行(表头)
|
|
|
|
|
|
list.add(new ArrayList<>()); |
|
|
|
|
|
list.add(new ArrayList<>()); |
|
|
|
|
|
//序号
|
|
|
|
|
|
int a = 1; |
|
|
|
|
|
//判断成员不为空
|
|
|
|
|
|
if (CollectionUtil.isNotEmpty(clockMembers)) { |
|
|
|
|
|
// 循环成员
|
|
|
|
|
|
for (ClockingInVo.ClockMember clockMember : clockMembers) { |
|
|
|
|
|
//计算工作日未打卡的记录
|
|
|
|
|
|
List<ClockingInVo.NotClockingIn> notList = notClocking(dateList, clockMember); |
|
|
|
|
|
//实际出勤天数row
|
|
|
|
|
|
List<PoiUtil.PoiUtilCell> clockingInTimes = new ArrayList<>(); |
|
|
|
|
|
//序号
|
|
|
|
|
|
clockingInTimes.add(new PoiUtil.PoiUtilCell(a + "", 1, 4 + (notList.size() == 0 ? 1 : notList.size()))); |
|
|
|
|
|
//成员名
|
|
|
|
|
|
clockingInTimes.add(new PoiUtil.PoiUtilCell(clockMember.getName(), 1, 4 + (notList.size() == 0 ? 1 : notList.size()))); |
|
|
|
|
|
clockingInTimes.add(new PoiUtil.PoiUtilCell("实际考勤天数")); |
|
|
|
|
|
clockingInTimes.add(new PoiUtil.PoiUtilCell(clockMember.getRecordMemberList().size() + "")); |
|
|
|
|
|
list.add(clockingInTimes); |
|
|
|
|
|
|
|
|
|
|
|
//请假天数row
|
|
|
|
|
|
list.add(getOneRow("请假天数",0 + "")); |
|
|
|
|
|
//加班天数row
|
|
|
|
|
|
list.add(getOneRow("加班天数",0 + " ")); |
|
|
|
|
|
//出差天数row
|
|
|
|
|
|
list.add(getOneRow("出差天数",0 + "")); |
|
|
|
|
|
|
|
|
|
|
|
//未打卡次数及时间
|
|
|
|
|
|
if(CollectionUtil.isEmpty(notList)){ |
|
|
|
|
|
List<PoiUtil.PoiUtilCell> notClocking = new ArrayList<>(); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell("未打卡次数及时间")); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell(0 + "次")); |
|
|
|
|
|
list.add(notClocking); |
|
|
|
|
|
}else { |
|
|
|
|
|
for (int i = 0; i < notList.size(); i++) { |
|
|
|
|
|
ClockingInVo.NotClockingIn notClockingIn = notList.get(i); |
|
|
|
|
|
List<PoiUtil.PoiUtilCell> notClocking = new ArrayList<>(); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
if(i == 0){ |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell("未打卡次数及时间", 1, notList.size())); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell(notList.size() + "次", 1, notList.size())); |
|
|
|
|
|
}else { |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
} |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell(notClockingIn.getTime())); |
|
|
|
|
|
notClocking.add(new PoiUtil.PoiUtilCell(notClockingIn.getType())); |
|
|
|
|
|
list.add(notClocking); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return list; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<PoiUtil.PoiUtilCell> getOneRow(String value,String times) { |
|
|
|
|
|
List<PoiUtil.PoiUtilCell> row = new ArrayList<>(); |
|
|
|
|
|
row.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
row.add(new PoiUtil.PoiUtilCell()); |
|
|
|
|
|
row.add(new PoiUtil.PoiUtilCell(value)); |
|
|
|
|
|
row.add(new PoiUtil.PoiUtilCell(times)); |
|
|
|
|
|
return row; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<ClockingInVo.NotClockingIn> notClocking(List<String> dateList, ClockingInVo.ClockMember clockMember) { |
|
|
|
|
|
List<ClockingInVo.NotClockingIn> notList = new ArrayList<>(); |
|
|
|
|
|
Map<String, ClockingInVo.RecordMember> recordMemberMap = clockMember.getRecordMemberMap(); |
|
|
|
|
|
if (CollectionUtil.isNotEmpty(dateList)) { |
|
|
|
|
|
//循环计算未打卡的记录
|
|
|
|
|
|
dateList.forEach(day -> { |
|
|
|
|
|
ClockingInVo.RecordMember recordMember = recordMemberMap.get(day); |
|
|
|
|
|
if (recordMember == null) { |
|
|
|
|
|
//工作日未打卡,将记录存入数组
|
|
|
|
|
|
ClockingInVo.NotClockingIn notMorning = new ClockingInVo.NotClockingIn(day, "早"); |
|
|
|
|
|
ClockingInVo.NotClockingIn notNight = new ClockingInVo.NotClockingIn(day, "晚"); |
|
|
|
|
|
notList.add(notMorning); |
|
|
|
|
|
notList.add(notNight); |
|
|
|
|
|
} else { |
|
|
|
|
|
if (recordMember.getMorning() == null || recordMember.getMorning() == 0) { |
|
|
|
|
|
ClockingInVo.NotClockingIn notMorning = new ClockingInVo.NotClockingIn(day, "早"); |
|
|
|
|
|
notList.add(notMorning); |
|
|
|
|
|
} |
|
|
|
|
|
if (recordMember.getMorning() == null || recordMember.getMorning() == 0) { |
|
|
|
|
|
ClockingInVo.NotClockingIn notNight = new ClockingInVo.NotClockingIn(day, "晚"); |
|
|
|
|
|
notList.add(notNight); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} |
|
|
|
|
|
return notList; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private List<String> getDateList(Long startTime, Long endTime) { |
|
|
|
|
|
List<String> dateList = new ArrayList<>(); |
|
|
|
|
|
DateFormat df = new SimpleDateFormat("MM-dd"); |
|
|
|
|
|
String isHoliday = ""; |
|
|
|
|
|
String overDay = ""; |
|
|
|
|
|
//获取假日调休信息
|
|
|
|
|
|
SysHolidaysExample holidaysExample = new SysHolidaysExample(); |
|
|
|
|
|
holidaysExample.createCriteria().andYearEqualTo(new SimpleDateFormat("yyyy").format(new Date())); |
|
|
|
|
|
List<SysHolidays> sysHolidays = holidaysMapper.selectByExample(holidaysExample); |
|
|
|
|
|
if (CollectionUtil.isNotEmpty(sysHolidays)) { |
|
|
|
|
|
isHoliday = sysHolidays.get(0).getHoliday(); |
|
|
|
|
|
overDay = sysHolidays.get(0).getWorkday(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Calendar min = Calendar.getInstance(); |
|
|
|
|
|
Calendar max = Calendar.getInstance(); |
|
|
|
|
|
min.setTime(new Date(startTime)); |
|
|
|
|
|
max.setTime(new Date(endTime)); |
|
|
|
|
|
max.add(Calendar.DATE, 1); |
|
|
|
|
|
while (max.after(min)) { |
|
|
|
|
|
int i = min.get(Calendar.DAY_OF_WEEK); |
|
|
|
|
|
//是调休 || (不是周末 && 不是节假日)
|
|
|
|
|
|
if (overDay.contains(df.format(min.getTime())) || ((i != 1 && i != 7) && !isHoliday.contains(df.format(min.getTime())))) { |
|
|
|
|
|
dateList.add(new SimpleDateFormat("yyyy-MM-dd").format(min.getTime())); |
|
|
|
|
|
} |
|
|
|
|
|
min.add(Calendar.DATE, 1); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return dateList; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|