前端传入Grule,后端保存到 .grl 文件中
- 通过简单的输入框,将Grule的部分拆解成
规则名称
规则描述
规则优先级
规则条件
规则逻辑
- Grule关键字
when
Then
模拟了if
判断的条件和逻辑部分- 类似于
shell
和ruby
之类的脚本语言,有then
关键字 when
的&&
相当于多个条件的与
操作Then
之后为脚本逻辑语句, 所以后面要加;
分号结束
- 类似于
前端编写
- 前端模板:
templates/grule.tmpl
, 可以让用户输入Grule- 表单用
POST
往源服务器的/grule/form/
发送表单 - 其中
规则条件
和规则逻辑
有增加按钮- 使用dom树获取点击事件
- 点击时增加表单输入框
- 表单用
<html>
<p>请编写你的Grule规则</p>
<form name="grule" method="POST" action="/grule/form/">
规则名称: <input name="ruleName"></input><br/>
规则描述: <input name="ruleDesc"></input><br/>
规则优先级: <input name="ruleSalience"></input><br/>
<div>
规则条件: <input name="ruleCondition"></input>
<button type="button" id="addRuleCondition">增加</button>
</div>
<div>
规则逻辑: <input name="ruleLogic"></input>
<button type="button" id="addRuleLogic">增加</button>
</div>
<button type="submit">确认</button>
</form>
<script>
// 增加按钮的逻辑
var addRuleConditionButton = document.getElementById('addRuleCondition');
var addRuleLogicButton = document.getElementById('addRuleLogic');
var ruleConditionContainer = addRuleConditionButton.parentNode;
var ruleLogicContainer = addRuleLogicButton.parentNode;
addRuleConditionButton.addEventListener('click', function() {
var newInput = document.createElement('input');
newInput.name = 'ruleCondition';
newInput.type = 'text';
ruleConditionContainer.insertBefore(newInput, addRuleConditionButton);
});
addRuleLogicButton.addEventListener('click', function() {
var newInput = document.createElement('input');
newInput.name = 'ruleLogic';
newInput.type = 'text';
ruleLogicContainer.insertBefore(newInput, addRuleLogicButton);
});
</script>
</html>
- 表单分别将
Grule
拆解成了下面几个输入框- 提交表单后
c.Redirect(http.StatusFound, "/grule/form/")
会重定向回该页面
- 提交表单后
后端部分
- 设置跳转到
grule.tmpl
的接口
r.GET("/index", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.tmpl", gin.H{})
})
- 设置接受Grule表单的接口
- 使用
c.ShouldBind(&form)
绑定表单到RuleForm
结构体上- 结构体tag
form:"ruleName"
对应表单input
的name
属性 RuleConditions
切片类型字段, 对应表单都为ruleCondition
的多个input
- 结构体tag
- 接口使用
fmt.Sprintf()
格式化Grule字符串 - 接口使用文件操作将字符串保存到
grule/规则名.grl
- 使用
c.Redirect()
重定向会表单页面
- 使用
// 接收表单的结构体
type RuleForm struct {
RuleName string `form:"ruleName"`
RuleDesc string `form:"ruleDesc"`
RuleSalience string `form:"ruleSalience"`
RuleConditions []string `form:"ruleCondition"`
RuleLogic []string `form:"ruleLogic"`
}
func main() {
r.POST("/grule/form/", func(c *gin.Context) {
var form RuleForm
c.ShouldBind(&form) // 绑定表单
// 格式化字符串
grule := fmt.Sprintf(`
rule %s "%s" salience %s {
when
%s
Then
%s;
}`,
form.RuleName, form.RuleDesc, form.RuleSalience, strings.Join(form.RuleConditions, " && "), strings.Join(form.RuleLogic, ";\n\t\t"))Ω
// 将grule字符串写入文件
err := ioutil.WriteFile(fmt.Sprintf("grule/%s.grl", form.RuleName), []byte(grule), 0644)
if err != nil {
log.Println(err)
}
// 重定向
c.Redirect(http.StatusFound, "/grule/form/")
})
}
演示