From a55b20234fa600031facd0311220d90268555acb Mon Sep 17 00:00:00 2001 From: Harryxzy <822365880@qq.com> Date: Tue, 16 Sep 2025 17:12:58 +0800 Subject: [PATCH] =?UTF-8?q?=E9=A2=86=E6=82=A6=E6=8A=A5=E8=A1=A82=E3=80=813?= =?UTF-8?q?=E3=80=814=EF=BC=9A=E8=96=AA=E9=85=AC=E6=A1=A3=E6=A1=88?= =?UTF-8?q?=E8=81=8C=E7=BA=A7=E7=BB=9F=E8=AE=A1=E6=8A=A5=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ly/param/LySalaryReportQueryParam.java | 3 + .../entity/salaryacct/dto/LyTxdaDTO.java | 44 ++ .../salary/entity/salaryacct/po/LyTxdaPO.java | 36 ++ .../salary/service/LySalaryReportService.java | 8 + .../impl/LySalaryReportServiceImpl.java | 487 ++++++++++++++++++ .../engine/salary/web/LySalaryController.java | 101 ++++ .../salary/wrapper/LySalaryWrapper.java | 17 + 7 files changed, 696 insertions(+) create mode 100644 src/com/engine/salary/entity/salaryacct/dto/LyTxdaDTO.java create mode 100644 src/com/engine/salary/entity/salaryacct/po/LyTxdaPO.java diff --git a/src/com/engine/salary/entity/ly/param/LySalaryReportQueryParam.java b/src/com/engine/salary/entity/ly/param/LySalaryReportQueryParam.java index edb4bf6cc..25a5d6242 100644 --- a/src/com/engine/salary/entity/ly/param/LySalaryReportQueryParam.java +++ b/src/com/engine/salary/entity/ly/param/LySalaryReportQueryParam.java @@ -54,4 +54,7 @@ public class LySalaryReportQueryParam extends BaseQueryParam { private boolean export; private List taxAgentIds; + + private String startDate; + private String endDate; } diff --git a/src/com/engine/salary/entity/salaryacct/dto/LyTxdaDTO.java b/src/com/engine/salary/entity/salaryacct/dto/LyTxdaDTO.java new file mode 100644 index 000000000..cef3de558 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/dto/LyTxdaDTO.java @@ -0,0 +1,44 @@ +package com.engine.salary.entity.salaryacct.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author Harryxzy + * @ClassName LyDazjtjReportDTO + * @date 2025/09/15 9:12 + * @description 领悦调薪档案 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LyTxdaDTO { + + private String lypq; + private Integer lypqShowOrder; + private String lyxm; + private Integer lyxmShowOrder; + + + // 职级 + private String zj; + + // 职务角色 + private Long zwjsId; + private String zwjs; + + // 调薪人次 + private Integer txrc; + + // 占周期内调薪总人数比例 + private String zzqntxzrsbl; + + // 年度调薪总额 + private String ndtxze; + + // 占周期内调薪总额比例 + private String zzqntxzebl; +} diff --git a/src/com/engine/salary/entity/salaryacct/po/LyTxdaPO.java b/src/com/engine/salary/entity/salaryacct/po/LyTxdaPO.java new file mode 100644 index 000000000..d7f34fe15 --- /dev/null +++ b/src/com/engine/salary/entity/salaryacct/po/LyTxdaPO.java @@ -0,0 +1,36 @@ +package com.engine.salary.entity.salaryacct.po; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.math.BigDecimal; +import java.util.Date; + +/** + * @author Harryxzy + * @ClassName LyDazjtjReportDTO + * @date 2025/09/15 9:12 + * @description 领悦调薪档案 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class LyTxdaPO { + + private Long yg; + private BigDecimal ndyqsrze; + private Date txrq; + + private Integer lyzj; + + private String lypq; + + private String lyxm; + + private String lyzwjs; + + private String dxyy; +} diff --git a/src/com/engine/salary/service/LySalaryReportService.java b/src/com/engine/salary/service/LySalaryReportService.java index bff227dd5..418269bc2 100644 --- a/src/com/engine/salary/service/LySalaryReportService.java +++ b/src/com/engine/salary/service/LySalaryReportService.java @@ -162,4 +162,12 @@ public interface LySalaryReportService { Map listLyXcdazwjstjReport(); XSSFWorkbook exportXcdazwjstjReport(); + + Map listLyTxdazjtjReport(LySalaryReportQueryParam param); + + XSSFWorkbook exportTxdazjtjReport(LySalaryReportQueryParam param); + + Map listLyTxdazwjstjReport(LySalaryReportQueryParam param); + + XSSFWorkbook exportTxdazwjstjReport(LySalaryReportQueryParam param); } diff --git a/src/com/engine/salary/service/impl/LySalaryReportServiceImpl.java b/src/com/engine/salary/service/impl/LySalaryReportServiceImpl.java index 588a7b29e..6821d1616 100644 --- a/src/com/engine/salary/service/impl/LySalaryReportServiceImpl.java +++ b/src/com/engine/salary/service/impl/LySalaryReportServiceImpl.java @@ -18,6 +18,8 @@ import com.engine.salary.entity.ly.po.UfSbInfo; import com.engine.salary.entity.salaryacct.bo.SalaryAcctFormulaBO; import com.engine.salary.entity.salaryacct.bo.SalaryAcctResultBO; import com.engine.salary.entity.salaryacct.dto.LyDazjtjReportDTO; +import com.engine.salary.entity.salaryacct.dto.LyTxdaDTO; +import com.engine.salary.entity.salaryacct.po.LyTxdaPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctEmployeePO; import com.engine.salary.entity.salaryacct.po.SalaryAcctRecordPO; import com.engine.salary.entity.salaryacct.po.SalaryAcctResultPO; @@ -57,6 +59,7 @@ import weaver.general.TimeUtil; import weaver.hrm.User; import weaver.wechat.util.Utils; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.math.RoundingMode; import java.text.SimpleDateFormat; @@ -3291,4 +3294,488 @@ public class LySalaryReportServiceImpl extends Service implements LySalaryReport //获取excel return ExcelUtilPlus.genWorkbookV2(rows, "薪酬档案职级统计报表", false); } + + @Override + public Map listLyTxdazjtjReport(LySalaryReportQueryParam param) { + Date startDate = SalaryDateUtil.dateStrToLocalDate(param.getStartDate()); + Date endDate = SalaryDateUtil.dateStrToLocalDate(param.getEndDate()); + if (startDate == null || endDate == null) { + throw new SalaryRunTimeException("开始或结束日期不存在或格式错误,正确格式yyyy-MM-dd"); + } + BaseBean baseBean = new BaseBean(); + RecordSet rs = new RecordSet(); + // 查询所有发薪的调薪档案 + String excludeTxyy = baseBean.getPropValue("lySalaryReport", "txdatj_exclued_txyy"); + try { + excludeTxyy = new String(excludeTxyy.getBytes("ISO-8859-1"), "utf-8"); + } catch (UnsupportedEncodingException e) { + } + List excluedeTxyy = Arrays.stream(excludeTxyy.split(",")).collect(Collectors.toList()); + String sql = "select yg,ndyqsrze,txrq,dxyy from uf_txda where txrq >=? and txrq<=? "; + rs.executeQuery(sql, Arrays.asList(startDate, endDate)); + List lyTxdaList = new ArrayList<>(); + while (rs.next()) { + Date txrqDate = SalaryDateUtil.dateStrToLocalDate(rs.getString("txrq")); + if (txrqDate != null) { + lyTxdaList.add(LyTxdaPO.builder() + .yg(NumberUtils.isCreatable(rs.getString("yg")) ? Long.valueOf(rs.getString("yg")) : -1L) + .ndyqsrze(SalaryEntityUtil.string2BigDecimalDefault0(rs.getString("ndyqsrze"))) + .txrq(txrqDate) + .dxyy(rs.getString("dxyy")) + .build()); + } + } + + String gwzjField = baseBean.getPropValue("lySalaryReport", "gwzj_field_id"); + String pqField = baseBean.getPropValue("lySalaryReport", "pq_field_id"); + // 查询职等职级信息 + rs.execute("select id,gwzj from uf_zdzj_new "); + Map zdzjInfoMap = new HashMap<>(); + while (rs.next()) { + String[] split = StringUtils.split(rs.getString("gwzj"), "-"); + if (split != null && split.length > 0) { + String gwzj = split[0]; + zdzjInfoMap.put(rs.getString("id"), SalaryEntityUtil.string2Integer(gwzj)); + } + } + // 查询员工对应的职级、片区信息 + List employeeIds = lyTxdaList.stream().map(txdaPO -> txdaPO.getYg()).distinct().collect(Collectors.toList()); + List> partition = Lists.partition(employeeIds, 800); + Map empZjMap = new HashMap<>(); + Map empPqMap = new HashMap<>(); + partition.forEach(part -> { + rs.execute("select id,"+gwzjField+","+pqField+" from cus_fielddata where scope='HrmCustomFieldByInfoType' and scopeid=-1 and id in (" + StringUtils.join(part, ",") + ")"); + while (rs.next()) { + String gwzj = Utils.null2String(rs.getString(gwzjField)); + if(StringUtils.isNotBlank(gwzj)) { + if (gwzj.contains("_")) { + String[] split = gwzj.split("_"); + gwzj = split != null && split.length > 0 ? split[split.length - 1] : ""; + } + empZjMap.put(Long.valueOf(rs.getInt("id")), zdzjInfoMap.get(gwzj)); + } + empPqMap.put(Long.valueOf(rs.getInt("id")), Utils.null2String(rs.getString(pqField))); + } + }); + // 获取人员分部信息 + Map employeeMap = SalaryEntityUtil.convert2Map(getSalaryEmployeeService(user).listByIds(employeeIds), DataCollectionEmployee::getEmployeeId); + // 获取所有分部信息 + Map subCompanyInfoMap = SalaryEntityUtil.convert2Map(getSalaryEmployeeService(user).listAllSubCompanyInfoList(), SubCompanyInfo::getId); + + // 所有档案赋值职级 + lyTxdaList.stream().forEach(txdaPO -> { + int zj = empZjMap.get(txdaPO.getYg()) == null ? -1 : empZjMap.get(txdaPO.getYg()); + txdaPO.setLyzj(zj); + txdaPO.setLypq(Utils.null2String(empPqMap.get(txdaPO.getYg()))); + txdaPO.setLyxm(Utils.null2String(employeeMap.get(txdaPO.getYg()) == null ? "" : employeeMap.get(txdaPO.getYg()).getSubcompanyid())); + }); + + // 调薪档案根据职级分组 + List reportDTOS = new ArrayList(); + Map> archiveGroupByZj = SalaryEntityUtil.group2Map(lyTxdaList, po -> po.getLyzj() + "_split" + po.getLypq() + "_split" + po.getLyxm()); + BigDecimal[] allNdtxzeSumVal = new BigDecimal[]{new BigDecimal("0")}; + int zrc =0; + for (Map.Entry> entry : archiveGroupByZj.entrySet()) { + Map zjSumValueMap = new HashMap<>(); + String[] split = entry.getKey().split("_split"); + Long zj = split != null && split.length > 0 && NumberUtils.isCreatable(split[0]) ? Long.valueOf(split[0]) : -1; + String lypq = split != null && split.length > 1 ? split[1] : ""; + String lyxm = split != null && split.length > 2 ? split[2] : ""; + Map> groupByYg = SalaryEntityUtil.group2Map(entry.getValue(), LyTxdaPO::getYg); + BigDecimal zjTxze = new BigDecimal("0"); + for (Map.Entry> ygEntry : groupByYg.entrySet()) { + // 计算每个人的调薪总额 + List sortedTxDTO = ygEntry.getValue().stream().sorted((o1, o2) -> o2.getTxrq().compareTo(o1.getTxrq())).collect(Collectors.toList()); + BigDecimal ndyqsrze = sortedTxDTO.get(0).getNdyqsrze() == null ? new BigDecimal("0") : sortedTxDTO.get(0).getNdyqsrze(); + BigDecimal ndyqsrzeLast = sortedTxDTO.get(sortedTxDTO.size()-1).getNdyqsrze() == null ? new BigDecimal("0") : sortedTxDTO.get(sortedTxDTO.size()-1).getNdyqsrze(); + BigDecimal txValue = ndyqsrze.subtract(ndyqsrzeLast); + zjTxze = zjTxze.add(txValue); + allNdtxzeSumVal[0] = allNdtxzeSumVal[0].add(txValue); + } + + // 封装 + SubCompanyInfo lypqInfo = subCompanyInfoMap.get(SalaryEntityUtil.string2Long(lypq)); + SubCompanyInfo lyxmInfo = subCompanyInfoMap.get(SalaryEntityUtil.string2Long(lyxm)); + Long txCount = entry.getValue().stream().filter(PO -> !excluedeTxyy.contains(PO.getDxyy())).count(); + reportDTOS.add(LyTxdaDTO.builder() + .lypq(lypqInfo == null ? "" : Utils.null2String(lypqInfo.getName())) + .lypqShowOrder(lypqInfo == null || lypqInfo.getShoworder() == null ? -1 :lypqInfo.getShoworder()) + .lyxm(lyxmInfo == null ? "" : Utils.null2String(lyxmInfo.getName())) + .lyxmShowOrder(lyxmInfo == null || lyxmInfo.getShoworder() == null? -1 : lyxmInfo.getShoworder()) + .zj(zj == null ? "-1" : zj.toString()) + .txrc(txCount.intValue()) + .ndtxze(zjTxze.toPlainString()) + .build()); + zrc = zrc + txCount.intValue(); + } + // 计算占周期内调薪总人数比例 + BigDecimal txZrc = BigDecimal.valueOf(zrc); + reportDTOS.stream().forEach(dto -> { + if (dto.getTxrc() != null) { + BigDecimal txrc = BigDecimal.valueOf(dto.getTxrc()); + dto.setZzqntxzrsbl(txrc.divide(txZrc, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString()); + } + if (NumberUtils.isCreatable(dto.getNdtxze())) { + BigDecimal ndtxze = new BigDecimal(dto.getNdtxze()); + dto.setZzqntxzebl(ndtxze.divide(allNdtxzeSumVal[0], 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString()); + } + }); + + // reportDTOS根据lypq和lyxm和zj排序 + reportDTOS = reportDTOS.stream().sorted(new Comparator() { + @Override + public int compare(LyTxdaDTO o1, LyTxdaDTO o2) { + Integer o1zj = NumberUtils.isCreatable(o1.getZj()) ? Integer.valueOf(o1.getZj()) : -1; + Integer o2zj = NumberUtils.isCreatable(o2.getZj()) ? Integer.valueOf(o2.getZj()) : -1; + if (o1zj.equals(o2zj)) { + Integer o1pq = o1.getLypqShowOrder() == null ? -1 : o1.getLypqShowOrder(); + Integer o2pq = o2.getLypqShowOrder() == null ? -1 : o2.getLypqShowOrder(); + if (o1pq.equals(o2pq)) { + Integer o1xm = o1.getLyxmShowOrder() == null ? -1 : o1.getLyxmShowOrder(); + Integer o2xm = o2.getLyxmShowOrder() == null ? -1 : o2.getLyxmShowOrder(); + return o1xm.compareTo(o2xm); + } else { + return o1pq.compareTo(o2pq); + } + } + return o1zj.compareTo(o2zj); + } + }).collect(Collectors.toList()); + + // 计算饼状图(根据职级汇总) + LinkedHashMap chartsMapA = new LinkedHashMap<>(); + LinkedHashMap chartsMapB = new LinkedHashMap<>(); + Map> groupByzj = SalaryEntityUtil.group2Map(reportDTOS, LyTxdaDTO::getZj); + LinkedHashMap> sortedGroupByzj = groupByzj.entrySet().stream() + .sorted(new Comparator>>() { + @Override + public int compare(Map.Entry> o1, Map.Entry> o2) { + Long key1 = NumberUtils.isCreatable(o1.getKey()) ? Long.valueOf(o1.getKey()) : -1L; + Long key2 = NumberUtils.isCreatable(o2.getKey()) ? Long.valueOf(o2.getKey()) : -1L; + return key1.compareTo(key2); + } + }) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, + LinkedHashMap::new)); + for ( Map.Entry> entry : sortedGroupByzj.entrySet()) { + String zj = entry.getKey(); + BigDecimal sumVal = entry.getValue().stream().map(LyTxdaDTO::getNdtxze).filter(NumberUtils::isCreatable).map(BigDecimal::new) + .reduce(new BigDecimal("0"), BigDecimal::add); + String zb = sumVal.divide(allNdtxzeSumVal[0], 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString(); + chartsMapB.put(zj, zb); + + BigDecimal txrcSumVal = entry.getValue().stream().map(LyTxdaDTO::getTxrc).filter(rc -> rc != null).map(BigDecimal::new) + .reduce(new BigDecimal("0"), BigDecimal::add); + String txrc = txrcSumVal.divide(txZrc, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString(); + chartsMapA.put(zj, txrc); + } + + + // 构建表头 + List columns = new ArrayList<>(); + columns.add(new WeaTableColumn("150px", "片区", "lypq")); + columns.add(new WeaTableColumn("150px", "项目", "lyxm")); + columns.add(new WeaTableColumn("150px", "职级", "zj")); + columns.add(new WeaTableColumn("150px", "调薪人次", "txrc")); + columns.add(new WeaTableColumn("150px", "占周期内调薪总人数比例", "zzqntxzrsbl")); + columns.add(new WeaTableColumn("150px", "年度调薪总额", "ndtxze")); + columns.add(new WeaTableColumn("150px", "占周期内调薪总额比例", "zzqntxzebl")); + + Map map = new HashMap<>(); + // if (param.isExport()) { + // // 合计或导出需要合计行 + // Map sumResultMap = new HashMap<>(); + // sumResultMap.put(gsmcItemId.toString(), "合计"); + // for (SalaryItemPO salaryItem : salaryItemList) { + // if (salaryItem.getDataType().equals(SalaryDataTypeEnum.NUMBER.getValue())) { + // BigDecimal sumValue = acctResultMap.stream() + // .map(m -> m.get(salaryItem.getId().toString())) + // .filter(value -> value != null && NumberUtils.isCreatable(value.toString())) + // .map(e -> SalaryEntityUtil.empty2Zero(e.toString())) + // .reduce(BigDecimal.ZERO, BigDecimal::add); + // sumResultMap.put(salaryItem.getId().toString(),sumValue); + // } + // } + // map.put("sumRow", sumResultMap); + // } + map.put("columns", columns); + map.put("data", reportDTOS); + map.put("chartsDataA", chartsMapA); + map.put("chartsDataB", chartsMapB); + return map; + } + + @Override + public XSSFWorkbook exportTxdazjtjReport(LySalaryReportQueryParam parm) { + Map resultMap = listLyTxdazjtjReport(parm); + List dataList = (List) resultMap.get("data"); + List columns = (List) resultMap.get("columns"); + // Map sum = (Map) resultMap.get("sum"); + // dataList.add(sum); + + List headerList = new ArrayList<>(columns.stream().map(WeaTableColumn::getText).collect(Collectors.toList())); + List> rows = new ArrayList<>(); + rows.add(headerList); + + for (LyTxdaDTO dto : dataList) { + List row = Lists.newArrayList(); + Map valueMap = BeanUtil.beanToMap(dto); + for (WeaTableColumn column : columns) { + row.add(Utils.null2String(valueMap.get(column.getColumn()))); + } + rows.add(row); + } + + //获取excel + return ExcelUtilPlus.genWorkbookV2(rows, "调薪档案职级统计报表", false); + } + + @Override + public Map listLyTxdazwjstjReport(LySalaryReportQueryParam param) { + Date startDate = SalaryDateUtil.dateStrToLocalDate(param.getStartDate()); + Date endDate = SalaryDateUtil.dateStrToLocalDate(param.getEndDate()); + if (startDate == null || endDate == null) { + throw new SalaryRunTimeException("开始或结束日期不存在或格式错误,正确格式yyyy-MM-dd"); + } + BaseBean baseBean = new BaseBean(); + RecordSet rs = new RecordSet(); + // 查询所有发薪的调薪档案 + String excludeTxyy = baseBean.getPropValue("lySalaryReport", "txdatj_exclued_txyy"); + try { + excludeTxyy = new String(excludeTxyy.getBytes("ISO-8859-1"), "utf-8"); + } catch (UnsupportedEncodingException e) { + } + List excluedeTxyy = Arrays.stream(excludeTxyy.split(",")).collect(Collectors.toList()); + String sql = "select yg,ndyqsrze,txrq,dxyy from uf_txda where txrq >=? and txrq<=? "; + rs.executeQuery(sql, Arrays.asList(startDate, endDate)); + List lyTxdaList = new ArrayList<>(); + while (rs.next()) { + Date txrqDate = SalaryDateUtil.dateStrToLocalDate(rs.getString("txrq")); + if (txrqDate != null) { + lyTxdaList.add(LyTxdaPO.builder() + .yg(NumberUtils.isCreatable(rs.getString("yg")) ? Long.valueOf(rs.getString("yg")) : -1L) + .ndyqsrze(SalaryEntityUtil.string2BigDecimalDefault0(rs.getString("ndyqsrze"))) + .txrq(txrqDate) + .dxyy(rs.getString("dxyy")) + .build()); + } + } + + String gwzjField = baseBean.getPropValue("lySalaryReport", "gwzj_field_id"); + String pqField = baseBean.getPropValue("lySalaryReport", "pq_field_id"); + String zwjsField = baseBean.getPropValue("lySalaryReport", "zwjs_field_id"); + // 查询职等职级信息 + rs.execute("select id,gwzj from uf_zdzj_new "); + Map zdzjInfoMap = new HashMap<>(); + while (rs.next()) { + String[] split = StringUtils.split(rs.getString("gwzj"), "-"); + if (split != null && split.length > 0) { + String gwzj = split[0]; + zdzjInfoMap.put(rs.getString("id"), SalaryEntityUtil.string2Integer(gwzj)); + } + } + // 查询员工对应的职级、片区信息 + List employeeIds = lyTxdaList.stream().map(txdaPO -> txdaPO.getYg()).distinct().collect(Collectors.toList()); + List> partition = Lists.partition(employeeIds, 800); + Map empZjMap = new HashMap<>(); + Map empPqMap = new HashMap<>(); + partition.forEach(part -> { + rs.execute("select id,"+gwzjField+","+pqField+" from cus_fielddata where scope='HrmCustomFieldByInfoType' and scopeid=-1 and id in (" + StringUtils.join(part, ",") + ")"); + while (rs.next()) { + String gwzj = Utils.null2String(rs.getString(gwzjField)); + if(StringUtils.isNotBlank(gwzj)) { + if (gwzj.contains("_")) { + String[] split = gwzj.split("_"); + gwzj = split != null && split.length > 0 ? split[split.length - 1] : ""; + } + empZjMap.put(Long.valueOf(rs.getInt("id")), zdzjInfoMap.get(gwzj)); + } + empPqMap.put(Long.valueOf(rs.getInt("id")), Utils.null2String(rs.getString(pqField))); + } + }); + + // 查询员工对应的职务角色信息 + Map empZwjsMap = new HashMap<>(); + partition.forEach(part -> { + rs.execute("select id,"+zwjsField+" from cus_fielddata where scope='HrmCustomFieldByInfoType' and scopeid=3 and id in (" + StringUtils.join(part, ",") + ")"); + while (rs.next()) { + empZwjsMap.put(Long.valueOf(rs.getInt("id")), Utils.null2String(rs.getString(zwjsField))); + } + }); + + + // 获取人员分部信息 + Map employeeMap = SalaryEntityUtil.convert2Map(getSalaryEmployeeService(user).listByIds(employeeIds), DataCollectionEmployee::getEmployeeId); + // 获取所有分部信息 + Map subCompanyInfoMap = SalaryEntityUtil.convert2Map(getSalaryEmployeeService(user).listAllSubCompanyInfoList(), SubCompanyInfo::getId); + // 获取所有职务角色数据 + rs.execute("select id,mc from uf_zwjs"); + Map zwjsMap = new HashMap<>(); + while (rs.next()) { + zwjsMap.put(rs.getString("id"), rs.getString("mc")); + } + + // 所有档案赋值职级 + lyTxdaList.stream().forEach(txdaPO -> { + // int zj = empZjMap.get(txdaPO.getYg()) == null ? -1 : empZjMap.get(txdaPO.getYg()); + // txdaPO.setLyzj(zj); + txdaPO.setLypq(Utils.null2String(empPqMap.get(txdaPO.getYg()))); + txdaPO.setLyxm(Utils.null2String(employeeMap.get(txdaPO.getYg()) == null ? "" : employeeMap.get(txdaPO.getYg()).getSubcompanyid())); + String zwjs = empZwjsMap.get(txdaPO.getYg()) == null ? "" : empZwjsMap.get(txdaPO.getYg()); + txdaPO.setLyzwjs(zwjs); + }); + + // 调薪档案根据职级分组 + List reportDTOS = new ArrayList(); + Map> archiveGroupByZwjs = SalaryEntityUtil.group2Map(lyTxdaList, po -> po.getLyzwjs() + "_split" + po.getLypq() + "_split" + po.getLyxm()); + BigDecimal[] allNdtxzeSumVal = new BigDecimal[]{new BigDecimal("0")}; + int zrc =0; + for (Map.Entry> entry : archiveGroupByZwjs.entrySet()) { + Map zwjsSumValueMap = new HashMap<>(); + String[] split = entry.getKey().split("_split"); + String zwjs = split != null && split.length > 0 ? split[0] : ""; + String lypq = split != null && split.length > 1 ? split[1] : ""; + String lyxm = split != null && split.length > 2 ? split[2] : ""; + Map> groupByYg = SalaryEntityUtil.group2Map(entry.getValue(), LyTxdaPO::getYg); + BigDecimal zwjsTxze = new BigDecimal("0"); + for (Map.Entry> ygEntry : groupByYg.entrySet()) { + // 计算每个人的调薪总额 + List sortedTxDTO = ygEntry.getValue().stream().sorted((o1, o2) -> o2.getTxrq().compareTo(o1.getTxrq())).collect(Collectors.toList()); + BigDecimal ndyqsrze = sortedTxDTO.get(0).getNdyqsrze() == null ? new BigDecimal("0") : sortedTxDTO.get(0).getNdyqsrze(); + BigDecimal ndyqsrzeLast = sortedTxDTO.get(sortedTxDTO.size()-1).getNdyqsrze() == null ? new BigDecimal("0") : sortedTxDTO.get(sortedTxDTO.size()-1).getNdyqsrze(); + BigDecimal txValue = ndyqsrze.subtract(ndyqsrzeLast); + zwjsTxze = zwjsTxze.add(txValue); + allNdtxzeSumVal[0] = allNdtxzeSumVal[0].add(txValue); + } + + // 封装 + SubCompanyInfo lypqInfo = subCompanyInfoMap.get(SalaryEntityUtil.string2Long(lypq)); + SubCompanyInfo lyxmInfo = subCompanyInfoMap.get(SalaryEntityUtil.string2Long(lyxm)); + Long txCount = entry.getValue().stream().filter(PO -> !excluedeTxyy.contains(PO.getDxyy())).count(); + reportDTOS.add(LyTxdaDTO.builder() + .lypq(lypqInfo == null ? "" : Utils.null2String(lypqInfo.getName())) + .lypqShowOrder(lypqInfo == null || lypqInfo.getShoworder() == null ? -1 :lypqInfo.getShoworder()) + .lyxm(lyxmInfo == null ? "" : Utils.null2String(lyxmInfo.getName())) + .lyxmShowOrder(lyxmInfo == null || lyxmInfo.getShoworder() == null? -1 : lyxmInfo.getShoworder()) + .zwjs(zwjsMap.getOrDefault(zwjs, "")) + .zwjsId(NumberUtils.isCreatable(zwjs) ? Long.valueOf(zwjs) : -1) + .txrc(txCount.intValue()) + .ndtxze(zwjsTxze.toPlainString()) + .build()); + zrc = zrc + txCount.intValue(); + } + // 计算占周期内调薪总人数比例 + BigDecimal txZrc = BigDecimal.valueOf(zrc); + reportDTOS.stream().forEach(dto -> { + if (dto.getTxrc() != null) { + BigDecimal txrc = BigDecimal.valueOf(dto.getTxrc()); + dto.setZzqntxzrsbl(txrc.divide(txZrc, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString()); + } + if (NumberUtils.isCreatable(dto.getNdtxze())) { + BigDecimal ndtxze = new BigDecimal(dto.getNdtxze()); + dto.setZzqntxzebl(ndtxze.divide(allNdtxzeSumVal[0], 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString()); + } + }); + + // reportDTOS排序 + reportDTOS = reportDTOS.stream().sorted(new Comparator() { + @Override + public int compare(LyTxdaDTO o1, LyTxdaDTO o2) { + Long o1zj = o1.getZwjsId() != null ? o1.getZwjsId() : -1L; + Long o2zj = o2.getZwjsId() != null ? o2.getZwjsId() : -1L; + if (o1zj.equals(o2zj)) { + Integer o1pq = o1.getLypqShowOrder() == null ? -1 : o1.getLypqShowOrder(); + Integer o2pq = o2.getLypqShowOrder() == null ? -1 : o2.getLypqShowOrder(); + if (o1pq.equals(o2pq)) { + Integer o1xm = o1.getLyxmShowOrder() == null ? -1 : o1.getLyxmShowOrder(); + Integer o2xm = o2.getLyxmShowOrder() == null ? -1 : o2.getLyxmShowOrder(); + return o1xm.compareTo(o2xm); + } else { + return o1pq.compareTo(o2pq); + } + } + return o1zj.compareTo(o2zj); + } + }).collect(Collectors.toList()); + + // 计算饼状图(根据职级汇总) + LinkedHashMap chartsMapA = new LinkedHashMap<>(); + LinkedHashMap chartsMapB = new LinkedHashMap<>(); + Map> groupByzj = SalaryEntityUtil.group2Map(reportDTOS, LyTxdaDTO::getZwjsId); + LinkedHashMap> sortedGroupByzj = groupByzj.entrySet().stream() + .sorted(Map.Entry.comparingByKey()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (oldValue, newValue) -> oldValue, + LinkedHashMap::new)); + for ( Map.Entry> entry : sortedGroupByzj.entrySet()) { + Long zwjsId = entry.getKey(); + BigDecimal sumVal = entry.getValue().stream().map(LyTxdaDTO::getNdtxze).filter(NumberUtils::isCreatable).map(BigDecimal::new) + .reduce(new BigDecimal("0"), BigDecimal::add); + String zb = sumVal.divide(allNdtxzeSumVal[0], 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString(); + chartsMapB.put(zwjsMap.getOrDefault(Utils.null2String(zwjsId), ""), zb); + + BigDecimal txrcSumVal = entry.getValue().stream().map(LyTxdaDTO::getTxrc).filter(rc -> rc != null).map(BigDecimal::new) + .reduce(new BigDecimal("0"), BigDecimal::add); + String txrc = txrcSumVal.divide(txZrc, 4, RoundingMode.HALF_UP).multiply(new BigDecimal("100")).setScale(2, RoundingMode.HALF_UP).toPlainString(); + chartsMapA.put(zwjsMap.getOrDefault(Utils.null2String(zwjsId), ""), txrc); + } + + + // 构建表头 + List columns = new ArrayList<>(); + columns.add(new WeaTableColumn("150px", "片区", "lypq")); + columns.add(new WeaTableColumn("150px", "项目", "lyxm")); + columns.add(new WeaTableColumn("150px", "职务角色", "zwjs")); + columns.add(new WeaTableColumn("150px", "调薪人次", "txrc")); + columns.add(new WeaTableColumn("150px", "占周期内调薪总人数比例", "zzqntxzrsbl")); + columns.add(new WeaTableColumn("150px", "年度调薪总额", "ndtxze")); + columns.add(new WeaTableColumn("150px", "占周期内调薪总额比例", "zzqntxzebl")); + + Map map = new HashMap<>(); + // if (param.isExport()) { + // // 合计或导出需要合计行 + // Map sumResultMap = new HashMap<>(); + // sumResultMap.put(gsmcItemId.toString(), "合计"); + // for (SalaryItemPO salaryItem : salaryItemList) { + // if (salaryItem.getDataType().equals(SalaryDataTypeEnum.NUMBER.getValue())) { + // BigDecimal sumValue = acctResultMap.stream() + // .map(m -> m.get(salaryItem.getId().toString())) + // .filter(value -> value != null && NumberUtils.isCreatable(value.toString())) + // .map(e -> SalaryEntityUtil.empty2Zero(e.toString())) + // .reduce(BigDecimal.ZERO, BigDecimal::add); + // sumResultMap.put(salaryItem.getId().toString(),sumValue); + // } + // } + // map.put("sumRow", sumResultMap); + // } + map.put("columns", columns); + map.put("data", reportDTOS); + map.put("chartsDataA", chartsMapA); + map.put("chartsDataB", chartsMapB); + return map; + } + + @Override + public XSSFWorkbook exportTxdazwjstjReport(LySalaryReportQueryParam param) { + Map resultMap = listLyTxdazwjstjReport(param); + List dataList = (List) resultMap.get("data"); + List columns = (List) resultMap.get("columns"); + // Map sum = (Map) resultMap.get("sum"); + // dataList.add(sum); + + List headerList = new ArrayList<>(columns.stream().map(WeaTableColumn::getText).collect(Collectors.toList())); + List> rows = new ArrayList<>(); + rows.add(headerList); + + for (LyTxdaDTO dto : dataList) { + List row = Lists.newArrayList(); + Map valueMap = BeanUtil.beanToMap(dto); + for (WeaTableColumn column : columns) { + row.add(Utils.null2String(valueMap.get(column.getColumn()))); + } + rows.add(row); + } + + //获取excel + return ExcelUtilPlus.genWorkbookV2(rows, "调薪档案职务角色统计报表", false); + } } diff --git a/src/com/engine/salary/web/LySalaryController.java b/src/com/engine/salary/web/LySalaryController.java index a02408602..0c45724a3 100644 --- a/src/com/engine/salary/web/LySalaryController.java +++ b/src/com/engine/salary/web/LySalaryController.java @@ -921,5 +921,106 @@ public class LySalaryController { throw e; } } + + /** + * 查询调薪档案职级统计报表 + * + * @param request + * @param response + * @param param + * @return + */ + @POST + @Path("/txdazjtjReport/list") + @Produces(MediaType.APPLICATION_JSON) + public String listLyTxdazjtjReport(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody LySalaryReportQueryParam param) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult>(user).run(getLySalaryWrapper(user)::listLyTxdazjtjReport, param); + } + + /** + * 导出领悦调薪档案职级统计报表 + * + * @param request + * @param response + * @param param + * @return + */ + @POST + @Path("/txdazjtjReport/export") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportTxdazjtjReport(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody LySalaryReportQueryParam param) { + try { + User user = HrmUserVarify.getUser(request, response); + XSSFWorkbook workbook = getLySalaryWrapper(user).exportTxdazjtjReport(param); + String time = LocalDate.now().toString(); + String fileName = "调薪档案职级统计报表" + "-" + time; + try { + fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + StreamingOutput output = outputStream -> { + workbook.write(outputStream); + outputStream.flush(); + }; + response.setContentType("application/octet-stream"); + return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build(); + } catch (Exception e) { + log.error("调薪档案职级统计报表导出异常", e); + throw e; + } + } + + + /** + * 查询调薪档案职务角色统计报表 + * + * @param request + * @param response + * @param param + * @return + */ + @POST + @Path("/txdazwjstjReport/list") + @Produces(MediaType.APPLICATION_JSON) + public String listLyTxdazwjstjReport(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody LySalaryReportQueryParam param) { + User user = HrmUserVarify.getUser(request, response); + return new ResponseResult>(user).run(getLySalaryWrapper(user)::listLyTxdazwjstjReport, param); + } + + /** + * 导出领悦调薪档案职务角色统计报表 + * + * @param request + * @param response + * @param param + * @return + */ + @POST + @Path("/txdazwjstjReport/export") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response exportTxdazwjstjReport(@Context HttpServletRequest request, @Context HttpServletResponse response, @RequestBody LySalaryReportQueryParam param) { + try { + User user = HrmUserVarify.getUser(request, response); + XSSFWorkbook workbook = getLySalaryWrapper(user).exportTxdazwjstjReport(param); + String time = LocalDate.now().toString(); + String fileName = "调薪档案职务角色统计报表" + "-" + time; + try { + fileName = URLEncoder.encode(fileName + ".xlsx", "UTF-8"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + StreamingOutput output = outputStream -> { + workbook.write(outputStream); + outputStream.flush(); + }; + response.setContentType("application/octet-stream"); + return Response.ok(output).header("Content-disposition", "attachment;filename=" + fileName).header("Cache-Control", "no-cache").build(); + } catch (Exception e) { + log.error("调薪档案职务角色统计报表导出异常", e); + throw e; + } + } //---------------------------------------------------------领悦薪资档案报表end----------------------------------------- } diff --git a/src/com/engine/salary/wrapper/LySalaryWrapper.java b/src/com/engine/salary/wrapper/LySalaryWrapper.java index 4f6b899d1..5b0e94eff 100644 --- a/src/com/engine/salary/wrapper/LySalaryWrapper.java +++ b/src/com/engine/salary/wrapper/LySalaryWrapper.java @@ -363,4 +363,21 @@ public class LySalaryWrapper extends Service { public XSSFWorkbook exportXcdazwjstjReport(LySalaryReportQueryParam param) { return getLySalaryReportService(user).exportXcdazwjstjReport(); } + + public Map listLyTxdazjtjReport(LySalaryReportQueryParam param) { + return getLySalaryReportService(user).listLyTxdazjtjReport(param); + } + + + public XSSFWorkbook exportTxdazjtjReport(LySalaryReportQueryParam param) { + return getLySalaryReportService(user).exportTxdazjtjReport(param); + } + + public Map listLyTxdazwjstjReport(LySalaryReportQueryParam param) { + return getLySalaryReportService(user).listLyTxdazwjstjReport(param); + } + + public XSSFWorkbook exportTxdazwjstjReport(LySalaryReportQueryParam param) { + return getLySalaryReportService(user).exportTxdazwjstjReport(param); + } }