Prechádzať zdrojové kódy

feat(hr): 添加关键行为评价报表功能

- 新增 GroupMaxStrFunction 自定义聚合函数用于字符串最大值计算
- 在 PositionStructureConstant 中新增岗位、聘任、结果等常量定义
- 优化 UnAnnualAdjustListPlugin 中的查询过滤逻辑
- 新增 KeyBeHavEvalProjRsltImportPlugin 导入插件处理关键行为评价结果
- 新增 KeyBeHavEvalReptQueryFromPlugin 和 KeyBeHavEvalReptQueryPlugin
  实现关键行为评价报表的行转列和动态列功能
- 更新 SeniorAppointMgmtFormPlugin 将关键行为人员列表改为报表展示
- 调整 KeyBeHavEvalTask 中的技能岗位等级配置和考核逻辑
- 优化 KeyBeHavEvalListPlugin 的数据处理和权限控制功能
wyc 2 týždňov pred
rodič
commit
3a11fc758f

+ 47 - 0
code/base/nckd-jxccl-base-common/src/main/java/nckd/jxccl/base/common/algo/GroupMaxStrFunction.java

@@ -0,0 +1,47 @@
+package nckd.jxccl.base.common.algo;
+
+import kd.bos.algo.CustomAggFunction;
+import kd.bos.algo.DataType;
+
+/**
+* 自定义聚合函数类(假设按字典序求最大字符串)
+* @author W.Y.C
+* @date 2025/12/27 16:57
+* @version 1.0
+*/
+public class GroupMaxStrFunction extends CustomAggFunction<String> {
+    public GroupMaxStrFunction() {
+        super("group_maxstr", DataType.StringType); // 注册函数名和返回类型
+    }
+
+    @Override
+    public String newAggValue() {
+        return ""; // 初始化为空字符串
+    }
+
+    @Override
+    public String addValue(String oldValue, Object newValue) {
+        String curRowData = String.valueOf(newValue);
+        // 按字典序比较,取较大值(若需其他规则,可修改比较逻辑)
+        return oldValue.compareTo(curRowData) < 0 ? curRowData : oldValue;
+    }
+
+    @Override
+    public String combineAggValue(String paramT1, String paramT2) {
+        // 如果不需要分批处理,可直接返回 null
+        return null;
+    }
+
+    @Override
+    public Object getResult(String result) {
+        return result;
+    }
+}
+/*
+
+// 2. 在业务代码中使用
+GroupMaxStrFunction groupMaxStr = new GroupMaxStrFunction();
+DataSet resultDataSet = dataSet.groupBy("分组字段")
+        .agg(groupMaxStr, "p_1", "max_p1") // 对 p_1 字段应用自定义聚合,结果别名为 max_p1
+        .finish();
+*/

+ 11 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/common/PositionStructureConstant.java

@@ -24,6 +24,8 @@ public class PositionStructureConstant extends FormConstant {
     public static final String NCKD_DIPLOMA = "nckd_diploma";
     /** 岗位 */
     public static final String NCKD_POSITIONHR = "nckd_positionhr";
+    /** 岗位 */
+    public static final String NCKD_POSITION = "nckd_position";
     /** 职称名称 */
     public static final String NCKD_RANKNAME = "nckd_rankname";
     /** 职称级别 */
@@ -319,8 +321,17 @@ public class PositionStructureConstant extends FormConstant {
     public static final String NCKD_PERSON = "nckd_person";
     /** 科研、创新、创效成果 */
     public static final String NCKD_INNOVATE = "nckd_innovate";
+    /** 科研、创新、创效成果 */
+    public static final String NCKD_APPOINT = "nckd_appoint";
     /** 工作年限 */
     public static final String NCKD_WORKYEAR = "nckd_workyear";
     /** 匹配情况说明 */
     public static final String NCKD_MATCHCONDDESC = "nckd_matchconddesc";
+    /** 配置关键行为人才标准项目分录 */
+    public static final String NCKD_KEYBEHAVCONFENTRY = "nckd_keybehavconfentry";
+    /** 配置关键行为人才标准项目分录 */
+    public static final String NCKD_RESULT = "nckd_result";
+
+    /** 关键行为项目评价结果-实体标识 */
+    public static final String KEYBEHAVEVALPROJRSLT_ENTITYID = "nckd_keybehavevalprojrslt";
 }

+ 16 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/annualadjust/UnAnnualAdjustListPlugin.java

@@ -10,9 +10,11 @@ import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.ShowType;
 import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
 import kd.bos.form.events.FilterContainerInitArgs;
 import kd.bos.form.events.SetFilterEvent;
 import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.orm.ORMHint;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
@@ -27,7 +29,9 @@ import nckd.jxccl.hr.psms.common.PositionStructureConstant;
 
 import java.time.LocalDateTime;
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 /**
 * 未生成年度调整列表
@@ -42,6 +46,7 @@ public class UnAnnualAdjustListPlugin extends AbstractListPlugin implements Plug
         super.filterContainerInit(args);
     }
 
+
     @Override
     public void setFilter(SetFilterEvent e) {
         //TODO 【待修改】-职位体系-默认过滤掉副科级及以上
@@ -60,6 +65,10 @@ public class UnAnnualAdjustListPlugin extends AbstractListPlugin implements Plug
             personIds.add(personId);
         }
 
+
+
+
+
         LocalDateTime lastYear = DateUtil.minusYears(localDateTime, 1);
         QFilter qFilter = new QFilter(FormConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
                 .and(FormConstant.IS_SEQLATESTRECORD, QCP.equals, EnableEnum.YES.getCode())
@@ -73,9 +82,15 @@ public class UnAnnualAdjustListPlugin extends AbstractListPlugin implements Plug
                 //初定时间不等于当年
                 .and(new QFilter(String.join(".", PositionStructureConstant.PERSONPOSFILE_ENTITYID+"init", PositionStructureConstant.NCKD_EXECUTEYEAR), QCP.not_equals2, localDateTime.getYear()))
                 //上年度有考核结果的人员
-                .and(new QFilter(String.join(".", PositionStructureConstant.PERFMANAGER_ENTITYID, PositionStructureConstant.PERFMANAGER_ENTRY_ENTITYID, PositionStructureConstant.APPRAISAL_YEAR_KEY), QCP.equals, DateUtil.toDate(lastYear)))
+//                .and(new QFilter(String.join(".", PositionStructureConstant.PERFMANAGER_ENTITYID, PositionStructureConstant.PERFMANAGER_ENTRY_ENTITYID, PositionStructureConstant.APPRAISAL_YEAR_KEY), QCP.equals, DateUtil.toDate(lastYear)))
                 //当年还未年度调整的人员
                 .and(new QFilter(FormConstant.EMPLOYEE_KEY, QCP.not_in, personIds));
+
+                /*.and(QFilter.join(FormConstant.EMPLOYEE_KEY,
+                                String.join(".", FormConstant.HRPI_PEREDUEXP, FormConstant.EMPLOYEE_KEY),
+                                QFilter.of(String.join(".", FormConstant.HRPI_PEREDUEXP, FormConstant.GRADUTIONDATE)+">="+String.join(".",PositionStructureConstant.PERSONPOSFILE_ENTITYID+"init", PositionStructureConstant.NCKD_BEGINDATE)),
+                        ORMHint.JoinHint.LEFT, Boolean.TRUE)
+                );*/
         e.addCustomQFilter(qFilter);
     }
 

+ 44 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/KeyBeHavEvalListPlugin.java

@@ -1,20 +1,56 @@
 package nckd.jxccl.hr.psms.plugin.form.other;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import kd.bos.consts.PermItemConst;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.LocaleString;
 import kd.bos.entity.datamodel.ListSelectedRow;
 import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.entity.datamodel.events.PackageDataEvent;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
+import kd.bos.form.IPageCache;
+import kd.bos.form.ListVisible;
 import kd.bos.form.ShowType;
+import kd.bos.form.control.grid.DataGrid;
+import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsEvent;
+import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsListener;
+import kd.bos.form.control.grid.events.DataGridBindDataEvent;
+import kd.bos.form.control.grid.events.DataGridBindDataListener;
 import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.BeforeCreateListColumnsArgs;
+import kd.bos.form.events.BeforeCreateListDataProviderArgs;
 import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.list.IListColumn;
+import kd.bos.list.ListColumn;
 import kd.bos.list.ListShowParameter;
 import kd.bos.list.events.ListRowClickEvent;
 import kd.bos.list.plugin.AbstractListPlugin;
+import kd.bos.mvc.list.ListDataProvider;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.hr.hbp.common.model.AuthorizedOrgResultWithSub;
+import kd.hr.hbp.common.model.OrgSubInfo;
+import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
 import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+import org.apache.commons.lang3.StringUtils;
 
+import java.util.ArrayList;
 import java.util.EventObject;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
 * 关键行为评价表
@@ -68,4 +104,12 @@ public class KeyBeHavEvalListPlugin extends AbstractListPlugin implements Plugin
             }
         }
     }
+
+
+    private static List<Long> extractOrgIds(List<OrgSubInfo> orgSubInfos) {
+        return orgSubInfos.stream()
+                .map(OrgSubInfo::getOrgId)
+                .collect(Collectors.toList());
+    }
+
 }

+ 48 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/KeyBeHavEvalReptFormPlugin.java

@@ -0,0 +1,48 @@
+package nckd.jxccl.hr.psms.plugin.form.other;
+
+import kd.bos.form.control.grid.DataGrid;
+import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsEvent;
+import kd.bos.form.control.grid.events.BeforeCreateDataGridColumnsListener;
+import kd.bos.form.control.grid.events.DataGridBindDataEvent;
+import kd.bos.form.control.grid.events.DataGridBindDataListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.sdk.plugin.Plugin;
+
+import java.util.EventObject;
+
+/**
+ * 动态表单插件
+ */
+public class KeyBeHavEvalReptFormPlugin extends AbstractFormPlugin implements  Plugin, BeforeCreateDataGridColumnsListener, DataGridBindDataListener {
+
+    /**
+     * 注册监听事件
+     * @param event
+     */
+    @Override
+    public void registerListener(EventObject event) {
+        registerDataGridListener();
+    }
+
+    /**
+     * 通过事件监听,注册数据表格监听事件
+     */
+    private void registerDataGridListener() {
+        DataGrid dataGrid = this.getControl("reportlistap");
+        // 注册创建列监听事件
+        dataGrid.addBeforeCreateDataGridColumnsListener(this);
+        // 注册绑定数据监听事件
+        dataGrid.addBindDataListener(this);
+
+    }
+
+    @Override
+    public void beforeCreateDataGridColumns(BeforeCreateDataGridColumnsEvent beforeCreateDataGridColumnsEvent) {
+
+    }
+
+    @Override
+    public void dataGridBindData(DataGridBindDataEvent dataGridBindDataEvent) {
+
+    }
+}

+ 7 - 1
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/SeniorAppointMgmtFormPlugin.java

@@ -58,7 +58,13 @@ public class SeniorAppointMgmtFormPlugin extends AbstractFormPlugin implements T
             openTargetPage("nckd_seniorappoint", "nckd_seniorappoint");
         } else if ("nckd_keybehaveval".equalsIgnoreCase(currentTab)) {
             //打开“关键行为人员”列表
-            openTargetPage("nckd_keybehaveval","nckd_keybehaveval");
+//            openTargetPage("nckd_keybehavevalrept","nckd_keybehaveval");
+            ReportShowParameter reportShowParameter = new ReportShowParameter();
+            reportShowParameter.setFormId("nckd_keybehavevalrept");
+            reportShowParameter.getOpenStyle().setShowType(ShowType.InContainer);
+            reportShowParameter.getOpenStyle().setTargetKey("nckd_keybehaveval");
+            reportShowParameter.setCaption("关键行为人员");
+            this.getView().showForm(reportShowParameter);
         }
     }
 

+ 38 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/impt/KeyBeHavEvalProjRsltImportPlugin.java

@@ -0,0 +1,38 @@
+package nckd.jxccl.hr.psms.plugin.form.other.impt;
+
+import kd.bos.orm.query.QFilter;
+import kd.hr.hbp.formplugin.web.HRDataBaseList;
+import kd.hr.impt.common.plugin.AfterLoadStartPageEventArgs;
+import kd.hr.impt.common.plugin.BeforeQueryRefBdEventArgs;
+import kd.hr.impt.common.plugin.HRImportPlugin;
+
+import java.util.LinkedHashSet;
+
+/**
+* 关键行为项目评价结果
+* 实体标识:nckd_keybehavevalprojrslt
+* @author W.Y.C
+* @date 2025/12/26 14:43
+* @version 1.0
+*/
+public class KeyBeHavEvalProjRsltImportPlugin extends HRDataBaseList implements HRImportPlugin {
+    @Override
+    public void afterLoadStartPage(AfterLoadStartPageEventArgs args) {
+        args.setFormId("nckd_keybehavevalprojrslt");
+    }
+
+    @Override
+    public void beforeQueryRefBd(BeforeQueryRefBdEventArgs args) {
+        String fieldId = args.getFieldId();
+        if(fieldId.equalsIgnoreCase("nckd_keybehavconfentry")){
+            LinkedHashSet<String> select = new LinkedHashSet<>();
+            select.add("id");
+            select.add("number");
+            select.add("name");
+            select.add("nckd_keybehavconf.nckd_org.name");
+            select.add("nckd_keybehavconf.nckd_jobseqhr.name");
+            args.setSelectFields(select);
+            args.setFilters( new QFilter[]{QFilter.of("1=1")});
+        }
+    }
+}

+ 111 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/report/KeyBeHavEvalReptQueryFromPlugin.java

@@ -0,0 +1,111 @@
+package nckd.jxccl.hr.psms.plugin.form.other.report;
+
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
+import kd.bos.form.CloseCallBack;
+import kd.bos.form.FormShowParameter;
+import kd.bos.form.ShowType;
+import kd.bos.form.control.Control;
+import kd.bos.form.control.events.RowClickEvent;
+import kd.bos.form.control.events.RowClickEventListener;
+import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.ClosedCallBackEvent;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.list.ListShowParameter;
+import kd.bos.list.events.BackPressedEvent;
+import kd.bos.list.events.EndSelectEvent;
+import kd.bos.list.events.ItemSelectEvent;
+import kd.bos.list.events.ListSelectedListener;
+import kd.bos.list.events.QueryListEvent;
+import kd.bos.list.events.SelectEvent;
+import kd.bos.plugin.sample.dynamicform.pcform.entrygrid.template.EntryRowClick;
+import kd.bos.report.ReportList;
+import kd.bos.report.ReportShowParameter;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.constant.FormConstant;
+import scala.Int;
+
+import java.util.ArrayList;
+import java.util.EventObject;
+import java.util.List;
+
+/**
+ * 动态表单插件
+ */
+public class KeyBeHavEvalReptQueryFromPlugin extends AbstractFormPlugin implements Plugin {
+
+    @Override
+    public void registerListener(EventObject e) {
+        ReportList reportList = getControl("reportlistap");
+        Integer currentPageIndex = reportList.getEntryState().getCurrentPageIndex();
+        Integer pageRows = reportList.getEntryState().getPageRows();
+        //报表行点击事件
+        reportList.addRowClickListener(new RowClickEventListener() {
+            //列表选择行事件监听
+            @Override
+            public void entryRowClick(RowClickEvent evt) {
+                int rowCount = reportList.getReportModel().getRowCount();
+                int row = evt.getRow();
+                int startRow = row - 3;
+                if(startRow <= 1){
+                    startRow = 1;
+                }
+                int endRow = row + 3;
+                if(endRow >= rowCount){
+                    endRow = rowCount;
+                }
+
+                DynamicObject selectRowData = reportList.getReportModel().getRowData(row);
+                if(selectRowData != null) {
+                    reportList.clearSelection();
+                    long selectPerson = selectRowData.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
+                    List<Integer> selectRows = new ArrayList<>();
+                    for (int i = startRow; i <= endRow; i++) {
+                        DynamicObject rowDate = reportList.getReportModel().getRowData(i);
+                        long personid = rowDate.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY));
+                        if(personid == selectPerson){
+                            selectRows.add( i);
+                        }
+                    }
+                    if(!selectRows.isEmpty()){
+                        int[] selectRowsArray = selectRows.stream().mapToInt(Integer::intValue).toArray();
+                        reportList.selectRows(selectRowsArray, selectRows.get(selectRows.size() - 1));
+                    }
+
+                }
+            }
+        });
+    }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        String operateKey = e.getOperateKey();
+        if(e.getOperationResult() != null && e.getOperationResult().isSuccess()){
+            if("newappointment".equalsIgnoreCase(operateKey)) {
+                ReportList reportList = this.getView().getControl("reportlistap");
+                int[] selectedRows = reportList.getEntryState().getSelectedRows();
+                if(selectedRows != null && selectedRows.length > 0) {
+                    DynamicObject rowData = reportList.getReportModel().getRowData(selectedRows[0]);
+                    FormShowParameter showParameter = new FormShowParameter();
+                    showParameter.setFormId("nckd_newseniorappoint");
+                    showParameter.getOpenStyle().setShowType(ShowType.Modal);
+                    showParameter.setCaption("新建聘任");
+                    showParameter.setCustomParam("selectRow", rowData.getLong(FormConstant.ID_KEY));
+                    showParameter.setCloseCallBack(new CloseCallBack(this, "nckd_newseniorappoint"));
+                    this.getView().showForm(showParameter);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void closedCallBack(ClosedCallBackEvent closedCallBackEvent) {
+        String actionId = closedCallBackEvent.getActionId();
+        if("nckd_newseniorappoint".equalsIgnoreCase(actionId)){
+            Object returnData = closedCallBackEvent.getReturnData();
+            if(returnData != null) {
+                this.getView().showSuccessNotification("聘任成功!");
+            }
+        }
+    }
+}

+ 433 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/form/other/report/KeyBeHavEvalReptQueryPlugin.java

@@ -0,0 +1,433 @@
+package nckd.jxccl.hr.psms.plugin.form.other.report;
+
+import kd.bos.algo.DataSet;
+import kd.bos.algo.GroupbyDataSet;
+import kd.bos.algo.JoinType;
+import kd.bos.algo.Row;
+import kd.bos.consts.PermItemConst;
+import kd.bos.context.RequestContext;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.LocaleString;
+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.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.QueryServiceHelper;
+import kd.hr.hbp.common.model.AuthorizedOrgResultWithSub;
+import kd.hr.hbp.common.model.OrgSubInfo;
+import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
+import kd.sdk.plugin.Plugin;
+import nckd.jxccl.base.common.algo.GroupMaxStrFunction;
+import nckd.jxccl.base.common.constant.FormConstant;
+import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.hr.psms.common.PositionStructureConstant;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+* 关键行为评价报表查询插件
+* 该插件用于查询和展示关键行为评价结果,支持动态列和行转列功能
+* 实体标识:nckd_keybehavevalrept
+* @author W.Y.C
+* @date 2025/12/27 18:05
+* @version 1.0
+*/
+public class KeyBeHavEvalReptQueryPlugin extends AbstractReportListDataPlugin implements Plugin {
+
+    // 常量定义
+    private static final String PERSON_ID_FIELD = String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY);
+    private static final String PROJECT_NUMBER_FIELD = String.join(".", PositionStructureConstant.NCKD_KEYBEHAVCONFENTRY, FormConstant.NUMBER_KEY);
+    private static final String PROJECT_NAME_FIELD = String.join(".", PositionStructureConstant.NCKD_KEYBEHAVCONFENTRY, FormConstant.NAME_KEY);
+    private static final String RESULT_FIELD = "case when "+PositionStructureConstant.NCKD_RESULT+" = '1' then '满足' else '不满足' end";
+
+//    private static final String RESULT_FIELD = PositionStructureConstant.NCKD_RESULT;
+
+    @Override
+    public void getDynamicColumns(DynamicReportColumnEvent event) {
+        super.getDynamicColumns(event);
+    }
+
+    /**
+     * 查询报表数据
+     * 实现行转列逻辑,将评价项目结果转换为报表列
+     */
+    @Override
+    public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {
+        // 1. 获取权限范围内的组织ID
+        List<Long> authorizedOrgIds = getAuthorizedOrgIds();
+        
+        // 2. 查询关键行为评价项目结果数据
+        DataSet keyBeHavEvalProjRsltDataSet = queryKeyBeHavEvalProjRsltDataSet(authorizedOrgIds);
+        
+        // 3. 获取唯一项目编号(需要用于动态列的项目)
+        Set<String> uniqueProjectNumbers = extractUniqueProjectNumbers(keyBeHavEvalProjRsltDataSet);
+        
+        // 4. 行转列处理
+        DataSet pivotResultDataSet = transformRowsToColumns(keyBeHavEvalProjRsltDataSet, uniqueProjectNumbers);
+
+        // 5. 查询主表数据
+        // 处理快速过滤条件
+        QFilter qFilter = QFilter.of("1=1");
+        processFastFilter(reportQueryParam, qFilter);
+        //其他过滤条件
+        processFilter(reportQueryParam, qFilter);
+        DataSet mainTableDataSet = queryMainTableDataSet(qFilter);
+        
+        // 6. 关联主表和行转列结果
+        DataSet finalResultDataSet = joinMainAndPivotData(mainTableDataSet, pivotResultDataSet);
+        
+        return finalResultDataSet;
+    }
+
+    /**
+     * 获取报表列定义
+     * 根据数据库中的项目动态生成报表列
+     */
+    @Override
+    public List<AbstractReportColumn> getColumns(List<AbstractReportColumn> columns) throws Throwable {
+        // 获取权限范围内的组织ID
+        List<Long> authorizedOrgIds = getAuthorizedOrgIds();
+        
+        // 获取唯一项目信息
+        List<ProjectInfo> projectInfoList = getUniqueProjectInfo(authorizedOrgIds);
+        
+        // 为每个唯一项目创建列
+        for (ProjectInfo projectInfo : projectInfoList) {
+            ReportColumn newColumn = createReportColumn(projectInfo);
+            columns.add(newColumn);
+        }
+        
+        return columns;
+    }
+
+    /**
+     * 创建报表列
+     */
+    private ReportColumn createReportColumn(ProjectInfo projectInfo) {
+        ReportColumn column = new ReportColumn();
+        column.setCaption(new LocaleString(projectInfo.getProjectName()));
+        column.setFieldKey("p_"+projectInfo.getProjectNumber());
+        column.setFieldType(ReportColumn.TYPE_TEXT);
+        return column;
+
+/*
+        // 1. 创建下拉列表列
+        ComboReportColumn comboColumn = new ComboReportColumn();
+        // 2. 设置关键属性
+        comboColumn.setFieldKey("fruitname"); // 与查询结果字段对应
+        comboColumn.setFieldType(ReportColumn.TYPE_COMBO); // 类型必须为 COMBO
+        comboColumn.setCaption(new LocaleString("水果名称")); // 列标题
+
+        // 3. (可选)设置下拉选项。这里示例是静态的,实际可从数据库或上下文动态获取。
+        List<ValueMapItem> items = new ArrayList<>();
+        items.add(new ValueMapItem("apple", "苹果"));
+        items.add(new ValueMapItem("banana", "香蕉"));
+        comboColumn.setComboItems(items);
+
+        // 4. 将列添加到列集合
+        columns.add(comboColumn);*/
+    }
+
+    /**
+     * 获取项目信息列表
+     */
+    private List<ProjectInfo> getUniqueProjectInfo(List<Long> orgIds) {
+        QueryFieldBuilder resultFieldBuilder = createResultFieldBuilder();
+        QFilter filter = createOrgFilter(orgIds);
+        DynamicObjectCollection keyBeHavEvalProjRslt = QueryServiceHelper.query(
+                PositionStructureConstant.KEYBEHAVEVALPROJRSLT_ENTITYID, 
+                resultFieldBuilder.buildSelect(), 
+                new QFilter[]{filter}
+        );
+        
+        // 根据项目编码去重
+        Set<String> processedProjectNumbers = new HashSet<>();
+        List<ProjectInfo> uniqueProjectList = new ArrayList<>();
+        for (DynamicObject obj : keyBeHavEvalProjRslt) {
+            String projectNumber = obj.getString(PROJECT_NUMBER_FIELD);
+            String projectName = obj.getString(PROJECT_NAME_FIELD);
+            
+            if (projectNumber != null && processedProjectNumbers.add(projectNumber)) {
+                uniqueProjectList.add(new ProjectInfo(projectNumber, projectName));
+            }
+        }
+        
+        return uniqueProjectList;
+    }
+
+    /**
+     * 获取用户有权限的组织ID列表
+     */
+    private List<Long> getAuthorizedOrgIds() {
+        Long currentUserId = RequestContext.get().getCurrUserId();
+        AuthorizedOrgResultWithSub userAdminOrgWithSub = HRPermissionServiceHelper.getUserAdminOrgsWithSub(
+                currentUserId, "nckd_psms", "nckd_keybehavconf",
+                PermItemConst.ITEM_VIEW, "nckd_org", new HashMap<>());
+        
+        if (userAdminOrgWithSub.isHasAllOrgPerm()) {
+            return new ArrayList<>(); // 如果有所有组织权限,返回空列表表示无限制
+        }
+        
+        return extractOrgIds(userAdminOrgWithSub.getHasPermOrgsWithSub());
+    }
+
+    /**
+     * 查询关键行为评价项目结果数据集
+     */
+    private DataSet queryKeyBeHavEvalProjRsltDataSet(List<Long> orgIds) {
+        QueryFieldBuilder resultFieldBuilder = createResultFieldBuilder();
+        QFilter filter = createOrgFilter(orgIds);
+        
+        return QueryServiceHelper.queryDataSet("", 
+                PositionStructureConstant.KEYBEHAVEVALPROJRSLT_ENTITYID, 
+                resultFieldBuilder.buildSelect(), 
+                new QFilter[]{filter}, 
+                null);
+    }
+
+    /**
+     * 创建结果字段构建器
+     */
+    private QueryFieldBuilder createResultFieldBuilder() {
+        return QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .addIdNumberName(FormConstant.NCKD_PERSON)
+                .addIdNumberName(PositionStructureConstant.NCKD_KEYBEHAVCONFENTRY)
+                .add(PositionStructureConstant.NCKD_RESULT);
+    }
+
+    /**
+     * 创建组织过滤器
+     */
+    private QFilter createOrgFilter(List<Long> orgIds) {
+        QFilter filter = QFilter.of("1=1");
+        if (orgIds != null && !orgIds.isEmpty()) {
+            filter.and(String.join(".", FormConstant.NCKD_ORG, FormConstant.ID_KEY), QCP.in, orgIds);
+        }
+        return filter;
+    }
+
+    /**
+     * 提取唯一的项目编号
+     */
+    private Set<String> extractUniqueProjectNumbers(DataSet keyBeHavEvalProjRsltDataSet) {
+        DataSet copyDataSet = keyBeHavEvalProjRsltDataSet.copy();
+        Set<String> uniqueProjectNumbers = new HashSet<>();
+        
+        while (copyDataSet.hasNext()) {
+            Row row = copyDataSet.next();
+            String projectNumber = row.getString(PROJECT_NUMBER_FIELD);
+            if (projectNumber != null) {
+                uniqueProjectNumbers.add(projectNumber);
+            }
+        }
+        
+        return uniqueProjectNumbers;
+    }
+
+    /**
+     * 将行数据转换为列数据(行转列)
+     */
+    private DataSet transformRowsToColumns(DataSet originalDataSet, Set<String> projectNumbers) {
+        DataSet workingDataSet = originalDataSet;
+        
+        // 为每个项目编号添加计算字段(行转列)
+        List<String> columnFieldNames = new ArrayList<>();
+        for (String projectNumber : projectNumbers) {
+            String caseExpression = String.format(
+                "CASE WHEN %s = '%s' THEN %s ELSE null END",
+                PROJECT_NUMBER_FIELD,
+                projectNumber,
+                RESULT_FIELD
+            );
+            
+            workingDataSet = workingDataSet.addField(caseExpression, "p_"+projectNumber);
+            columnFieldNames.add("p_"+projectNumber);
+        }
+
+        GroupMaxStrFunction groupMaxStr = new GroupMaxStrFunction();
+        GroupbyDataSet groupbyDataSet = workingDataSet.groupBy(new String[]{PERSON_ID_FIELD});
+        for (String projectNumber : projectNumbers) {
+            groupbyDataSet
+                    .agg(groupMaxStr,"p_"+projectNumber, "p_"+projectNumber);
+        }
+        // 添加人员ID字段用于关联
+        columnFieldNames.add(PERSON_ID_FIELD);
+        return groupbyDataSet.finish();
+    }
+
+    /**
+     * 查询主表数据
+     */
+    private DataSet queryMainTableDataSet(QFilter qFilter) {
+        QueryFieldBuilder queryFieldBuilder = buildQueryFieldBuilder();
+        return QueryServiceHelper.queryDataSet("KeyBeHavEvalReptQueryPlugin", 
+                PositionStructureConstant.KEYBEHAVEVAL_ENTITYID, 
+                queryFieldBuilder.buildSelect(),
+                new QFilter[]{qFilter},
+                queryFieldBuilder.buildOrder());
+    }
+
+    /**
+     * 关联主表和行转列结果
+     */
+    private DataSet joinMainAndPivotData(DataSet mainTableDataSet, DataSet pivotDataSet) {
+        String[] mainTableFieldNames = mainTableDataSet.getRowMeta().getFieldNames();
+        String[] pivotFieldNames = pivotDataSet.getRowMeta().getFieldNames();
+        
+        return mainTableDataSet.join(pivotDataSet, JoinType.LEFT)
+                .on(String.join(".", FormConstant.NCKD_PERSON), 
+                    PERSON_ID_FIELD)
+                .select(mainTableFieldNames, pivotFieldNames)
+                .finish();
+    }
+
+    /**
+     * 构建主表查询字段
+     */
+    private QueryFieldBuilder buildQueryFieldBuilder() {
+        return QueryFieldBuilder.create()
+                .add(FormConstant.ID_KEY)
+                .add(FormConstant.NCKD_PERSON)
+                .add(FormConstant.NCKD_DEP)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_FIRSTORG)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_SECONDORG)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_THIRDORG)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_FOURTHORG)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_FIFTHORG)
+                .add(FormConstant.NCKD_DEP, FormConstant.NCKD_SIXTHORG)
+                .add(FormConstant.NCKD_JOBSEQ)
+                .add(PositionStructureConstant.NCKD_POSITION)
+                .add(PositionStructureConstant.NCKD_JOBLEVEL)
+                .add(PositionStructureConstant.NCKD_APPRAISALRESULT)
+                .add(PositionStructureConstant.NCKD_APPOINT)
+                .add(PositionStructureConstant.NCKD_MATCHCONDDESC)
+                .orderDesc(String.join(".",FormConstant.NCKD_PERSON,FormConstant.EMP_NUMBER_KEY))
+                .orderAsc(PositionStructureConstant.NCKD_JOBLEVEL);
+    }
+
+    /**
+     * 提取组织ID列表
+     */
+    private static List<Long> extractOrgIds(List<OrgSubInfo> orgSubInfos) {
+        return orgSubInfos.stream()
+                .map(OrgSubInfo::getOrgId)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 项目信息内部类
+     */
+    private static class ProjectInfo {
+        private final String projectNumber;
+        private final String projectName;
+
+        public ProjectInfo(String projectNumber, String projectName) {
+            this.projectNumber = projectNumber;
+            this.projectName = projectName;
+        }
+
+        public String getProjectNumber() {
+            return projectNumber;
+        }
+
+        public String getProjectName() {
+            return projectName;
+        }
+    }
+
+    /**
+     * 关键行为评价项目结果值对象(保留原有类,用于兼容性)
+     */
+    class KeyBeHavEvalProjRsltVo {
+        private Long personId;
+        private String projectNumber;
+        private String projectName;
+        private String projectResult;
+
+        public KeyBeHavEvalProjRsltVo(Long personId, String projectNumber, String projectName, String projectResult) {
+            this.personId = personId;
+            this.projectNumber = projectNumber;
+            this.projectName = projectName;
+            this.projectResult = projectResult;
+        }
+    }
+
+    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.NCKD_PERSON,FormConstant.EMP_NUMBER_KEY))
+                            .replace("nckd_namefastfilter", String.join(".", FormConstant.NCKD_PERSON,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_secondorg.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_DEP,FormConstant.NCKD_SECONDORG,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+            if ("nckd_thirdorg.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_DEP,FormConstant.NCKD_THIRDORG,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+            if ("nckd_fourthorg.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_DEP,FormConstant.NCKD_FOURTHORG,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+            if ("nckd_fifthorg.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_DEP,FormConstant.NCKD_FIFTHORG,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+            if ("nckd_sixthorg.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_DEP,FormConstant.NCKD_SIXTHORG,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+            if ("nckd_position.id".equalsIgnoreCase(property)){
+                qFilter.and(new QFilter(String.join(".", FormConstant.NCKD_POSITION_KEY,FormConstant.ID_KEY),filter.getCP(),filter.getValue()));
+            }
+        }
+    }
+}

+ 13 - 189
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/task/KeyBeHavEvalTask.java

@@ -73,7 +73,7 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
     public final static Map<String,List<Integer>> jobSeqJobLevelMap = ImmutableMap.<String, List<Integer>>builder()
             .put(JobSeqEnum.TECHNICALS.getCode(), Lists.newArrayList(13,14,15))
             .put(JobSeqEnum.FUNCTIONAL.getCode(), Lists.newArrayList(13,14,15))
-            .put(JobSeqEnum.SKILL.getCode(), Lists.newArrayList(12,13,14))
+            .put(JobSeqEnum.SKILL.getCode(), Lists.newArrayList(13,14,15))
             .build();
 
     @Override
@@ -101,51 +101,8 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
                 ));
         logger.info("员工信息分组完成,分组后Map大小: {}", empPosOrgRelMap.size());
 
-        //查询服务年限
-        logger.info("开始查询服务年限,查询职务数量: {}", assignmentIds.size());
-        DynamicObject[] perSerLenArray = EmpPosOrgRelHelper.getPerSerLen(assignmentIds);
-        logger.info("查询到服务年限数据数量: {}", perSerLenArray != null ? perSerLenArray.length : 0);
-        Map<Long, DynamicObject> perSerLenMap = Arrays.stream(perSerLenArray)
-                .collect(Collectors.groupingBy(
-                        obj -> obj.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)),
-                        Collectors.toList()
-                ))
-                .entrySet()
-                .stream()
-                .collect(Collectors.toMap(
-                        Map.Entry::getKey,
-                        entry -> entry.getValue().get(0) // 由于已按日期降序排列,取第一条即为
-                ));
-        logger.info("服务年限数据分组完成,分组后Map大小: {}", perSerLenMap.size());
-
-        //查询职位档案
-        logger.info("开始查询职位档案,员工数量: {}", personIds.size());
-        QFilter personPosFileFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
-                .and(PositionStructureConstant.NCKD_TYPESTATE, QCP.in, new String[]{TypeStateEnum.NEW_ENTRY.getCode(),TypeStateEnum.IN_SERVICE_LEVEL.getCode(),TypeStateEnum.ANNUAL_ADJUSTMENT.getCode(),TypeStateEnum.POSITION_TRANSFER.getCode()})
-                .and(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY),QCP.in,personIds);
-        QueryFieldBuilder personPosFileFieldBuilder = QueryFieldBuilder.create()
-                .addIdNumberName(PositionStructureConstant.NCKD_PERSON)
-                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR)
-                .addIdNumberNameWithExtras(new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},FormConstant.JOBLEVELSEQ)
-                .add(PositionStructureConstant.NCKD_BEGINDATE)
-                .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);
-        DynamicObjectCollection personPosFileList = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, personPosFileFieldBuilder.buildSelect(), new QFilter[]{personPosFileFilter}, personPosFileFieldBuilder.buildOrder());
-        logger.info("职位档案查询完成,查询结果数量: {}", personPosFileList.size());
-        // 按人员分组,取最新一条记录
-        Map<Long, DynamicObject> personPosLatestMap = personPosFileList.stream()
-                .collect(Collectors.groupingBy(
-                        obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)),
-                        Collectors.toList()
-                ))
-                .entrySet()
-                .stream()
-                .collect(Collectors.toMap(
-                        Map.Entry::getKey,
-                        entry -> entry.getValue().get(0) // 由于已按日期降序排列,取第一条即为最新
-                ));
-        logger.info("职位档案分组完成,分组后Map大小: {}", personPosLatestMap.size());
-
 
+        //TODO 职称/技能
 
         //查询近3年考核结果
         logger.info("开始查询近3年考核结果");
@@ -170,53 +127,6 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
                 ));
         logger.info("考核结果分组完成,分组后Map大小: {}", perfManagerResultMap.size());
 
-        //查询近3年科研创新积分
-        logger.info("开始查询近3年科研创新积分");
-        QFilter contribBillFilter = QFilterCommonHelper.getBillStatusFilter()
-                .and(ContributionConstant.NCKD_YEAR,QCP.large_equals,beginDate)
-                .and(ContributionConstant.NCKD_YEAR,QCP.less_equals, endDate)
-                .and(String.join( ".",FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON),QCP.in,personIds)
-                .and(String.join( ".",ContributionConstant.NCKD_SCOREITEM, FormConstant.NUMBER_KEY),QCP.equals, ScoreItemEnum.RESEARCH_SCORE.getCode());
-        QueryFieldBuilder scoreItemConfFieldBuilder = QueryFieldBuilder.create()
-                .add(ContributionConstant.NCKD_YEAR)
-                .addIdNumberName(ContributionConstant.NCKD_SCOREITEM)
-                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB)
-                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMSUB, ContributionConstant.NCKD_SCOREITEMLEVEL)
-                .addIdNumberName(ContributionConstant.NCKD_SCOREITEMRANK) // 添加积分项目名次字段
-                .addIdNumberName(FormConstant.NCKD_ENTRYENTITY, ContributionConstant.NCKD_PERSON);
-        DynamicObjectCollection contribBillList = QueryServiceHelper.query(ContributionConstant.CONTRIBBILL_ENTITYID, scoreItemConfFieldBuilder.buildSelect(), new QFilter[]{contribBillFilter}, scoreItemConfFieldBuilder.buildOrder());
-        logger.info("科研创新积分查询完成,查询结果数量: {}", contribBillList.size());
-        Map<Long, List<DynamicObject>> contribMap = contribBillList.stream()
-                .collect(Collectors.groupingBy(obj ->
-                        obj.getLong(String.join(".",FormConstant.NCKD_ENTRYENTITY, FormConstant.NCKD_PERSON, FormConstant.ID_KEY))
-                ));
-        logger.info("科研创新积分分组完成,分组后Map大小: {}", contribMap.size());
-
-        //查询当前已聘任的高级人才
-        logger.info("开始查询当前已聘任的高级人才");
-        QFilter keyFilter = new QFilter(PositionStructureConstant.NCKD_DISABLE, QCP.equals, EnableEnum.NO.getCode())
-                .and(PositionStructureConstant.NCKD_TYPESTATE,QCP.equals, TypeStateEnum.HIGH_PROFESSIONAL_EMPLOYMENT.getCode());
-        QueryFieldBuilder keyFieldBuilder = QueryFieldBuilder.create()
-                .addIdNumberName(PositionStructureConstant.NCKD_PERSON)
-                .addIdNumberName(PositionStructureConstant.NCKD_JOBSEQHR)
-                .addIdNumberNameWithExtras(new String[]{PositionStructureConstant.NCKD_JOBLEVELHR},FormConstant.JOBLEVELSEQ)
-                .add(PositionStructureConstant.NCKD_BEGINDATE)
-                .orderDesc(PositionStructureConstant.NCKD_BEGINDATE);
-        DynamicObjectCollection keyList = QueryServiceHelper.query(PositionStructureConstant.PERSONPOSFILE_ENTITYID, keyFieldBuilder.buildSelect(), new QFilter[]{keyFilter}, keyFieldBuilder.buildOrder());
-        logger.info("高级人才查询完成,查询结果数量: {}", keyList.size());
-        // 按人员分组,取最新一条记录
-        Map<Long, DynamicObject> keyListLatestMap = keyList.stream()
-                .collect(Collectors.groupingBy(
-                        obj -> obj.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY)),
-                        Collectors.toList()
-                ))
-                .entrySet()
-                .stream()
-                .collect(Collectors.toMap(
-                        Map.Entry::getKey,
-                        entry -> entry.getValue().get(0) // 由于已按日期降序排列,取第一条即为最新
-                ));
-        logger.info("高级人才分组完成,分组后Map大小: {}", keyListLatestMap.size());
 
         //开始
         logger.info("开始处理员工数据,总员工数: {}", empPosOrgRelMap.size());
@@ -225,39 +135,20 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
         for (DynamicObject person : empPosOrgRelMap.values()) {
             long personId = person.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY));
             logger.debug("处理员工ID: {}", personId);
-            DynamicObject personPosFile = personPosLatestMap.get(personId);
             int jobLevelSeq = -2;
             String jobSeqNumber = null;
             DynamicObject jobSeqObj = null;
-            if(personPosFile == null){
-                continue;
-                /*DynamicObject position = person.getDynamicObject(FormConstant.POSITION_KEY);
-                if(position != null) {
-                    jobSeqObj = position.getDynamicObject(FormConstant.NCKD_JOBSEQ);
-                    if(jobSeqObj != null) {
-                        jobSeqNumber = jobSeqObj.getString(FormConstant.NUMBER_KEY);
-                    }
-                }*/
-            }else{
-                jobLevelSeq = personPosFile.getInt(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.JOBLEVELSEQ));
-                jobSeqNumber = personPosFile.getString(String.join(".", PositionStructureConstant.NCKD_JOBSEQHR, FormConstant.NUMBER_KEY));
-                long jobSeqId = personPosFile.getLong(String.join(".", PositionStructureConstant.NCKD_JOBSEQHR, FormConstant.ID_KEY));
-                jobSeqObj = EntityHelper.newEntity(FormConstant.HBJM_JOBSEQHR,jobSeqId);
+            DynamicObject position = person.getDynamicObject(FormConstant.POSITION_KEY);
+            if(position != null) {
+                jobSeqObj = position.getDynamicObject(FormConstant.NCKD_JOBSEQ);
+                if(jobSeqObj != null) {
+                    jobSeqNumber = jobSeqObj.getString(FormConstant.NUMBER_KEY);
+                }
             }
             if(StringUtils.isBlank(jobSeqNumber)){
                 logger.debug("员工ID {} 的职位序列号为空,跳过处理", personId);
                 continue;
             }
-            DynamicObject perSerLe = perSerLenMap.get(personId);
-            BigDecimal socialWorkAge = perSerLe != null ? perSerLe.getBigDecimal(FormConstant.SOCIALWORKAGE) : BigDecimal.ZERO;
-            DynamicObject keyDynObj = keyListLatestMap.get(personId);
-            //当前高级人才聘任的职级
-            int keyJobLevelSeq = 0;
-            if(keyDynObj != null){
-                keyJobLevelSeq = keyDynObj.getInt(String.join(".", PositionStructureConstant.NCKD_JOBLEVELHR, FormConstant.JOBLEVELSEQ));
-            }
-            logger.debug("员工ID: {}, 职位序列号: {}, 当前职级: {}, 工龄: {}, 高级人才职级: {}", 
-                personId, jobSeqNumber, jobLevelSeq, socialWorkAge, keyJobLevelSeq);
             
             List<DynamicObject> perfManagerResult = perfManagerResultMap.get(personId);
             logger.debug("员工ID {} 查询到考核结果数量: {}", personId, perfManagerResult != null ? perfManagerResult.size() : 0);
@@ -295,9 +186,6 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
                     currentYear - 3, appraisalResultYearName3);
             }
 
-            //科研、创新、创效成果
-            List<DynamicObject> contribList = contribMap.get(personId);
-            logger.debug("员工ID {} 查询到科研创新成果数量: {}", personId, contribList != null ? contribList.size() : 0);
 
             List<Integer> jobLevelList = jobSeqJobLevelMap.get(jobSeqNumber);
             if(jobLevelList == null){
@@ -309,110 +197,56 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
             logger.debug("员工ID {} 职位序列: {}, 处理职级列表: {}", personId, jobSeq.getName(), jobLevelList);
             for (Integer jobLevel : jobLevelList) {
                 logger.debug("处理员工ID {} 的职级: {}", personId, jobLevel);
-                boolean isInnovation = false;
                 boolean isAppraisalResult = false;
-                boolean isWorkYear= false;
+                boolean isAppoint = false;
                 if(jobSeq == JobSeqEnum.TECHNICALS){
                     //技术
                     if(jobLevel == 13){
-                        logger.debug("员工ID {} 技术序列13级条件判断", personId);
-                        isInnovation = hasFactoryTechInnovationThirdPrizeOrAbove(contribList);
-                        logger.debug("员工ID {} 技术序列13级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上
                         isAppraisalResult = isAllAppraisalQualifyOrAbove(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技术序列13级绩效条件判断结果: {}", personId, isAppraisalResult);
 
-                        //工作年限≥10 年,任前职级7至12级
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(10)) >= 0 && jobLevelSeq > 7;
-                        logger.debug("员工ID {} 技术序列13级工作年限条件判断结果: {}, 工龄: {}, 当前职级: {}", personId, isWorkYear, socialWorkAge, jobLevelSeq);
 
                     }else if(jobLevel == 14){
-                        logger.debug("员工ID {} 技术序列14级条件判断", personId);
-                        isInnovation = hasFactoryTechSecondAndCompanyTechThird(contribList);
-                        logger.debug("员工ID {} 技术序列14级创新条件判断结果: {}", personId, isInnovation);
-
                         // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技术序列14级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //在13职级工作不少于一个聘期
-                        isWorkYear = keyJobLevelSeq >= 13;
-                        logger.debug("员工ID {} 技术序列14级工作年限条件判断结果: {}, 高级人才职级: {}", personId, isWorkYear, keyJobLevelSeq);
                     }else if(jobLevel == 15){
                         logger.debug("员工ID {} 技术序列15级条件判断", personId);
-                        isInnovation = hasCompanyTechSecondAndProvinceTechThird(contribList);
-                        logger.debug("员工ID {} 技术序列15级创新条件判断结果: {}", personId, isInnovation);
-                        // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
+
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技术序列15级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //工作年限≥15年,在14职级工作不少于一个聘期
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(15)) >= 0 && keyJobLevelSeq >= 14;
-                        logger.debug("员工ID {} 技术序列15级工作年限条件判断结果: {}, 工龄: {}, 高级人才职级: {}", personId, isWorkYear, socialWorkAge, keyJobLevelSeq);
+
                     }
                 }else if(jobSeq == JobSeqEnum.FUNCTIONAL){
                     //职能序列
                     if(jobLevel == 13){
-                        logger.debug("员工ID {} 职能序列13级条件判断", personId);
-                        isInnovation = hasCompanyManagementInnovationThird(contribList);
-                        logger.debug("员工ID {} 职能序列13级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上
                         isAppraisalResult = isAllAppraisalQualifyOrAbove(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 职能序列13级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //工作年限≥10 年,任前职级7至12级
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(10)) >= 0 && jobLevelSeq > 7;
-                        logger.debug("员工ID {} 职能序列13级工作年限条件判断结果: {}, 工龄: {}, 当前职级: {}", personId, isWorkYear, socialWorkAge, jobLevelSeq);
                     }else if(jobLevel == 14){
-                        logger.debug("员工ID {} 职能序列14级条件判断", personId);
-                        isInnovation = hasCompanyManagementInnovationSecond(contribList);
-                        logger.debug("员工ID {} 职能序列14级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 职能序列14级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //在13职级工作不少于一个聘期
-                        isWorkYear = keyJobLevelSeq >= 13;
-                        logger.debug("员工ID {} 职能序列14级工作年限条件判断结果: {}, 高级人才职级: {}", personId, isWorkYear, keyJobLevelSeq);
                     }else if(jobLevel == 15){
-                        logger.debug("员工ID {} 职能序列15级条件判断", personId);
-                        isInnovation = hasCompanyManagementInnovationFirst(contribList);
-                        logger.debug("员工ID {} 职能序列15级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 职能序列15级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //工作年限≥15年,在14职级工作不少于一个聘期
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(15)) >= 0 && keyJobLevelSeq >= 14;
-                        logger.debug("员工ID {} 职能序列15级工作年限条件判断结果: {}, 工龄: {}, 高级人才职级: {}", personId, isWorkYear, socialWorkAge, keyJobLevelSeq);
                     }
                 }else if(jobSeq == JobSeqEnum.SKILL){
                     //技能序列
                     if(jobLevel == 12){
-                        logger.debug("员工ID {} 技能序列12级条件判断", personId);
-                        isInnovation = hasFactoryInnovationThird(contribList);
-                        logger.debug("员工ID {} 技能序列12级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上
                         isAppraisalResult = isAllAppraisalQualifyOrAbove(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技能序列12级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //工作年限≥10 年,任前职级7至11级
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(10)) >= 0 && jobLevelSeq > 7;
-                        logger.debug("员工ID {} 技能序列12级工作年限条件判断结果: {}, 工龄: {}, 当前职级: {}", personId, isWorkYear, socialWorkAge, jobLevelSeq);
                     }else if(jobLevel == 13){
-                        logger.debug("员工ID {} 技能序列13级条件判断", personId);
-                        isInnovation = hasFactoryInnovationSecondAndCompanyTechThird(contribList);
-                        logger.debug("员工ID {} 技能序列13级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技能序列13级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //在12职级工作不少于一个聘期
-                        isWorkYear = keyJobLevelSeq >= 12;
-                        logger.debug("员工ID {} 技能序列13级工作年限条件判断结果: {}, 高级人才职级: {}", personId, isWorkYear, keyJobLevelSeq);
                     }else if(jobLevel == 14){
-                        logger.debug("员工ID {} 技能序列14级条件判断", personId);
-                        isInnovation = hasCompanyInnovationSecondAndProvinceTechThird(contribList);
-                        logger.debug("员工ID {} 技能序列14级创新条件判断结果: {}", personId, isInnovation);
                         // 判断近3年绩效定格均在合格及以上,且至少有一次优秀
                         isAppraisalResult = isAllAppraisalQualifyOrAboveWithExcellent(appraisalResultYear1, appraisalResultYear2, appraisalResultYear3);
                         logger.debug("员工ID {} 技能序列14级绩效条件判断结果: {}", personId, isAppraisalResult);
-                        //工作年限≥15年,在13职级工作不少于一个聘期
-                        isWorkYear = socialWorkAge.compareTo(new BigDecimal(15)) >= 0 && keyJobLevelSeq >= 13;
-                        logger.debug("员工ID {} 技能序列14级工作年限条件判断结果: {}, 工龄: {}, 高级人才职级: {}", personId, isWorkYear, socialWorkAge, keyJobLevelSeq);
                     }
                 }
                 String appraisalResultsDisplay = String.join("、",
@@ -420,30 +254,20 @@ public class KeyBeHavEvalTask extends AbstractTask implements Plugin {
                         appraisalResultYearName2 != null ? appraisalResultYearName2 : "无",
                         appraisalResultYearName3 != null ? appraisalResultYearName3 : "无");
                 StringJoiner matchCondDescJoin = new StringJoiner(StrFormatter.LINE_SEPARATOR);
-                String contribString = getContribString(contribList);
-                matchCondDescJoin.add(StrFormatter.format("职位序列:{},匹配职级:{},员工职位档案最新职级:{}",jobSeq.getName(),jobLevel,jobLevelSeq == -2 ? "无" : jobLevelSeq));
-                matchCondDescJoin.add(StrFormatter.format("科研、创新、创效成果:【{}】,获奖情况:{}",(isInnovation ? "满足" : "不满足"),StringUtils.isBlank(contribString) ? "无" : contribString));
+                matchCondDescJoin.add(StrFormatter.format("职位序列:{}",jobSeq.getName()));
                 matchCondDescJoin.add(StrFormatter.format("绩效表现:【{}】,近三年考核结果:【{}】",(isAppraisalResult ? "满足" : "不满足"),appraisalResultsDisplay));
-                matchCondDescJoin.add(StrFormatter.format("工作年限:【{}】,工龄:【{}】,员工职位档案最新职级:【{}】,高级人才聘任职级:【{}】",
-                        (isWorkYear ? "满足" : "不满足"),
-                        socialWorkAge != null ? socialWorkAge.setScale(2, RoundingMode.HALF_UP) : BigDecimal.ZERO,
-                        jobLevelSeq == -2 ? "无" : jobLevelSeq,
-                        keyDynObj != null ? keyJobLevelSeq : "无"));
                 DynamicObject keyBeHavEval = EntityHelper.newEntity(PositionStructureConstant.KEYBEHAVEVAL_ENTITYID);
                 keyBeHavEval.set(FormConstant.NCKD_PERSON, person.getDynamicObject(FormConstant.EMPLOYEE_KEY));
                 keyBeHavEval.set(FormConstant.NCKD_DEP, person.getDynamicObject(FormConstant.ADMINORG));
                 keyBeHavEval.set(FormConstant.NCKD_POSITION_KEY, person.getDynamicObject(FormConstant.POSITION_KEY));
                 keyBeHavEval.set(FormConstant.NCKD_JOBSEQ, jobSeqObj);
                 keyBeHavEval.set(PositionStructureConstant.NCKD_JOBLEVEL, jobLevel);
-                keyBeHavEval.set(PositionStructureConstant.NCKD_INNOVATE, isInnovation ? EnableEnum.YES.getCode() : EnableEnum.NO.getCode());
-                keyBeHavEval.set(PositionStructureConstant.NCKD_WORKYEAR, isWorkYear ? EnableEnum.YES.getCode() : EnableEnum.NO.getCode());
+                keyBeHavEval.set(PositionStructureConstant.NCKD_APPOINT, isAppoint ? EnableEnum.YES.getCode() : EnableEnum.NO.getCode());
                 keyBeHavEval.set(PositionStructureConstant.NCKD_APPRAISALRESULT, isAppraisalResult ? EnableEnum.YES.getCode() : EnableEnum.NO.getCode());
                 keyBeHavEval.set(PositionStructureConstant.NCKD_MATCHCONDDESC+"_tag", matchCondDescJoin.toString());
                 keyBeHavEval.set(PositionStructureConstant.STATUS,  StatusEnum.C.toString());
                 keyBeHavEval.set(PositionStructureConstant.ENABLE,  EnableEnum.YES.getCode());
 
-                logger.debug("员工ID {} 职级 {} 的评估结果: 创新条件={}, 绩效条件={}, 工作年限条件={}", 
-                    personId, jobLevel, isInnovation, isAppraisalResult, isWorkYear);
                 saveKeyBeHavEval.add(keyBeHavEval);
                 processedCount++;
             }

+ 9 - 0
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/result/AnnualPerfDetailFormPlugin.java

@@ -12,6 +12,7 @@ import kd.bos.form.FormShowParameter;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.ShowType;
 import kd.bos.form.events.AfterDoOperationEventArgs;
+import kd.bos.form.events.PreOpenFormEventArgs;
 import kd.bos.form.plugin.AbstractFormPlugin;
 import kd.bos.report.ReportList;
 import kd.bos.servicehelper.operation.OperationServiceHelper;
@@ -36,6 +37,14 @@ import java.util.stream.Stream;
 */
 public class AnnualPerfDetailFormPlugin extends AbstractFormPlugin implements Plugin {
 
+    @Override
+    public void preOpenForm(PreOpenFormEventArgs e) {
+        // 1. 获取表单显示参数对象
+        FormShowParameter showParameter = (FormShowParameter) e.getSource();
+        // 2. 设置页面标题
+        showParameter.setCaption("年度绩效结果明细");
+        super.preOpenForm(e);
+    }
 
     @Override
     public void afterDoOperation(AfterDoOperationEventArgs e) {

+ 1 - 0
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/result/AnnualPerfDetailReportListDataPlugin.java

@@ -33,6 +33,7 @@ import java.util.Map;
 */
 public class AnnualPerfDetailReportListDataPlugin extends AbstractReportListDataPlugin implements Plugin {
 
+
     @Override
     public DataSet query(ReportQueryParam reportQueryParam, Object o) throws Throwable {