Browse Source

feat(hr): 添加优秀生津贴功能模块

- 新增优秀生津贴常量类ExcellsConstant定义相关字段
- 实现优秀生津贴表单插件ExcellentssAllowanceFormPlugin
- 在FormConstant中添加全日制和最高学历常量
- 更新员工岗位组织关系查询条件增加在岗状态筛选
- 优化绩效明细报表取数插件移除冗余导入
wyc 1 tuần trước cách đây
mục cha
commit
3489b6ec95

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

@@ -486,5 +486,9 @@ public class FormConstant {
     public static final String NCKD_JOBTJOBTYPMAIN_LEAVE_NUMBER = "05";
     /**工龄年限*/
     public static final String SOCIALWORKAGE = "socialworkage";
+    /**是否最高学历*/
+    public static final String NCKD_ISHIGHDEG = "nckd_ishighdeg";
+    /**全日制*/
+    public static final String ISFULLTIME = "isfulltime";
 
 }

+ 3 - 1
code/base/nckd-jxccl-base-helper/src/main/java/nckd/jxccl/base/hrpi/helper/EmpPosOrgRelHelper.java

@@ -171,7 +171,9 @@ public class EmpPosOrgRelHelper {
                 .and(FormConstant.IS_PRIMARY, QCP.equals, EnableEnum.YES.getCode())
                 .and(FormConstant.STARTDATE, QCP.less_equals, new Date())
                 .and(FormConstant.ENDDATE, QCP.large_equals, new Date())
-                .and(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode());
+                .and(FormConstant.ISCURRENTDATA, QCP.equals, EnableEnum.YES.getCode())
+                //在岗
+                .and(String.join( ".", FormConstant.POS_STATUS, FormConstant.POST_STATE_CLS, FormConstant.NUMBER_KEY),QCP.equals,"1010_S");
 
         // 添加额外查询条件(如果有)
         if (otherFilter != null) {

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/business/.gitkeep


+ 39 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/common/ExcellsConstant.java

@@ -0,0 +1,39 @@
+package nckd.jxccl.hr.excells.common;
+
+import nckd.jxccl.base.common.constant.FormConstant;
+
+/**
+ * 优秀生津贴常量类
+ *
+ * @author W.Y.C
+ * @version 1.0
+ * @date 2026-01-02 20:48:06
+ */
+public class ExcellsConstant extends FormConstant {
+    /** 优秀生津贴-实体标识 */
+    public static final String ENTITYID = "nckd_excellentssallowance";
+    /** 金额 */
+    public static final String NCKD_MONEY = "nckd_money";
+    /** 生效日期 */
+    public static final String NCKD_EFFDT = "nckd_effdt";
+    /** 失效日期 */
+    public static final String NCKD_LEFFDT = "nckd_leffdt";
+    /** 说明 */
+    public static final String NCKD_DESC = "nckd_desc";
+    /** 岗位 */
+    public static final String NCKD_POSITION = "nckd_position";
+    /** 全日制最高学历 */
+    public static final String NCKD_PEREDUEXP = "nckd_pereduexp";
+    /** 优秀生类型 */
+    public static final String NCKD_HONORTYPE = "nckd_honortype";
+    /** 本科专业 */
+    public static final String NCKD_UNDERGRADMAJOR = "nckd_undergradmajor";
+    /** 本科毕业学校 */
+    public static final String NCKD_UNIV = "nckd_univ";
+    /** 上年度绩效结果 */
+    public static final String NCKD_APPRAISALRESULT = "nckd_appraisalresult";
+    /** 上年度单元排名 */
+    public static final String NCKD_RANKANDTOTAL = "nckd_rankandtotal";
+    /** 全日制最高学历毕业时间(折算)*/
+    public static final String NCKD_FTTOPGRAD = "nckd_fttopgrad";
+}

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/mservice/.gitkeep


+ 279 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/plugin/form/ExcellentssAllowanceFormPlugin.java

@@ -0,0 +1,279 @@
+package nckd.jxccl.hr.excells.plugin.form;
+
+import kd.bos.common.enums.EnableEnum;
+import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.dataentity.entity.DynamicObjectCollection;
+import kd.bos.dataentity.entity.ILocaleString;
+import kd.bos.dataentity.metadata.IDataEntityProperty;
+import kd.bos.entity.BasedataEntityType;
+import kd.bos.entity.EntityMetadataCache;
+import kd.bos.entity.MainEntityType;
+import kd.bos.entity.datamodel.events.ChangeData;
+import kd.bos.entity.datamodel.events.IDataModelChangeListener;
+import kd.bos.entity.datamodel.events.PropertyChangedArgs;
+import kd.bos.entity.property.BasedataProp;
+import kd.bos.form.field.BasedataEdit;
+import kd.bos.form.field.events.AfterBindingDataEvent;
+import kd.bos.form.field.events.BasedataEditListener;
+import kd.bos.form.field.events.BeforeF7SelectEvent;
+import kd.bos.form.field.events.BeforeF7SelectListener;
+import kd.bos.form.plugin.AbstractFormPlugin;
+import kd.bos.orm.query.QCP;
+import kd.bos.orm.query.QFilter;
+import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.QueryServiceHelper;
+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 nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.entity.helper.EntityHelper;
+import nckd.jxccl.base.hrpi.helper.EmpPosOrgRelHelper;
+import nckd.jxccl.hr.excells.common.ExcellsConstant;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.EventObject;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+* 优秀生津贴
+* 实体标识:nckd_excellentssallowance
+* @author W.Y.C
+* @date 2026/1/2 20:49
+* @version 1.0
+*/
+public class ExcellentssAllowanceFormPlugin extends AbstractFormPlugin implements Plugin, BeforeF7SelectListener, BasedataEditListener, IDataModelChangeListener {
+
+    @Override
+    public void registerListener(EventObject e) {
+        // 1. 获取基础资料字段控件
+        BasedataEdit materialEdit = this.getView().getControl(FormConstant.NCKD_PERSON);
+        if(materialEdit != null) {
+            // 2. 注册 beforeF7Select 事件监听器
+            materialEdit.addBeforeF7SelectListener(this);
+        }
+
+        BasedataEdit mulEdit = this.getControl("nckd_pereduexp");
+        mulEdit.addBasedataEditListener(this);
+    }
+
+
+    @Override
+    public void beforeF7Select(BeforeF7SelectEvent event) {
+        String fieldName = event.getProperty().getName();
+        if (FormConstant.NCKD_PERSON.equals(fieldName)) {
+            //查询优秀生
+            QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberName(FormConstant.EMPLOYEE_KEY).add("nckd_fttopgrad");
+            QFilter qFilter = new QFilter(ExcellsConstant.NCKD_HONORTYPE, QCP.is_notnull, null)
+                    .and(ExcellsConstant.NCKD_HONORTYPE, QCP.large_equals, 0);
+            DynamicObjectCollection query = QueryServiceHelper.query("nckd_hrpi_topstudent", queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+            LocalDateTime tenYearsAgo = DateUtil.addYears(DateUtil.now(), 10);
+
+            Date date = DateUtil.toDate(tenYearsAgo);
+            List<Long> personId = query.stream()
+                    .filter(dynamicObject -> {
+                        Date nckdFttopgrad = dynamicObject.getDate("nckd_fttopgrad");
+                        if (nckdFttopgrad == null) {
+                            return false; // 排除空值
+                        }
+                        LocalDateTime nckdFttopgradLocalDateTime = DateUtil.toLocalDateTime(nckdFttopgrad);
+                        return nckdFttopgrad.compareTo(date) <= 0;
+                    })
+                    .map(dynamicObject -> dynamicObject.getLong(String.join(".", FormConstant.EMPLOYEE_KEY, FormConstant.ID_KEY)))
+                    .collect(Collectors.toList());
+            // 4. 创建过滤条件:物料编码 like 'Item%'
+            QFilter filter = new QFilter(FormConstant.ID_KEY, QCP.in, personId);
+            // 5. 将条件添加到事件中
+            event.getCustomQFilters().add(filter);
+        }
+    }
+
+    @Override
+    public void propertyChanged(PropertyChangedArgs e) {
+        String name = e.getProperty().getName();
+        ChangeData[] changeSet = e.getChangeSet();
+        Object newValue = changeSet[0].getNewValue();
+        Object oldValue = changeSet[0].getOldValue();
+        if(FormConstant.NCKD_PERSON.equalsIgnoreCase( name)){
+            int rowIndex = changeSet[0].getRowIndex();
+            if(newValue != null) {
+                if(!Objects.equals(newValue, oldValue)) {
+                    DynamicObject person = ConvertUtil.toDynamicObjectOrNull(newValue);
+                    if (person != null) {
+                        initValue(person.getLong(FormConstant.ID_KEY), rowIndex);
+
+                        Date effdt = ConvertUtil.toDate(this.getModel().getValue(ExcellsConstant.NCKD_EFFDT, rowIndex));
+                        if (effdt != null) {
+                            lastPerfRank(person.getLong(FormConstant.ID_KEY), effdt, rowIndex);
+                        }
+                    }
+                }
+
+            }else{
+                this.getModel().setValue(ExcellsConstant.NCKD_DEP,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_FTTOPGRAD,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_POSITION,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_UNIV,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_UNDERGRADMAJOR,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_PEREDUEXP,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_HONORTYPE,null,rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,null, rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, null,rowIndex);
+            }
+        }else if("nckd_effdt".equalsIgnoreCase( name)){
+            int rowIndex = changeSet[0].getRowIndex();
+            if(newValue != null) {
+                if(!Objects.equals(newValue, oldValue)) {
+                    Date date = ConvertUtil.toDate(this.getModel().getValue(ExcellsConstant.NCKD_EFFDT));
+
+                    Object value = this.getModel().getValue(FormConstant.NCKD_PERSON, rowIndex);
+                    if (date != null && value != null) {
+                        DynamicObject person = ConvertUtil.toDynamicObjectOrNull(value);
+                        if (person != null) {
+                            lastPerfRank(person.getLong(FormConstant.ID_KEY), date, rowIndex);
+                        }
+                    }
+                }
+            }else{
+                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,null, rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, null,rowIndex);
+            }
+
+
+
+        }
+    }
+
+    private void lastPerfRank(Long personId, Date date, int rowIndex) {
+        if(personId != null && personId > 0) {
+            Date lastDate = DateUtil.minusYears(date, 1);
+            //上年度绩效和排名
+            QueryFieldBuilder perfRankMgmtFieldBuilder = QueryFieldBuilder.create()
+                    .add("nckd_topranks")
+                    .addGroup(new String[]{"nckd_perfrankmgmtentry"}, "nckd_toprank")
+                    .addIdNumberName("nckd_perfrankmgmtentry", "nckd_appraisalresult");
+            QFilter qFilter1 = new QFilter(String.join(".", "nckd_perfrankmgmtentry", "nckd_person"), QCP.equals, personId)
+                    .and("nckd_theyear", QCP.less_equals, DateUtil.getYear(lastDate));
+            DynamicObjectCollection query = QueryServiceHelper.query("nckd_perfrankmgmt", perfRankMgmtFieldBuilder.buildSelect(), new QFilter[]{qFilter1});
+            if(!query.isEmpty()){
+                String topRanks = query.get(0).getString("nckd_topranks");
+                String topRank = query.get(0).getString(String.join(".", "nckd_perfrankmgmtentry", "nckd_toprank"));
+                this.getModel().setValue(ExcellsConstant.NCKD_RANKANDTOTAL,topRank+"/"+topRanks, rowIndex);
+                long appraisalResultId = query.get(0).getLong(String.join(".", "nckd_perfrankmgmtentry", "nckd_appraisalresult", FormConstant.ID_KEY));
+                if(appraisalResultId > 0) {
+                    DynamicObject dynamicObject = EntityHelper.newEntity("nckd_appraisalresult", appraisalResultId);
+                    String appraisalResultName = query.get(0).getString(String.join(".", "nckd_perfrankmgmtentry", "nckd_appraisalresult", FormConstant.NAME_KEY));
+                    dynamicObject.set(FormConstant.NAME_KEY, appraisalResultName);
+                    this.getModel().setValue(ExcellsConstant.NCKD_APPRAISALRESULT, dynamicObject,rowIndex);
+                }
+            }
+        }
+    }
+
+    private void initValue(Long personId,int rowIndex){
+        //任职经历
+        DynamicObject empPosOrgRel = EmpPosOrgRelHelper.queryEmpPosOrgRelByEmployees(personId);
+        if(empPosOrgRel != null) {
+            this.getModel().setValue(ExcellsConstant.NCKD_DEP,empPosOrgRel.getDynamicObject(FormConstant.ADMINORG),rowIndex);
+            this.getModel().setValue(ExcellsConstant.NCKD_POSITION,empPosOrgRel.getDynamicObject(FormConstant.POSITION_KEY),rowIndex);
+        }
+
+        //--------------------------- 最高学历 和 本科学历 begin --------------------------
+        QueryFieldBuilder perEduExpFieldBuilder = QueryFieldBuilder.create().add(FormConstant.ID_KEY);
+        QFilter highEducationFilter = new QFilter(ExcellsConstant.ISFULLTIME, QCP.equals, EnableEnum.YES.getCode());
+        //本科
+        QFilter undergradEducationFilter = new QFilter(String.join(".",ExcellsConstant.EDUCATION_KEY,FormConstant.NUMBER_KEY), QCP.equals, "1030_S");
+        QFilter educationFilter = highEducationFilter.or(undergradEducationFilter).and(FormConstant.EMPLOYEE_KEY, QCP.equals, personId);
+        DynamicObjectCollection perEduExp = QueryServiceHelper.query(FormConstant.HRPI_PEREDUEXP, perEduExpFieldBuilder.buildSelect(), new QFilter[]{educationFilter});
+        List<Long> eduExpIds = perEduExp.stream().map(dynamicObject -> dynamicObject.getLong(FormConstant.ID_KEY)).collect(Collectors.toList());
+        MainEntityType eduExpEntityType = EntityMetadataCache.getDataEntityType(FormConstant.HRPI_PEREDUEXP);
+        DynamicObject[] eduExpArray = BusinessDataServiceHelper.load(eduExpIds.toArray(new Long[0]), eduExpEntityType);
+        for (DynamicObject eduExp : eduExpArray) {
+            boolean isFulltime = eduExp.getBoolean(FormConstant.ISFULLTIME);
+            DynamicObject education = eduExp.getDynamicObject(ExcellsConstant.EDUCATION_KEY);
+            String educationNumber = education.getString(FormConstant.NUMBER_KEY);
+            if("1030_S".equalsIgnoreCase(educationNumber)){
+                this.getModel().setValue(ExcellsConstant.NCKD_UNIV,eduExp.getString("schoolrecord"),rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_UNDERGRADMAJOR,eduExp.getString("major"),rowIndex);
+            }
+            if(isFulltime){
+                this.getModel().setValue(ExcellsConstant.NCKD_PEREDUEXP,eduExp,rowIndex);
+            }
+        }
+        //--------------------------- 最高学历 和 本科学历 end --------------------------
+
+        //--------------------------- 优秀生类型 begin --------------------------
+        QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create().addIdNumberName(ExcellsConstant.NCKD_HONORTYPE).add(ExcellsConstant.NCKD_FTTOPGRAD);
+        QFilter qFilter = new QFilter(ExcellsConstant.NCKD_HONORTYPE, QCP.is_notnull, null)
+                .and(ExcellsConstant.NCKD_HONORTYPE, QCP.large_equals, 0)
+                .and(FormConstant.EMPLOYEE_KEY, QCP.equals, personId);
+        DynamicObjectCollection query = QueryServiceHelper.query("nckd_hrpi_topstudent", queryFieldBuilder.buildSelect(), new QFilter[]{qFilter});
+        if(!query.isEmpty()) {
+            List<Long> collect = query.stream().map(dynamicObject -> dynamicObject.getLong(String.join(".", ExcellsConstant.NCKD_HONORTYPE, FormConstant.ID_KEY))).collect(Collectors.toList());
+            MainEntityType honorTypeEntityType = EntityMetadataCache.getDataEntityType("nckd_hbss_honortype");
+            DynamicObject[] honorTypeArray = BusinessDataServiceHelper.load(collect.toArray(new Long[0]), honorTypeEntityType);
+            if (honorTypeArray != null && honorTypeArray.length > 0) {
+                this.getModel().setValue(ExcellsConstant.NCKD_HONORTYPE, honorTypeArray[0], rowIndex);
+                this.getModel().setValue(ExcellsConstant.NCKD_FTTOPGRAD, query.get(0).getDate(ExcellsConstant.NCKD_FTTOPGRAD), rowIndex);
+            }
+        }
+        //--------------------------- 优秀生类型 begin --------------------------
+    }
+
+
+    @Override
+    public void afterBindingData(AfterBindingDataEvent evt) {
+        BasedataEdit edit = (BasedataEdit) evt.getSource();
+        String fieldKey = edit.getFieldKey();
+        //修改“全日制最高学历”F7显示字段
+        if ("nckd_pereduexp".equalsIgnoreCase(fieldKey)) {
+            Object v = evt.getDataEntity();
+            Object editSearchProp = null;
+            Object displayProp = "";
+            if (v == null) {
+                return;
+            }
+
+            BasedataEntityType dt;
+            if (((DynamicObject) v).getDataEntityType() instanceof BasedataEntityType) {
+                dt = (BasedataEntityType) ((DynamicObject) v).getDataEntityType();
+            } else {
+                dt = (BasedataEntityType) ((BasedataProp) edit.getProperty()).getComplexType();
+            }
+
+            //获取数据包中的名称字段值
+            String nameKey = dt.getNameProperty();
+            IDataEntityProperty p2 = dt.findProperty(nameKey);
+            if (p2 != null) {
+                displayProp = p2.getValueFast(v);
+                if (displayProp instanceof ILocaleString) {
+                    displayProp = displayProp.toString();
+                }
+            }
+
+            //动态修改基础资料的显示属性为名称(部门)
+            if ("nckd_pereduexp".equals(edit.getKey())) {
+                nameKey = "education";
+            }
+            IDataEntityProperty p4 = dt.findProperty(nameKey);
+            if (p4 != null) {
+                Object valueFast = p4.getValueFast(v);
+                if (valueFast instanceof DynamicObject) {
+                    displayProp = ConvertUtil.toDynamicObjectOrNull(valueFast).getString(FormConstant.NAME_KEY);
+                    editSearchProp = ConvertUtil.toDynamicObjectOrNull(valueFast).getString(FormConstant.NUMBER_KEY);
+
+                }
+            }
+
+            //设置显示属性
+            evt.setDisplayProp(displayProp.toString());
+            //设置编辑显示属性
+            evt.setEditSearchProp(editSearchProp == null ? "" : editSearchProp.toString());
+
+        }
+    }
+
+}

+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/plugin/operate/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/plugin/other/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/plugin/report/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/plugin/workflow/.gitkeep


+ 0 - 0
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/excells/webapi/.gitkeep


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

@@ -1,7 +1,6 @@
 package nckd.jxccl.opmc.pm.plugin.form.print;
 
 import kd.bos.algo.DataSet;
-import kd.bos.algo.DataType;
 import kd.bos.algo.GroupbyDataSet;
 import kd.bos.algo.JoinType;
 import kd.bos.algo.Row;
@@ -10,23 +9,17 @@ import kd.bos.context.RequestContext;
 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.IReportBatchQueryInfo;
 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.bos.servicehelper.QueryServiceHelper;
 import kd.bos.servicehelper.model.PermissionStatus;
-import kd.fi.frm.mservice.algo.DistinctConcatAggFunction;
 import kd.hr.hbp.business.servicehelper.HRQueryEntityHelper;
-import kd.hr.hbp.common.cache.HRPageCache;
 import kd.sdk.hr.hbp.business.helper.permission.HRPermissionServiceHelper;
 import kd.sdk.plugin.Plugin;
 import nckd.jxccl.base.common.algo.DistinctConcatFunction;
@@ -44,7 +37,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 
 /**
 * 年度绩效结果明细-报表取数插件