可以使用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不默认提供这个方法呢?