智能销售系统day3

crud

1.添加功能

准备弹出框(当点击添加时弹出输入数据的窗口) 使用easyui-dialog组件
弹出框中使用的是form表单 展示要输入的字段
easyui-dialog中的属性:
closed:true 定义是否可以关闭窗口
modal:true 模态化(弹出框弹出时不允许操作除弹出框之外的数据)
buttons:’按钮的id’ 弹出的对话框窗口底部按钮

底部按钮 使用easyui-linkbutton组件 设置id(该id与easyui-dialog相绑定)
两个a标签:

  1. 确认按钮:设置data-method=“方法” js代码会获取所有带data-method属性的标签,给该标签绑定事件,当点击时会将该属性所对应的方法传送到后台操作数据
  2. 取消按钮:绑定事件取消操作"$(’#对话框窗口’).dialog(‘close’)

持久化到数据库 data-method中的保存方法
通过jquery的ajax进行提交,easyui(form)提供的方案

employeeForm.form('submit',{
    url:url,    //根据路径自动获取数据
    onSubmit: function(){
        // 一般在这里面做验证功能
        //validate:做表单字段验证,当所有字段都有效的时候返回true。该方法使用validatebox(验证框)插件
        return employeeForm.form("validate");
    },
    success:function(data){
        /**
         *  data为后台返回的数据,由SpingMVC返回
         *  SpringMVC返回的是一个JSON字符串,
         *  它返回的时候会在响应中告诉前端返回的是JSON数据
            jQuery如果发现响应头是JSON字符串会自动转成JSON来使用
         * */

        //把JSON格式的字符串转成一个JSON的对象值
        //var result = eval("("+data+")");
        var result = JSON.parse(data); //标准的JSON格式
        if(result.success){
            employeDlg.dialog("close");//关闭窗口
            employeeGrid.datagrid("reload");//刷新数据        
	}else{
	  //如果保存错误,给出提示信息,并给出错误的原因
            $.messager.alert('提示信息','保存失败! 原因:'+result.msg,'error');
        }
    }
});

Controller层

  1. 准备一个返回json对象的公共类(JsonResult)
    准备两个字段:
    success:默认为true,当操作发生错误时,修改为false
    msg:错误信息
  2. 添加控制层,这里将保存和修改分开是为了之后权限限制的设置
@RequestMapping("/save")
@ResponseBody
public JsonResult save(Employee employee){
    return saveOrUpdate(employee);
}
添加与修改的方法是一样的,区别在于有无id,所以抽取成一个方法
private JsonResult saveOrUpdate(Employee employee){
    JsonResult result = new JsonResult();
    try {
        //根据id执行删除方法,success默认为true则刷新数据
        employeeService.save(employee);
    }catch (Exception e){
        e.printStackTrace();
        //如果出错那么修改success为false,为false则不刷新数据
        result.setSuccess(false);
        //给出错误信息
        result.setMsg(e.getMessage());
    }
    return result;
}

注:
1.添加按钮每一次打开一个新的对话框需要将上一次输入的数据清除
employeeForm.form(“clear”);
2.打开显示对话框的位置
employeDlg.dialog(“center”).dialog(“open”);

2.删除功能

  1. 首先选中行,如果没有选中行给出提示信息
  2. 选中行后,再次确认是否删除
  3. 通过ajax请求进行删除,带着选中行的id发送到控制层
  4. 如果删除成功刷新数据,失败则给出提示并给出错误的信息
//首先获取选中的行
var row = employeeGrid.datagrid("getSelected");
//这时row中就有了所有的数据
//判断是否选中了行,就判断row中是否有数据
if (row){
    //有数据那么进行删除确认,询问是否确定要删除
    $.messager.confirm('确认','您确认想要删除记录吗?',function(r){
        if (r){
            //确认后,通过ajax请求进行删除
            //将row中的id传到后台的删除方法进行删除
            $.get("/employee/delete",{id:row.id},function (result) {
                //如果删除成功那么刷新数据
                if (result.success){
                    $("#employeeGrid").datagrid("reload");
                }else {
                    //删除失败,给出提示,并提示错误信息msg
                    $.messager.alert('提示信息','删除失败!,原因:'+result.msg,"error");
                }
            })
        }
    });
}else {
    //row中没有数据,提示要先选中行
    $.messager.alert('提示信息','请选择你要删除的记录!',"info");
}

Controller层

@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
    JsonResult result = new JsonResult();
    try {
        //根据id执行删除方法,success默认为true则刷新数据
        employeeService.delete(id);
    }catch (Exception e){
        e.printStackTrace();
        //如果出错那么修改success为false,为false则不刷新数据
        result.setSuccess(false);
        //给出错误信息
        result.setMsg(e.getMessage());
    }
    return result;
}

3.修改功能

  1. 首先选中行,如果没有选中行给出提示信息
  2. 需要将上一次输入的数据清除
  3. 数据的回显
  4. 部门的id(在这里部门的id获取不到,因为id名不同,需要将id名改为一样的)
update(){
    //修改方法
    //首先获取选中的行
    var row = employeeGrid.datagrid("getSelected");
    if(row){
        //同样需要清除或重置数据,避免上一次修改的数据会出行
        employeeForm.form("clear");
        //修改需要将要修改的数据显示出来,数据回显(注:必须在清除数据的后面)
        // 关连对象回显需要做的操作
        if(row.department){
            /**
             * 解决部门数据显示不出来的问题
             * row:{"department":{"id":2,name:"xxx"}}
             * row:{"department.id":2}
             * 因为id不同,直接获取的是row中的属性department中的属性,里面有id,name等,然后才是值
             * 需要获取的是row中的department.id的的值,直接拿到值而不是属性
             *
             * 注意:这里department.id需要加双引号,不加会默认是一个变量而不是一个json的字符串
             * */
            row["department.id"] = row.department.id;
        }
        //进行数据的回显
        employeeForm.form("load",row);
        //弹出界面
        employeDlg.dialog("center").dialog("open");
    }else {
        $.messager.alert('提示信息','请选择你要修改的记录!','info');
    }

Controller层

//修改方法 添加与修改是一样的 就是看有没有id
@RequestMapping("/update")
@ResponseBody
public JsonResult update(Employee employee){
    return saveOrUpdate(employee);
}

持久化到数据库	data-method中的保存方法
修改与添加的方法是一样的,区别只是在于有没有id
在这里添加一个区分,看前台的数据有没有id,有则修改
剩下的持久化数据库与保存的一样
/**
 * 区分路径是为了之后的权限设置
 * */
//准备路径(默认是保存)
var url = "/employee/save";
//拿到表单的id(有值的话,路径进行修改)
var id = $("#employeeId").val();
if(id){
    url = "/employee/update";
}

4.验证功能

引入验证功能的代码

<%--验证功能支持的js--%>

<%--验证功能支持的css--%>


验证完成功能的代码

1.邮件验证(validType规则)

    email:
    


2.密码验证

    <%--
        validType="equals['password','id']"
        与密码绑定,equals判断两次输入的密码是否一致
        通过id绑定,制定规则
    --%>
    密码确认:
    


自定义验证功能

1.验证用户名重复
//自定义验证功能(验证用户名重复)
$.extend($.fn.validatebox.defaults.rules, {
    //自己定义的规则名 与用户名标签中的validType:'checkName'属性名一致
    checkName: {
        //这个方法里面就是验证规则 返回true:验证成功   返回false:验证失败
        // value:验证框中的值  param:验证的参数(数组)
        validator: function(value, param){
            //获到id的值,是因为修改页面需要id
            var employeeId = $("#employeeId").val();
            //异步:导致数据还没有返回,但是后面代码已经执行完了 -> 解决方案:同步
            //一定要使用同步方案
            var result = $.ajax({
                url: "/employee/checkName", //传送到控制层进行查询数据库中是否有这个用户名
                data:{username:value,id:employeeId},//返回查询到的用户名,id是为了修改的验证
                async: false //同步
            }).responseText;
            return result == "true";//将数据库查出来的用户名和前台传进来的用户名相比较
			//注意:这里的data是json的字符串,需要打上引号
        },
        //验证失败给出提示
        message: '该用户名已经被占用!'
    }
});

Controller层

@RequestMapping("/checkName")
@ResponseBody
public boolean checkName(String username,Long id){
    if(id!=null){
        //代表是修改,如果没有id传过来那么就是保存的用户名验证
        //根据id到数据库中查询员工
        Employee dbEmp = employeeService.findOne(id);
        //如果名称数据库的员工名称与前台传过来的相等,就直接返回true
        if(dbEmp.getUsername().equals(username)){
            return true;
        }
    }
    return employeeService.checkName(username);
}

修改对话框同样需要进行用户名验证:
后台获取id,根据id拿到对应用户,如果数据库的用户名称和传过来的名称相应,直接返回true,代表这个名字是可以用的

问题:

  1. 修改的时候没有密码,密码规则又让我们两次密码必须相等,所以修改不了
    解决:

    1. 在修改对话框直接将密码不显示出来并禁用
      //把所有带 data-save属性的元素隐藏起来
      $("[data-save]").hide();
      //对应的元素禁用(这个值就不会提交到后台)
      $("
      [data-save] input").validatebox(“disable”);
    2. 在保存对话框又将密码显示出来解除禁用
      //把所有带 data-save属性的元素显示起来
      $("[data-save]").show();
      //把对应的元素启用
      $("
      [data-save] input").validatebox(“enable”)
  2. 数据丢失问题
    数据修改时,出现了脏数据更新,导致数据丢失
    解决:

    1. 隐藏域(只隐藏,但是数据还是需要传递)代码量太大
    2. 在JPA的相应字段上加标签@Column(updatable = false) 不能修改了
    3. 先查询数据库,获取持久状态的对象,然后把页面的数据set到对象里面

在这里使用的方法3:
先查询数据库,获取持久状态的对象,然后把页面输入的数据添加到持久状态的对象中去,这样要修改的数据被改变了,没有被修改的数据就是原来从数据库中查到的数据
使用的注解

@ModelAttribute : 在路径访问这个方法的时候会先执行它
当修改才查询:添加:/employee/save 修改:/employee/update?cmd=update
@ModelAttribute("editEmployee")
public Employee beforeEdit(Long id,String cmd){
    //修改的时候才查询(只要有id会就进行一次查询,这是不对的)
	//所以设置一个字段,只有是修改时才进行查询
    if(id!=null && "update".equals(cmd)) {
        Employee dbEmp = employeeService.findOne(id);
        //把要传过来的关联对象都清空,就可以解决n-to-n的问题
        dbEmp.setDepartment(null);
        return dbEmp;
    }
    return null;
}

//这里的ModelAttribute和上面的名称是对应上的
@RequestMapping("/update")
@ResponseBody
public JsonResult update(@ModelAttribute("editEmployee")Employee employee){
    return saveOrUpdate(employee);
}
  1. n-to-n问题
    修改的时候也在相应的修改它的部门,这时候部门是一个持久化对象,它的id是不允许进行修改的
    解决:
    在获取员工的时候把部门设置为空

你可能感兴趣的:(智能销售系统day3)