单据审批时,如何知道其他审批人此时正在审批

栏目:云苍穹知识作者:金蝶来源:金蝶云社区发布:2024-09-23浏览:1

单据审批时,如何知道其他审批人此时正在审批


1 问题描述

业务单据在多人操作打开时,会有网络互斥,提示“xxx正在编辑”;而审批页面的网络互斥是在提交审批时触发,并不会在进入时提示。在节点多人审批的场景下,如希望进入审批界面即提示“他人正在编辑”,可以减少重复审批的时间、提高审批效率。

2 解决思路

  • 由于对应单据的审批页面在打开时不进行网络互斥的校验,所以需要写插件处理。

  • 可以使用接口kd.bos.mutex.DataMutex#batchrequire与kd.bos.mutex.DataMutex#batchRelease进行申请和释放互斥锁来实现逻辑。

3 解决方案

1、首先,batchrequire的使用示例如下:

(上图为官网接口文档内容DataMutex (SDK) (kingdee.com)

  • 其中需要注意到,因为当前场景属于标准操作(view)的互斥,所以groupId使用默认;

  • entityKey即为当前单据的实体标识;

  • PARAMNAME_DATAOBJID为数据ID,可使用fid。可以通过如下代码获取到fid:

Object pkValue = this.getModel().getDataEntity().getPkValue();
  • PARAMNAME_DATA_OBJ_NUMBER为数据编码,单据为单据编号、基础资料为编码;同上,billNo也可以通过代码获取

Object billNo = this.getModel().getDataEntity().get("billNo");
  • PARAMNAME_OPERATIONKEY为操作标识,如修改:modify 提交:submit。当前场景为查看,即"view";

  • 其余参数,使用默认或自定义即可。


2、 如互斥锁申请成功,需要执行第五步的操作,获取当前用户并放入缓存;如已有互斥锁,可以进行弹窗提示或其他操作:

if (ret) {
    //申请互斥成功;获取当前用户,用于释放互斥锁
        long currentUserId = UserServiceHelper.getCurrentUserId();
        pageCache.put("currentUserId", Long.toString(currentUserId));
} else {
    Map<String, String> lockInfo = dataMutex.getLockInfo(objId, groupId, entityKey);
    if (lockInfo != null) {
        //申请锁失败,提示已经存在的锁信息
        this.getView().showTipNotification("已有其他人打开此单据");
    }
}


3 、为了防止与单据列表点击后进入的相同单据冲突,可以进行打开方式为工作流的校验:

Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
String openType=(String) customParams.get("SOURCE");
if("WF".equals(openType)){
   //业务逻辑
}


4 、至此,获取互斥锁已经完成,还需考虑释放互斥锁。释放的话可以考虑在事件pageRelease中进行(pageRelease事件),因为此时页面已经释放,所以释放互斥锁需要的一些参数需要在申请互斥锁时,存到缓存里,然后在pageRelease事件获取到进行释放。


5、 还需要考虑的一点:以防其他用户在页面关闭时释放了当前用户的互斥锁,所以还需要记录申请锁的用户,存入缓存后,在释放互斥锁中进行判断。


完整代码如下:

package nm21.plugin.formPlugin;

import com.esotericsoftware.minlog.Log;
import kd.bos.bill.AbstractBillPlugIn;
import kd.bos.form.IPageCache;
import kd.bos.form.control.Control;
import kd.bos.mutex.DataMutex;
import kd.sdk.plugin.Plugin;

import java.util.*;

/**
 * 单据界面插件
 */
public class ErrShowPlugin extends AbstractBillPlugIn implements Plugin {

    //如果需要和标准操作(如保存、提交、审核...)互斥,则可使用default_netctrl(默认分组),不需要和标准操作互斥则需要用自定义的groupId
    String groupId = "default_netctrl";
    String entityKey = "nm21_520test";

    @Override
    public void afterLoadData(EventObject e) {
        super.afterLoadData(e);
        //检测打开方式为工作流
        Map<String, Object> customParams = this.getView().getFormShowParameter().getCustomParams();
        String openType = (String) customParams.get("SOURCE");
        if ("WF".equals(openType)) {
            IPageCache pageCache = this.getPageCache();
            pageCache.put("SOURCE", "WF");
            try (DataMutex dataMutex = DataMutex.create()) {
                //申请网络互斥锁
                
                List<Map<String, Object>> mutexRequireList = new ArrayList<>(1);
                Map<String, Object> requireParam = new HashMap<>();
                //fid
                Object pkValue = this.getModel().getDataEntity().getPkValue();
                //billNo
                Object billNo = this.getModel().getDataEntity().get("billNo");
                pageCache.put("fid", pkValue.toString());
                requireParam.put(DataMutex.PARAMNAME_DATAOBJID, pkValue.toString());
                requireParam.put(DataMutex.PARAMNAME_DATA_OBJ_NUMBER, billNo.toString());
                requireParam.put(DataMutex.PARAMNAME_GROUPID, groupId);
                requireParam.put(DataMutex.PARAMNAME_ENTITYKEY, entityKey);
                requireParam.put(DataMutex.PARAMNAME_OPERATIONKEY, "view");
                requireParam.put(DataMutex.PARAMNAME_ISSTRICT, true);
                //建议设置自定义标识,用于后续区分标准操作和自定义申请的网控
                requireParam.put(DataMutex.PARAMNAME_DATA_CALL_SOURCE, "testxixi");
                mutexRequireList.add(requireParam);
                Map<String, Boolean> mutexResult = dataMutex.batchrequire(mutexRequireList);

                // 分析网控申请结果
                for (Map.Entry<String, Boolean> mutexItem : mutexResult.entrySet()) {
                    String objId = mutexItem.getKey();
                    Boolean ret = mutexItem.getValue();

                    if (ret) {
                        //申请互斥成功的;获取当前用户,用于释放互斥锁
                        long currentUserId = UserServiceHelper.getCurrentUserId();
                        pageCache.put("currentUserId", Long.toString(currentUserId));
                    } else {
                        Map<String, String> lockInfo = dataMutex.getLockInfo(objId, groupId, entityKey);
                        if (lockInfo != null) {
                            //申请锁失败,提示已经存在的锁信息
                            this.getView().showTipNotification("已有其他人打开此单据");
                        }
                    }
                }
            } catch (Exception err) {
                Log.error(String.valueOf(err));
            }
        }
    }

    @Override
    public void pageRelease(EventObject e) {
        super.pageRelease(e);
        IPageCache pageCache = this.getPageCache();
        String source = pageCache.get("SOURCE");
        String currentUserId = pageCache.get("currentUserId");
        if ("WF".equals(source) && null != currentUserId 
        && currentUserId.equals(Long.toString(UserServiceHelper.getCurrentUserId()))) {
            //释放网络互斥锁
            try (DataMutex dataMutex = DataMutex.create()) {
                List<Map<String, Object>> releaseMutexList = new ArrayList<>(1);
                Map<String, Object> releaseParam = new HashMap<>();
                String fid = pageCache.get("fid");
                releaseParam.put(DataMutex.PARAMNAME_DATAOBJID, fid);
                releaseParam.put(DataMutex.PARAMNAME_GROUPID, groupId);
                releaseParam.put(DataMutex.PARAMNAME_ENTITYKEY, entityKey);
                releaseParam.put(DataMutex.PARAMNAME_OPERATIONKEY, "view");
                releaseMutexList.add(releaseParam);

                Map<String, Boolean> releaseResult = dataMutex.batchRelease(releaseMutexList);
                // 分析释放结果
                for (Map.Entry<String, Boolean> releaseItem : releaseResult.entrySet()) {
                    boolean releaseRet = releaseItem.getValue();
                    if (!releaseRet) {
                        //记录释放失败的锁
                    }
                }
            } catch (Exception err) {
                Log.error(String.valueOf(err));
            }
        }
    }
}

最后,如多人同时打开审批页面,后续审批人会有如下提示:


3 适用版本

  • 演示环境为金蝶云·苍穹V6.0.1。


4 注意事项

  • 该实现方案为单据级别,需要将插件注册到相关单据上。


5 参考资料

单据审批时,如何知道其他审批人此时正在审批

1 问题描述业务单据在多人操作打开时,会有网络互斥,提示“xxx正在编辑”;而审批页面的网络互斥是在提交审批时触发,并不会在进入时提示...
点击下载文档
确认删除?
回到顶部
客服QQ
  • 客服QQ点击这里给我发消息