前端传入Grule,后端保存到 .grl 文件中
- 通过简单的输入框,将Grule的部分拆解成
规则名称规则描述规则优先级规则条件规则逻辑 - Grule关键字
whenThen模拟了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/")
})
}
演示





















