219 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			219 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			Java
		
	
	
	
package shkd.repc.resm.formplugin;
 | 
						||
 | 
						||
import kd.bos.bill.AbstractBillPlugIn;
 | 
						||
import kd.bos.dataentity.OperateOption;
 | 
						||
import kd.bos.dataentity.entity.DynamicObject;
 | 
						||
import kd.bos.dataentity.entity.DynamicObjectCollection;
 | 
						||
import kd.bos.dataentity.utils.StringUtils;
 | 
						||
import kd.bos.form.control.Control;
 | 
						||
import kd.bos.logging.Log;
 | 
						||
import kd.bos.logging.LogFactory;
 | 
						||
import kd.bos.orm.query.QCP;
 | 
						||
import kd.bos.orm.query.QFilter;
 | 
						||
import kd.bos.servicehelper.BusinessDataServiceHelper;
 | 
						||
import kd.bos.servicehelper.botp.BFTrackerServiceHelper;
 | 
						||
import kd.bos.servicehelper.operation.SaveServiceHelper;
 | 
						||
import kd.bos.servicehelper.org.OrgUnitServiceHelper;
 | 
						||
import kd.bos.servicehelper.org.OrgViewType;
 | 
						||
import kd.scm.bid.common.constant.entity.BidTemplateMangeEntity;
 | 
						||
import kd.sdk.plugin.Plugin;
 | 
						||
 | 
						||
import java.math.BigDecimal;
 | 
						||
import java.math.RoundingMode;
 | 
						||
import java.util.ArrayList;
 | 
						||
import java.util.EventObject;
 | 
						||
import java.util.List;
 | 
						||
import java.util.Map;
 | 
						||
import java.util.stream.Collectors;
 | 
						||
 | 
						||
/**
 | 
						||
 * 自动设置考察任务考察对象
 | 
						||
 */
 | 
						||
public class AutomaticallySetObjectPlugin extends AbstractBillPlugIn implements Plugin {
 | 
						||
 | 
						||
    private static final Log logger = LogFactory.getLog(AutomaticallySetObjectPlugin.class);
 | 
						||
 | 
						||
    @Override
 | 
						||
    public void afterBindData(EventObject e) {
 | 
						||
        super.afterBindData(e);
 | 
						||
 | 
						||
        DynamicObject dataEntity = this.getModel().getDataEntity();
 | 
						||
        DynamicObjectCollection entry = dataEntity.getDynamicObjectCollection("entry_evaldetail");
 | 
						||
 | 
						||
        if (entry == null || entry.isEmpty()) return;
 | 
						||
 | 
						||
        String object = entry.get(0).getString("entryevaluatorstr");
 | 
						||
 | 
						||
        // 状态暂存且分录考察人为空
 | 
						||
        if ("A".equals(this.getModel().getValue("billstatus")) && "".equals(object)) {
 | 
						||
 | 
						||
            // 获取取值逻辑
 | 
						||
            DynamicObject dataModel = BusinessDataServiceHelper.loadSingle("qeug_datamodel",
 | 
						||
                    (new QFilter("qeug_projectsource", QCP.equals, "考察计划")).toArray());
 | 
						||
 | 
						||
            if (dataModel == null) return;
 | 
						||
 | 
						||
            String projectSource = dataModel.getString("qeug_projectsource");
 | 
						||
            Long orgId;
 | 
						||
            if ("考察计划".equals(projectSource)) {
 | 
						||
 | 
						||
                // 获取考察详情
 | 
						||
                QFilter qFilter = new QFilter("plandetails.evaltask", QCP.equals, dataEntity.getPkValue());
 | 
						||
                DynamicObject plane = BusinessDataServiceHelper.loadSingle("resm_investigationplan", qFilter.toArray());
 | 
						||
 | 
						||
                if (plane == null) return;
 | 
						||
 | 
						||
                DynamicObject project = plane.getDynamicObject("qeug_project");
 | 
						||
                if (project == null) return;
 | 
						||
 | 
						||
                // 获取项目-所属组织
 | 
						||
                QFilter qFilter1 = new QFilter("id", QCP.equals, project.get("id"));
 | 
						||
                DynamicObject dynamicObject1 = BusinessDataServiceHelper.loadSingle("repmd_projectbill", qFilter1.toArray());
 | 
						||
                if (dynamicObject1 == null) return;
 | 
						||
 | 
						||
                DynamicObject org = dynamicObject1.getDynamicObject("org");
 | 
						||
                if (org == null) return;
 | 
						||
 | 
						||
                orgId = org.getLong("id");
 | 
						||
                DynamicObjectCollection dataModelEntry = dataModel.getDynamicObjectCollection("entryentity");
 | 
						||
 | 
						||
                // 使用 Stream API 获取所有匹配的 role 对象
 | 
						||
                List<DynamicObject> matchingRoles = dataModelEntry.stream()
 | 
						||
                        .map(modelEntry -> modelEntry.getString("qeug_rolenumber"))
 | 
						||
                        .filter(roleNumber -> roleNumber != null)
 | 
						||
                        .map(roleNumber -> BusinessDataServiceHelper.loadSingle("wf_role", new QFilter("number", QCP.equals, roleNumber).toArray()))
 | 
						||
                        .filter(roleDynamic -> roleDynamic != null)
 | 
						||
                        .filter(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry") != null && !roleDynamic.getDynamicObjectCollection("roleentry").isEmpty()) // 跳过 roleentry 为空的情况
 | 
						||
                        .flatMap(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry").stream())
 | 
						||
                        .filter(role -> {
 | 
						||
                            Long roleOrgId = role.getLong("org.id");
 | 
						||
                            return roleOrgId != null && roleOrgId.compareTo(orgId) == 0; // 筛选符合条件的 role
 | 
						||
                        })
 | 
						||
                        .collect(Collectors.toList());
 | 
						||
                // 如果有匹配项
 | 
						||
                if (!((List<?>) matchingRoles).isEmpty()) {
 | 
						||
                    creatExamData(matchingRoles, entry);
 | 
						||
                } else {
 | 
						||
                    findParentOrgMatch(entry, orgId, dataModelEntry);
 | 
						||
                }
 | 
						||
                SaveServiceHelper.saveOperate("resm_exam_task", new DynamicObject[]{dataEntity}, OperateOption.create());
 | 
						||
            }
 | 
						||
        }
 | 
						||
        this.getView().updateView("entry_evaldetail");
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 递归查找上级组织
 | 
						||
     *
 | 
						||
     * @param entry          考察任务分录
 | 
						||
     * @param orgId          当前工作流角色组织
 | 
						||
     * @param dataModelEntry 取数模板
 | 
						||
     */
 | 
						||
    private void findParentOrgMatch(DynamicObjectCollection entry, Long orgId, DynamicObjectCollection dataModelEntry) {
 | 
						||
        if (orgId == null) return;
 | 
						||
        //取上级组织.
 | 
						||
        List<Long> dptIds = new ArrayList<>();
 | 
						||
        dptIds.add(orgId);
 | 
						||
        Map<Long, Long> orgParentMap = OrgUnitServiceHelper.getDirectSuperiorOrg(OrgViewType.Admin, dptIds);
 | 
						||
        if (orgParentMap != null) {
 | 
						||
            Long parentId = orgParentMap.get(orgId);
 | 
						||
            DynamicObject parentOrg = BusinessDataServiceHelper.loadSingle(parentId, "bos_adminorg");
 | 
						||
            if (parentOrg != null) {
 | 
						||
                orgId = parentOrg.getLong("id");
 | 
						||
                // 使用 Stream API 获取所有匹配的 role 对象
 | 
						||
                Long finalOrgId = orgId;
 | 
						||
                List<DynamicObject> matchingRoles = dataModelEntry.stream()
 | 
						||
                        .map(modelEntry -> modelEntry.getString("qeug_rolenumber"))
 | 
						||
                        .filter(roleNumber -> roleNumber != null)
 | 
						||
                        .map(roleNumber -> BusinessDataServiceHelper.loadSingle("wf_role", new QFilter("number", QCP.equals, roleNumber).toArray()))
 | 
						||
                        .filter(roleDynamic -> roleDynamic != null)
 | 
						||
                        .filter(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry") != null && !roleDynamic.getDynamicObjectCollection("roleentry").isEmpty()) // 跳过 roleentry 为空的情况
 | 
						||
                        .flatMap(roleDynamic -> roleDynamic.getDynamicObjectCollection("roleentry").stream())
 | 
						||
                        .filter(role -> {
 | 
						||
                            Long roleOrgId = role.getLong("org.id");
 | 
						||
                            return roleOrgId != null && roleOrgId.compareTo(finalOrgId) == 0; // 筛选符合条件的 role
 | 
						||
                        })
 | 
						||
                        .collect(Collectors.toList());
 | 
						||
                // 如果有匹配项,则返回;否则递归查找上级组织
 | 
						||
                if (!matchingRoles.isEmpty()) {
 | 
						||
                    creatExamData(matchingRoles, entry);
 | 
						||
                } else {
 | 
						||
                    findParentOrgMatch(entry, orgId, dataModelEntry); // 没有匹配项,递归调用上级组织
 | 
						||
                }
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 生成考察人
 | 
						||
     * @param matchingRoles 收集符合条件的人员
 | 
						||
     * @param entry         考察任务分录
 | 
						||
     */
 | 
						||
    private void creatExamData(List<DynamicObject> matchingRoles, DynamicObjectCollection entry) {
 | 
						||
        for (DynamicObject dynamicObject : entry) {
 | 
						||
            StringBuilder objectText = new StringBuilder();
 | 
						||
            DynamicObject examuator = BusinessDataServiceHelper.newDynamicObject("resm_examuator");
 | 
						||
            String pkValue = dynamicObject.getString("id");
 | 
						||
            examuator.set("evalentryid", pkValue);
 | 
						||
 | 
						||
            DynamicObjectCollection entryCollection = examuator.getDynamicObjectCollection("entry_evaluator");
 | 
						||
 | 
						||
            boolean isSingleRole = matchingRoles.size() == 1;
 | 
						||
 | 
						||
            for (int i = 0; i < matchingRoles.size(); i++) {
 | 
						||
                DynamicObject matchingRole = matchingRoles.get(i);
 | 
						||
                DynamicObject evaluator = entryCollection.addNew();
 | 
						||
                evaluator.set("user", matchingRole.getLong("user.id"));
 | 
						||
                evaluator.set("userposition", matchingRole.getLong("userposition.id"));
 | 
						||
 | 
						||
                String name = matchingRole.getString("user.name");
 | 
						||
                BigDecimal weight = calculateWeight(matchingRoles.size(), i);
 | 
						||
                String weightPercentage = formatWeight(weight);
 | 
						||
 | 
						||
                if (isSingleRole) {
 | 
						||
                    objectText.append(name).append("(").append(weightPercentage).append(")");
 | 
						||
                } else {
 | 
						||
                    if (i > 0) objectText.append(";");
 | 
						||
                    objectText.append(name).append("(").append(weightPercentage).append(")");
 | 
						||
                }
 | 
						||
 | 
						||
                evaluator.set("weight", weight);
 | 
						||
                evaluator.set("seq", i + 1);
 | 
						||
            }
 | 
						||
            dynamicObject.set("entryevaluatorstr", objectText);
 | 
						||
            try {
 | 
						||
                SaveServiceHelper.saveOperate("resm_examuator", new DynamicObject[]{examuator}, OperateOption.create());
 | 
						||
            } catch (Exception ex) {
 | 
						||
                logger.error("保存考察人数据失败", ex);
 | 
						||
            }
 | 
						||
        }
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    /**
 | 
						||
     * 权重计算
 | 
						||
     * @param totalRoles 人员列表
 | 
						||
     * @param currentIndex 行数
 | 
						||
     * @return 权重
 | 
						||
     */
 | 
						||
    private BigDecimal calculateWeight(int totalRoles, int currentIndex) {
 | 
						||
        BigDecimal weight = new BigDecimal(1.0 / totalRoles).setScale(2, RoundingMode.HALF_UP);
 | 
						||
        if (totalRoles % 2 == 1 && currentIndex == totalRoles - 1 && totalRoles != 1) {
 | 
						||
            weight = weight.add(new BigDecimal(0.01));
 | 
						||
        }
 | 
						||
        return weight;
 | 
						||
    }
 | 
						||
 | 
						||
    /**
 | 
						||
     * 权重转百分比
 | 
						||
     * @param weight 权重
 | 
						||
     * @return 百分比字符串
 | 
						||
     */
 | 
						||
    private String formatWeight(BigDecimal weight) {
 | 
						||
        return weight.multiply(new BigDecimal(100)).setScale(0, RoundingMode.HALF_UP) + "%";
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
 | 
						||
} |