不积跬步,无以至千里;不积小流,无以成江海。

Dean's blog

  • Join Us on Facebook!
  • Follow Us on Twitter!
  • LinkedIn
  • Subcribe to Our RSS Feed

H3BPM通过代码发起流程

可以使用H3的/Portal/webservices/BPMService.asmx服务来发起流程。在发起调用服务之前,可以先生成WebService代理类,方法如下:

wsdl /o:BPMService.cs http://192.168.154.128:8010/Portal/webservices/BPMService.asmx

这样,就可以使用BPMService.cs来访问BPMService.asmx服务了。

对于一般的简单流程,可以使用其中的StartWorkflow()方法来启动,如下:

    var workflowCode = "jbsp";
    var userCode = "oatest";
    var finishStart = true;
    var paramValues = new DataItemParam[]{
        new DataItemParam{ ItemName = "ysbm", ItemValue = "2323" }
    };
    
    var service = new BPMService();
    service.AuthenticationValue = new Authentication
    {
        UserCode = "oatest",
        Password = "123"
    };

    var result = service.StartWorkflow(workflowCode, userCode, finishStart, paramValues); 

 

其中workflowCode和userCode分别对应流程的编码和用户编码,而paramValues就是流程数据,每个ItemName分别对应数据模型数据项的编码。提交后,就一般就可以发起一个流程了。

但是这个方法是有局限性的,它只适应于没有子表的情况,如果存在子表,则需要对BPMService.asmx进行扩展才行。大于可以以这样的思路:

        将表单的数据以JSON的方式提交过来,解释每个数据项,将它转换为DataItemParam

具体如下:

 

	/// <summary>
	/// 使用JSON数据启动H3流程实例
	/// </summary>
	/// <param name="workflowCode">流程模板编码</param>
	/// <param name="userCode">启动流程的用户编码</param>
	/// <param name="finishStart">是否结束第一个活动</param>
	/// <param name="paramValues">流程实例启动初始化数据项集合</param>
	/// <returns></returns>
	[System.Web.Services.Protocols.SoapHeader("authentication")]
	[WebMethod(Description = "使用JSON数据启动H3流程实例")]
	public BPMServiceResult StartWorkflowByJson(
	    string workflowCode,
	    string userCode,
	    bool finishStart,
	    string json)
	{
	    ValidateSoapHeader();
	    return startWorkflow(workflowCode, userCode, finishStart, json);
	}

	private List<DataItemParam> GetDataValuesWithDtl(OThinker.H3.DataModel.BizObject bo, OThinker.Organization.User user, string jsonData)
	{
	    List<DataItemParam> paramValues = new List<DataItemParam>();
	    var jt = JToken.Parse(jsonData);

	    foreach (JProperty jp in jt)
	    {
	        if (jp.Value is JArray)
	        {
	            //业务对象数组
	            var childBoList = new List<DataModel.BizObject>();
	            var prosch = bo.Schema.GetProperty(jp.Name);
	            if (prosch.ChildSchema != null)
	            {
	                OThinker.H3.DataModel.BizObject childBo = new DataModel.BizObject(
	                               this.Engine.Organization,
	                               this.Engine.MetadataRepository,
	                               this.Engine.BizObjectManager,
	                               prosch.ChildSchema,
	                               user.ObjectID,
	                               user.ParentID);
	                foreach (JToken ja in (JArray)jp.Value)
	                {
	                    foreach (JProperty jpt in ja)
	                    {
	                        string dataKeyChild = jpt.Name;
	                        string dataValueChild = jpt.Value.ToString();


	                        if (childBo.Schema.GetProperty(dataKeyChild) == null) continue;
	                        if (string.IsNullOrEmpty(dataValueChild)) continue;


	                        childBo.SetValue(dataKeyChild, dataValueChild);

	                    }
	                    childBoList.Add(childBo);

	                }
	                paramValues.Add(new DataItemParam()
	                {
	                    ItemName = jp.Name,
	                    ItemValue = childBoList.ToArray()
	                });
	            }
	            else
	            {
	                //多人参与者赋值 转换成数组
	                var arr = (JArray)jp.Value;
	                paramValues.Add(new DataItemParam()
	                {
	                    ItemName = jp.Name,
	                    ItemValue = arr.ToArray()
	                });
	            }
	        }
	        else
	        {
	            paramValues.Add(new DataItemParam()
	            {
	                ItemName = jp.Name,
	                ItemValue = jp.Value
	            });

	        }
	    }
	    return paramValues;
	}

	private BPMServiceResult startWorkflow(
	    string workflowCode,
	    string userCode,
	    bool finishStart,
	    string json)
	{
	    ValidateSoapHeader();
	    string workItemID, keyItem, errorMessage;
	    workItemID = keyItem = errorMessage = string.Empty;
	    BPMServiceResult result;

	    try
	    {
	        // 获取模板
	        OThinker.H3.WorkflowTemplate.PublishedWorkflowTemplateHeader workflowTemplate = GetWorkflowTemplate(workflowCode);
	        if (workflowTemplate == null)
	        {
	            result = new BPMServiceResult(false, "流程启动失败,流程模板不存在,模板编码:" + workflowCode + "。");
	            return result;
	        }
	        // 查找流程发起人
	        OThinker.Organization.User user = this.Engine.Organization.GetUnitByCode(userCode) as Organization.User;
	        if (user == null)
	        {
	            result = new BPMServiceResult(false, "流程启动失败,用户{" + userCode + "}不存在。");
	            return result;
	        }

	        OThinker.H3.DataModel.BizObjectSchema schema = this.Engine.BizObjectManager.GetPublishedSchema(workflowTemplate.BizObjectSchemaCode);
	        OThinker.H3.DataModel.BizObject bo = new DataModel.BizObject(
	            this.Engine.Organization,
	            this.Engine.MetadataRepository,
	            this.Engine.BizObjectManager,
	            schema,
	            OThinker.Organization.User.SystemUserID,
	            OThinker.Organization.Company.DefaultCompanyId);


	        var paramValues = GetDataValuesWithDtl(bo, user, json);
	            
	        if (paramValues != null)
	        {
	            // 这里可以在创建流程的时候赋值
	            foreach (DataItemParam param in paramValues)
	            {
	                if (bo.Schema.ContainsField(param.ItemName))
	                {
	                    bo[param.ItemName] = param.ItemValue;
	                }
	            }
	        }

	        bo.Create();

	        // 创建流程实例
	        string InstanceId = this.Engine.InstanceManager.CreateInstance(
	             bo.ObjectID,
	             workflowTemplate.WorkflowCode,
	             workflowTemplate.WorkflowVersion,
	             null,
	             null,
	             user.UnitID,
	             null,
	             null,
	             false,
	             Instance.InstanceContext.UnspecifiedID,
	             null,
	             Instance.Token.UnspecifiedID);

	        // 设置紧急程度为普通
	        OThinker.H3.Messages.MessageEmergencyType emergency = Messages.MessageEmergencyType.Normal;
	        // 这里也可以在启动流程的时候赋值
	        Dictionary<string, object> paramTables = new Dictionary<string, object>();

	        // 启动流程的消息
	        OThinker.H3.Messages.StartInstanceMessage startInstanceMessage
	            = new OThinker.H3.Messages.StartInstanceMessage(
	                emergency,
	                InstanceId,
	                paramTables,
	                Instance.PriorityType.Normal,
	                true,
	                null,
	                false,
	                OThinker.H3.Instance.Token.UnspecifiedID,
	                null);
	        Engine.InstanceManager.SendMessage(startInstanceMessage);
	        result = new BPMServiceResult(true, InstanceId, workItemID, "流程实例启动成功!", "");
	    }
	    catch (Exception ex)
	    {
	        result = new BPMServiceResult(false, "流程实例启动失败!错误:" + ex.ToString());
	    }
	    return result;
	}

其中:GetDataValuesWithDtl是将JSON转为DataItemParam[],其它的就与StartWorkflow流程一致了。重新使用wsdl生成代理类后,调用方式如下:

    var workflowCode = "qrssplc";
    var userCode = "oatest";
    var finishStart = true;
    var data = new {
        ysbm = 23231,
        kmys = new object[] {
            new { ysyjkm = "工资" }
        }
    };
    var json = Newtonsoft.Json.JsonConvert.SerializeObject(data);
    
    var service = new BPMService();
    service.AuthenticationValue = new Authentication
    {
        UserCode = "oatest",
        Password = "123"
    };

    var result = service.StartWorkflowByJson(workflowCode, userCode, finishStart, json);
    return result.InstanceID;

亲测可以。

BTW:为什么H3不默认提供这个方法呢?

不允许评论
粤ICP备17049187号-1