业务需求业务流程中的单据,在自动清分节点上根据不同的业务规则分配给不同岗位上的员工处理。业务规则存储在数据库中。每次清分单据的时候获取这些规则用drools 拼成业务规则模板
将单据记录分给不同岗位的员工。
使用业务规则的好处是避免程序代码中的if else 的不断增加需要重新编译code部署。
规则模板
template header
RULE_NAME
WHEN_DSL
DEAL_POST
package com.taikang.fol.module.common.vo
template "DispatchRule"
rule "DispatchRule_@{RULE_NAME}"
when
apply : TCommonApply(@{WHEN_DSL})
then
apply.setDealPost("@{DEAL_POST}");
end
end template
function boolean iscontain(String des,String org){
return des.contains(org);
}
调用的action
public class WebServicesAction {
public static final Logger log = Logger.getLogger(WebServicesAction.class) ;
@In(value = "#{dispatchRuleBO}", required = false)
private DispatchRuleBO dispatchRuleBO;// 清分规则业务方法
@In(value = "#{reimBO}", required = false)
private ReimBO reimBO;
@In(value = "#{budgetBO}", required = false)
private BudgetBO budgetBO;
// 数据库操作
@In(value = "#{reimTravelBO}", required = false)
private ReimTravelBO reimTravelBO;
@In(value="#{ldapBO}",required=true)
protected LdapBO ldapBO;
@In(value = "#{OAInterfaceBO}", required = false)
private OAInterfaceBO oaBo;
private DispatchRule createRule(String ruleName, String whenDsl,
String dealPost) {
DispatchRule rule = new DispatchRule(ruleName, whenDsl, dealPost);
return rule;
}
public String dispatch(final String applyid) {
try {
/*
* 取出对应表单
*/
TCommonApply apply = dispatchRuleBO.getTCommonApplyByApplyid(applyid);
if(apply==null){
log.error("找不到单据"+applyid+",执行自动清分失败");
return "";
}
final RuleDataDrivenTemplate template=RuleDataDrivenTemplate.getInstance();
/*
* 取所有规则
*/
final List<TShareDispatchRule> ruleList = dispatchRuleBO.loadRules();
template.execute(new RuleComplierCallBack(){
/* (non-Javadoc)
* @see com.taikang.fol.module.share.rule.RuleComplierCallBack#doComplier(org.drools.template.DataProviderCompiler)
*/
public String doComplier(final DataProviderCompiler converter) {
final List<DispatchRule> rules = new ArrayList<DispatchRule>();
for(TShareDispatchRule rule : ruleList){
List<TShareDispatchCondGroup> groups=rule.getTShareDispatchCondGroups();
for (TShareDispatchCondGroup condGroup : groups) {
/*
* 取第一个条件,第一个条件无逻辑运算符,此条件需排在首位
*/
String whenDsl = "";
String firstWhenDsl="";
List<TShareDispatchCond> conds=condGroup.getTShareDispatchConds();
for (TShareDispatchCond cond : conds) {
if(StringUtils.isEmpty(cond.getLogicOperator())){
firstWhenDsl=cond.getWhenDsl();
continue;
}
whenDsl += (" " + cond.getWhenDsl() + " ");
}
rules.add(createRule(condGroup.getId(), firstWhenDsl+whenDsl, condGroup.getPositioncode()));
}
}
template.getDispatchDataProvider().setRules(rules);
InputStream inputStream=new ByteArrayInputStream(template.getDispatchTemplateStr().getBytes());
String dsl=converter.compile(template.getDispatchDataProvider(),inputStream);
try {
inputStream.close();
} catch (IOException e) {
}
log.debug(applyid+"生成的规则内容:\n"+dsl);
return dsl;
}
}, apply);
log.info(applyid+"费用类型["+apply.getBusinesstypecode()+"]清分后的岗位为:<"+apply.getDealPost()+">");
if(apply.getDealPost()==null||apply.getDealPost().equals("")){
this.reimTravelBO.getBaseDAO().bulkUpdate("update TCommonApply set status=? where applyid=?", new String[]{SysConst.HAND_DISPATCH,applyid});//手动清分
}else{
this.reimTravelBO.getBaseDAO().bulkUpdate("update TCommonApply set status=? where applyid=?", new String[]{SysConst.AUDITING,applyid});//待审核
}
return apply.getDealPost() == null ? "" : apply.getDealPost();
} catch (Exception e) {
log.error("单据"+applyid+"执行自动清分失败", e);
this.reimTravelBO.getBaseDAO().bulkUpdate("update TCommonApply set status=? where applyid=?", new String[]{SysConst.HAND_DISPATCH,applyid});//手动清分
return "";
}
}
public class DispatchRule {
private String ruleName;
private String whenDsl;
private String dealPost;
public DispatchRule(){}
public DispatchRule(String ruleName, String whenDsl, String dealPost) {
this.ruleName = ruleName;
this.whenDsl = whenDsl;
this.dealPost = dealPost;
}
}
public String getWhenDsl() {
if(!StringUtils.isEmpty(logicOperator)){
whenDsl+=(logicOperator.equals("and")?"&&":"||");
}
if(!StringUtils.isEmpty(operator)){
if(operator.equals("in")){
getOperatorValues();
List<String> codeList=new ArrayList<String>();
for(SelectItem item : operatorValues){
codeList.add("("+item.getValue()+")");
}
String tempCode="\"(\"+"+code+"+\")\"";
whenDsl+="eval(iscontain(\""+StringUtils.join(codeList, ',')+"\","+tempCode+"))";
}else{
operator=StringUtils.replace(operator, "lt", "<");
if(code.equals("amount")){
whenDsl+=(code+operator+operatorValue);
}else{
whenDsl+=(code+operator+"\""+operatorValue+"\"");
}
}
}
return whenDsl;
}
public List<SelectItem> getOperatorValues() {
operatorValues.clear();
String[] strs=StringUtils.split(operatorValue, ',');
for(String str : strs){
//取公司名
String name=StringUtils.substringBetween(str, "[", "(");
String code=StringUtils.substringBetween(str, "(", ")");
operatorValues.add(new SelectItem(code,name));
}
return operatorValues;
}
public class RuleDataDrivenTemplate {
private final static Logger logger = Logger.getLogger(RuleDataDrivenTemplate.class);
private static RuleDataDrivenTemplate instance=null;
private KnowledgeBuilder kbuilder=null;
private DataProviderCompiler provider=null;
private KnowledgeBase kbase = null;
private StatelessKnowledgeSession ksession=null;
private DispatchDataProvider dispatchDataProvider=null;
//private InputStream dispatchTemplate=null;
private String dispatchTemplateStr="";
private RuleDataDrivenTemplate(){
//kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
provider=new DataProviderCompiler();
kbase = KnowledgeBaseFactory.newKnowledgeBase();
dispatchDataProvider=new DispatchDataProvider();
//dispatchTemplate=RuleDataDrivenTemplate.class.getResourceAsStream("template/DispatchRules.drt");
try {
char[] bts=new char[1024];
FileReader reader=new FileReader(RuleDataDrivenTemplate.class.getResource("template/DispatchRules.drt").getPath());
int num=reader.read(bts);
dispatchTemplateStr=new String(bts,0,num);
reader.close();
} catch (FileNotFoundException e) {
logger.error("找不到文件DispatchRules.drt", e);
}catch (IOException e) {
logger.error("无法读取文件DispatchRules.drt", e);
}
}
public static RuleDataDrivenTemplate getInstance(){
if(instance==null){
instance=new RuleDataDrivenTemplate();
}
return instance;
}
public String getDispatchTemplateStr() {
return dispatchTemplateStr;
}
public void setDispatchTemplateStr(String dispatchTemplateStr) {
this.dispatchTemplateStr = dispatchTemplateStr;
}
public DispatchDataProvider getDispatchDataProvider() {
return dispatchDataProvider;
}
public void setDispatchDataProvider(DispatchDataProvider dispatchDataProvider) {
this.dispatchDataProvider = dispatchDataProvider;
}
public void execute(RuleComplierCallBack complier,Object object){
logger.debug("开始执行单据清分...");
if(kbuilder==null){
kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
String dsl=complier.doComplier(provider);//这个方法被重写了
kbuilder.add(ResourceFactory.newByteArrayResource(dsl.getBytes()), ResourceType.DRL);
if (kbuilder.hasErrors()) {
for(KnowledgeBuilderError error : kbuilder.getErrors()){
logger.error("line:["+error.getErrorLines().toString()+"] message:"+error.getMessage());
}
throw new RuntimeException("ERROR-无法编译规则,规则执行失败");
}
final Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(pkgs);
}
ksession = kbase.newStatelessKnowledgeSession();
ksession.execute(object);
logger.debug("执行规则完成");
}
public KnowledgeBuilder getKbuilder() {
return kbuilder;
}
public void setKbuilder(KnowledgeBuilder kbuilder) {
this.kbuilder = kbuilder;
}
}
public class DispatchDataProvider implements DataProvider {
private Iterator<DispatchRule> iterator;
public DispatchDataProvider() {
}
public void setRules(List<DispatchRule> rows){
this.iterator=rows.iterator();
}
public boolean hasNext() {
return iterator.hasNext();
}
public String[] next() {
DispatchRule nextRule = iterator.next();
String[] row = new String[]{ nextRule.getRuleName(),
nextRule.getWhenDsl(),
nextRule.getDealPost()};
return row;
}
}