笔记二(easyui改进所有功能)

        有了笔记一中建立的前台页面框架,以及对于控制层和拦截器的配置之后,只需要对于login.ftl文件进行简单的修改即可改善登录功能。

登录改进

1、修改验证码验证的控制层YanzhengmaController.java,修改验证码的验证方式,改用easyui中的异步验证

//验证验证码
	@RequestMapping("validatecode")
	@ResponseBody
	public boolean isyanzhengma(HttpServletRequest request,String yanzhengma) {
		HttpSession session = request.getSession(true); 
		String yanzhengmasession=(String)session.getAttribute("yanzhengma");
		boolean flag= false;
		if(yanzhengmasession!=null&&yanzhengmasession.equalsIgnoreCase(yanzhengma)){
			flag= true;
		}
		return flag;
	}
        $("#codeImg").on("click",function(){changeImg()});
		
	var changeImg = function(){
		$(codeImg).prop("src","${base}/code/init?temp="+Math.random());
	}
		
	$('#code').validatebox({    
		   required: true,    
		   validType: "remote['${base}/code/validatecode','yanzhengma']",
		   tipPosition:'bottom' ,
		   deltaX:20
	}); 

2、为login.ftl页面中的表单添加表单验证
      也就是为用户名和密码添加非空验证。

<form id="loginForm">
	<div>
		用户名:<input type="text" id="userName" class="easyui-textbox" required=true/></br>
		密 &nbsp;码:<input type="password" id="userPass" class="easyui-textbox" required=true/></br>
		验证码:<input type="text"  id="code"/>
			<img src="${base}/code/init" id="codeImg"/></br>
	</div>
</form>

3、登录方法的修改
      只有当所有的表单验证通过之后才可以提交内容,进行登录

function user_login(){
	var isValid = $("#loginForm").form('validate')
	var userNameval = $("#userName").val();
	var userPassval = $("#userPass").val();
	if(isValid){
		$.ajax({
			url:"${base}/logincontroller/login",
			data:{"userName":userNameval,"userPass":userPassval},
			type:"get",
			dataType:"json",
			success:function(data){
				console.log(data);
				if(data == 0){
					$.messager.alert("提示","用户名或密码错误!");
					//重置表单
					$("#loginForm").form('reset');
					//切换验证码
					changeImg()
				}else{
					$.messager.alert("提示","登录成功");
					location.href="${base}/";
				}
			}
		});
	}
}

      其他的后台验证方法都不需要进行修改。

列表功能改进

      之前的列表页面中,需要有两个控制层方法才可以进行一步的数据查询,并且在进行数据列表的时候还需要手动的进行数据的输出,以及分页的配置。而使用了easyui中的分页组件,以及datagrid之后,明显没有那么复杂了。但是,使用easyui中的组件,很多的属性名称必须要与之对应起来,否则无法接受与传送数据。
      对于easyui的分页组件中,它在列表发送请求之后,会自动的发送两个参数:①page:当前页,②rows:表示每页显示的条数。所以如果还想继续使用之前的分页模式,就必须将PageUtil.java类中的属性名称进行修改。
1、修改PageUtil.java类

public class PageUtil {
	
	//easyUI的分页默认会发送这样两个固定名字的属性过来,所以为了接收方便,定义如下两个属性。
	private int page = 1;
	private int rows = 3;
	public int getPage() {
		return page;
	}
	public void setPage(int page) {
		this.page = page;
	}
	public int getRows() {
		return rows;
	}
	public void setRows(int rows) {
		this.rows = rows;
	}

}

     同时在进行查询之后,页面中的组件会接收①rows:所有查询出来的数据和②total:数据的总条数两个参数。所以还需要修改BookServiceImpl.java中的分页设置以及返回的内容。并且也没有必要在使用另外ServicePageUtil.java类来进行操作,因为其要求的返回值内容已经非常少了。

@Override
public Map<String, Object> list(Book vo) {
	if(vo != null){
		if(vo.getBookLabel() != null && !"".equals(vo.getBookLabel())){
			String labels = vo.getBookLabel().substring(1);
			vo.setLabels(Arrays.asList(labels.split(",")));
		}
		Map<String,Object> map = new HashMap<String,Object>();
		PageHelper.startPage(vo.getPage(), vo.getRows());
		List<Book> list = this.bookDAO.findAll(vo);
		Page page = (Page) list;
		//获取总条数
		long total = page.getTotal();
		map.put("total", total);
		map.put("rows", list);
		return map;
	}
	return null;
}

      分页修改好之后,还需要修改控制层的方法,所以需要修改BookController.java,删除show()方法,只保留一个list()方法即可
2、修改BookController.java类

@RequestMapping("list")
@ResponseBody
public Map<String,Object> list(HttpServletRequest request,Model model,Book vo){
	if(vo != null){
		Integer uid = (Integer) request.getSession().getAttribute("uid");
		vo.setUserId(uid);
		return this.bookService.list(vo);
	}
	return null;
}
//添加访问listBooks.ftl文件的路径,因为要在选项中显示listBooks.ftl文件
@RequestMapping("toList")
public String list() {
	return "book/listBooks";
}

3、修改listBooks.ftl,并且删除showBooks.ftl文件。由于所有操作都要从listBooks.ftl文件出发,所以先修改列表操作。
 

<#assign base=request.contextPath />
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<div data-options="region:'center',split:true"">
		<#-- 声明数据表格容器 -->
		<table id="tbcon"></table>
	</div>
<script type="text/javascript">
	//初始化数据表格
	$("#tbcon").datagrid({
		//数据接口
		url:"${base}/book/list",
		//开启分页
		pagination:true,
		//可选每页条数
		pageList:[3,6,9],
		//每页条数,必须设置首选项,否则默认值显示
		pageSize:3,
		//分页工具栏位置
		//pagePosition:'bottom',
		//自适应窗口大小
		fit:true,
		//列属性
		columns:[[    
	        {field:'suibian',checkbox:true},
	        {field:'bookId',title:'书籍ID'},    
	        {field:'bookName',title:'书籍名称'},    
	        {field:'bookAuthor',title:'书籍作者'},
			//对于复杂的列,可以通过formatter对其内容进行设置,其方法中,value表示当前的值,row表示该行数据
	        {field:'bookCover',title:'书籍封面',
	        		formatter: function(value,row,index){
	       				//如下的写法太复杂了,注意只有数字才这么写.
				    	var imgPath ="${base}" + value;
				    	//imgPath = imgPath.replace(/\,/,"")
				    	//console.log(imgPath)
				    	return '<img width="120px" height="60px" border="0" src='+imgPath+'/>';
			    	}  
	        },
	        {field:'bookPrice',title:'书籍价格'},
	        {field:'bookType',title:'书籍类型',
	        	formatter: function(value,row,index){
					return row.bookType.typeName;
				}
	        },
	        {field:'bookPress',title:'书籍出版社',
	        	formatter: function(value,row,index){
					return row.bookPress.pressName;
				}
	        },
	        {field:'bookStatus',title:'书籍状态',
		        formatter: function(value,row,index){
		        	if(row.bookStatus == 1){
						return "上架";
					}else{
						return "下架";
					}
				}
			},
			{field:'bookAddTime',title:'书籍上架时间'},
	       	{field:'bookLabel',title:'书籍标签',
	        	formatter: function(value,row,index){
	        		var str = "";
	        		if(null != value && 0 < value.length){
	        			if(-1 != value.indexOf(1)){
	        				str += ",校园";
	        			}
	        			if(-1 != value.indexOf(2)){
	        				str += ",青春";
	        			}
	        			if(-1 != value.indexOf(3)){
	        				str += ",政治";
	        			}
	        			if(-1 != value.indexOf(4)){
	        				str += ",经济";
	        			}
	        		}
	        		
	        		if(0 < str.length){
	        			str = str.substr(1)
	        		} 
					return str;
				}
	        },
	        {field:'bookDesc',title:'书籍描述'},
	        {field:'proLocation',title:'作者所在省',
	        	formatter: function(value,row,index){
					return row.proLocation.locationName;
				}
	        },
	        {field:'cityLocation',title:'作者所在市',
	        	formatter: function(value,row,index){
					return row.cityLocation.locationName;
				}
	        },
	        {field:'user',title:'操作用户',
		        formatter: function(value,row,index){
		        	//console.log(row);
					return row.user.userName;
				}
			}
	    ]],
        toolbar: [
	    	{
		    	text:"搜索",
				iconCls: 'icon-search',
				handler: function(){
                    //进行条件搜索的方法
					user_search()
				}
			}
		]	
	});
</script>
</body>
</html>

      其中列表展示页面,包括了单选、多选、下拉列表、图片、以及多表查询返回的内容的数据展示时,数据的格式化操作。对于分页可以看出,框架一出现,所有的分页操作几乎变成了内置的,而且还是最简化的,不过你如果想使用人家的框架,必须要符合人家的要求。这一点会比较难受。

条件查询

      当数据可以展示出来之后,面临的自认就是如何快速定位到想要的数据,所以还需要继续改进条件搜索的方式,也就是实现user_search()方法,并且需要设置相应的查询表格,而在设置过程中,又会接触到另一种下拉列表的生成,在easyui中叫做组合框comoboBox。
1、在显示页面补充条件查询所需要的表格,并且进行格式布局设置

<div class="easyui-layout" data-options="fit:true">
	<div data-options="region:'north',split:true"">
		<table border="1">
			<tr>
				<td>书籍名称</td>
				<td>
					<input name="bookName" id="bookName" class="easyui-textbox">
				</td>
			</tr>
			<tr>
				<td>书籍类型</td>
				<td>
					<input  id="bookTypeId" />
				</td>
			</tr>
			<tr>
				<td>书籍出版社</td>
				<td>
					<input  id="bookPressId" />
				</td>
			</tr>
			<tr>
				<td>文章状态</td>
				<td>
					<input type="radio" name="bookStatus" value="1"/>上架
					<input type="radio" name="bookStatus" value="2"/>下架
				</td>
			</tr>
			<tr>
				<td>发布日期</td>
				<td>
		        	<input id="startTime" name="startTime" class="easyui-datebox">
                            --><input id="endTime" name="endTime" class="easyui-datebox">
				</td>
			</tr>
			<tr>
				<td>文章标签</td>
				<td>
					<input type="checkbox" name="bookLabel" value="1"/>校园
					<input type="checkbox" name="bookLabel" value="2"/>青春
					<input type="checkbox" name="bookLabel" value="3"/>政治
					<input type="checkbox" name="bookLabel" value="4"/>经济
				</td>
			</tr>
		</table>
	</div>
	<div data-options="region:'center',split:true"">
		<#-- 声明数据表格容器 -->
		<table id="tbcon"></table>
		
	</div>
</div>

      其中根据类型搜索以及根据出版社搜索,这两个操作都是需要生成对应的下拉列表,由于需要从数据库中读取,并且会自动生成,而且其默认不会选中value值为“-1”的"<option>”,所以还需要进行修改book-mapper.xml中之前的类型出版社条件查询的条件,并且还需要在其各自的业务层实现类中,设置第一个默认被选中的值,操作如下:

①修改BookTypeServiceImpl.java类中的内容

@Override
public List<BookType> list() {
	
	List<BookType> booktype = this.typeDAO.findAll();
	BookType type = new BookType();
	type.setTypeName("--请选择--");
	type.setTypeId(0);
	booktype.add(0, type);
	return booktype;
}

②修改BookPressServiceImpl.java类的内容

@Override
public List<BookPress> list() {
	List<BookPress> bookpress = this.pressDAO.findAll();
	BookPress press = new BookPress();
	press.setPressName("--请选择--");
	press.setPressId(0);
	bookpress.add(0, press);
	return bookpress;
}

③修改book-mapper.xml文件中的判断条件

<if test=" null != bookTypeId and 0 != bookTypeId"> AND p.book_type_id = #{bookTypeId}</if>
<if test=" null != bookPressId and 0 != bookPressId"> AND p.book_press_id = #{bookPressId}</if>

④为类型和出版社设置值,并且建立user_search()方法

$("#bookTypeId").combobox({
	url:'${base}/booktype/listAll',    
	valueField:'typeId',    
	textField:'typeName'   
}); 
$("#bookPressId").combobox({
	url:'${base}/bookpress/listAll',    
	valueField:'pressId',    
	textField:'pressName'   
}); 
//搜索
function user_search(search_type) {
	var bookName = $("#bookName").textbox("getValue");
	var bookTypeId = $("#bookTypeId").combobox("getValue");
	var bookPressId = $("#bookPressId").combobox("getValue");
	var bookStatus = $("[name='bookStatus']:checked").val();
	var startTime = $("#startTime").datebox("getValue");
	var endTime = $("#endTime").datebox("getValue");
	var labels = "";
	$("[name='bookLabel']:checked").each(function(){
		labels += "," + $(this).val();
	});
	var data = {
		bookName:bookName,
		bookTypeId:bookTypeId,
		bookPressId:bookPressId,
		bookStatus:bookStatus,
		startTime:startTime,
		endTime:endTime,
		bookLabel:labels,
	};
	
	//考虑到修改成功之后可能需要在原页面停留  null和undefined是一致的
	if(null == search_type ){
		search_type = "load"
	}
	$("#tbcon").datagrid(search_type,data);
}

 其中的作用已经描述的非常清楚了。至此,条件查询以及列表展示都已经修改完成。然后开始设置添加数据,和修改数据,以及状态修改,删除,批量删除操作。
      删除和批量删除操作使用的是同一个方法,所以在此处将其合并,不在分开使用,并且,也不需要自己手动的设置全选反选的操作,只需要在datagrid初始化的columns中添加新的行“ {field:'suibian',checkbox:true}”,其中的“field”名字随意,如果要添加其他的与具体数据库列无关之类的操作,也可以按照类似的方式。

批删操作

      首先需要在datagrid中的toolbar中继续添加一个新的按钮

'-',{
	text:"删除",
	iconCls: 'icon-remove',
	handler: function(){
		del_all();
	}

      注意,按钮之间使用“ '_' ”间隔,然后实现del_all()方法

//批量删除操作
function del_all() {
	//是否选中了数据
	var dataarrry = $("#tbcon").datagrid("getSelections");
	if (0 == dataarrry.length) {
		$.messager.alert("提示", "请至少选中一条数据");
	} else {
		$.messager.confirm('确认','您确认想要删除记录吗?',function(bool){    
			if (bool){    
				//删除操作   
				var ids = "";
				for (var i = 0; i < dataarrry.length; i++) {
					ids = ids + "," + dataarrry[i].bookId;
				}
				if (0 < ids.length) {
					ids = ids.substr(1);
				}
				$.ajax({
					url:"${base}/book/rm",
					data:{ids:ids},
					type:"post",
					success:function(data) {
						user_search();
					}
				});
			}    
		});
	}
}
	

用户的上下架操作

      在datagrid的toolbar中添加新的工具

,'-',{
	text:"更新状态",
	iconCls: 'icon-update',
	handler: function(){
		edit_status();
	}
}

      编辑edit_status()方法

//修改状态操作
function edit_status() {
	var dataarrry = $("#tbcon").datagrid("getSelections");
	if (1 == dataarrry.length) {
		var bookid = dataarrry[0].bookId;
		var status = 0;
		if(1 == dataarrry[0].bookStatus){
			status = 2;
		}else{
			status = 1
		}
		$.ajax({
			url:"${base}/book/editStatus",
			data:{bookId:bookid,bookStatus:status},
			type:"post",
			dataType:"json",
			success:function(data) {
				user_search("reload");
			}
		});
	
	} else {
		$.messager.alert("提示", "只能更新一条数据");
	}
}

      本来希望为每一行数据都添加一个按钮,然后通过onclick()事件来完成操作的,可是,加了linkbutton的方式不太懂,而且即使加上了,按钮在主题中并不会显示为一个button的样式。而下载图片的判断与此操作完全相同,所以略过。

增加和修改数据功能

      在listBooks.ftl文件中添加datagrid中的toolBar中添加新的工具

,'-',{
	text:"添加",
	iconCls: 'icon-add',
	handler: function(){
		open_add_dialog();
	}
},'-',{
	text:"修改",
	iconCls: 'icon-edit',
	handler: function(){
		open_edit_dialog()
	}
}

 ①完成open_add_dialog()方法

function open_add_dialog(){
	var add_dialog = $("<div></div>").dialog({
		title:"添加信息",
		width:500,
		height:380,
		modal:true,
		onClose:function(){
			$(this).dialog("destroy");
		},
		href:"${base}/book/toAddftl",
		buttons:[
					{
						text:'保存',
						handler:function(){
							//ajax提交表单textbox textbox-invalid
							data_sync();
							$('#add_my_form').form('submit', {
								url:"${base}/book/add",
								type:"post",
								success: function(data){
									//回掉函数中关闭对话框   
									add_dialog.dialog("destroy");
									//刷新datagrid列表
									user_search();
								}    
							});
						}
					},{
						text:'关闭',
						handler:function(){
							add_dialog.dialog("destroy");
						}
					}
				]
	});
	}

      然后修改addBook.ftl文件,该页面不需要提交表单,所以不需要提交按钮,同时下拉框可以使用easyui的组合框读取完成自动设置相应的内容,与listBooks.ftl文件中的条件查询中的下拉框生成类似。

②完成open_edit_dialog()方法

function open_edit_dialog(){
	//是否选中了数据
	var edit_arrry = $("#tbcon").datagrid("getSelections");
	if (1 == edit_arrry.length) {
		var bookId = edit_arrry[0].bookId;
		var edit_dialog = $("<div></div>").dialog({
			title:"编辑信息",
			width:500,
			height:380,
			modal:true,
			onClose:function(){
				$(this).dialog("destroy");
			},
			href:"${base}/book/editPre?bookId=" + bookId,
			buttons:[{
				text:'保存',
				handler:function(){
					//ajax提交表单
					data_sync();
					$('#edit_my_form').form('submit', {
						url:"${base}/book/edit",
						success: function(data){ 
							//回掉函数中关闭对话框   
							edit_dialog.dialog("destroy");
							//刷新datagrid列表
							user_search("reload");
						}    
					});
				}
			},{
				text:'关闭',
				handler:function(){
					edit_dialog.dialog("destroy");
				}
			}]
		});
	} else {
		$.messager.alert('提示', '只能编辑一条数据');
	}
}

    至此,基本的内容改造,就已经完成了。在改造的过程中发现,真正的MVC中,前后台是完全独立的,修改前台页面的展示,并不会修改很多的后天代码,只是参数不合适的时候,才可能出现,不过这也可能是设计的不合理所造成的耦合。

猜你喜欢

转载自blog.csdn.net/xiaoxiaoqiang666/article/details/81169147