Browse Source

feat(print): 新增年度绩效明细报表打印功能

- 在FormConstant中新增参加工作日期、出生日期和性别常量
- 修改PerfBatchPrintListPlugin继承自AbstractReportFormPlugin以支持报表功能
- 调整packageData方法逻辑,适配ReportColumn字段获取方式
- 新增PrintPerfDetailReportListDataPlugin类用于处理年度绩效结果明细报表数据
- 实现动态列生成及近五年绩效结果的数据查询与转换逻辑
- 添加对快速过滤和普通过滤条件的支持,优化数据展示效果
- 完善字段映射关系,确保报表能正确显示员工相关信息
wyc 1 week ago
parent
commit
c425b06f08

+ 6 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/constant/FormConstant.java

@@ -398,5 +398,11 @@ public class FormConstant {
     public static final String LEVEL_KEY = "level";
     /** 手机号码 */
     public static final String PHONE_KEY = "phone";
+    /** 参加工作日期 */
+    public static final String NCKD_JOINWORKTIME = "nckd_joinworktime";
+    /** 出生日期 */
+    public static final String BIRTHDAY = "birthday";
+    /** 性别 */
+    public static final String GENDER = "gender";
 
 }

+ 19 - 2
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/print/PerfBatchPrintListPlugin.java

@@ -2,23 +2,39 @@ package nckd.jxccl.opmc.pm.plugin.form.print;
 
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
+import com.kingdee.bos.ctrl.reportone.r1.print.data.R1PrintDataSource;
+import kd.bos.dataentity.SqlParameter;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
 import kd.bos.dataentity.utils.ObjectUtils;
 import kd.bos.dataentity.utils.StringUtils;
+import kd.bos.entity.EntityType;
+import kd.bos.entity.datamodel.ListField;
 import kd.bos.entity.datamodel.events.PackageDataEvent;
+import kd.bos.entity.list.IListDataProvider;
+import kd.bos.entity.list.SummaryResult;
+import kd.bos.entity.list.option.ListUserOption;
+import kd.bos.entity.report.ReportColumn;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.Toolbar;
 import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
 import kd.bos.form.events.ClosedCallBackEvent;
 import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.orm.query.QFilter;
+import kd.bos.report.plugin.AbstractReportFormPlugin;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.common.utils.DateUtil;
 
+import java.util.Collections;
 import java.util.Date;
 import java.util.EventObject;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -28,7 +44,7 @@ import java.util.Map;
 * @date 2025/12/7 21:20
 * @version 1.0
 */
-public class PerfBatchPrintListPlugin extends AbstractListPlugin implements Plugin {
+public class PerfBatchPrintListPlugin extends AbstractReportFormPlugin implements Plugin {
 
     @Override
     public void registerListener(EventObject e) {
@@ -64,12 +80,13 @@ public class PerfBatchPrintListPlugin extends AbstractListPlugin implements Plug
         }
     }
 
+
     @Override
     public void packageData(PackageDataEvent e) {
         String fileIssueTime = this.getPageCache().get("fileIssueTime");
         if(StringUtils.isNotEmpty(fileIssueTime)){
             JSONObject jsonObject = JSON.parseObject(fileIssueTime);
-            String colKey = e.getColKey();
+            String colKey = ((ReportColumn)e.getSource()).getFieldKey();
             if ("nckd_fileissuetime".equalsIgnoreCase(colKey) && jsonObject.containsKey("nckd_fileissuetime")) {
                 e.setFormatValue(DateUtil.format(jsonObject.getDate("nckd_fileissuetime"),DateUtil.NORM_DATE_PATTERN));
             } else if ("nckd_stamptime".equalsIgnoreCase(colKey) && jsonObject.containsKey("nckd_stamptime")) {

+ 269 - 0
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/print/PrintPerfDetailReportListDataPlugin.java

@@ -0,0 +1,269 @@
+package nckd.jxccl.opmc.pm.plugin.form.print;
+
+import kd.bos.algo.DataSet;
+import kd.bos.algo.GroupbyDataSet;
+import kd.bos.dataentity.entity.LocaleString;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.QueryEntityType;
+import kd.bos.entity.cache.AppCache;
+import kd.bos.entity.cache.IAppCache;
+import kd.bos.entity.report.AbstractReportColumn;
+import kd.bos.entity.report.AbstractReportListDataPlugin;
+import kd.bos.entity.report.DynamicReportColumnEvent;
+import kd.bos.entity.report.FastFilter;
+import kd.bos.entity.report.ReportColumn;
+import kd.bos.entity.report.ReportQueryParam;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.DateUtil;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+* 年度绩效结果明细-报表取数插件
+* 实体标识:nckd_annualperfdetail
+* @author W.Y.C
+* @date 2025/11/13 16:09
+* @version 1.0
+*/
+public class PrintPerfDetailReportListDataPlugin extends AbstractReportListDataPlugin implements Plugin {
+
+    @Override
+    public void getDynamicColumns(DynamicReportColumnEvent event) {
+        super.getDynamicColumns(event);
+    }
+
+    @Override
+    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
+
+        // 构建查询字段
+        QueryFieldBuilder queryFieldBuilder = buildQueryFieldBuilder();
+
+        LocalDate now = LocalDate.now();
+        // 获取5年前的年份
+        int fiveYearsAgo = LocalDate.now().minusYears(5).getYear();
+        Date beginDate = DateUtil.toDate(LocalDate.of(fiveYearsAgo, 1, 1));
+
+        int currentYear = LocalDate.now().getYear() - 1; // 不包含今年
+        Date endDate = DateUtil.toDate(LocalDate.of(currentYear, 1, 1));
+        //查询最近5年的数据
+        /*QFilter qFilter = new QFilter(PerfManagerFormConstant.NCKD_BEGINYEAR, QCP.less_equals, endDate)
+                .and(new QFilter(PerfManagerFormConstant.NCKD_ENDYEAR, QCP.large_equals, beginDate));*/
+        QFilter qFilter = QFilter.of("1=1");
+
+        // 处理快速过滤条件
+        processFastFilter(reportQueryParam, qFilter);
+
+        //其他过滤条件
+        processFilter(reportQueryParam, qFilter);
+
+        // 执行基础查询
+        QueryEntityType queryEntityType = (QueryEntityType) EntityMetadataCache.getDataEntityType("annualperfdetailquery");
+        DataSet dataSet = HRQueryEntityHelper.getInstance().getQueryDataSet(queryEntityType,queryFieldBuilder.buildSelect(), new QFilter[]{qFilter}, null);
+
+        dataSet.print( true);
+
+        //过滤调实际结束实际之外的年份分录
+        DataSet withYearFields = dataSet.filter("year("+String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALYEAR) +") " +
+                "<= year(CASE WHEN nckd_actendyear is not null THEN nckd_actendyear ELSE "+PerfManagerFormConstant.NCKD_ENDYEAR+" end)");
+        withYearFields.print(true);
+
+        // 动态添加年份字段;行转列
+        int tempIndex = 1;
+        for (int year = fiveYearsAgo; year <= currentYear; year++) {
+            withYearFields = withYearFields.addField(
+                    "CASE WHEN year(" + String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALYEAR) + ") = " + year + " THEN " + String.join(".", PerfManagerFormConstant.PERFMANAGERENTRY, PerfManagerFormConstant.NCKD_APPRAISALRESULT,FormConstant.ID_KEY)+ " ELSE null END",
+                    "temp_" + tempIndex
+            );
+            tempIndex++;
+        }
+        withYearFields.print(true);
+
+        // 按分组字段聚合
+        GroupbyDataSet groupbyDataSet = withYearFields.groupBy(new String[]{
+                String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY),
+                String.join(".", FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.EMP_NUMBER_KEY),
+                String.join(".", FormConstant.NCKD_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY, FormConstant.NAME_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_FIRSTORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_SECONDORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_THIRDORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_FOURTHORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_FIFTHORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.ADMINORG, FormConstant.NCKD_SIXTHORG, FormConstant.ID_KEY),
+                String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.POS_STATUS, FormConstant.ID_KEY),
+                String.join(".", FormConstant.NCKD_PERSON, FormConstant.NCKD_JOINWORKTIME),
+                String.join(".", FormConstant.NCKD_PERSON, FormConstant.BIRTHDAY),
+                String.join(".", FormConstant.NCKD_PERSON, FormConstant.GENDER,FormConstant.NAME_KEY),
+                String.join(".", FormConstant.HRPI_PEREDUEXP, FormConstant.EDUCATION_KEY,FormConstant.NAME_KEY),
+//                String.join(".", FormConstant.NCKD_EMPPOSORGREL, FormConstant.POSITION_KEY, FormConstant.ID_KEY),
+                String.join(".", "last_perfmanager", PerfManagerFormConstant.NCKD_BEGINYEAR),
+                String.join(".", "last_perfmanager", PerfManagerFormConstant.NCKD_ENDYEAR)
+        });
+        int tempIndex1 = 1;
+        for (int year = fiveYearsAgo; year <= currentYear; year++) {
+            groupbyDataSet
+                    .max("temp_"+tempIndex1, tempIndex1+"_result");
+            tempIndex1++;
+        }
+        IAppCache nckdPm = AppCache.get("nckd_pm");
+
+        DataSet result = groupbyDataSet.finish();
+        result.print( true);
+        return result;
+    }
+
+    @Override
+    public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
+        // 获取5年前的年份
+        int fiveYearsAgo = LocalDate.now().minusYears(5).getYear();
+        int currentYear = LocalDate.now().getYear() - 1; // 不包含今年
+
+        for (AbstractReportColumn column : columns) {
+            if (column instanceof ReportColumn) {
+                ReportColumn rColumn = (ReportColumn) column;
+                String fieldKey = rColumn.getFieldKey();
+                // 检查是否为年份相关的字段
+                if (fieldKey != null && fieldKey.startsWith("nckd_year")) {
+                    try {
+                        // 提取年份索引(从字段名中提取数字)
+                        int yearIndex = Integer.parseInt(fieldKey.replace("nckd_year", ""));
+                        // 设置对应年份的标题
+                        int displayYear = fiveYearsAgo + yearIndex - 1;
+                        if(displayYear <= currentYear) {
+                            rColumn.setCaption(new LocaleString(displayYear + "年"));
+                            rColumn.setHide(false);
+                        }
+                    } catch (NumberFormatException ignored) {
+                    }
+                }
+            }
+        }
+        return columns;
+    }
+
+    /**
+     * 构建查询字段
+     */
+    private QueryFieldBuilder buildQueryFieldBuilder() {
+        return QueryFieldBuilder.create()
+                .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
+                .add(PerfManagerFormConstant.NCKD_ENDYEAR)
+                .add(PerfManagerFormConstant.NCKD_ACTENDYEAR)
+                .addGroup(new String[]{PerfManagerFormConstant.PERFMANAGERENTRY},PerfManagerFormConstant.NCKD_APPRAISALRESULT)
+                .addIdNumberName(PerfManagerFormConstant.PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT)
+                .addGroup(new String[]{PerfManagerFormConstant.PERFMANAGERENTRY},PerfManagerFormConstant.NCKD_APPRAISALYEAR)
+                .addGroup(new String[]{PerfManagerFormConstant.PERFMANAGERENTRY},PerfManagerFormConstant.ID_KEY)
+                .addGroup(new String[]{FormConstant.NCKD_EMPPOSORGREL,FormConstant.EMPLOYEE_KEY}, FormConstant.EMP_NUMBER_KEY, FormConstant.NAME_KEY)
+                .addIdNumberName(FormConstant.NCKD_PERSON)
+                .add(String.join(".", FormConstant.NCKD_PERSON, FormConstant.NCKD_JOINWORKTIME))
+                .add(String.join(".", FormConstant.NCKD_PERSON, FormConstant.BIRTHDAY))
+                .add(String.join(".", FormConstant.NCKD_PERSON, FormConstant.GENDER,FormConstant.NAME_KEY))
+                .add(String.join(".", FormConstant.HRPI_PEREDUEXP, FormConstant.EDUCATION_KEY,FormConstant.NAME_KEY))
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.POS_STATUS)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_FIRSTORG)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_SECONDORG)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_THIRDORG)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_FOURTHORG)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_FIFTHORG)
+                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG,FormConstant.NCKD_SIXTHORG)
+//                .addIdNumberName(FormConstant.HRPI_EMPPOSORGREL,FormConstant.POSITION_KEY)
+                .addGroup(new String[]{"last_perfmanager"},
+                        PerfManagerFormConstant.NCKD_BEGINYEAR,
+                        PerfManagerFormConstant.NCKD_ENDYEAR);
+
+    }
+
+    /**
+     * 处理过滤条件
+     */
+    private void processFilter(ReportQueryParam reportQueryParam, QFilter qFilter) {
+        List<QFilter> qFilters = reportQueryParam.getFilter().getQFilters();
+            for (QFilter filter : qFilters) {
+            //由于页面命名限制不允许配置对应数据库字段(例如:position.id的格式),这里只能手动转换为数据库实际的字段
+            String property = filter.getProperty();
+            if ("nckd_posstatus.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.HRPI_EMPPOSORGREL,FormConstant.POS_STATUS,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }else if("nckd_beginyearfilter".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter("last_perfmanager."+PerfManagerFormConstant.NCKD_BEGINYEAR,filter.getCP(),filter.getValue()));
+            }else if("nckd_endyearfilter".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter("last_perfmanager."+PerfManagerFormConstant.NCKD_ENDYEAR,filter.getCP(),filter.getValue()));
+            }else if("nckd_org.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".",FormConstant.HRPI_EMPPOSORGREL,FormConstant.ADMINORG),filter.getCP(),filter.getValue()));
+            }else if("nckd_employee.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".",FormConstant.NCKD_EMPPOSORGREL,FormConstant.EMPLOYEE_KEY),filter.getCP(),filter.getValue()));
+            }
+        }
+    }
+
+    /**
+     * 处理快速过滤条件
+     */
+    private void processFastFilter(ReportQueryParam reportQueryParam, QFilter qFilter) {
+        FastFilter fastFilter = reportQueryParam.getFilter().getFastFilter();
+        if (fastFilter != null) {
+            List<Map<String, List<Object>>> fastFilterList = fastFilter.getFastFilter();
+            for (Map<String, List<Object>> stringListMap : fastFilterList) {
+                //nckd_empnumfastfilter转为employee.empnumber,nckd_namefastfilter转换为employee.name,转换后添加到fields中
+                List<Object> fieldList = stringListMap.get("FieldName");
+                List<Object> valueList = stringListMap.get("Value");
+                String[] fields = new String[fieldList.size()];
+                for (int i = 0; i < fieldList.size(); i++) {
+                    fields[i] = fieldList.get(i).toString()
+                            .replace("nckd_empnumfastfilter", String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.EMP_NUMBER_KEY))
+                            .replace("nckd_namefastfilter", String.join(".", FormConstant.HRPI_EMPPOSORGREL, FormConstant.EMPLOYEE_KEY,FormConstant.NAME_KEY));
+                }
+                //valueList转到values
+                String[] values = new String[valueList.size()];
+                for (int i = 0; i < valueList.size(); i++) {
+                    values[i] = valueList.get(i).toString();
+                }
+                QFilter orFilter = null;
+                for (String field : fields) {
+                    for (String value : values) {
+                        if (orFilter == null) {
+                            orFilter = new QFilter(field, QCP.like, "%" + value + "%");
+                        } else {
+                            orFilter = orFilter.or(field, QCP.like, "%" + value + "%");
+                        }
+                    }
+
+                }
+
+               if(orFilter != null) {
+                   qFilter.and(orFilter);
+               }
+            }
+        }
+    }
+
+    /**
+     * 处理过滤条件
+     */
+   /* private void processFilter(ReportQueryParam reportQueryParam, QFilter qFilter) {
+        List<QFilter> qFilters = reportQueryParam.getFilter().getQFilters();
+        for (QFilter filter : qFilters) {
+            //由于页面命名限制不允许配置对应数据库字段(例如:position.id的格式),这里只能手动转换为数据库实际的字段
+            String property = filter.getProperty();
+            if ("nckd_positionfilter.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.POSITION_KEY, FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }else if("nckd_orgfilter.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.COMPANY_KEY, FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }else if("nckd_joblevelhrffilter.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_JOBLEVELHR,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }else if("nckd_begindatefilter".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID, PositionStructureConstant.NCKD_BEGINDATE),filter.getCP(),filter.getValue()));
+            }
+        }
+    }*/
+
+
+}