一:优惠券设计
动态模板表:里面有各种优惠的模板,比如满减模板,递减的模板,里面是动态的字段。
优惠券表:优惠券表对应各种优惠的模板。
实现类:每一个动态模板表对应的实现类,实现动态字段自动的注入到实现类
二:字典表和字典数据表
这两个表可以动态的指定某些字典的值。将如下这些具有相同类型的配置项,配置到系统的数据字典表中,方便系统维护,由超级管理员统一在后台进行数据字典维护,如果用户需求要增加变更配置项,只需要修改数据字典表记录即可,不需要修改代码。
三:字典管理的实现效果
四:优惠模板的管理实现效果
步骤:
- 创建模板时,动态的添加表单字段。
2.字段的属性输入,动态添加到页面上,还要有下标,识别出添加的第几个字段属性- 动态字段类型选择触发事件:当选择动态字段输入类型时字典数据要出来
4.提交模板:在优惠模板管理,需要展示出来,这就决定了要将动态字段拼接json,放入隐藏域
5.移除index字段,当不需要一些模板的时候可以删掉,这个时候就根据id去定位,这也是为什么要index的原因
这里为什么要把模板的动态字段设置成json字符串呢?因为后面反射生成优惠规则是需要动态的。
4.1:实现字典在动态字段的下拉框中实现字典展现
4.2前端代码:
//全局变量,表示当前的动态字段的数量
var index=0;
/**
* 创建模板时,动态的添加表单字段
*/
function addDynamicField() {
var html="";
html +="<div id='dyname_div"+index+"'>"
html +="<hr/>";
html +="动态字段的标识(页面显示的名称)";
html +="<input name='field_title"+index+"'/><br/>";
html +="动态字段的名称(name属性):";
html +="<input id='field_name"+index+"'/><br/>";
html +="动态字段输入类型";
html +="<select id='field_type"+index+"' οnchange='fieldTypeChange("+index+",this.value)'>";
html +="<option value='0'>文本框</option>";
html +="<option value='1'>密码框</option>";
html +="<option value='2'>日期选择框</option>";
html +="<option value='3'>单选框</option>";
html +="<option value='4'>复选框</option>";
html +="<option value='5'>下拉框</option>";
html +="</select>";
html +="<span id='field_dic"+index+"'><span>";
html +="<button type='button' οnclick='removeDynamicField("+index+");'>-</button><br/>";
html +="</div>";
//讲字段的属性输入,动态添加到页面上
$("#dyname_div").append(html);
index++;
}
/**
* 移除index字段
*/
function removeDynameField() {
$("dyname_div"+index).remove();
}
/**
* 动态字段类型选择触发事件
*/
function fieldTypeChange(index,type) {
//获得当前选择类型
if (type == 3 || type == 4 || type == 5) {
//需要显示字典选择
$.ajax({
url: "http://localhost/dic/list",
success: function (data) {
if (data.code == 200) {
//获得字典表
var dics = data.data;
//将字典列表转换成下拉框
var dicSelect = "<select id='field_dic" + index + "'>";
//循环字典列表
for (var i = 0; i < dics.length(); i++) {
dicSelect = "<option value='" + dics[i].id + "'>" + dics[i].name + "</option>"
}
dicSelect += "</select>";
$("#field_dic" + index).html(dicSelect);
}
}
})
} else {
//无需选择字典
$("#field_dic" + index).html("");
}
}
/**
* 提交模板
*/
function submitTemplate() {
//字段的数组
var fields=[]
//获得所有的动态字段
for (var i=0;i<index;i++){
//当前元素被删除
if ($("#dyname_div"+i).length==0){
continue;
}
//创建一个字段对象
var field={};
//获得第i个动态字段的标识
var title=$("#field_title"+i);
field.title=title;
//动态字段的name属性
var name=$("#field_name"+i);
field.name=name;
//动态字段的输入类型
var type=$("#field_type"+i);
field.type=type;
if (type==3||type==4||type==5){
//字典id
var dic=$("#field_dic"+i).find("option:selected").val();
field.dic=dic;
}
//将字段对象放入数组对象中
fields.push(field);
}
//将动态字段拼接json
console.log(JSON.stringify(fields));
//放入隐藏域
$("#templateDynamic").val(JSON.stringify(fields));
//提交表单
$("#formid").submit();
}
五:新增优惠券时动态的表单的展示
5.1:在新增优惠券的时候要选择不同的的优惠模板,在选择的同时要获得对应的数据。
他的实现方式基本都是:在新增模板有下拉框的都要写一个方法获得下拉框里面的值
/**
* 动态请求限制模板和规则模板
*/
function getTemplates() {
$.ajax({
url:"http://localhost/template/list",
success:function (data) {
if (data.code==200){
var ruleHtml="<select id='rule_select' οnchange='showDynamicField(0,this);'>";
var limitHtml="<select id='limit_select' οnchange='showDynamicField(1,this);'>";
ruleHtml +="<option>--请选择--</option>";
limitHtml +="<option>--请选择--</option>";
var templates=data.data;
console.log(JSON.stringify(templates));
//循环模板
for (var i=0;i<templates;i++){
//其中一个模板
var template=templates[i];
var temHtml="";
temHtml +="<option value='"+template.id+"' templateClass='"+template.templateClass+"' templateField='"+template.templateDynamic+"'>"+template.tname+"</option>";
//判断模板类型
if (template.templateType==0){
//规则模板
ruleHtml += temHtml;
}else{
//限制模板
limitHtml +=temHtml;
}
}
ruleHtml +="</select>";
limitHtml+="</select>";
//分别设置到指定的div中
$("#rule_div").html(ruleHtml);
$("#limit_div").html(limitHtml);
}
}
});
}
/**
* 动态展示模板的动态字段
*/
function showDynamicField(type,ele) {
//获得当前需要展示的动态字段
var templateClass=$(ele).find("option:selected").attr("templateClass");
var templateFeild=$(ele).find("option:selected").attr("templateField");
//处理动态字段
var fieldHtml ="";
var templateFieldJson =JSON.parse(templateFeild);
for (var i =0;i<templateFeildjson.length;i++){
//每循环一次就代表一个属性字段
fieldHtml +=templateFeildjson[i].title;
fieldHtml +=getFieldHtml(templateFeildjson[i],type);
fieldHtml +="<br/>";
}
//将实现类保存到隐藏域,等提交表单时处理
if (type==0){
$("#ruleClass").val(templateClass);
$("#rule_field_div").html(fieldHtml);
}else {
$("#limitClass").val(templateClass);
$("#limit_field_div").html(fieldHtml);
}
}
/**
* 根据动态字段的类型返回字段的输入html
* @param fieldJson
*/
function getFieldHtml(fieldJson,type) {
//获得当前字段的输入类型
var inputType=fieldJson.type;
var inputHtml ="<span inputType='"+inputType+"' type='"+type+"'>";
//如果类型3/4/5需要动态的获取字典数据
}
switch (parseInt(inputType)) {
case 0:
//输入数
inputHtml += "<input type='text' name='" + fieldJson.name + "'/>";
break;
case 1:
//密码框
inputHtml += "<input type='password' name='" + fieldJson.name + "'/>";
break;
case 2:
//日期选择数
inputHtml += "<input type='date' name='" + fieldJson.name + "'/>";
break;
case 3:
case 4:
case 5:
//单选框
//复选框
//下拉框
//请求字典数据
var dic = fieldJson.dic;
//ajax请求字典数据
$.ajax({
async:false, //设置ajax为同步请求
url: "htpp://localhost/dic/getContentByDid",
data: {
did: dic
},
success: function (data) {
if (data.code == 200) {
//获得字典的数据列表
var dicContents = data.data;
if (inputType == 5) {
inputHtml += "<select name='" + fieldJson.name + "'>";
}
for (var j = 0; j < dicContents.length; j++) {
if (inputType == 3) {
//单选框
inputHtml += "<input type='radio' name='" + fieldJson.name + "' value='" + dicContents[j].value + "'/>" + dicContents[j].name;
} else if (inputType == 4) {
//复选框
inputHtml += "<input type='checkbox' name='" + fieldJson.name + "' value='" + dicContents[j].value + "'/>" + dicContents[j].name;
} else if (inputType == 5) {
//下拉框
inputHtml += "<option value='" + dicContents[j].value + "'>" + dicContents[j].name + "</option>";
}
}
if (inputType == 5) {
inputHtml += "</select>";
}
}
}
})
break;
}
5.2提交表单
/**
* 提交表单时,获得动态表单的输入内容
*/
function getDynamicField(type) {
//获得所有规则的动态属性
var fields=$("[inputType][type='"+type+"']");
//获得对应的实现类
var myClasss=$("#"+(type ==0 ? "ruleClass" : "limitClass")).val();
//准备一个字段的数据
var fieldsArray= [];
//最终的对象
fieldsArray.myClasss=myClasss;
for (var i=0;i<fields.length;i++){
var span=fields[i];
//获得span下的输入类型
var inputType= $(span).attr("inputType");
//创建动态属性对象
var field = {};
field.type=inputType;
switch (parseInt(inputType)) {
case 0:
case 1:
case 2:
//文本框
var input=$(span).find(":first-child");
field.name=input.attr("name");
field.value=input.val();
break;
case 3:
//单选框
var inputRadio=$(span).find("input[type='radio']:checked");
field.name=inputRadio.attr("name");
field.value=inputRadio.val();
break;
case 4:
//复选框
var inputCheckckbox=$(span).find("input[type='checkbox']:checked");
field.name = inputCheckckbox.attr("name");
var array =[];
for (var j=0;j<inputCheckckbox.length;j++){
array.push(inputCheckckbox[j].value);
}
field.value=array;
break;
case 5:
//下拉框
var select = $(span).find("select");
field.name =select.attr("name");
var option=$(select).find("option:selected")
field.value=option.val();
break;
}
fieldsArray.push(field);
}
//打印当前的动态字段
fieldsArray.fields=fieldsArray;
return couponObj;
}
六:发布优惠券
<head>
<meta charset="UTF-8">
<title>优惠券发布页面</title>
<script src="resources/scripts/jquery-1.8.3.min.js"></script>
<!--时间控件-->
<script src="resources/widget/My97DatePicker/WdatePicker.js"></script>
<script>
//发布类型的选择触发
function updateMehod(type) {
if (type == 0) {
$("#timDiv").hide();
} else {
$("#timDiv").show();
}
}
//有效类型的选择触发
function updateType(type) {
if (type == 0) {
$("#scopDiv1").show();
$("#scopDiv2").hide();
} else {
$("#scopDiv2").show();
$("#scopDiv1").hide();
}
}
</script>
</head>
<body>
<h1>发布优惠券</h1>
<form action="/system/couponissue" method="post">
<!--隐藏域保存需要发布的优惠券id-->
<input type="hidden" name="cid" th:value="${#request.getParameter('cid')}"/>
发布类型:<select name="method" onchange="updateMehod(this.value)">
<option>--请选择--</option>
<option value="0">领券中心</option>
<option value="1">定时抢购</option>
</select><br/>
<div id="timDiv" style="display: none ; margin-top: 5px" >
定时抢购的开始时间:<input type="text" name="goStartTime" onclick="WdatePicker({dateFmt:'yyyy-MM-dd HH:mm:ss',minData:'%y-%M-%d {%H+1}:00:00'})" class="Wdate" onautocomplete="off">
定时抢购的结束时间:<input type="text" name="goStopTime" onclick="WdatePicker({dataFmt:'yyyy-MM-dd HH:mm:ss',minData:'%y-%M-%d {%H+1}:00:00'})" class="Wdate" onautocomplete="off})">
</div>
有效类型:<select name="type" onchange="updateType(this.value)">
<option>--请选择--</option>
<option value="0">时间范围时效</option>
<option value="1">领取时效</option>
</select><br/>
<div id="scopDiv1" style="display: none; margin-top: 5px">
有效开始时间:<input type="text" name="beginTime" onclick="WdatePicker()" class="Wdata"/></div><br/>
有效结束时间:<input type="text" name="endTime" onclick="WdatePicker" class="Wdata"/>
</div>
<div id="scopDiv2" style="display: none;margin-top: 5px">
有效天数:<input type="text" name="days"/>
</div>
发现数量:<input type="text" name="number"/><span style="font-weight: 900; color: red;">* -1代表无上限</span><br/>
<button type="submit">发布</button>
</form>
</body>