Browse Source

20211103导出考勤表样式2

master
zy_Java 4 years ago
parent
commit
304baf7a48
  1. 8
      src/main/java/com/ccsens/defaultwbs/api/ClockingInController.java
  2. 50
      src/main/java/com/ccsens/defaultwbs/bean/vo/ClockingInVo.java
  3. 15
      src/main/java/com/ccsens/defaultwbs/bean/vo/RoleVo.java
  4. 9
      src/main/java/com/ccsens/defaultwbs/persist/dao/ProClockingInDao.java
  5. 180
      src/main/java/com/ccsens/defaultwbs/service/ClockingInService.java
  6. 2
      src/main/java/com/ccsens/defaultwbs/service/IClockingInService.java
  7. 4
      src/main/resources/application.yml
  8. 4
      src/main/resources/druid-dev.yml
  9. 49
      src/main/resources/mapper_dao/ProClockingInDao.xml
  10. 7
      src/main/resources/mbg.xml
  11. BIN
      src/main/resources/templates/ClcokingIn.xlsx

8
src/main/java/com/ccsens/defaultwbs/api/ClockingInController.java

@ -67,4 +67,12 @@ public class ClockingInController {
ClockingInVo.ExcelUrl excelUrl = clockingInService.exportRecord(params.getParam(), params.getUserId()); ClockingInVo.ExcelUrl excelUrl = clockingInService.exportRecord(params.getParam(), params.getUserId());
return JsonResponse.newInstance().ok(excelUrl); return JsonResponse.newInstance().ok(excelUrl);
} }
@MustLogin
@ApiOperation(value = "导出考勤excel", notes = "")
@RequestMapping(value = "/export1", method = RequestMethod.POST, produces = {"application/json;charset=UTF-8"})
public JsonResponse<ClockingInVo.ExcelUrl> export1(@ApiParam @Validated @RequestBody QueryDto<ClockingInDto.QueryClockingIn> params) throws Exception{
ClockingInVo.ExcelUrl excelUrl = clockingInService.exportRecord1(params.getParam(), params.getUserId());
return JsonResponse.newInstance().ok(excelUrl);
}
} }

50
src/main/java/com/ccsens/defaultwbs/bean/vo/ClockingInVo.java

@ -1,12 +1,18 @@
package com.ccsens.defaultwbs.bean.vo; package com.ccsens.defaultwbs.bean.vo;
import cn.hutool.core.collection.CollectionUtil;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import javafx.print.Collation;
import lombok.Data; import lombok.Data;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
@Data @Data
public class ClockingInVo { public class ClockingInVo {
@ -68,4 +74,48 @@ public class ClockingInVo {
@ApiModelProperty("上次检查人名字") @ApiModelProperty("上次检查人名字")
private String lastCheckerName; private String lastCheckerName;
} }
@Data
public static class ClockMember{
private Long id;
private String name;
private Map<String,RecordMember> recordMemberMap;
private List<RecordMember> recordMemberList;
public Map<String, RecordMember> getRecordMemberMap() {
Map<String, RecordMember> map = new HashMap<>();
if(CollectionUtil.isNotEmpty(recordMemberList)){
recordMemberList.forEach(recordMember -> {
if(recordMember.getMorning() != 0){
map.put(new SimpleDateFormat("yyyy-MM-dd").format(recordMember.getMorning()),recordMember);
}else if(recordMember.night != 0){
map.put(new SimpleDateFormat("yyyy-MM-dd").format(recordMember.getMorning()),recordMember);
}
});
}
return map;
}
}
@Data
public static class RecordMember{
private Long recordId;
private Long morning;
private Long night;
}
@Data
public static class NotClockingIn{
private String time;
private String type;
public NotClockingIn(String time, String type) {
this.time = time;
this.type = type;
}
public NotClockingIn() {
}
}
} }

15
src/main/java/com/ccsens/defaultwbs/bean/vo/RoleVo.java

@ -5,6 +5,7 @@ import io.swagger.annotations.ApiModelProperty;
import lombok.Data; import lombok.Data;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author * @author
@ -34,4 +35,18 @@ public class RoleVo {
@ApiModelProperty("排序") @ApiModelProperty("排序")
private Long sequence; private Long sequence;
} }
@Data
@ApiModel("查找需要的成员信息")
public static class QueryMember{
@ApiModelProperty("成员id")
private Long id;
@ApiModelProperty("名字")
private String name;
@ApiModelProperty("用户id")
private Long userId;
@ApiModelProperty("是不是我(0-否,1-是)")
private Byte isMine = 0;
}
} }

9
src/main/java/com/ccsens/defaultwbs/persist/dao/ProClockingInDao.java

@ -3,6 +3,7 @@ package com.ccsens.defaultwbs.persist.dao;
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.bean.vo.DeliverVo; import com.ccsens.defaultwbs.bean.vo.DeliverVo;
import com.ccsens.defaultwbs.bean.vo.RoleVo;
import com.ccsens.defaultwbs.persist.mapper.ProClockingInMapper; import com.ccsens.defaultwbs.persist.mapper.ProClockingInMapper;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
@ -54,5 +55,11 @@ public interface ProClockingInDao extends ProClockingInMapper {
*/ */
List<ClockingInVo.ClockRecord> queryMemberByIdList(@Param("memberIdList") List<Long> memberIdList,@Param("roleId") Long roleId); List<ClockingInVo.ClockRecord> queryMemberByIdList(@Param("memberIdList") List<Long> memberIdList,@Param("roleId") Long roleId);
/**
* 根据角色id查询成员信息成员id为空则查询全部
* @param memberIdList 成员id列表
* @param roleId 角色id
* @return 返回成员信息
*/
List<ClockingInVo.ClockMember> queryMemberClockingIn(@Param("memberIdList")List<Long> memberIdList, @Param("roleId")Long roleId, @Param("startTime")Long startTime, @Param("endTime")Long endTime);
} }

180
src/main/java/com/ccsens/defaultwbs/service/ClockingInService.java

@ -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;
}
} }

2
src/main/java/com/ccsens/defaultwbs/service/IClockingInService.java

@ -41,5 +41,7 @@ public interface IClockingInService {
*/ */
ClockingInVo.ExcelUrl exportRecord(ClockingInDto.QueryClockingIn params, Long userId) throws IOException; ClockingInVo.ExcelUrl exportRecord(ClockingInDto.QueryClockingIn params, Long userId) throws IOException;
ClockingInVo.ExcelUrl exportRecord1(ClockingInDto.QueryClockingIn params, Long userId) throws Exception;
void auditRecord1(ClockingInDto.Audit param, Long userId); void auditRecord1(ClockingInDto.Audit param, Long userId);
} }

4
src/main/resources/application.yml

@ -1,4 +1,4 @@
spring: spring:
profiles: profiles:
active: test active: dev
include: common, util-test include: common, util-dev

4
src/main/resources/druid-dev.yml

@ -28,8 +28,8 @@ spring:
testOnReturn: false testOnReturn: false
testWhileIdle: true testWhileIdle: true
timeBetweenEvictionRunsMillis: 60000 timeBetweenEvictionRunsMillis: 60000
# url: jdbc:mysql://49.233.89.188:3306/defaultwbs?useUnicode=true&characterEncoding=UTF-8 url: jdbc:mysql://49.233.89.188:3306/defaultwbs?useUnicode=true&characterEncoding=UTF-8
url: jdbc:mysql://www.tall.wiki/defaultwbs?useUnicode=true&characterEncoding=UTF-8 # url: jdbc:mysql://www.tall.wiki/defaultwbs?useUnicode=true&characterEncoding=UTF-8
# url: jdbc:mysql://127.0.0.1/mt?useUnicode=true&characterEncoding=UTF-8 # url: jdbc:mysql://127.0.0.1/mt?useUnicode=true&characterEncoding=UTF-8
username: root username: root
validationQuery: SELECT 1 FROM DUAL validationQuery: SELECT 1 FROM DUAL

49
src/main/resources/mapper_dao/ProClockingInDao.xml

@ -105,4 +105,53 @@
</foreach> </foreach>
</select> </select>
<resultMap id="queryMemberRecord" type="com.ccsens.defaultwbs.bean.vo.ClockingInVo$ClockMember">
<id column="id" property="id"/>
<result column="name" property="name"/>
<collection property="recordMemberList" ofType="com.ccsens.defaultwbs.bean.vo.ClockingInVo$RecordMember" >
<id column="recordId" property="recordId"/>
<result column="morning" property="morning"/>
<result column="night" property="night"/>
</collection>
</resultMap>
<select id="queryMemberClockingIn" resultMap="queryMemberRecord">
SELECT
m.id,
m.`name`,
c.id,
c.morning,
c.night
FROM
t_pro_member m
LEFT JOIN t_pro_role_member rm ON m.id = rm.member_id
LEFT JOIN t_pro_clocking_in c on m.id = c.member_id and c.rec_status = 0
WHERE
rm.role_id = #{roleId}
<if test="memberIdList != null and memberIdList.size() > 0" >
AND m.id IN
<foreach collection="memberIdList" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</if>
and m.rec_status = 0
and rm.rec_status = 0
and
(
(
(c.morning_status = 1 or c.morning_status = 3)
and c.morning >= #{startTime}
and c.morning &lt; #{endTime}
)
or
(
(c.night_status = 1 or c.night_status = 3)
and c.night >= #{startTime}
and c.night &lt; #{endTime}
)
)
</select>
</mapper> </mapper>

7
src/main/resources/mbg.xml

@ -78,9 +78,10 @@
<!-- <table tableName="t_pro_task_sub" domainObjectName="ProTaskSub"></table>--> <!-- <table tableName="t_pro_task_sub" domainObjectName="ProTaskSub"></table>-->
<!-- <table tableName="t_pro_task_version" domainObjectName="ProTaskVersion"></table>--> <!-- <table tableName="t_pro_task_version" domainObjectName="ProTaskVersion"></table>-->
<!-- <table tableName="t_pro_member_stakeholder" domainObjectName="ProMemberStakeholder"></table>--> <!-- <table tableName="t_pro_member_stakeholder" domainObjectName="ProMemberStakeholder"></table>-->
<table tableName="t_pro_deliver" domainObjectName="ProDeliver"></table> <!-- <table tableName="t_pro_deliver" domainObjectName="ProDeliver"></table>-->
<table tableName="t_pro_deliver_checker" domainObjectName="ProDeliverChecker"></table> <!-- <table tableName="t_pro_deliver_checker" domainObjectName="ProDeliverChecker"></table>-->
<table tableName="t_pro_clocking_in" domainObjectName="ProClockingIn"></table> <!-- <table tableName="t_pro_clocking_in" domainObjectName="ProClockingIn"></table>-->
<table tableName="t_sys_holidays" domainObjectName="SysHolidays"></table>
<!-- 有些表的字段需要指定java类型 <!-- 有些表的字段需要指定java类型
<table schema="" tableName=""> <table schema="" tableName="">

BIN
src/main/resources/templates/ClcokingIn.xlsx

Binary file not shown.
Loading…
Cancel
Save