跳转至

主子流程,子流程获取主流程第几个实例1开始

本文档内容来源于 http://doc.myapps.cn/docs/common-script/common-script-1f1a4sk6oc6hf

脚本说明

该脚本用于在主子流程场景中,子流程获取主流程的第几个实例(从1开始计数)。当主流程启动多个子流程实例时,子流程需要知道自己是主流程的第几个实例。

常见实现方式

方式1:通过文档关联查询

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();  // 获取主流程文档ID

    if(parentId != null && parentId.trim().length > 0){
        // 查询主流程下所有子流程,按创建时间排序
        var sql = "select domainid,id,created ";
        sql += "from tlk_子表表单 ";
        sql += "where parent = '"+parentId+"' ";
        sql += "order by created";

        var datas = queryBySQL(sql);

        if(datas != null && datas.size() > 0){
            var index = 1;
            var currentDocId = doc.getId();

            for(var it = datas.iterator(); it.hasNext(); ){
                var data = it.next();
                if(data.getId() === currentDocId){
                    return index;  // 返回当前子流程是第几个实例
                }
                index++;
            }
        }
    }

    return 0;  // 未找到或没有父流程
})();

方式2:通过流程状态表查询

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId != null && parentId.trim().length > 0){
        // 查询主流程的流程状态
        var mainFlowSql = "select domainid,flowstatert_id ";
        mainFlowSql += "from t_flowstatert ";
        mainFlowSql += "where docid = '"+parentId+"'";
        var mainFlow = findBySQL(mainFlowSql);

        if(mainFlow != null){
            var mainFlowStateId = mainFlow.getItemValueAsString("flowstatert_id");

            // 查询该主流程下的所有子流程,按创建时间排序
            var sql = "select domainid,fs.id,fs.created ";
            sql += "from t_flowstatert fs ";
            sql += "inner join tlk_子表表单 d on fs.docid = d.id ";
            sql += "where d.parent = '"+parentId+"' ";
            sql += "order by fs.created";

            var datas = queryBySQL(sql);

            if(datas != null && datas.size() > 0){
                var index = 1;
                var currentDocId = doc.getId();

                for(var it = datas.iterator(); it.hasNext(); ){
                    var data = it.next();
                    if(data.getId() === currentDocId){
                        return index;
                    }
                    index++;
                }
            }
        }
    }

    return 0;
})();

方式3:通过流程ID查询

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId != null && parentId.trim().length > 0){
        // 获取主流程的流程ID
        var mainDoc = findDocument(parentId);
        if(mainDoc != null){
            var mainFlowId = mainDoc.getFlowid();

            // 查询主流程下所有子流程的流程ID
            var sql = "select domainid,d.id,d.flowid ";
            sql += "from tlk_子表表单 d ";
            sql += "inner join t_flowstatert fs on d.id = fs.docid ";
            sql += "where d.parent = '"+parentId+"' ";
            sql += "and fs.flow_id = '"+mainFlowId+"' ";
            sql += "order by d.created";

            var datas = queryBySQL(sql);

            if(datas != null && datas.size() > 0){
                var index = 1;
                var currentDocId = doc.getId();

                for(var it = datas.iterator(); it.hasNext(); ){
                    var data = it.next();
                    if(data.getId() === currentDocId){
                        return index;
                    }
                    index++;
                }
            }
        }
    }

    return 0;
})();

扩展示例

示例1:获取实例序号并设置到字段

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId != null && parentId.trim().length > 0){
        var sql = "select domainid,id,created ";
        sql += "from tlk_子表表单 ";
        sql += "where parent = '"+parentId+"' ";
        sql += "order by created";

        var datas = queryBySQL(sql);

        if(datas != null && datas.size() > 0){
            var index = 1;
            var currentDocId = doc.getId();

            for(var it = datas.iterator(); it.hasNext(); ){
                var data = it.next();
                if(data.getId() === currentDocId){
                    // 设置到字段
                    doc.findItem("实例序号").setValue(index);
                    return index;
                }
                index++;
            }
        }
    }

    return 0;
})();

示例2:获取实例序号并格式化显示

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId != null && parentId.trim().length > 0){
        var sql = "select domainid,id,created ";
        sql += "from tlk_子表表单 ";
        sql += "where parent = '"+parentId+"' ";
        sql += "order by created";

        var datas = queryBySQL(sql);

        if(datas != null && datas.size() > 0){
            var index = 1;
            var currentDocId = doc.getId();
            var total = datas.size();

            for(var it = datas.iterator(); it.hasNext(); ){
                var data = it.next();
                if(data.getId() === currentDocId){
                    return "第" + index + "个实例(共" + total + "个)";
                }
                index++;
            }
        }
    }

    return "未找到实例序号";
})();

示例3:根据实例序号执行不同逻辑

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId != null && parentId.trim().length > 0){
        var sql = "select domainid,id,created ";
        sql += "from tlk_子表表单 ";
        sql += "where parent = '"+parentId+"' ";
        sql += "order by created";

        var datas = queryBySQL(sql);

        if(datas != null && datas.size() > 0){
            var index = 1;
            var currentDocId = doc.getId();

            for(var it = datas.iterator(); it.hasNext(); ){
                var data = it.next();
                if(data.getId() === currentDocId){
                    // 根据实例序号执行不同逻辑
                    if(index == 1){
                        doc.findItem("处理方式").setValue("第一个实例,优先处理");
                    }else if(index == datas.size()){
                        doc.findItem("处理方式").setValue("最后一个实例,最后处理");
                    }else{
                        doc.findItem("处理方式").setValue("第" + index + "个实例");
                    }
                    return index;
                }
                index++;
            }
        }
    }

    return 0;
})();

示例4:获取主流程信息和实例序号

(function(){
    var doc = getCurrentDocument();
    var parentId = doc.getParent();

    if(parentId == null || parentId.trim().length == 0){
        return "没有主流程";
    }

    // 获取主流程文档
    var mainDoc = findDocument(parentId);
    if(mainDoc == null){
        return "主流程文档不存在";
    }

    // 获取实例序号
    var sql = "select domainid,id,created ";
    sql += "from tlk_子表表单 ";
    sql += "where parent = '"+parentId+"' ";
    sql += "order by created";

    var datas = queryBySQL(sql);
    var instanceIndex = 0;
    var totalInstances = 0;

    if(datas != null && datas.size() > 0){
        totalInstances = datas.size();
        var index = 1;
        var currentDocId = doc.getId();

        for(var it = datas.iterator(); it.hasNext(); ){
            var data = it.next();
            if(data.getId() === currentDocId){
                instanceIndex = index;
                break;
            }
            index++;
        }
    }

    return {
        mainDocId: parentId,
        mainDocName: mainDoc.getItemValueAsString("名称"),
        instanceIndex: instanceIndex,
        totalInstances: totalInstances
    };
})();

关键函数说明

  • getCurrentDocument(): 获取当前文档对象
  • doc.getParent(): 获取父文档ID(主流程文档ID)
  • findDocument(docId): 根据文档ID查找文档对象
  • queryBySQL(sql): 执行SQL查询
  • doc.getId(): 获取文档ID

主子流程关系说明

  • 主流程: 启动子流程的流程
  • 子流程: 由主流程启动的流程实例
  • 实例序号: 子流程在主流程中的顺序,从1开始计数
  • 父子关系: 通过 parent 字段建立父子文档关系

查询逻辑说明

  1. 获取父文档ID: 通过 doc.getParent() 获取主流程文档ID
  2. 查询所有子流程: 查询 parent = 主流程ID 的所有子流程文档
  3. 排序: 按创建时间(created)排序,确保顺序一致
  4. 查找当前文档: 遍历查询结果,找到当前文档的位置
  5. 返回序号: 返回当前文档在列表中的位置(从1开始)

注意事项

  • ⚠️ 父文档ID必须存在: 确保子流程有正确的父文档ID
  • ⚠️ 排序方式: 使用 created 字段排序,确保顺序稳定
  • ⚠️ 序号从1开始: 实例序号从1开始计数,不是从0开始
  • ⚠️ 表单名称: SQL中的 tlk_子表表单 需要替换为实际的子表表单名称
  • 如果子流程没有父流程,返回0或null
  • 查询时注意字段名称的正确性
  • 建议在保存前或提交前脚本中使用

使用场景

  • 子流程需要知道自己是第几个实例
  • 根据实例序号执行不同的业务逻辑
  • 显示实例序号给用户
  • 主子流程数据关联
  • 流程实例统计

如需查看完整脚本代码,请访问源文档链接。