|
|
|
@ -0,0 +1,332 @@
|
|
|
|
|
package com.engine.attendance.component.ImportAndExport.service.impl;
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
|
|
import com.cloudstore.eccom.pc.table.WeaTableColumn;
|
|
|
|
|
import com.engine.attendance.component.ImportAndExport.service.ExcelExportImportService;
|
|
|
|
|
import com.engine.attendance.component.ImportAndExport.service.param.ImportParam;
|
|
|
|
|
import com.engine.attendance.component.calendarscheduling.service.WorkRulesService;
|
|
|
|
|
import com.engine.attendance.component.calendarscheduling.service.impl.WorkRulesServiceImpl;
|
|
|
|
|
import com.engine.attendance.enums.ApplicableOrganizationEnum;
|
|
|
|
|
import com.engine.attendance.enums.SchedulingApproachEnum;
|
|
|
|
|
import com.engine.common.exception.AttendanceRunTimeException;
|
|
|
|
|
import com.engine.common.util.*;
|
|
|
|
|
import com.engine.common.util.excel.ExcelParseHelper;
|
|
|
|
|
import com.engine.common.util.excel.ExcelSupport;
|
|
|
|
|
import com.engine.common.util.excel.ExcelUtil;
|
|
|
|
|
import com.engine.core.impl.Service;
|
|
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
import org.apache.commons.collections4.CollectionUtils;
|
|
|
|
|
import org.apache.commons.lang3.StringUtils;
|
|
|
|
|
import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
|
import org.apache.poi.util.IOUtils;
|
|
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
|
import weaver.file.ImageFileManager;
|
|
|
|
|
import weaver.general.Util;
|
|
|
|
|
import weaver.hrm.User;
|
|
|
|
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
import static com.engine.common.util.excel.ExcelSupport.EXCEL_TYPE_XLSX;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @Author: sy
|
|
|
|
|
* @Description:
|
|
|
|
|
* @Date: 2024/6/5
|
|
|
|
|
**/
|
|
|
|
|
@Slf4j
|
|
|
|
|
public class ExcelExportImportServiceImpl extends Service implements ExcelExportImportService {
|
|
|
|
|
|
|
|
|
|
private WorkRulesService getWorkRulesService(User user) {
|
|
|
|
|
return ServiceUtil.getService(WorkRulesServiceImpl.class,user);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public XSSFWorkbook exportSchedule(Map<String, Object> paramMap) {
|
|
|
|
|
String total = Util.null2String(paramMap.get("total"));
|
|
|
|
|
if ("".equals(total) || "0".equals(total)) {
|
|
|
|
|
paramMap.put("pageSize", "9999");
|
|
|
|
|
} else {
|
|
|
|
|
paramMap.put("pageSize", total);
|
|
|
|
|
}
|
|
|
|
|
paramMap.put("pageindex", "1");
|
|
|
|
|
|
|
|
|
|
Map<String, Object> scheduleResult = getWorkRulesService(user).getDepartSchedule(paramMap);
|
|
|
|
|
List<WeaTableColumn> columns = buildScheduleColumns((List<Map<String, Object>>) scheduleResult.get("columns"));
|
|
|
|
|
List<Map<String, Object>> records = buildScheduleRecords((List<Map<String, Object>>) scheduleResult.get("datas"));
|
|
|
|
|
|
|
|
|
|
List<List<Object>> excelSheetData = new ArrayList<>();
|
|
|
|
|
//工作簿名称
|
|
|
|
|
String sheetName = "日历排班";
|
|
|
|
|
excelSheetData.add(Arrays.asList(columns.stream().map(WeaTableColumn::getText).toArray()));
|
|
|
|
|
|
|
|
|
|
//工作簿数据
|
|
|
|
|
List<List<Object>> rows = new LinkedList<>();
|
|
|
|
|
for (Map<String, Object> recordData : records) {
|
|
|
|
|
List<Object> row = new LinkedList<>();
|
|
|
|
|
for (WeaTableColumn column : columns) {
|
|
|
|
|
row.add(recordData.get(column.getColumn()));
|
|
|
|
|
}
|
|
|
|
|
rows.add(row);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
excelSheetData.addAll(rows);
|
|
|
|
|
String dateTime = Util.null2String(paramMap.get("dateTime"));
|
|
|
|
|
return ExcelUtil.genWorkbookV2(excelSheetData, sheetName, dateTime, columns.size());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Map<String, Object>> buildScheduleRecords(List<Map<String, Object>> dataInfo) {
|
|
|
|
|
List<Map<String, Object>> result = new ArrayList<>();
|
|
|
|
|
if (dataInfo != null && dataInfo.size() > 0) {
|
|
|
|
|
Map<String, Object> dayItem;
|
|
|
|
|
Map<String, Object> record;
|
|
|
|
|
for (Map<String, Object> dataItem : dataInfo) {
|
|
|
|
|
record = new HashMap<>();
|
|
|
|
|
record.put("workcode", Util.null2String(dataItem.get("workcode")));
|
|
|
|
|
record.put("lastname", Util.null2String(dataItem.get("lastname")));
|
|
|
|
|
record.put("subcompany", Util.null2String(dataItem.get("subcompany")));
|
|
|
|
|
record.put("department", Util.null2String(dataItem.get("department")));
|
|
|
|
|
for (Map.Entry<String, Object> entry : dataItem.entrySet()) {
|
|
|
|
|
if (DateUtil.dateIsValid(entry.getKey())) {
|
|
|
|
|
dayItem = (Map<String, Object>) entry.getValue();
|
|
|
|
|
record.put(entry.getKey(), Util.null2String(dayItem.get("title")));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
result.add(record);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<WeaTableColumn> buildScheduleColumns(List<Map<String,Object>> columnInfo) {
|
|
|
|
|
List<WeaTableColumn> list = new ArrayList<>();
|
|
|
|
|
if (columnInfo != null && columnInfo.size() > 0) {
|
|
|
|
|
for (Map<String, Object> columnItem : columnInfo) {
|
|
|
|
|
list.add(new WeaTableColumn("150px", Util.null2String(columnItem.get("title")), Util.null2String(columnItem.get("dataIndex"))));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return list;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Map<String, Object> importSchedule(ImportParam param) {
|
|
|
|
|
|
|
|
|
|
if (StringUtils.isBlank(param.getImageId())) {
|
|
|
|
|
throw new AttendanceRunTimeException("导入文件id为空!");
|
|
|
|
|
}
|
|
|
|
|
int successCount = 0;
|
|
|
|
|
int errorCount = 0;
|
|
|
|
|
//查询formmodeid
|
|
|
|
|
Map<String,String> formModeIdMap = Utils.getFormmodeIdMap();
|
|
|
|
|
String formModeId = formModeIdMap.get("uf_pbjg");
|
|
|
|
|
// 获取所有人员信息
|
|
|
|
|
List<Map<String, Object>> employeeInfoList = getAllEmpInfo();
|
|
|
|
|
//获取班次名称对于班次信息的映射
|
|
|
|
|
Map<String,Object> shiftMapWithMc = getShiftInfoToMc();
|
|
|
|
|
// 待入库数据
|
|
|
|
|
List<Map<String, Object>> toImportScheduleInfos = new ArrayList<>();
|
|
|
|
|
// 待处理数据
|
|
|
|
|
InputStream fileInputStream = null;
|
|
|
|
|
// 待处理数据关联的人员ids
|
|
|
|
|
List<String> empIds = new ArrayList<>();
|
|
|
|
|
try {
|
|
|
|
|
fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(param.getImageId()));
|
|
|
|
|
if (fileInputStream == null) {
|
|
|
|
|
throw new AttendanceRunTimeException("excel文件解析失败!");
|
|
|
|
|
}
|
|
|
|
|
Sheet sheet = ExcelSupport.parseFile(fileInputStream, 0, EXCEL_TYPE_XLSX);
|
|
|
|
|
//标题
|
|
|
|
|
List<String> titles = ExcelSupport.getSheetHeader(sheet, 0);
|
|
|
|
|
String title = titles.get(0);
|
|
|
|
|
log.info("处理前年月信息:{}",title);
|
|
|
|
|
//年月格式的转换处理
|
|
|
|
|
if (StrUtil.isNotBlank(title) && title.length() > 7) {
|
|
|
|
|
title = title.substring(0, 7);
|
|
|
|
|
log.info("处理后年月信息:{}",title);
|
|
|
|
|
}
|
|
|
|
|
if (StrUtil.isNotBlank(title) && !DateUtil.checkYearMonth(title.replace("/", "-"))) {
|
|
|
|
|
throw new AttendanceRunTimeException("excel首行'年月'时间格式错误,正确格式为yyyy-mm或者yyyy-mm-dd或者yyyy/mm或者yyyy/mm/dd");
|
|
|
|
|
}
|
|
|
|
|
int monthDays = DateUtil.getDays(title, Calendar.DAY_OF_MONTH);
|
|
|
|
|
// 表头
|
|
|
|
|
List<String> headers = ExcelSupport.getSheetHeader(sheet, 1);
|
|
|
|
|
log.info("headers数据:{}", headers);
|
|
|
|
|
// 错误sheet数据
|
|
|
|
|
List<Map<String, Object>> errorData = new LinkedList<>();
|
|
|
|
|
// 错误提示
|
|
|
|
|
List<Map<String, String>> excelComments = new LinkedList<>();
|
|
|
|
|
// 处理数值
|
|
|
|
|
List<Map<String, Object>> data = ExcelParseHelper.parse2Map(sheet, 2, 1);
|
|
|
|
|
log.info("excel导入数据:[{}]", data);
|
|
|
|
|
//单行记录
|
|
|
|
|
Map<String, Object> map;
|
|
|
|
|
for (int i = 0; i < data.size(); i++) {
|
|
|
|
|
map = data.get(i);
|
|
|
|
|
boolean isError = false;
|
|
|
|
|
Map<String, String> singleCheck = new HashMap<>();
|
|
|
|
|
for (int j = 0; j < headers.size(); j++) {
|
|
|
|
|
//组装单条数据基础数据
|
|
|
|
|
String key = headers.get(j);
|
|
|
|
|
if (key == null) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
singleCheck.put(key, Optional.ofNullable(map.get(key)).orElse("").toString());
|
|
|
|
|
}
|
|
|
|
|
log.info(i + 3 + "-singleCheck:[{}]", singleCheck);
|
|
|
|
|
isError = singleScheduleLineCheck(singleCheck, title, monthDays, toImportScheduleInfos, employeeInfoList, shiftMapWithMc, excelComments, i + 3, formModeId, empIds);
|
|
|
|
|
if (isError) {
|
|
|
|
|
errorCount += 1;
|
|
|
|
|
// 添加错误数据
|
|
|
|
|
errorData.add(map);
|
|
|
|
|
} else {
|
|
|
|
|
successCount += 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// 数据入库处理
|
|
|
|
|
handleScheduleImportData(toImportScheduleInfos, empIds, title, monthDays);
|
|
|
|
|
|
|
|
|
|
Map<String, Object> apidatas = new HashMap<String, Object>();
|
|
|
|
|
apidatas.put("successCount", successCount);
|
|
|
|
|
apidatas.put("errorCount", errorCount);
|
|
|
|
|
apidatas.put("errorData", excelComments);
|
|
|
|
|
return apidatas;
|
|
|
|
|
} finally {
|
|
|
|
|
IOUtils.closeQuietly(fileInputStream);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Map<String, Object>> getAllEmpInfo() {
|
|
|
|
|
String sql = "select a.id, a.lastname, a.workcode, d.departmentname, s.subcompanyname " +
|
|
|
|
|
"from hrmresource a left join hrmdepartment d on d.id = a.departmentid " +
|
|
|
|
|
"left join hrmsubcompany s on s.id = a.subcompanyid1 ";
|
|
|
|
|
List<Map<String, Object>> empInfo = DbTools.getSqlToList(sql);
|
|
|
|
|
return empInfo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private Map<String, Object> getShiftInfoToMc() {
|
|
|
|
|
String sql = "select id, mc, sfxx from uf_jcl_kq_bcxx ";
|
|
|
|
|
List<Map<String, Object>> shiftInfo = DbTools.getSqlToList(sql);
|
|
|
|
|
Map<String,Object> shiftMapWithMc = shiftInfo.stream().collect(Collectors.toMap(e->e.get("mc").toString(), e->e));
|
|
|
|
|
return shiftMapWithMc;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean singleScheduleLineCheck(Map<String, String> singleCheck, String yearMonth, int monthDays,
|
|
|
|
|
List<Map<String, Object>> toImportScheduleInfos, List<Map<String, Object>> employeeByIds,
|
|
|
|
|
Map<String,Object> shiftMapWithMc, List<Map<String, String>> excelComments, int index, String formModeId, List<String> empIds) {
|
|
|
|
|
boolean isError = false;
|
|
|
|
|
String workCode = Util.null2String(singleCheck.get("编号"));
|
|
|
|
|
String lastName = Util.null2String(singleCheck.get("姓名"));
|
|
|
|
|
String subCompany = Util.null2String(singleCheck.get("分部"));
|
|
|
|
|
String department = Util.null2String(singleCheck.get("部门"));
|
|
|
|
|
String rowIndex = "第" + index + "行";
|
|
|
|
|
//校验该行数据中员工信息是否唯一存在
|
|
|
|
|
List<Map<String, Object>> targetEmpInfo = matchImportEmp(employeeByIds, lastName, subCompany, department, workCode);
|
|
|
|
|
if (CollectionUtils.isEmpty(targetEmpInfo)) {
|
|
|
|
|
Map<String, String> errorMessageMap = new HashMap<>();
|
|
|
|
|
errorMessageMap.put("message", rowIndex + "员工信息不存在!");
|
|
|
|
|
excelComments.add(errorMessageMap);
|
|
|
|
|
isError = true;
|
|
|
|
|
return isError;
|
|
|
|
|
} else if (targetEmpInfo.size() > 1) {
|
|
|
|
|
Map<String, String> errorMessageMap = new HashMap<>();
|
|
|
|
|
errorMessageMap.put("message", rowIndex + "员工信息存在多个匹配的员工!");
|
|
|
|
|
excelComments.add(errorMessageMap);
|
|
|
|
|
isError = true;
|
|
|
|
|
return isError;
|
|
|
|
|
}
|
|
|
|
|
String employeeId = Util.null2String(targetEmpInfo.get(0).get("id"));
|
|
|
|
|
if (empIds.size() > 0 && empIds.contains(employeeId)) {
|
|
|
|
|
Map<String, String> errorMessageMap = new HashMap<>();
|
|
|
|
|
errorMessageMap.put("message", rowIndex + "表格中同一员工不可存在多组排班数据!");
|
|
|
|
|
excelComments.add(errorMessageMap);
|
|
|
|
|
isError = true;
|
|
|
|
|
return isError;
|
|
|
|
|
}
|
|
|
|
|
//获取目标人员目标月日期类型对日期的映射
|
|
|
|
|
List<Map<String,Object>> rqlxInfo = CommonUtil.getYearCalendarList(employeeId, yearMonth.substring(0, 4));
|
|
|
|
|
Map<String, String> rqlxInfoWithRq = rqlxInfo.stream().filter(f -> f.get("rq").toString().contains(yearMonth)).collect(Collectors.toMap(e->e.get("rq").toString(), e->e.get("rqlx").toString()));
|
|
|
|
|
//暂存本次调用中的导入数据
|
|
|
|
|
List<Map<String, Object>> singleToImportScheduleInfos = new ArrayList<>();
|
|
|
|
|
//排班日期、班次名称
|
|
|
|
|
String scheduleDate = "";
|
|
|
|
|
String shiftName = "";
|
|
|
|
|
Map<String, Object> shiftInfo;
|
|
|
|
|
Map<String, Object> toImportItem;
|
|
|
|
|
for (int i = 1; i <= monthDays; i++) {
|
|
|
|
|
shiftName = Util.null2String(singleCheck.get(String.valueOf(i)));
|
|
|
|
|
scheduleDate = i < 10 ? yearMonth + "-0" + i : yearMonth + "-" + i;
|
|
|
|
|
//获取班次id
|
|
|
|
|
shiftInfo = (Map<String, Object>) shiftMapWithMc.get(shiftName);
|
|
|
|
|
if (!"".equals(shiftName) && shiftInfo == null) {
|
|
|
|
|
Map<String, String> errorMessageMap = new HashMap<>();
|
|
|
|
|
errorMessageMap.put("message", rowIndex + "班次名称-" + shiftName + ", 找不到对应的班次信息,检查是否编辑有误!");
|
|
|
|
|
excelComments.add(errorMessageMap);
|
|
|
|
|
isError = true;
|
|
|
|
|
}
|
|
|
|
|
if (!isError) {
|
|
|
|
|
toImportItem = new HashMap<>();
|
|
|
|
|
if ("".equals(shiftName)) {
|
|
|
|
|
//设置排班数据
|
|
|
|
|
toImportItem.put("sfxx", "1");
|
|
|
|
|
toImportItem.put("bcxx", null);
|
|
|
|
|
} else {
|
|
|
|
|
//设置排班数据
|
|
|
|
|
toImportItem.put("sfxx", shiftInfo.get("sfxx").toString());
|
|
|
|
|
toImportItem.put("bcxx", shiftInfo.get("id").toString());
|
|
|
|
|
}
|
|
|
|
|
toImportItem.put("formmodeid",formModeId);
|
|
|
|
|
toImportItem.put("modeuuid", UUID.randomUUID().toString());
|
|
|
|
|
toImportItem.put("modedatacreater","1");
|
|
|
|
|
toImportItem.put("modedatacreatertype","0");
|
|
|
|
|
toImportItem.put("modedatacreatedate", DateUtil.getCurrentTime().split(" ")[0]);
|
|
|
|
|
toImportItem.put("modedatacreatetime",DateUtil.getCurrentTime().split(" ")[1]);
|
|
|
|
|
|
|
|
|
|
// toImportItem.put("szjg", );
|
|
|
|
|
toImportItem.put("pbtj", SchedulingApproachEnum.IMPORT.getKey());
|
|
|
|
|
toImportItem.put("dxlx", ApplicableOrganizationEnum.PERSONNEL.getKey());
|
|
|
|
|
toImportItem.put("bcrq", scheduleDate);
|
|
|
|
|
toImportItem.put("rqlx", rqlxInfoWithRq.get(scheduleDate));
|
|
|
|
|
toImportItem.put("sfdkpp", "0");
|
|
|
|
|
toImportItem.put("pbrq", DateUtil.getCurrentDate());
|
|
|
|
|
toImportItem.put("pbsj", DateUtil.getCurrentTime("yyyy-MM-dd HH:mm").split(" ")[1]);
|
|
|
|
|
toImportItem.put("pbdxry", employeeId);
|
|
|
|
|
|
|
|
|
|
singleToImportScheduleInfos.add(toImportItem);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!isError) {
|
|
|
|
|
empIds.add(employeeId);
|
|
|
|
|
toImportScheduleInfos.addAll(singleToImportScheduleInfos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return isError;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private List<Map<String, Object>> matchImportEmp(List<Map<String, Object>> employeeByIds, String lastName, String subCompany, String department, String workCode) {
|
|
|
|
|
employeeByIds = employeeByIds.stream().filter(e ->
|
|
|
|
|
(StrUtil.isBlank(workCode) || Objects.equals(e.get("workcode").toString(), workCode))
|
|
|
|
|
&& (StrUtil.isBlank(lastName) || Objects.equals(e.get("lastname").toString(), lastName))
|
|
|
|
|
&& (StringUtils.isBlank(department) || Objects.equals(e.get("departmentname"), department))
|
|
|
|
|
&& (StringUtils.isBlank(subCompany) || Objects.equals(e.get("subcompanyname"), subCompany)))
|
|
|
|
|
.collect(Collectors.toList());
|
|
|
|
|
return employeeByIds;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void handleScheduleImportData(List<Map<String, Object>> toImportScheduleInfos, List<String> empIds, String yearMonth, int monthDays) {
|
|
|
|
|
if (toImportScheduleInfos.size() > 0 && empIds.size() > 0) {
|
|
|
|
|
//获取日期集合
|
|
|
|
|
List<String> dateList = new ArrayList<>();
|
|
|
|
|
for (int i = 1; i <= monthDays; i++) {
|
|
|
|
|
dateList.add(i < 10 ? yearMonth + "-0" + i : yearMonth + "-" + i);
|
|
|
|
|
}
|
|
|
|
|
//删除老数据
|
|
|
|
|
String delSql = " delete from uf_pbjg where dxlx = " + ApplicableOrganizationEnum.PERSONNEL.getKey()
|
|
|
|
|
+ " and bcrq in ('"+String.join("','",dateList)+"') and pbdxry in (" + String.join(",",empIds) + ")";
|
|
|
|
|
boolean delSign = DbTools.update(delSql);
|
|
|
|
|
//插入数据
|
|
|
|
|
boolean insertSign = CommonUtil.insertBatch(toImportScheduleInfos, "uf_pbjg");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|