Ver código fonte

feat(opmc): 实现考核周期批量修改功能

- 新增批量修改考核周期的入口和相关逻辑-优化考核周期生成逻辑,修复年份计算问题
- 完善考核周期保存校验规则,增强数据准确性
- 调整考核周期列表界面交互,支持批量操作
-修复考核周期删除时的历史周期判断逻辑
-优化考核周期实体查询和数据处理逻辑
- 增加考核周期分录数据的动态加载和展示
- 改进考核周期保存操作的参数传递和处理方式
-修复考核周期生成时的描述信息显示问题
- 优化考核周期批量操作的界面参数传递
wyc 2 semanas atrás
pai
commit
efa84c2f74

+ 8 - 2
code/hr/nckd-jxccl-hr/src/main/java/nckd/jxccl/hr/psms/plugin/operate/adjust/NewDynamicAdjustmentOperationPlugIn.java

@@ -9,6 +9,7 @@ import kd.bos.entity.ExtendedDataEntity;
 import kd.bos.entity.constant.StatusEnum;
 import kd.bos.entity.plugin.AbstractOperationServicePlugIn;
 import kd.bos.entity.plugin.AddValidatorsEventArgs;
+import kd.bos.entity.plugin.args.BeforeOperationArgs;
 import kd.bos.entity.plugin.args.BeginOperationTransactionArgs;
 import kd.bos.entity.validate.AbstractValidator;
 import kd.bos.logging.Log;
@@ -148,10 +149,15 @@ public class NewDynamicAdjustmentOperationPlugIn extends AbstractOperationServic
     }
 
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+    public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
         if(!this.getOperationResult().isSuccess()){
-            return;
+            e.setCancel(true);
         }
+    }
+
+    @Override
+    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+
         logger.info("【职位体系】-动态调整-开始");
         List<Long> personIds = new ArrayList<>(e.getDataEntities().length);
         List<DynamicObject> newPersonPosFiles = new ArrayList<>(e.getDataEntities().length);

+ 15 - 5
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/helper/PerfManagerHelper.java

@@ -2,12 +2,15 @@ package nckd.jxccl.opmc.pm.helper;
 
 import kd.bos.common.enums.EnableEnum;
 import kd.bos.dataentity.entity.DynamicObject;
+import kd.bos.entity.MainEntityType;
 import kd.bos.orm.query.QCP;
 import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.BusinessDataServiceHelper;
+import kd.bos.servicehelper.MetadataServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
 import nckd.jxccl.base.common.constant.FormConstant;
 import nckd.jxccl.base.common.utils.QueryFieldBuilder;
+import nckd.jxccl.base.orm.helper.QFilterCommonHelper;
 import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
 
 import java.util.ArrayList;
@@ -36,6 +39,13 @@ public class PerfManagerHelper {
         return getNewestPerfManagerByPerson(personIds,null);
     }
 
+    public static DynamicObject[] getById(Collection<Long> ids) {
+        QFilter filter = QFilterCommonHelper.getIdInFilter(ids);
+        MainEntityType dataEntityType = MetadataServiceHelper.getDataEntityType(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
+
+        return BusinessDataServiceHelper.load(ids.toArray(new Long[0]),dataEntityType);
+    }
+
 
     /**
      * 根据人员获取当前最新的考核周期(“是否当前最新记录 = true” 并且  “周期状态 = 1”)
@@ -58,8 +68,8 @@ public class PerfManagerHelper {
                 .add(PerfManagerFormConstant.NCKD_WHYEND)
                 .add(PerfManagerFormConstant.NCKD_THESTATUS)
                 .add(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST)
-                .addIdNumberName(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT})
-                .addIdNumberName(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALYEAR});
+                .addIdNumberName(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT)
+                .addGroup(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY},PerfManagerFormConstant.NCKD_APPRAISALRESULT,PerfManagerFormConstant.NCKD_APPRAISALYEAR,PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
 
         QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST, QCP.equals, EnableEnum.YES.getCode())
                 .and(new QFilter(PerfManagerFormConstant.NCKD_THESTATUS, QCP.equals, EnableEnum.YES.getCode()))
@@ -81,7 +91,7 @@ public class PerfManagerHelper {
      */
     public static List<DynamicObject> getNewestPerfManagerByPersonAndBeginYear(Collection<Long> personIds,QFilter otherFilter) {
         QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
-                .addIdNumberName()
+                .add(FormConstant.ID_KEY)
                 .addIdNumberName(FormConstant.NCKD_PERSON)
                 .addIdNumberName(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT)
                 .addIdNumberName(PerfManagerFormConstant.NCKD_SECONDYEARRESULT)
@@ -93,8 +103,8 @@ public class PerfManagerHelper {
                 .add(PerfManagerFormConstant.NCKD_THESTATUS)
                 .add(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST)
                 .add(PerfManagerFormConstant.CREATE_TIME_KEY)
-                .addIdNumberName(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT})
-                .addIdNumberName(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALYEAR})
+                .addIdNumberName(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY,PerfManagerFormConstant.NCKD_APPRAISALRESULT)
+                .addGroup(new String[]{PerfManagerFormConstant.NCKD_PERFMANAGERENTRY},PerfManagerFormConstant.NCKD_APPRAISALRESULT,PerfManagerFormConstant.NCKD_APPRAISALYEAR,PerfManagerFormConstant.NCKD_ISALLRANKSOURCE)
                 .orderDesc(PerfManagerFormConstant.NCKD_BEGINYEAR);
 
         QFilter filter = new QFilter(PerfManagerFormConstant.NCKD_PERSON, QCP.in, personIds);

+ 247 - 61
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/cycle/BatchEvalCycleFormPlugin.java

@@ -9,9 +9,10 @@ import kd.bos.entity.operate.result.IOperateInfo;
 import kd.bos.entity.operate.result.OperationResult;
 import kd.bos.form.ConfirmCallBackListener;
 import kd.bos.form.ConfirmTypes;
+import kd.bos.form.FormShowParameter;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.MessageBoxResult;
-import kd.bos.form.control.Control;
+import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.MessageBoxClosedEvent;
 import kd.bos.form.plugin.AbstractFormPlugin;
 import kd.bos.org.utils.DynamicObjectUtils;
@@ -25,16 +26,22 @@ import nckd.jxccl.base.common.utils.StrFormatter;
 import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
 import nckd.jxccl.opmc.pm.helper.PerfManagerHelper;
+import org.apache.commons.lang3.StringUtils;
 
 import java.time.LocalDateTime;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.Date;
 import java.util.EventObject;
 import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.StringJoiner;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 
 /**
@@ -47,54 +54,119 @@ import java.util.stream.Collectors;
 public class BatchEvalCycleFormPlugin extends AbstractFormPlugin implements Plugin {
 
     @Override
-    public void registerListener(EventObject e) {
-        this.addClickListeners(FormConstant.BTN_OK_OP);
-    }
-
+    public void afterCreateNewData(EventObject e) {
+        // 获取当前页面的FormShowParameter对象
+        FormShowParameter showParameter = this.getView().getFormShowParameter();
+        //获取列表选择的人员
+        String isAddOrUpdate = ConvertUtil.toStr(showParameter.getCustomParam("nckd_isaddorupdate"));
+        if("2".equalsIgnoreCase(isAddOrUpdate)) {
+            //批量修改
+            this.getModel().setValue("nckd_isaddorupdate", isAddOrUpdate);
+            this.getView().updateView("nckd_isaddorupdate");
 
-    @Override
-    public void click(EventObject evt) {
-
-        super.click(evt);
-        Control source = (Control)evt.getSource();
-        if(FormConstant.BTN_OK_OP.equalsIgnoreCase(source.getKey())){
-            DynamicObjectCollection perfManagerList = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-            Set<Long> personIds = new HashSet<>(perfManagerList.size());
-            //转换为考核周期实体
-            for (DynamicObject dynamicObject : perfManagerList) {
-                DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
-                personIds.add(person.getLong(FormConstant.ID_KEY));
+            List<Long> selectedRows = ConvertUtil.toList(showParameter.getCustomParam("selectedRows"));
+            int max = Math.max(selectedRows.size() - 1, 0);
+            if(max > 0) {
+                this.getModel().batchCreateNewEntryRow(FormConstant.NCKD_ENTRYENTITY, max);
             }
+            DynamicObject[] perfManagerList = PerfManagerHelper.getById(selectedRows);
+            AtomicInteger index = new AtomicInteger(0);
+            for (DynamicObject perfManager : perfManagerList) {
+                int i = index.getAndIncrement();
+                Date beginYear = perfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR);
+                Date endYear = perfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);
+                this.getModel().setValue(PerfManagerFormConstant.PERFMANAGER_ENTITYID,perfManager, i);
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_PERSON,perfManager.getDynamicObject(PerfManagerFormConstant.NCKD_PERSON), i);
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_BEGINYEAR,beginYear, i);
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_ENDYEAR,endYear, i);
+                this.getModel().setValue(PerfManagerFormConstant.DESCRIPTION_KEY,perfManager.getString(FormConstant.DESCRIPTION_KEY), i);
 
-            //最新上一考核周期
-            DynamicObject[] newestPerfManagerByPerson = PerfManagerHelper.getNewestPerfManagerByPerson(personIds);
-            Map<Long, DynamicObject> lastPerfManagerMap; lastPerfManagerMap = Arrays.stream(newestPerfManagerByPerson)
-                    .collect(Collectors.toMap(
-                            perfManager -> perfManager.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY),
-                            perfManager -> perfManager,
-                            (existing, replacement) -> existing
-                    ));
-            StringJoiner confirMmsg = new StringJoiner(",");
-            for (DynamicObject lastPerfManager : lastPerfManagerMap.values()) {
-                String personName = lastPerfManager.getDynamicObject(FormConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
-                LocalDateTime beginYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
-                LocalDateTime endYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
-                confirMmsg.add(StrFormatter.format("{}(周期:{}~{})", personName, beginYear.getYear(), endYear.getYear()));
-            }
-            if(confirMmsg.length() > 0){
-                // 创建回调监听器,指定回调ID和处理此回调的插件(this)
-                ConfirmCallBackListener confirmCallBacks = new ConfirmCallBackListener(PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID, this);
-                // 弹出确认框
-                this.getView().showConfirm(StrFormatter.format("检测到本次新增的人员中存在【未结束】的考核周期,新周期新增成功后会自动结束上一周期,请确认是否继续。{}", confirMmsg),
-                        MessageBoxOptions.OKCancel,
-                        ConfirmTypes.Default,
-                        confirmCallBacks);
-            }else{
-                executeOperateSave();
+                DynamicObjectCollection entrys = perfManager.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
+                for (DynamicObject entry : entrys) {
+                    boolean isAllRankSource = entry.getBoolean(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
+                    Date appraisalYear = entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+
+                    if (isAllRankSource && appraisalYear != null) {
+                        LocalDateTime appraisalLocalDate = DateUtil.toLocalDateTime(appraisalYear);
+                        LocalDateTime beginLocalDate = DateUtil.toLocalDateTime(beginYear);
+
+                        // 计算是第几年(分录中的年份-(周期开始时间 + 1))
+                        long yearsDiff = appraisalLocalDate.getYear() - beginLocalDate.getYear() + 1;
+                        // 根据年份差异禁用对应的考核结果字段
+                        switch ((int) yearsDiff) {
+                            case 1:
+                                this.getView().setEnable(Boolean.FALSE, i, PerfManagerFormConstant.NCKD_FIRSTYEARRESULT);
+                                break;
+                            case 2:
+                                this.getView().setEnable(Boolean.FALSE, i, PerfManagerFormConstant.NCKD_SECONDYEARRESULT);
+                                break;
+                            case 3:
+                                this.getView().setEnable(Boolean.FALSE, i, PerfManagerFormConstant.NCKD_THIRDYEARRESULT);
+                                break;
+                        }
+                    }
+                }
+
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT,perfManager.getDynamicObject(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT), i);
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_SECONDYEARRESULT,perfManager.getDynamicObject(PerfManagerFormConstant.NCKD_SECONDYEARRESULT), i);
+                this.getModel().setValue(PerfManagerFormConstant.NCKD_THIRDYEARRESULT,perfManager.getDynamicObject(PerfManagerFormConstant.NCKD_THIRDYEARRESULT), i);
             }
 
+            this.getView().updateView(FormConstant.NCKD_ENTRYENTITY);
         }
+    }
+
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        if(e.getOperationResult() != null && e.getOperationResult().isSuccess()){
+            String operateKey = e.getOperateKey();
+            if(FormConstant.CONFIRM_OP.equalsIgnoreCase(operateKey)){
+                String isAddOrUpdate = ConvertUtil.toStr(this.getModel().getValue("nckd_isaddorupdate"));
+                boolean isUpdate = "2".equalsIgnoreCase(isAddOrUpdate);
+
+                DynamicObjectCollection perfManagerList = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
+                Set<Long> personIds = new HashSet<>(perfManagerList.size());
+                //转换为考核周期实体
+                for (DynamicObject dynamicObject : perfManagerList) {
+                    DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
+                    personIds.add(person.getLong(FormConstant.ID_KEY));
+                }
+                if(isUpdate){
+                    //修改
+                    executeOperateSave();
+                }else{
+                    //新增
+                    //最新上一考核周期
+                    DynamicObject[] newestPerfManagerByPerson = PerfManagerHelper.getNewestPerfManagerByPerson(personIds);
+                    Map<Long, DynamicObject> lastPerfManagerMap; lastPerfManagerMap = Arrays.stream(newestPerfManagerByPerson)
+                            .collect(Collectors.toMap(
+                                    perfManager -> perfManager.getDynamicObject(FormConstant.NCKD_PERSON).getLong(FormConstant.ID_KEY),
+                                    perfManager -> perfManager,
+                                    (existing, replacement) -> existing
+                            ));
+                    StringJoiner confirMmsg = new StringJoiner(",");
+                    for (DynamicObject lastPerfManager : lastPerfManagerMap.values()) {
+                        String personName = lastPerfManager.getDynamicObject(FormConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
+                        LocalDateTime beginYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
+                        LocalDateTime endYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
+                        confirMmsg.add(StrFormatter.format("{}(周期:{}~{})", personName, beginYear.getYear(), endYear.getYear()));
+                    }
+                    if(confirMmsg.length() > 0){
+                        // 创建回调监听器,指定回调ID和处理此回调的插件(this)
+                        ConfirmCallBackListener confirmCallBacks = new ConfirmCallBackListener(PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID, this);
+                        // 弹出确认框
+                        this.getView().showConfirm(StrFormatter.format("检测到本次新增的人员中存在【未结束】的考核周期,新周期新增成功后会自动结束上一周期,并将上一周期结束时间更新为当前新周期开始年前一年。请确认是否继续。{}", confirMmsg),
+                                MessageBoxOptions.OKCancel,
+                                ConfirmTypes.Default,
+                                confirmCallBacks);
+                    }else{
+                        executeOperateSave();
+                    }
+                }
 
+            }
+        }
     }
 
     @Override
@@ -102,50 +174,164 @@ public class BatchEvalCycleFormPlugin extends AbstractFormPlugin implements Plug
         // 判断回调ID和用户点击的按钮
         if (PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID.equals(messageBoxClosedEvent.getCallBackId())
                 && messageBoxClosedEvent.getResult() == MessageBoxResult.Yes) {
-
             executeOperateSave();
         }
     }
 
     private void executeOperateSave() {
-        DynamicObject createorg = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(FormConstant.CREATEORG_KEY));
-        DynamicObject useorg = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(FormConstant.USEORG_KEY));
-        DynamicObject org = ConvertUtil.toDynamicObjectOrNull(this.getModel().getValue(FormConstant.ORG_KEY));
 
+        String isAddOrUpdate = ConvertUtil.toStr(this.getModel().getValue("nckd_isaddorupdate"));
+        boolean isUpdate = "2".equalsIgnoreCase(isAddOrUpdate);
         DynamicObjectCollection perfManagerList = this.getModel().getEntryEntity(FormConstant.NCKD_ENTRYENTITY);
-        Set<Long> personIds = new HashSet<>(perfManagerList.size());
-        List<DynamicObject> savePerfManager = new ArrayList<>();
+        List<Long> perfManagerIds = Collections.emptyList();
+        Map<Long, DynamicObject> perfManagerMap = null;
+        if(isUpdate){
+            perfManagerIds = perfManagerList.stream()
+                    .map(dynamicObject -> dynamicObject.getDynamicObject(PerfManagerFormConstant.PERFMANAGER_ENTITYID))
+                    .filter(Objects::nonNull)
+                    .map(perfManager -> perfManager.getLong(FormConstant.ID_KEY))
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
+            DynamicObject[] byId = PerfManagerHelper.getById(perfManagerIds);
+            perfManagerMap = Arrays.stream(byId)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toMap(
+                            perfManager -> perfManager.getLong(FormConstant.ID_KEY),
+                            perfManager -> perfManager,
+                            (existing, replacement) -> existing
+                    ));
+        }
+        List<DynamicObject> savePerfManagerList = new ArrayList<>();
+
         //转换为考核周期实体
         for (DynamicObject dynamicObject : perfManagerList) {
             DynamicObject person = dynamicObject.getDynamicObject(FormConstant.NCKD_PERSON);
             String personName = person.getString(FormConstant.NAME_KEY);
             LocalDateTime beginYear = DateUtil.toLocalDateTime(dynamicObject.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
             LocalDateTime endYear = DateUtil.toLocalDateTime(dynamicObject.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
-            DynamicObject newPerfManager = EntityHelper.newAvailableBasicEntity(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
-            DynamicObjectUtils.copy(dynamicObject, newPerfManager);
-            newPerfManager.set(PerfManagerFormConstant.CREATEORG_KEY, createorg);
-            newPerfManager.set(PerfManagerFormConstant.USEORG_KEY, useorg);
-            newPerfManager.set(PerfManagerFormConstant.ORG_KEY, org);
-            newPerfManager.set(PerfManagerFormConstant.CTRLSTRATEGY_KEY, CtrlStrategyEnum.GLOBAL_SHARE.getCtrlStrategy());
-            newPerfManager.set(FormConstant.NAME_KEY, StrFormatter.format("【{}】{}~{}的考核周期",personName,beginYear.getYear(),endYear.getYear()));
-            savePerfManager.add(newPerfManager);
-            personIds.add(person.getLong(FormConstant.ID_KEY));
+            String description = dynamicObject.getString(PerfManagerFormConstant.DESCRIPTION_KEY);
+            DynamicObject savePerfManager = null;
+            if(isUpdate){
+                //修改
+                DynamicObject perfManager = dynamicObject.getDynamicObject(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
+                long id = perfManager.getLong(FormConstant.ID_KEY);
+                DynamicObject dbPerfManager = perfManagerMap.get(id);
+
+
+                dbPerfManager.set(PerfManagerFormConstant.DESCRIPTION_KEY, description);
+                LocalDateTime dbBeginYear = DateUtil.toLocalDateTime(dbPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
+                LocalDateTime dbEndYear = DateUtil.toLocalDateTime(dbPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
+
+                boolean isCycleRangeChange = Boolean.FALSE;
+                DynamicObjectCollection dbPerfManagerEntry = dbPerfManager.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
+                if(!Objects.equals(dbBeginYear, beginYear)){
+                    isCycleRangeChange = true;
+                    dbPerfManager.set(PerfManagerFormConstant.NCKD_BEGINYEAR, DateUtil.toDate(beginYear));
+                }
+                if(!Objects.equals(dbEndYear, endYear)){
+                    isCycleRangeChange = true;
+                    dbPerfManager.set(PerfManagerFormConstant.NCKD_ENDYEAR, DateUtil.toDate(endYear));
+                }
+                Iterator<DynamicObject> iterator = dbPerfManagerEntry.iterator();
+                while (iterator.hasNext()) {
+                    DynamicObject entry = iterator.next();
+                    Date appraisalYear = entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+                    if (appraisalYear != null) {
+                        LocalDateTime appraisalLocalDate = DateUtil.toLocalDateTime(appraisalYear);
+                        long yearsDiff = appraisalLocalDate.getYear() - dbBeginYear.getYear();
+                        // 判断年份是否在范围外
+                        if (appraisalLocalDate.getYear() < beginYear.getYear() || appraisalLocalDate.getYear() > endYear.getYear()) {
+                            // 删除不在范围内的考核结果记录
+                            iterator.remove();
+                        }
+                    }
+                }
+
+                // 考核结果写回到分录,save操作的时候会将分录的结果写回到表头
+                DynamicObject firstYearResult = dynamicObject.getDynamicObject(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT);
+                DynamicObject secondYearResult = dynamicObject.getDynamicObject(PerfManagerFormConstant.NCKD_SECONDYEARRESULT);
+                DynamicObject thirdYearResult = dynamicObject.getDynamicObject(PerfManagerFormConstant.NCKD_THIRDYEARRESULT);
+
+                DynamicObject dbFirstYearResult = dbPerfManager.getDynamicObject(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT);
+                DynamicObject dbSecondYearResult = dbPerfManager.getDynamicObject(PerfManagerFormConstant.NCKD_SECONDYEARRESULT);
+                DynamicObject dbThirdYearResult = dbPerfManager.getDynamicObject(PerfManagerFormConstant.NCKD_THIRDYEARRESULT);
+
+                // 判断跟数据库的有没有变化,有变化才写回到分录
+               /* Long firstYearResultId = firstYearResult != null ? firstYearResult.getLong(FormConstant.ID_KEY) : null;
+                Long dbFirstYearResultId = dbFirstYearResult != null ? dbFirstYearResult.getLong(FormConstant.ID_KEY) : null;
+                if (!Objects.equals(firstYearResultId, dbFirstYearResultId) || isCycleRangeChange) {
+                    updateAppraisalResult(dbPerfManagerEntry, beginYear, firstYearResult, 0);
+                }
+
+                Long secondYearResultId = secondYearResult != null ? secondYearResult.getLong(FormConstant.ID_KEY) : null;
+                Long dbSecondYearResultId = dbSecondYearResult != null ? dbSecondYearResult.getLong(FormConstant.ID_KEY) : null;
+                if (!Objects.equals(secondYearResultId, dbSecondYearResultId) || isCycleRangeChange) {
+                    updateAppraisalResult(dbPerfManagerEntry, beginYear, secondYearResult, 1);
+                }
+
+                Long thirdYearResultId = thirdYearResult != null ? thirdYearResult.getLong(FormConstant.ID_KEY) : null;
+                Long dbThirdYearResultId = dbThirdYearResult != null ? dbThirdYearResult.getLong(FormConstant.ID_KEY) : null;
+                if (!Objects.equals(thirdYearResultId, dbThirdYearResultId) || isCycleRangeChange) {
+                    updateAppraisalResult(dbPerfManagerEntry, beginYear, thirdYearResult, 2);
+                }*/
+                savePerfManager = dbPerfManager;
+            }else{
+                //新增
+                savePerfManager = EntityHelper.newAvailableBasicEntity(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
+                DynamicObjectUtils.copy(dynamicObject, savePerfManager);
+                savePerfManager.set(PerfManagerFormConstant.CTRLSTRATEGY_KEY, CtrlStrategyEnum.GLOBAL_SHARE.getCtrlStrategy());
+                savePerfManager.set(FormConstant.NAME_KEY, StrFormatter.format("【{}】{}~{}的考核周期",personName,beginYear.getYear(),endYear.getYear()));
+            }
+            savePerfManagerList.add(savePerfManager);
         }
 
         OperateOption option = OperateOption.create();
         option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, Boolean.TRUE+"");
-        OperationResult operationResult =  OperationServiceHelper.executeOperate(FormConstant.SAVE_OP, PerfManagerFormConstant.PERFMANAGER_ENTITYID, savePerfManager.toArray(new DynamicObject[0]), option);
+        //告诉OP此次操作类型
+        option.setVariableValue("isUpdate", isUpdate+"");
+        OperationResult operationResult =  OperationServiceHelper.executeOperate(FormConstant.SAVE_OP, PerfManagerFormConstant.PERFMANAGER_ENTITYID, savePerfManagerList.toArray(new DynamicObject[0]), option);
 
         if (!operationResult.isSuccess()) {
-            StringJoiner errorMsg = new StringJoiner(StrFormatter.LINE_SEPARATOR);
+            StringJoiner errorMsgJoiner = new StringJoiner(StrFormatter.LINE_SEPARATOR);
             for (IOperateInfo error : operationResult.getAllErrorOrValidateInfo()) {
-                errorMsg.add(error.getMessage());
+                errorMsgJoiner.add(error.getMessage());
             }
-            throw new ValidationException(errorMsg.toString());
+            String errorMsg = errorMsgJoiner.toString();
+            if(StringUtils.isBlank(errorMsg)){
+                errorMsg = operationResult.getMessage();
+            }
+            throw new ValidationException(errorMsg);
         }else{
             this.getView().getParentView().showSuccessNotification("保存成功");
             this.getView().getParentView().invokeOperation(FormConstant.REFRESH_OP);
             this.getView().close();
         }
     }
+
+
+    private void updateAppraisalResult(DynamicObjectCollection perfManagerEntry,
+                                       LocalDateTime beginYear,
+                                       DynamicObject result,
+                                       int yearOffset) {
+        boolean isExist = false;
+        for (DynamicObject entry : perfManagerEntry) {
+            Date appraisalYear = entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+            if (appraisalYear != null) {
+                LocalDateTime appraisalLocalDate = DateUtil.toLocalDateTime(appraisalYear);
+                long yearsDiff = appraisalLocalDate.getYear() - beginYear.getYear();
+                if (yearsDiff == yearOffset) {
+                    entry.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, result);
+                    isExist = true;
+                    break;
+                }
+            }
+        }
+
+        if (!isExist) {
+            DynamicObject entry = perfManagerEntry.addNew();
+            entry.set(PerfManagerFormConstant.NCKD_APPRAISALYEAR,
+                    DateUtil.toDate(DateUtil.addYears(beginYear, yearOffset)));
+            entry.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, result);
+        }
+    }
 }

+ 35 - 31
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/form/cycle/PerfManagerListPlugin.java

@@ -1,55 +1,29 @@
 package nckd.jxccl.opmc.pm.plugin.form.cycle;
 
-import kd.bos.algo.Algo;
-import kd.bos.algo.AlgoContext;
-import kd.bos.algo.DataSet;
-import kd.bos.algo.Row;
-import kd.bos.common.enums.EnableEnum;
-import kd.bos.consts.PermItemConst;
-import kd.bos.context.RequestContext;
 import kd.bos.dataentity.OperateOption;
 import kd.bos.dataentity.entity.DynamicObject;
-import kd.bos.dataentity.entity.DynamicObjectCollection;
-import kd.bos.entity.EntityMetadataCache;
-import kd.bos.entity.QueryEntityType;
+import kd.bos.entity.datamodel.ListSelectedRowCollection;
 import kd.bos.entity.operate.OperateOptionConst;
-import kd.bos.entity.operate.result.IOperateInfo;
 import kd.bos.entity.operate.result.OperationResult;
-import kd.bos.ext.hr.service.query.QueryEntityHelper;
 import kd.bos.form.CloseCallBack;
 import kd.bos.form.FormShowParameter;
 import kd.bos.form.MessageBoxOptions;
 import kd.bos.form.ShowType;
+import kd.bos.form.StyleCss;
 import kd.bos.form.control.events.ItemClickEvent;
+import kd.bos.form.events.AfterDoOperationEventArgs;
 import kd.bos.form.events.BeforeDoOperationEventArgs;
-import kd.bos.form.events.ClosedCallBackEvent;
 import kd.bos.form.operate.FormOperate;
 import kd.bos.list.plugin.AbstractListPlugin;
-import kd.bos.orm.query.QCP;
-import kd.bos.orm.query.QFilter;
 import kd.bos.servicehelper.operation.OperationServiceHelper;
-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.constant.SystemQueryConstant;
-import nckd.jxccl.base.common.enums.AppraisalResultEnum;
 import nckd.jxccl.base.common.exception.ValidationException;
-import nckd.jxccl.base.common.utils.DateUtil;
-import nckd.jxccl.base.common.utils.QueryFieldBuilder;
-import nckd.jxccl.base.common.utils.StrFormatter;
+import nckd.jxccl.base.common.utils.ConvertUtil;
 import nckd.jxccl.base.entity.helper.EntityHelper;
 import nckd.jxccl.opmc.pm.common.PerfManagerFormConstant;
-import nckd.jxccl.opmc.pm.plugin.operate.cycle.PerfManagerSaveOpPlugin;
 
-import java.time.LocalDateTime;
-import java.util.ArrayList;
-import java.util.Date;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
-import java.util.StringJoiner;
 import java.util.stream.Collectors;
 
 /**
@@ -65,7 +39,6 @@ public class PerfManagerListPlugin extends AbstractListPlugin implements Plugin
     public void itemClick(ItemClickEvent evt) {
         String itemKey = evt.getItemKey();
         if ("nckd_new".equals(itemKey)) {
-            //弹出【批量】在职人员初定窗口
             FormShowParameter showParameter = new FormShowParameter();
             showParameter.setFormId(PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID);
             showParameter.getOpenStyle().setShowType(ShowType.Modal);
@@ -80,6 +53,7 @@ public class PerfManagerListPlugin extends AbstractListPlugin implements Plugin
     public void beforeDoOperation(BeforeDoOperationEventArgs args) {
         String operateKey = ((FormOperate) args.getSource()).getOperateKey();
         if (operateKey.equals("list_cyclegenerate")) {
+            //周期生成
             OperateOption option = OperateOption.create();
             option.setVariableValue(OperateOptionConst.IGNOREINTERACTION, Boolean.TRUE+"");
             DynamicObject perfManager = EntityHelper.newEntity(PerfManagerFormConstant.PERFMANAGER_ENTITYID);
@@ -100,4 +74,34 @@ public class PerfManagerListPlugin extends AbstractListPlugin implements Plugin
             }
         }
     }
+
+    @Override
+    public void afterDoOperation(AfterDoOperationEventArgs e) {
+        if(e.getOperationResult() != null && e.getOperationResult().isSuccess()) {
+            String operateKey = e.getOperateKey();
+            if ("batchupdate".equals(operateKey)) {
+
+                this.getView().setVisible(Boolean.FALSE, "nckd_advconbaritemap","nckd_advconbaritemap1");
+                ListSelectedRowCollection selectedRows = this.getSelectedRows();
+                FormShowParameter showParameter = new FormShowParameter();
+                showParameter.setFormId(PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID);
+                showParameter.getOpenStyle().setShowType(ShowType.Modal);
+                showParameter.setCaption("批量修改考核周期");
+                showParameter.setSendToClient(true);
+                showParameter.setCloseCallBack(new CloseCallBack(this, PerfManagerFormConstant.BATCHEVALCYCLE_ENTITYID));
+                showParameter.setCustomParam("nckd_isaddorupdate","2");
+                if(!selectedRows.isEmpty()) {
+                    List<Long> selectedIds = selectedRows.stream()
+                            .map(row -> ConvertUtil.toLong(row.getPrimaryKeyValue()))
+                            .collect(Collectors.toList());
+                    showParameter.setCustomParam("selectedRows", selectedIds);
+                }
+                StyleCss styleCss = new StyleCss();
+               /* styleCss.setWidth("1100");
+                styleCss.setHeight("600");*/
+                showParameter.getOpenStyle().setInlineStyleCss(styleCss);
+                this.getView().showForm(showParameter);
+            }
+        }
+    }
 }

+ 5 - 5
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/CycleGenerateOpPlugin.java

@@ -151,8 +151,8 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
      */
     public static Map<Long, PerfManagerSaveOpPlugin.PersonPerfInfo> getPendingCyclePersonnel() {
         LocalDateTime now = DateUtil.beginOfYear(DateUtil.now());
-        LocalDateTime lastDate = now;
-        // LocalDateTime lastDate = DateUtil.minusYears(now, 1);
+        // LocalDateTime lastDate = now;
+        LocalDateTime lastDate = DateUtil.minusYears(now, 1);
         LocalDateTime lastBegin = DateUtil.beginOfYear(lastDate);
         LocalDateTime lastEnd = DateUtil.endOfYear(lastDate);
 
@@ -325,7 +325,7 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
             person.set(FormConstant.NAME_KEY, personName);
 
             PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
-                    person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
+                    person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
             personPerfInfo.setId(id);
 
             LocalDateTime endYearLocalDateTime = DateUtil.toLocalDateTime(endYear);
@@ -395,7 +395,7 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
             person.set(FormConstant.NAME_KEY, personName);
 
             PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
-                    person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
+                    person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
             personPerfInfo.setId(personIdAndIdMap.get(filteredPersonId));
             personPerfInfo.setWhyEnd("上年度无绩效结果");
 
@@ -432,7 +432,7 @@ public class CycleGenerateOpPlugin extends AbstractOperationServicePlugIn implem
                 person.set(FormConstant.NAME_KEY, personName);
 
                 PerfManagerSaveOpPlugin.PersonPerfInfo personPerfInfo = new PerfManagerSaveOpPlugin.PersonPerfInfo(
-                        person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
+                        person, DateUtil.toDate(now), DateUtil.toDate(DateUtil.addYears(now, 2)), "周期生成");
                 personPerfInfo.setId(id);
                 personPerfInfo.setWhyEnd("三年考评周期结束(周期生成)");
 

+ 1 - 1
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/PerfManagerDeleteOpPlugin.java

@@ -43,7 +43,7 @@ public class PerfManagerDeleteOpPlugin extends AbstractOperationServicePlugIn im
                     DynamicObject data = rowDataEntity.getDataEntity();
                     boolean isCurrentNewest = data.getBoolean(PerfManagerFormConstant.NCKD_ISCURRENTNEWEST);
                     if(!isCurrentNewest){
-                        addMessage(rowDataEntity,"不能删除历史周期,只能删除最新考核周期");
+                        // addMessage(rowDataEntity,"不能删除历史周期,只能删除最新考核周期");
                     }
                     String theStatus = data.getString(PerfManagerFormConstant.NCKD_THESTATUS);
                     if(!"1".equalsIgnoreCase(theStatus)){

+ 120 - 72
code/opmc/nckd-jxccl-opmc/src/main/java/nckd/jxccl/opmc/pm/plugin/operate/cycle/PerfManagerSaveOpPlugin.java

@@ -23,6 +23,7 @@ import kd.bos.servicehelper.QueryServiceHelper;
 import kd.bos.servicehelper.operation.SaveServiceHelper;
 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.common.utils.StrFormatter;
@@ -32,7 +33,6 @@ import org.apache.commons.lang3.StringUtils;
 
 import java.time.LocalDateTime;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -51,11 +51,10 @@ import java.util.stream.Collectors;
  */
 public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn implements Plugin {
 
-    private List<PersonPerfInfo> personPerfInfos = new ArrayList<>();
 
-    private Map<Long, DynamicObject> lastPerfManagerMap;
+    private Map<Long, DynamicObject> lastPerfManagerMap = new HashMap<>();
 
-    private  List<Long> personIds;
+    private  List<Long> personIds = new ArrayList<>();
     private  List<Long> ids = new ArrayList<>();
 
     private final static String INTERACTION_SPONORE = PerfManagerSaveOpPlugin.class.getName();
@@ -77,66 +76,67 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
                     Date endYear = data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR);
                     String description = data.getString(FormConstant.DESCRIPTION_KEY);
                     DynamicObjectCollection perfManagerEntry = data.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
-                    PersonPerfInfo personPerfInfo = new PersonPerfInfo(person, beginYear, endYear, description, dataEntityIndex, perfManagerEntry);
-                    if(id > 0){
-                        personPerfInfo.setId(id);
-                        ids.add(id);
-                    }
-                    personPerfInfos.add(personPerfInfo);
+                    personIds.add(person.getLong(FormConstant.ID_KEY));
+                    ids.add(id);
                 }
 
                 QueryFieldBuilder queryFieldBuilder = QueryFieldBuilder.create()
                         .addIdNumberName(FormConstant.NCKD_PERSON)
                         .add(PerfManagerFormConstant.NCKD_BEGINYEAR)
                         .add(PerfManagerFormConstant.NCKD_ENDYEAR);
-                personIds = personPerfInfos.stream()
-                        .map(personPerfInfo -> personPerfInfo.getPerson().getLong(FormConstant.ID_KEY))
-                        .collect(Collectors.toList());
-                QFilter filter = new QFilter(FormConstant.NCKD_PERSON, QCP.in, personIds)
-                        .and(PerfManagerFormConstant.NCKD_THESTATUS,QCP.equals,"1");
-                if(!ids.isEmpty()){
+                QFilter filter = new QFilter(FormConstant.NCKD_PERSON, QCP.in, personIds);
+                if(!ids.isEmpty()) {
                     filter = filter.and(new QFilter(FormConstant.ID_KEY, QCP.not_in, ids));
                 }
+                //根据人员查询出当前自己之外的其他考核周期
                 DynamicObjectCollection query = QueryServiceHelper.query(PerfManagerFormConstant.PERFMANAGER_ENTITYID, queryFieldBuilder.buildSelect(), new QFilter[]{filter});
-
-                //开始校验 - 优化后的代码
+                //按人员分组
                 Map<Long, List<DynamicObject>> groupedQueryResults = query.stream()
                         .collect(Collectors.groupingBy(
                                 dynamicObject -> dynamicObject.getLong(String.join(".", FormConstant.NCKD_PERSON, FormConstant.ID_KEY))
                         ));
-
-                for (PersonPerfInfo personPerfInfo : personPerfInfos) {
-
-                    long personId = personPerfInfo.getPerson().getLong(FormConstant.ID_KEY);
-                    LocalDateTime beginYear = personPerfInfo.getBeginYear();
-                    LocalDateTime endYear = personPerfInfo.getEndYear();
+                for (ExtendedDataEntity rowDataEntity : getDataEntities()) {
+                    DynamicObject data = rowDataEntity.getDataEntity();
+                    DynamicObject person = data.getDynamicObject(FormConstant.NCKD_PERSON);
+                    long personId = person.getLong(FormConstant.ID_KEY);
+                    String personName = person.getString(FormConstant.NAME_KEY);
+                    LocalDateTime beginYear = ConvertUtil.toLocalDateTime(data.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
+                    LocalDateTime endYear = ConvertUtil.toLocalDateTime(data.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
 
                     // 判断beginYear和endYear是不是间隔3年,例如:开始2025年,结束必须为2027年
                     if (beginYear != null && endYear != null) {
                         int beginYearValue = beginYear.getYear();
                         int endYearValue = endYear.getYear();
                         if (endYearValue - beginYearValue != 2) {
-                            addFatalErrorMessage(getDataEntities()[personPerfInfo.getDataEntityIndex()],
+                            addFatalErrorMessage(rowDataEntity,
                                     StrFormatter.format("周期开始年份【{}】与结束年份【{}】必须间隔3年,请检查!",
                                             beginYearValue, endYearValue));
                         }
                     }
 
-
                     //校验是否存在相同周期开始年的记录 begin
                     List<DynamicObject> personRecords = groupedQueryResults.getOrDefault(personId, Collections.emptyList());
                     for (DynamicObject dynamicObject : personRecords) {
                         LocalDateTime dbBeginYear = DateUtil.toLocalDateTime(dynamicObject.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
                         //判断beginYear和dbBeginYear的年份是否相同
                         if (isSameYear(beginYear, dbBeginYear)) {
-                            addFatalErrorMessage(getDataEntities()[personPerfInfo.getDataEntityIndex()],
+                            addFatalErrorMessage(rowDataEntity,
                                     StrFormatter.format("人员【{}】已经存在周期开始年份【{}】的周期,无需进行创建。",
-                                            personPerfInfo.getPerson().getString(FormConstant.NAME_KEY),
+                                            personName,
                                             beginYear.getYear()));
                         }
+                        //当前周期必须大于之前周期的开始时间
+                        /*if (beginYear != null && beginYear.isBefore(dbBeginYear)) {
+                            addFatalErrorMessage(rowDataEntity,
+                                    StrFormatter.format("人员【{}】当前周期开始时间【{}】必须大于之前周期开始时间【{}】。",
+                                            personName,
+                                            beginYear.getYear(),
+                                            dbBeginYear.getYear()));
+                        }*/
                     }
+
                     //校验是否存在相同周期开始年的记录 end
-                    DynamicObjectCollection entrys = personPerfInfo.getEntrys();
+                    DynamicObjectCollection entrys = data.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
                     if(entrys != null) {
                         List<Date> dateList = entrys.stream().map(entry -> entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR)).collect(Collectors.toList());
                         if (beginYear != null && endYear != null) {
@@ -151,7 +151,7 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
 
                             if (!outOfRangeYears.isEmpty()) {
                                 String outOfRangeYearsStr = String.join(",", outOfRangeYears);
-                                addFatalErrorMessage(getDataEntities()[personPerfInfo.getDataEntityIndex()],
+                                addFatalErrorMessage(rowDataEntity,
                                         StrFormatter.format("考评年份【{}】不在周期范围内,请检查!", outOfRangeYearsStr));
                             }
                         }
@@ -159,11 +159,13 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
                         List<String> duplicateYears = getDuplicateYears(dateList);
                         if (!duplicateYears.isEmpty()) {
                             String duplicateYearsStr = String.join(",", duplicateYears);
-                            addFatalErrorMessage(getDataEntities()[personPerfInfo.getDataEntityIndex()],
+                            addFatalErrorMessage(rowDataEntity,
                                     StrFormatter.format("考评结果存在重复的考核年份【{}】,请检查!", duplicateYearsStr));
                         }
                     }
 
+                    //规则: 如果年度排名管理中已存在某年度的考核结果,则不允许在人员考评管理中修改该年度的考核结果。
+                    //规则: 对于已处理的调薪情况,不允许修改或删除相关的年度考核结果。
                 }
             }
 
@@ -175,6 +177,10 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
 
     @Override
     public void beforeExecuteOperationTransaction(BeforeOperationArgs e) {
+        if(!this.getOperationResult().isSuccess()){
+            e.setCancel(true);
+            return;
+        }
         //最新上一考核周期
         QFilter filter = null;
         if(!ids.isEmpty()) {
@@ -190,10 +196,6 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
 
         String ignoreInteraction = this.getOption().getVariableValue(OperateOptionConst.IGNOREINTERACTION, "");
         if(!"true".equalsIgnoreCase(ignoreInteraction)){
-            personIds = personPerfInfos.stream()
-                    .map(personPerfInfo -> personPerfInfo.getPerson().getLong(FormConstant.ID_KEY))
-                    .collect(Collectors.toList());
-
             StringJoiner confirMmsg = new StringJoiner(",");
             for (DynamicObject lastPerfManager : lastPerfManagerMap.values()) {
                 String personName = lastPerfManager.getDynamicObject(FormConstant.NCKD_PERSON).getString(FormConstant.NAME_KEY);
@@ -208,7 +210,7 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
 
     }
     @Override
-    public void beginOperationTransaction(BeginOperationTransactionArgs e) {
+        public void beginOperationTransaction(BeginOperationTransactionArgs e) {
         //事务开始之后将其他考核周期设置为非最新
         PerfManagerHelper.markAsNotCurrentNewest(personIds.toArray(new Long[0]));
 
@@ -226,18 +228,90 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
             }
             //上一周期标记为“已结束”并设置“实际结束时间” begin
             DynamicObject lastPerfManager = lastPerfManagerMap.get(personId);
-            if(lastPerfManager != null && "1".equalsIgnoreCase(lastPerfManager.getString(PerfManagerFormConstant.NCKD_THESTATUS))) {
-                lastPerfManager.set(PerfManagerFormConstant.NCKD_THESTATUS, "3");
-                LocalDateTime localDateTime = DateUtil.minusYears(beginYear, 1);
-                lastPerfManager.set(PerfManagerFormConstant.NCKD_ACTENDYEAR, DateUtil.toDate(localDateTime));
-                dataEntity.set(PerfManagerFormConstant.NCKD_LASTPERFMANAGER, lastPerfManagerMap.get(personId));
+            if(lastPerfManager != null) {
+                if("1".equalsIgnoreCase(lastPerfManager.getString(PerfManagerFormConstant.NCKD_THESTATUS))) {
+                    lastPerfManager.set(PerfManagerFormConstant.NCKD_THESTATUS, "3");
+                    LocalDateTime localDateTime = DateUtil.minusYears(beginYear, 1);
+                    lastPerfManager.set(PerfManagerFormConstant.NCKD_ACTENDYEAR, DateUtil.toDate(localDateTime));
+                    dataEntity.set(PerfManagerFormConstant.NCKD_LASTPERFMANAGER, lastPerfManagerMap.get(personId));
+                }
+
+                LocalDateTime lastBeginYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_BEGINYEAR));
+                LocalDateTime lastEndYear = DateUtil.toLocalDateTime(lastPerfManager.getDate(PerfManagerFormConstant.NCKD_ENDYEAR));
+                if(!Objects.equals(lastBeginYear, beginYear) || !Objects.equals(lastEndYear, endYear)) {
+                    //当周期范围发生变化,需要保障数据连续性:若新旧考评周期存在重叠年份,且该年份在旧周期中已存在来源于【年度绩效排名】的考核结果,则新周期将自动继承该结果。
+                    DynamicObjectCollection lastPerfManagerEntrys = lastPerfManager.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
+                    DynamicObjectCollection perfManagerEntrys = dataEntity.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
+                    for (DynamicObject lastPerfManagerEntry : lastPerfManagerEntrys) {
+                        Date lastAppraisalYear = lastPerfManagerEntry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+                        DynamicObject appraisalResult = lastPerfManagerEntry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);
+                        if (lastAppraisalYear != null && appraisalResult != null) {
+                            boolean isAllRankSource = lastPerfManagerEntry.getBoolean(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
+                            if (isAllRankSource) {
+                                LocalDateTime lastAppraisalYearLocalDateTime = DateUtil.toLocalDateTime(lastAppraisalYear);
+                                //判断appraisalYearLocalDateTime是不是在beginYear和endYear之间
+                                if (DateUtil.isInRange(lastAppraisalYearLocalDateTime, beginYear, endYear)) {
+                                    boolean isExist = false;
+                                    for (DynamicObject perfManager : perfManagerEntrys) {
+                                        Date appraisalYear = perfManager.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+                                        if(appraisalYear != null){
+                                            //如果分录存在相同年份则更新
+                                            LocalDateTime appraisalYearLocalDateTime = DateUtil.toLocalDateTime(appraisalYear);
+                                            if(appraisalYearLocalDateTime.getYear() == lastAppraisalYearLocalDateTime.getYear()){
+                                                perfManager.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, appraisalResult);
+                                                isExist = true;
+                                            }
+                                        }
+                                    }
+                                    if(!isExist) {
+                                        //分录不存在当前年份,则添加
+                                        DynamicObject dynamicObject = perfManagerEntrys.addNew();
+                                        dynamicObject.set(PerfManagerFormConstant.NCKD_APPRAISALYEAR, lastAppraisalYear);
+                                        dynamicObject.set(PerfManagerFormConstant.NCKD_APPRAISALRESULT, appraisalResult);
+                                        dynamicObject.set(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE, true);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
             }
             //上一周期标记为“已结束”并设置“实际结束时间” end
-        }
 
-
-        DynamicObject[] lastPerfManagerArray = lastPerfManagerMap.values().toArray(new DynamicObject[0]);
-        SaveServiceHelper.update(lastPerfManagerArray);
+            dataEntity.set(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT, null);
+            dataEntity.set(PerfManagerFormConstant.NCKD_SECONDYEARRESULT, null);
+            dataEntity.set(PerfManagerFormConstant.NCKD_THIRDYEARRESULT, null);
+            DynamicObjectCollection entrys = dataEntity.getDynamicObjectCollection(PerfManagerFormConstant.NCKD_PERFMANAGERENTRY);
+            for (DynamicObject entry : entrys) {
+                boolean isAllRankSource = entry.getBoolean(PerfManagerFormConstant.NCKD_ISALLRANKSOURCE);
+                Date appraisalYear = entry.getDate(PerfManagerFormConstant.NCKD_APPRAISALYEAR);
+                DynamicObject appraisalResult = entry.getDynamicObject(PerfManagerFormConstant.NCKD_APPRAISALRESULT);
+
+                if (appraisalYear != null && appraisalResult != null) {
+                    LocalDateTime appraisalLocalDate = DateUtil.toLocalDateTime(appraisalYear);
+                    LocalDateTime beginLocalDate = beginYear;
+
+                    // 计算是第几年(分录中的年份-(周期开始时间 + 1))
+                    long yearsDiff = appraisalLocalDate.getYear() - beginLocalDate.getYear() + 1;
+                    // 根据年份差异设置表头对应的考核结果字段
+                    switch ((int) yearsDiff) {
+                        case 1:
+                            dataEntity.set(PerfManagerFormConstant.NCKD_FIRSTYEARRESULT, appraisalResult);
+                            break;
+                        case 2:
+                            dataEntity.set(PerfManagerFormConstant.NCKD_SECONDYEARRESULT, appraisalResult);
+                            break;
+                        case 3:
+                            dataEntity.set(PerfManagerFormConstant.NCKD_THIRDYEARRESULT, appraisalResult);
+                            break;
+                    }
+                }
+            }
+        }
+        if(lastPerfManagerMap != null && !lastPerfManagerMap.values().isEmpty()) {
+            DynamicObject[] lastPerfManagerArray = lastPerfManagerMap.values().toArray(new DynamicObject[0]);
+            SaveServiceHelper.update(lastPerfManagerArray);
+        }
     }
 
     @Override
@@ -260,7 +334,7 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
         InteractionContext interactionContext = new InteractionContext();
         interactionContext.setSimpleMessage("存在【未结束】的考核周期");
         OperateErrorInfo errorInfo = new OperateErrorInfo();
-        errorInfo.setMessage(StrFormatter.format("检测到本次新增的人员中存在【未结束】的考核周期,新周期新增成功后会自动结束上一周期。{}", confirMmsg));
+        errorInfo.setMessage(StrFormatter.format("检测到本次新增的人员中存在【未结束】的考核周期,新周期新增成功后会自动结束上一周期,并将上一周期结束时间更新为当前新周期开始年前一年。{}", confirMmsg));
         errorInfo.setLevel(ErrorLevel.Warning);
 
         Map<String, String> custInfos = new HashMap<>();
@@ -302,9 +376,6 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
         private final String description;
         private int dataEntityIndex;
         private DynamicObjectCollection entrys;
-        private DynamicObject useorg;
-        private DynamicObject org;
-        private DynamicObject createorg;
         private String whyEnd;
         private LocalDateTime actEndYear;
 
@@ -356,29 +427,6 @@ public class PerfManagerSaveOpPlugin extends AbstractOperationServicePlugIn impl
             return entrys;
         }
 
-        public DynamicObject getCreateorg() {
-            return createorg;
-        }
-
-        public void setCreateorg(DynamicObject createorg) {
-            this.createorg = createorg;
-        }
-
-        public DynamicObject getOrg() {
-            return org;
-        }
-
-        public void setOrg(DynamicObject org) {
-            this.org = org;
-        }
-
-        public DynamicObject getUseorg() {
-            return useorg;
-        }
-
-        public void setUseorg(DynamicObject useorg) {
-            this.useorg = useorg;
-        }
 
         public Long getId() {
             return id;

+ 0 - 92
code/wtc/nckd-jxccl-wtc/src/main/java/nckd/jxccl/wtc/task/SyncPunchCardTask.java

@@ -1,92 +0,0 @@
-package nckd.jxccl.wtc.task;
-
-import com.alibaba.fastjson.JSON;
-import com.hikvision.artemis.sdk.ArtemisHttpUtil;
-import com.hikvision.artemis.sdk.config.ArtemisConfig;
-import kd.bos.context.RequestContext;
-import kd.bos.entity.param.CustomParam;
-import kd.bos.exception.KDException;
-import kd.bos.schedule.executor.AbstractTask;
-import kd.bos.servicehelper.parameter.SystemParamServiceHelper;
-import kd.sdk.plugin.Plugin;
-import nckd.jxccl.wtc.utils.SyncPunchCardHelper;
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-
-import java.text.SimpleDateFormat;
-import java.util.Calendar;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * 后台任务插件
- */
-public class SyncPunchCardTask extends AbstractTask implements Plugin {
-    private static final String ARTEMIS_PATH = "/artemis";
-    static final String getCamsApi = ARTEMIS_PATH + "/api/acs/v2/door/events";
-    static Map<String, String> path = new HashMap<String, String>(2) {
-        {
-            put("https://", getCamsApi);
-        }
-    };
-
-    public void initConfig() {
-        CustomParam customParam = new CustomParam();
-        customParam.getSearchKeySet().add("PUNCH_CARD_HOST");
-        customParam.getSearchKeySet().add("PUNCH_CARD_APP_KEY");
-        customParam.getSearchKeySet().add("PUNCH_CARD_APP_SECRET");
-        Map<String, String> cusTomMap = SystemParamServiceHelper.loadCustomParameterFromCache(customParam);
-        ArtemisConfig.host  = cusTomMap.get("PUNCH_CARD_HOST");
-        ArtemisConfig.appKey = cusTomMap.get("PUNCH_CARD_APP_KEY");
-        ArtemisConfig.appSecret = cusTomMap.get("PUNCH_CARD_APP_SECRET");
-    }
-
-    @Override
-    public void execute(RequestContext requestContext, Map<String, Object> map) throws KDException {
-        try {
-            initConfig();
-            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
-            Calendar date = Calendar.getInstance();
-            System.out.println(sdf.format(date.getTime()));
-            String endTime = sdf.format(date.getTime()) + "T23:59:59+08:00";
-            Integer days = Integer.valueOf(map.get("days").toString());
-            date.set(Calendar.DATE, date.get(Calendar.DATE) - days);
-            System.out.println(sdf.format(date.getTime()));
-            String startTime = sdf.format(date.getTime()) + "T00:00:00+08:00";
-            getAllCards(startTime, endTime);
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    public static void getAllCards(String startTime, String endTime) {
-        JSONObject firstPageJson = getOnePageCard(startTime, endTime, 1);
-        JSONArray firstPageListJson = firstPageJson.getJSONArray("list");
-        // 保存第一页
-        SyncPunchCardHelper.savePunchCardData(firstPageListJson);
-        Integer totalPage = firstPageJson.getInteger("totalPage");
-        if (totalPage <= 1) {
-            return;
-        }
-        // 从第二页开始保存
-        for(int i=2; i<=totalPage; i++) {
-            JSONObject pageJson = getOnePageCard(startTime, endTime, i);
-            JSONArray pageListJson = pageJson.getJSONArray("list");
-            SyncPunchCardHelper.savePunchCardData(pageListJson);
-        }
-    }
-
-    public static JSONObject getOnePageCard(String startTime, String endTime, int pageNo) {
-        JSONObject jsonBody = new JSONObject();
-        jsonBody.put("pageNo", pageNo);
-        jsonBody.put("pageSize", 1000);
-        jsonBody.put("startTime", startTime);
-        jsonBody.put("endTime", endTime);
-        jsonBody.put("userId", "admin");
-        String body = jsonBody.toString();
-        String result = ArtemisHttpUtil.doPostStringArtemis(path, body, null, null, "application/json", null);
-        JSONObject jsonData = JSON.parseObject(result).getJSONObject("data");
-        return jsonData;
-    }
-
-}