前端传入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 RuleFormc.ShouldBind(&form) // 绑定表单// 格式化字符串grule := fmt.Sprintf(`
rule %s "%s" salience %s {when%sThen%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/")})
}
演示