|
|
@@ -1,6 +1,7 @@
|
|
|
|
|
|
package org.sky.scientific.service.impl;
|
|
|
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
import com.alibaba.excel.ExcelWriter;
|
|
|
import com.alibaba.excel.support.ExcelTypeEnum;
|
|
|
@@ -13,6 +14,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
|
|
import lombok.AllArgsConstructor;
|
|
|
import lombok.SneakyThrows;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
import org.sky.core.log.exception.ServiceException;
|
|
|
import org.sky.core.mp.base.BaseServiceImpl;
|
|
|
import org.sky.core.mp.support.Condition;
|
|
|
@@ -20,6 +22,8 @@ import org.sky.core.mp.support.Query;
|
|
|
import org.sky.core.secure.utils.SecureUtil;
|
|
|
import org.sky.core.tool.utils.*;
|
|
|
import org.sky.scientific.excel.TechnicianExcel;
|
|
|
+import org.sky.scientific.excel.handle.MergeCellRangeWriteHandler;
|
|
|
+import org.sky.scientific.excel.handle.XmcyryhzmExcel;
|
|
|
import org.sky.scientific.mapper.*;
|
|
|
import org.sky.scientific.pojo.dto.TechnicianDTO;
|
|
|
import org.sky.scientific.pojo.dto.XmSalaryDto;
|
|
|
@@ -36,9 +40,11 @@ import org.springframework.stereotype.Service;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
+import java.math.BigDecimal;
|
|
|
import java.net.URLEncoder;
|
|
|
import java.util.*;
|
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
|
+import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
@@ -73,10 +79,10 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
}
|
|
|
technician.setUnicode(unicode);
|
|
|
|
|
|
- if(Func.isNull(technician.getId())){
|
|
|
+ if (Func.isNull(technician.getId())) {
|
|
|
//新增
|
|
|
return this.save(technician);
|
|
|
- }else {
|
|
|
+ } else {
|
|
|
return this.updateById(technician);
|
|
|
}
|
|
|
// LambdaQueryWrapper<TechnicianEntity> wrapper = Wrappers.<TechnicianEntity>lambdaQuery()
|
|
|
@@ -147,8 +153,8 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
for (TechnicianExcel excel : data) {
|
|
|
TechnicianEntity technician = Objects.requireNonNull(BeanUtil.copyProperties(excel, TechnicianDTO.class));
|
|
|
|
|
|
- technician.setNumber(Func.isBlank(technician.getNumber())? null:technician.getNumber().trim());
|
|
|
- technician.setIdCard(Func.isBlank(technician.getIdCard())?null:technician.getIdCard().trim());
|
|
|
+ technician.setNumber(Func.isBlank(technician.getNumber()) ? null : technician.getNumber().trim());
|
|
|
+ technician.setIdCard(Func.isBlank(technician.getIdCard()) ? null : technician.getIdCard().trim());
|
|
|
//转换 性别字典
|
|
|
technician.setGender(Integer.valueOf(DictCache.getKey(DictEnum.SEX, excel.getGenderName())));
|
|
|
technician.setYearAndMonth(yearAndMonth);
|
|
|
@@ -170,19 +176,19 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
}
|
|
|
technician.setDepartmentId(dbDepartment.getId());
|
|
|
}
|
|
|
- String unicode = baseMapper.getUnicodeByNumberAndIdentityCard(technician.getNumber(), technician.getIdCard());
|
|
|
+ String unicode = baseMapper.getUnicodeByNumberAndIdentityCard(technician.getNumber(), technician.getIdCard());
|
|
|
if (unicode == null) {
|
|
|
unicode = UUID.randomUUID().toString();
|
|
|
}
|
|
|
technician.setUnicode(unicode);
|
|
|
|
|
|
insertList.add(technician);
|
|
|
- if(insertList.size() %20==0){
|
|
|
+ if (insertList.size() % 20 == 0) {
|
|
|
this.saveBatch(insertList);
|
|
|
insertList.clear();
|
|
|
}
|
|
|
}
|
|
|
- if(Func.isNotEmpty(insertList)){
|
|
|
+ if (Func.isNotEmpty(insertList)) {
|
|
|
this.saveBatch(insertList);
|
|
|
}
|
|
|
}
|
|
|
@@ -294,20 +300,20 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
- public IPage<XmTechnicianEntity> meiyueshijicanyuanrenyuanmingdan( IPage<XmTechnicianEntity> page,XmTechnicianDto entity) {
|
|
|
+ public IPage<XmTechnicianEntity> meiyueshijicanyuanrenyuanmingdan(IPage<XmTechnicianEntity> page, XmTechnicianDto entity) {
|
|
|
return xmTechnicianMapper.meiyueshijicanyuanrenyuanmingdan(page, entity);
|
|
|
}
|
|
|
|
|
|
@SneakyThrows
|
|
|
@Override
|
|
|
- public void exportXmTechnicianMonthly(HttpServletResponse response,XmTechnicianDto dto) {
|
|
|
+ public void exportXmTechnicianMonthly(HttpServletResponse response, XmTechnicianDto dto) {
|
|
|
Query query = new Query().setCurrent(1).setSize(Integer.MAX_VALUE);
|
|
|
List<XmTechnicianEntity> list = this.meiyueshijicanyuanrenyuanmingdan(Condition.getPage(query), dto).getRecords();
|
|
|
|
|
|
AtomicInteger i = new AtomicInteger(1);
|
|
|
list.forEach(temp -> {
|
|
|
- temp.setXh(i.getAndIncrement()+"");
|
|
|
- });
|
|
|
+ temp.setXh(i.getAndIncrement() + "");
|
|
|
+ });
|
|
|
|
|
|
InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/每月实际参研人员名单.xls");
|
|
|
response.setContentType("application/vnd.ms-excel");
|
|
|
@@ -321,8 +327,8 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
|
|
//设置list集合数据
|
|
|
excelWriter.fill(list, writeSheet);
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
- map.put("year", dto.getYearAndMonth().substring(0,4));
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("year", dto.getYearAndMonth().substring(0, 4));
|
|
|
map.put("month", dto.getYearAndMonth().substring(4));
|
|
|
excelWriter.fill(map, writeSheet);
|
|
|
excelWriter.finish();
|
|
|
@@ -406,11 +412,22 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
// 参研项目列表
|
|
|
vo.setXmList(xmTechnicianMapper.selectXmListByUnicodeAndYear(vo.getUnicode(), entity.getYearAndMonth()));
|
|
|
// 参研时长列表
|
|
|
- vo.setHoursList(xmTechnicianHoursMapper.selectHoursListByUnicodeAndYear(vo.getUnicode(), entity.getYearAndMonth()));
|
|
|
+ List<DailyAttendance> attendances = xmTechnicianHoursMapper.selectHoursListByUnicodeAndYear(vo.getUnicode(), entity.getYearAndMonth());
|
|
|
+
|
|
|
+
|
|
|
+ vo.setHoursList(attendances);
|
|
|
}
|
|
|
return page.setRecords(list);
|
|
|
}
|
|
|
|
|
|
+// public static void main(String[] args) {
|
|
|
+// List<Integer> list = new ArrayList<>();
|
|
|
+// list.add(1);
|
|
|
+// list.add(2);
|
|
|
+// list.add(0, 5);
|
|
|
+// System.out.println(list);
|
|
|
+// }
|
|
|
+
|
|
|
@Override
|
|
|
public IPage<TechnicianVO> niandugaokejirenyuanhuizongbiao(IPage<TechnicianVO> page, TechnicianDTO dto) {
|
|
|
//TODO 目前因测试数据不多,需求是 年度天数大于183的才显示,这里先用18代替,后期要改回来
|
|
|
@@ -462,11 +479,25 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
Query query = new Query().setCurrent(1).setSize(Integer.MAX_VALUE);
|
|
|
List<XmTechnicianVO> list = this.canyanrenyuanhuamingce(Condition.getPage(query), dto).getRecords();
|
|
|
|
|
|
+ List<Map<String, Object>> resultList = new ArrayList<>(list.size());
|
|
|
+
|
|
|
AtomicInteger i = new AtomicInteger(1);
|
|
|
list.forEach(temp -> {
|
|
|
- temp.setXh(i.getAndIncrement()+"");
|
|
|
+ temp.setXh(i.getAndIncrement() + "");
|
|
|
temp.setXmmcJoin(temp.getXmList().stream().map(XmEntity::getXmmc).collect(Collectors.joining(";")));
|
|
|
temp.setXmCount(temp.getXmList().size());
|
|
|
+
|
|
|
+ List<BigDecimal> hours1 = new ArrayList<>(temp.getHoursList().stream().map(x -> BigDecimal.valueOf(x.getWorkHours())).toList());
|
|
|
+ Map<String, Object> map = BeanUtil.beanToMap(temp);
|
|
|
+ for (int k = 0; k<12; k++) {
|
|
|
+ String month = k < 10 ? "0" + (k+1) : (k+1) + "";
|
|
|
+ if (temp.getHoursList().stream().noneMatch(a -> Func.equals(a.getWorkDate(), dto.getYearAndMonth() + month))) {
|
|
|
+ hours1.add(k, new BigDecimal(0));
|
|
|
+ }
|
|
|
+ map.put("month" + (k+1), hours1.get(k));
|
|
|
+ }
|
|
|
+ map.put("hoursByMonth", hours1.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
|
|
|
+ resultList.add(map);
|
|
|
});
|
|
|
|
|
|
InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/参研人员花名册.xls");
|
|
|
@@ -480,9 +511,9 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
|
|
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
|
|
//设置list集合数据
|
|
|
- excelWriter.fill(list, writeSheet);
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
- map.put("year", dto.getYearAndMonth().substring(0,4));
|
|
|
+ excelWriter.fill(resultList, writeSheet);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("year", dto.getYearAndMonth().substring(0, 4));
|
|
|
map.put("month", dto.getYearAndMonth().substring(4));
|
|
|
excelWriter.fill(map, writeSheet);
|
|
|
excelWriter.finish();
|
|
|
@@ -494,28 +525,52 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
@SneakyThrows
|
|
|
@Override
|
|
|
public void exportXmcyryhzb(HttpServletResponse response, XmTechnicianEntity dto) {
|
|
|
+
|
|
|
+ InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/项目参研人员汇总表.xls");
|
|
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
+ response.setCharacterEncoding("utf-8");
|
|
|
+ response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("项目参研人员汇总表.xls", Charsets.UTF_8));
|
|
|
+
|
|
|
Query query = new Query().setCurrent(1).setSize(Integer.MAX_VALUE);
|
|
|
List<XmTechnicianSummary> list = this.xiangmucanyanrenyuanhuizongbiao(Condition.getPage(query), dto).getRecords();
|
|
|
|
|
|
+ List<XmcyryhzmExcel> dataList = new ArrayList<>();
|
|
|
AtomicInteger i = new AtomicInteger(1);
|
|
|
+
|
|
|
list.forEach(temp -> {
|
|
|
- temp.setXh(i.getAndIncrement()+"");
|
|
|
+
|
|
|
+ List<XmTechnicianEntity> technicianList = temp.getTechnicianList();
|
|
|
+ technicianList.forEach(technician -> {
|
|
|
+ XmcyryhzmExcel data = new XmcyryhzmExcel();
|
|
|
+ data.setXh(i.getAndIncrement()+"");
|
|
|
+ data.setXmbh(temp.getXmbh());
|
|
|
+ data.setXmmc(temp.getXmmc());
|
|
|
+ data.setName(technician.getName());
|
|
|
+ data.setNumber(technician.getNumber());
|
|
|
+ data.setIdCard(technician.getIdCard());
|
|
|
+ data.setDepartment(technician.getDepartment());
|
|
|
+ data.setPost(technician.getPost());
|
|
|
+ data.setPostLocation(technician.getPostLocation());
|
|
|
+ data.setNature(technician.getNature());
|
|
|
+ data.setSituation(technician.getSituation());
|
|
|
+ data.setPersonnelType(technician.getPersonnelType());
|
|
|
+ dataList.add(data);
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
- InputStream templateFileName = this.getClass().getClassLoader().getResourceAsStream("export-template/项目参研人员汇总表.xls");
|
|
|
- response.setContentType("application/vnd.ms-excel");
|
|
|
- response.setCharacterEncoding("utf-8");
|
|
|
- response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("项目参研人员汇总表.xls", Charsets.UTF_8));
|
|
|
+ List<CellRangeAddress> rangeCellList = createCellRange(dataList, new int[]{1,2}, 2, XmcyryhzmExcel::getXmbh);
|
|
|
+
|
|
|
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream())
|
|
|
.withTemplate((templateFileName))
|
|
|
+ .registerWriteHandler(new MergeCellRangeWriteHandler(rangeCellList))
|
|
|
.excelType(ExcelTypeEnum.XLS)
|
|
|
.build();
|
|
|
|
|
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
|
|
//设置list集合数据
|
|
|
- excelWriter.fill(list, writeSheet);
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
- map.put("year", dto.getYearAndMonth().substring(0,4));
|
|
|
+ excelWriter.fill(dataList, writeSheet);
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("year", dto.getYearAndMonth().substring(0, 4));
|
|
|
map.put("month", dto.getYearAndMonth().substring(4));
|
|
|
excelWriter.fill(map, writeSheet);
|
|
|
excelWriter.finish();
|
|
|
@@ -524,6 +579,44 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 生成合并区域
|
|
|
+ *
|
|
|
+ * @param detailList 数据列表
|
|
|
+ * @param mergeColumnIndex 要合并的列索引
|
|
|
+ * @param startRowIndex 起始行(含表头时,表头行数)
|
|
|
+ * @param groupFunction 分组函数,如 e -> e.get某字段()
|
|
|
+ * @return 合并区域集合
|
|
|
+ */
|
|
|
+ public static <T> List<CellRangeAddress> createCellRange(List<T> detailList, int[] mergeColumnIndex, int startRowIndex, Function<T, String> groupFunction) {
|
|
|
+ if (detailList == null || detailList.isEmpty()) {
|
|
|
+ return Collections.emptyList();
|
|
|
+ }
|
|
|
+ // 计算每个key下的数量
|
|
|
+ Map<String, Long> groupMap = new LinkedHashMap<>();
|
|
|
+ for (T item : detailList) {
|
|
|
+ String key = groupFunction.apply(item);
|
|
|
+ groupMap.put(key, groupMap.getOrDefault(key, 0L) + 1);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CellRangeAddress> rangeCellList = new ArrayList<>();
|
|
|
+ // 当前行数
|
|
|
+ int lineCount = startRowIndex;
|
|
|
+
|
|
|
+ for (Map.Entry<String, Long> entry : groupMap.entrySet()) {
|
|
|
+ int count = entry.getValue().intValue();
|
|
|
+ if (count > 1) {
|
|
|
+ int endRowIndex = lineCount + count - 1;
|
|
|
+ for (int columnIndex : mergeColumnIndex) {
|
|
|
+ rangeCellList.add(new CellRangeAddress(lineCount, endRowIndex, columnIndex, columnIndex));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ lineCount += count;
|
|
|
+ }
|
|
|
+
|
|
|
+ return rangeCellList;
|
|
|
+ }
|
|
|
+
|
|
|
@SneakyThrows
|
|
|
@Override
|
|
|
public void exportNdgkjryhzb(HttpServletResponse response, TechnicianDTO dto) {
|
|
|
@@ -547,8 +640,8 @@ public class TechnicianServiceImpl extends BaseServiceImpl<TechnicianMapper, Tec
|
|
|
WriteSheet writeSheet = EasyExcel.writerSheet().build();
|
|
|
//设置list集合数据
|
|
|
excelWriter.fill(list, writeSheet);
|
|
|
- Map<String,Object> map = new HashMap<>();
|
|
|
- map.put("year", dto.getYearAndMonth().substring(0,4));
|
|
|
+ Map<String, Object> map = new HashMap<>();
|
|
|
+ map.put("year", dto.getYearAndMonth().substring(0, 4));
|
|
|
excelWriter.fill(map, writeSheet);
|
|
|
excelWriter.finish();
|
|
|
if (templateFileName != null) {
|