前端页面主要是使用了Easy UI框架进行布局,需要引入Easy UI相关的css和js文件。
在登录页面输入用户名和密码,单击登录按钮,执行JavaScript函数中checkAdminLogin,其通过jQuery向后台发送请求,请求地址为admin/login,这个地址将映射待控制器类AdminInfoController的login方法上,如果判断登录用户和密码正确,则打开后台管理首页面admin.jsp,否则通过消息框给出提示信息。
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head>
<title>电子商务平台——后台登录页title>
<link href="EasyUI/themes/default/easyui.css" rel="stylesheet" type="text/css" />
<link href="EasyUI/themes/icon.css" rel="stylesheet" type="text/css" />
<link href="EasyUI/demo.css" rel="stylesheet" type="text/css" />
<script src="EasyUI/jquery.min.js" type="text/javascript">script>
<script src="EasyUI/jquery.easyui.min.js" type="text/javascript">script>
<script src="EasyUI/easyui-lang-zh_CN.js" type="text/javascript">script>
head>
<body>
<script type="text/javascript">
function clearForm() {
$('#adminLoginForm').form('clear');
}
function checkAdminLogin() {
$("#adminLoginForm").form("submit", {
// 向控制器类AdminInfoController中login方法发送请求
url : 'admininfo/login',
success : function(result) {
var result = eval('(' + result + ')');
if (result.success == 'true') {
window.location.href = 'admin.jsp';
$("#adminLoginDlg").dialog("close");
} else {
$.messager.show({
title : "提示信息",
msg : result.message
});
}
}
});
}
script>
<div id="adminLoginDlg" class="easyui-dialog"
style="left: 550px; top: 200px;width: 300;height: 200"
data-options="title:'后台登录',buttons:'#bb',modal:true">
<form id="adminLoginForm" method="post">
<table style="margin:20px;font-size: 13;">
<tr>
<th >用户名th>
<td><input class="easyui-textbox" type="text" id="name"
name="name" data-options="required:true" value="admin">input>td>
tr>
<tr>
<th>密码th>
<td><input class="easyui-textbox" type="text" id="pwd"
name="pwd" data-options="required:true" value="123456">input>td>
tr>
table>
form>
div>
<div id="bb">
<a href="javascript:void(0)" class="easyui-linkbutton"
onclick="checkAdminLogin()">登录a>
<a href="javascript:void(0)" class="easyui-linkbutton"
onclick="clearForm();">重置a>
div>
body>
html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
if (session.getAttribute("admin") == null)
response.sendRedirect("/admin_login.jsp");
%>
<html>
<head>
<title>后台管理页面title>
<link href="EasyUI/themes/default/easyui.css" rel="stylesheet"
type="text/css" />
<link href="EasyUI/themes/icon.css" rel="stylesheet" type="text/css" />
<link href="EasyUI/demo.css" rel="stylesheet" type="text/css" />
<script src="EasyUI/jquery.min.js" type="text/javascript">script>
<script src="EasyUI/jquery.easyui.min.js" type="text/javascript">script>
<script src="EasyUI/easyui-lang-zh_CN.js" type="text/javascript">script>
head>
<body class="easyui-layout">
<div data-options="region:'north',border:false"
style="height: 60px; background: #B3DFDA; padding: 10px">
<div align="left">
<div style="font-family: Microsoft YaHei; font-size: 16px;">电商平台后台管理系统div>
div>
<div align="right">
欢迎您,<font color="Red">${sessionScope.admin.name}font>
div>
div>
<div data-options="region:'west',split:true,title:'功能菜单'"
style="width: 180px">
<ul id="tt">ul>
div>
<div data-options="region:'south',border:false"
style="height: 50px; background: #A9FACD; padding: 10px; text-align: center">powered
by miaoyongdiv>
<div data-options="region:'center'">
<div id="tabs" data-options="fit:true" class="easyui-tabs"
style="width: 500px; height: 250px;">div>
div>
<script type="text/javascript">
// 为tree指定数据
$('#tt').tree({
url : 'admininfo/getTree?adminid=${sessionScope.admin.id}'
});
$('#tt').tree({
onClick : function(node) {
if ("商品列表" == node.text) {
if ($('#tabs').tabs('exists', '商品列表')) {
$('#tabs').tabs('select', '商品列表');
} else {
$('#tabs').tabs('add', {
title : node.text,
href : 'productlist.jsp',
closable : true
});
}
} else if ("商品类型列表" == node.text) {
if ($('#tabs').tabs('exists', '商品类型列表')) {
$('#tabs').tabs('select', '商品类型列表');
} else {
$('#tabs').tabs('add', {
title : node.text,
href : 'typelist.jsp',
closable : true
});
}
} else if ("查询订单" == node.text) {
if ($('#tabs').tabs('exists', '查询订单')) {
$('#tabs').tabs('select', '查询订单');
} else {
$('#tabs').tabs('add', {
title : node.text,
href : 'searchorder.jsp',
closable : true
});
}
} else if ("创建订单" == node.text) {
if ($('#tabs').tabs('exists', '创建订单')) {
$('#tabs').tabs('select', '创建订单');
} else {
$('#tabs').tabs('add', {
title : node.text,
href : 'createorder.jsp',
closable : true
});
}
} else if ("用户列表" == node.text) {
if ($('#tabs').tabs('exists', '用户列表')) {
$('#tabs').tabs('select', '用户列表');
} else {
$('#tabs').tabs('add', {
title : node.text,
href : 'userlist.jsp',
closable : true
});
}
} else if ("退出系统" == node.text) {
$.ajax({
url : 'admininfo/logout',
success : function(data) {
window.location.href = "admin_login.jsp";
}
})
}
}
});
script>
body>
html>
在接口中,selectByNameAndPwd方法通过@Select注解来查询是否为管理员登录,AdminInfo类型的参数adminInfo用于封装查询条件。SelectById方法通过注解来根据管理员id获取管理员对象及其关联的功能集合,并通过@Results注解映射查询结果。
public interface AdminInfoDao {
//根据登录名和密码查询管理员
@Select("select * from admin_info where name = #{name} and pwd = #{pwd}")
public AdminInfo selectByNameAndPwd(AdminInfo adminInfo);
// 根据管理员id获取管理员对象及关联的功能集合
@Select("select * from admin_info where id = #{id}")
@Results({ @Result(id = true, column = "id", property = "id"), @Result(column = "name", property = "name"),
@Result(column = "pwd", property = "pwd"),
@Result(column = "id", property = "fs", many = @Many(select = "com.hcz.dao.FunctionDao.selectByAdminId", fetchType = FetchType.EAGER)) })
public AdminInfo selectById(int id);
}
public interface FunctionDao {
//根据管理员id,获取功能权限
@Select("select * from functions where id in (select fid from powers where aid=#{aid})")
public List<Function> selectByAdminId(Integer aid);
}
public interface AdminInfoService {
//登录验证方法
public AdminInfo login(AdminInfo adminInfo);
//根据管理员编号,获取管理员对象及关联的功能权限
public AdminInfo getAdminAndFunctions(int id) ;
}
@Service("adminInfoService")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class AdminInfoServiceImpl implements AdminInfoService {
//注入dao类
@Autowired
private AdminInfoDao adminInfoDao;
//登录验证方法
@Override
public AdminInfo login(AdminInfo adminInfo) {
return adminInfoDao.selectByNameAndPwd(adminInfo);
}
@Override
public AdminInfo getAdminAndFunctions(int id) {
return adminInfoDao.selectById(id);
}
}
通过@Controller注解表示该类是一个控制器类,login方法中有两个参数,第一个是用于封装由前端传过来的用户名和密码;第二个是用于存放登录成功后的管理员对象信息,并通过@SessionAttributes注解将其存入Session范围中。
/**
* 管理员控制类
*/
@SessionAttributes(value = {"admin"})
@Controller
@RequestMapping("/admininfo")
public class AdminInfoController {
@Autowired
private AdminInfoService adminInfoService;
@RequestMapping(value = "/login", produces = "text/html;charset=UTF-8")
@ResponseBody
public String login(AdminInfo adminInfo, Model model){
//后台登录验证,将页面传入的帐号密码进行验证
AdminInfo ad = adminInfoService.login(adminInfo);
System.out.println("====================="+ad);
if (ad != null && ad.getName() != null){
//验证通过之后,判断是否已经为该管理员分配功能的权限
if (adminInfoService.getAdminAndFunctions(ad.getId()).getFs().size()>0){
//如果通过验证且已经分配功能权限,则将admininfo对象存入model中
model.addAttribute("admin",ad);
// 以JSON格式向页面发送成功信息
return "{\"success\":\"true\",\"message\":\"登录成功\"}";
} else {
return "{\"success\":\"false\",\"message\":\"您没有权限,请联系超级管理员设置权限!\"}";
}
} else
return "{\"success\":\"false\",\"message\":\"登录失败\"}";
}
@RequestMapping("/getTree")
@ResponseBody
public List<TreeNode> getTree(@RequestParam(value="adminid") String adminid){
//根据管理员编号,获取AdminInfo对象
System.out.println("====="+adminid);
AdminInfo adminInfo = adminInfoService.getAdminAndFunctions(Integer.parseInt(adminid));
List<TreeNode> nodes = new ArrayList<>();
//获取关联的Function对象集合
List<Function> functionsList = adminInfo.getFs();
//对List类型的Function集合进行排序
Collections.sort(functionsList);
//将排序好的Functions集合转换到List类型的列表nodes
for (Function function : functionsList){
TreeNode node = new TreeNode();
node.setId(function.getId());
node.setFid(function.getParentid());
node.setText(function.getName());
nodes.add(node);
}
//调用工具类JsonFact的buildtree方法,为node列表中的各个TreeNode元素中的children属性赋值
List<TreeNode> treeNodes = JsonFactory.buildTree(nodes, 0);
return treeNodes;
}
}
商品管理包括商品列表显示、查询商品、添加商品、商品下架、商品修改和商品类型列表添加和修改等功能。
在商品显示页面中定义了三个id属性:第一个id为dg_productinfo的< table>标签,用来显示商品记录;第二个id为tb_productinfo的< div>标签工具栏,在< div>标签中又定义了三个< a>标签,用于创建添加、修改和删除三个按钮控件;第三个id为searchtb_productinfo的< div>标签搜索栏,在搜索栏中商品类型组合框显示的数据来自type数据表,因此在属性中设置了url属性为type/getType/1将这个请求映射到TypeController控制器的getType方法中来获取对应的值。
<%@ page language="java" import="java.util.*"
contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>商品列表页title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
head>
<body>
<table id="dg_productinfo" class="easyui-datagrid">table>
<div id="tb_productinfo" style="padding: 2px 5px;">
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-add" plain="true" onclick="addProduct();">添加a>
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-edit" plain="true" onclick="editProduct();">修改a>
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-remove" onclick="removeProduct();" plain="true">删除a>
div>
<div id="searchtb_productinfo" style="padding: 2px 5px;">
<form id="searchForm_productinfo" method="post">
<div style="padding: 3px">
商品编号
<input class="easyui-textbox" name="productinfo_search_code" id="productinfo_search_code" style="width: 110px" />
div>
<div style="padding: 3px">
商品名称
<input class="easyui-textbox" name="productinfo_search_name" id="productinfo_search_name" style="width: 110px" />
商品类型
<input style="width: 110px;" id="productinfo_search_tid" class="easyui-combobox" name="productinfo_search_tid"
data-options="valueField:'id',textField:'name',url:'type/getType/1'" value="0">
商品品牌
<input class="easyui-textbox" name="productinfo_search_brand" id="productinfo_search_brand" style="width: 110px" />
价格:
<input class="easyui-numberbox" name="productinfo_search_priceFrom" id="productinfo_search_priceFrom" style="width: 80px;" />
~
<input class="easyui-numberbox" name="productinfo_search_priceTo" id="productinfo_search_priceTo" style="width: 80px;" />
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-search" plain="true" onclick="searchProduct();">查找a>
div>
form>
div>
<div id="dlg_productinfo" class="easyui-dialog" title="添加商品"
closed="true" style="width: 500px;">
<div style="padding: 10px 60px 20px 60px">
<form id="ff_productinfo" method="POST" action="" enctype="multipart/form-data">
<table cellpadding="5">
<tr>
<td>商品状态:td>
<td><select id="status" class="easyui-combobox" name="status" style="width: 150px;">
<option value="1">在售option>
<option value="0">下架option>
select>td>
tr>
<tr>
<td>商品类型:td>
<td><input style="width: 150px;" id="type.id" class="easyui-combobox" name="type.id"
data-options="valueField:'id',textField:'name',url:'type/getType/0'"/>
td>
tr>
<tr>
<td>商品名称:td>
<td><input class="easyui-textbox" type="text" id="name" name="name" data-options="required:true"/>td>
tr>
<tr>
<td>商品编码:td>
<td><input class="easyui-textbox" type="text" id="code" name="code" data-options="required:true"/>td>
tr>
<tr>
<td>商品品牌:td>
<td><input class="easyui-textbox" type="text" id="brand" name="brand" data-options="required:true"/>td>
tr>
<tr>
<td>商品数量:td>
<td><input class="easyui-textbox" type="text" id="num" name="num" data-options="required:true"/>td>
tr>
<tr>
<td>商品价格:td>
<td><input class="easyui-textbox" type="text" id="price" name="price" data-options="required:true"/>td>
tr>
<tr>
<td>商品描述:td>
<td><input class="easyui-textbox" name="intro" id="intro" data-options="multiline:true" style="height: 60px"/>td>
tr>
<tr>
<td>商品图片:td>
<td><input class="easyui-filebox" id="file" name="file" style="width: 200px" value="选择图片"/>td>
tr>
table>
form>
<div style="text-align: center; padding: 5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="saveProduct();">保存a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm();">清空a>
div>
div>
div>
<script type="text/javascript">
$(function() {
$('#dg_productinfo').datagrid({//为id为dg_productinfo的datagrid控件 指定数据源
singleSelect : false, //设置datagrid为多选
url : 'productinfo/list', //datagrid数据源通过提交productinfo/list请求获得
pagination : true, //启用分页
pageSize : 10, //设置初始每页记录数(页大小)
pageList : [ 10, 15, 20 ], //设置可供选择的页大小
rownumbers : true, //显示行号
fit : true, //设置自适应
toolbar : '#tb_productinfo', //为datagrid添加工具栏
header : '#searchtb_productinfo', //为datagrid标头添加搜索栏
columns : [ [ { //编辑datagrid的列
title : '序号',
field : 'id',
align : 'center',
checkbox : true
}, {
field : 'name',
title : '商品名称',
width : 200
}, {
field : 'type',
title : '商品类型',
formatter : function(value, row, index) {
if (row.type) {
return row.type.name;
} else {
return value;
}
},
width : 60
}, {
field : 'status',
title : '商品状态',
formatter : function(value, row, index) {
if (row.status == 1) {
return "在售";
} else {
return "下架";
}
},
width : 60
}, {
field : 'code',
title : '商品编码',
width : 100
}, {
field : 'brand',
title : '品牌',
width : 120
}, {
field : 'price',
title : '价格',
width : 50
}, {
field : 'num',
title : '库存',
width : 50
}, {
field : 'intro',
title : '商品描述',
width : 450
} ] ]
});
});
var urls;
var data;
// 删除商品(商品下架)
function removeProduct() {
var rows = $("#dg_productinfo").datagrid('getSelections');//获取从id为dg_productinfo的datagrid控件中选择的多行(s)内容
if (rows.length > 0) {
$.messager.confirm('Confirm', '确认要删除么?', function(r) {//当选择了内容后显示确认对话框
if (r) {
var ids = "";
for (var i = 0; i < rows.length; i++) {
ids += rows[i].id + ",";//将选择的内容的id保存到ids中,并用逗号分隔
}
$.post('productinfo/deleteProduct', {//以post方式提交productinfo/deleteProduct请求,并传递参数id和flag(=0表示下架)
id : ids,
flag : 0
}, function(result) {//回调函数,请求结果将保存到result中
if (result.success == 'true') {//删除成功时
$("#dg_productinfo").datagrid('reload');//重新加载id为dg_productinfo的datagrid控件,并显示下面信息
$.messager.show({
title : '提示信息',
msg : result.message
});
} else {//删除不成功时显示相关信息
$.messager.show({
title : '提示信息',
msg : result.message
});
}
}, 'json');
}
});
} else {//没有选择内容时给一个提示对话框
$.messager.alert('提示', '请选择要删除的行', 'info');
}
}
// 打开新增商品对话框
function addProduct() {
$('#dlg_productinfo').dialog('open').dialog('setTitle', '新增商品');//打开id为dlg_productinfo的对话框,并设置标题
$('#dlg_productinfo').form('clear');//清空对话框
urls = 'productinfo/addProduct';//设置参数urls代保存时使用
}
// 保存商品信息
function saveProduct() {
$("#ff_productinfo").form("submit", {//单击ff_productinfo的submit按钮(即保存按钮)时执行本函数
url : urls, //提交内容使用前面增加商品或修改商品中的参数urls
success : function(result) {//回调函数,用于将请求返回的内容保存到result中
var result = eval('(' + result + ')');
if (result.success == 'true') {
$("#dg_productinfo").datagrid("reload");//请求成功时重新加载id为dg_productinfo的datagrid控件,并关闭id为dlg_productinfo的对话框
$("#dlg_productinfo").dialog("close");
}
$.messager.show({
title : "提示信息",
msg : result.message
});
}
});
}
function clearForm() {//清空id为ff_productinfo的对话框
$('#ff_productinfo').form('clear');
}
// 打开修改商品对话框(与新增商品对话框共用)
function editProduct() {
var rows = $("#dg_productinfo").datagrid('getSelections');//选择多行(后面有s)
if (rows.length > 0) {
var row = $("#dg_productinfo").datagrid("getSelected");//选择一行
if (row) {
$("#dlg_productinfo").dialog("open").dialog('setTitle', '修改商品信息');
$("#ff_productinfo").form("load", {//加载对话框,并设置对话框中的内容
"type.id" : row.type.id,
"name" : row.name,
"code" : row.code,
"brand" : row.brand,
"num" : row.num,
"price" : row.price,
"intro" : row.intro,
"status" : row.status,
});
urls = "productinfo/updateProduct?id=" + row.id;
}
} else {
$.messager.alert('提示', '请选择要修改的行', 'info');
}
}
// 查询商品
function searchProduct() {
var productinfo_search_code = $('#productinfo_search_code').textbox("getValue");
var productinfo_search_name = $('#productinfo_search_name').textbox("getValue");
var productinfo_search_tid = $('#productinfo_search_tid').combobox("getValue");
var productinfo_search_brand = $('#productinfo_search_brand').textbox("getValue");
var productinfo_search_priceFrom;
if ($("#productinfo_search_priceFrom").val() != null&& $("#productinfo_search_priceFrom").val() != "")
{
productinfo_search_priceFrom = $('#productinfo_search_priceFrom').textbox("getValue");
}
else {
productinfo_search_priceFrom = "0";
}
var productinfo_search_priceTo;
if ($("#productinfo_search_priceTo").val() != null&& $("#productinfo_search_priceTo").val() != "")
{
productinfo_search_priceTo = $('#productinfo_search_priceTo').textbox("getValue");
}
else {
productinfo_search_priceTo = "0";
}
$("#dg_productinfo").datagrid('load', {
"code" : productinfo_search_code,
"name" : productinfo_search_name,
"type.id" : productinfo_search_tid,
"brand" : productinfo_search_brand,
"priceFrom" : productinfo_search_priceFrom,
"priceTo" : productinfo_search_priceTo
});
}
script>
body>
html>
商品信息接口ProductInfoDao:实现分页获取商品信息和查询商品总数
商品类型接口TypeDao:实现根据ID值来查询商品类型对象和查询所有的全部的商品类型,将其显示到搜索栏中的组合框中去;
/**
* 商品信息接口
*/
public interface ProductInfoDao {
//分页获取商品
@Results({
@Result(id = true,column = "id",property = "id"),
@Result(column = "tid",property = "type",
one = @One(select = "com.hcz.dao.TypeDao.selectById",fetchType = FetchType.EAGER))})
@SelectProvider(type = ProductInfoDynaSqlProvider.class, method = "selectWithParam")
List<ProductInfo> selectByPage(Map<String, Object> params);
// 根据条件查询商品总数
@SelectProvider(type = ProductInfoDynaSqlProvider.class, method = "count")
Integer count(Map<String, Object> params);
}
在dao.provider包中创建动态SQL类ProductInfoDynaSqlProvider:(根据参数生成查询商品信息的SQL语句)
/**
* 动态SQL类:根据参数生成查询商品信息的SQL语句
*/
public class ProductInfoDynaSqlProvider {
// 分页动态查询
public String selectWithParam(final Map<String, Object> params) {
String sql = new SQL() {
{
SELECT("*");
FROM("product_info");
if (params.get("productInfo") != null) {
ProductInfo productInfo = (ProductInfo) params.get("productInfo");
if (productInfo.getCode() != null && !"".equals(productInfo.getCode())) {
WHERE(" code = #{productInfo.code} ");
}
if (productInfo.getName() != null && !productInfo.getName().equals("")) {
WHERE(" name LIKE CONCAT ('%',#{productInfo.name},'%') ");
}
if (productInfo.getBrand() != null && !productInfo.getBrand().equals("")) {
WHERE(" brand LIKE CONCAT ('%',#{productInfo.brand},'%') ");
}
if (productInfo.getType() != null && productInfo.getType().getId() > 0) {
WHERE(" tid = #{productInfo.type.id} ");
}
if (productInfo.getPriceFrom() > 0) {
WHERE(" price > #{productInfo.priceFrom} ");
}
if (productInfo.getPriceTo() > 0) {
WHERE(" price <= #{productInfo.priceTo} ");
}
}
}
}.toString();
if (params.get("pager") != null) {
sql += " limit #{pager.firstLimitParam} , #{pager.perPageRows} ";
}
return sql;
}
// 根据条件动态查询商品总记录数
public String count(final Map<String, Object> params) {
return new SQL() {
{
SELECT("count(*)");
FROM("product_info");
if (params.get("productInfo") != null) {
ProductInfo productInfo = (ProductInfo) params.get("productInfo");
if (productInfo.getCode() != null && !"".equals(productInfo.getCode())) {
WHERE(" code = #{productInfo.code} ");
}
if (productInfo.getName() != null && !productInfo.getName().equals("")) {
WHERE(" name LIKE CONCAT ('%',#{productInfo.name},'%') ");
}
if (productInfo.getBrand() != null && !productInfo.getBrand().equals("")) {
WHERE(" brand LIKE CONCAT ('%',#{productInfo.brand},'%') ");
}
if (productInfo.getType() != null && productInfo.getType().getId() > 0) {
WHERE(" tid = #{productInfo.type.id} ");
}
if (productInfo.getPriceFrom() > 0) {
WHERE(" price > #{productInfo.priceFrom} ");
}
if (productInfo.getPriceTo() > 0) {
WHERE(" price <= #{productInfo.priceTo} ");
}
}
}
}.toString();
}
}
/**
* 商品类型接口
*/
public interface TypeDao {
//查询所有商品类型
@Select("select * from type")
List<Type> selectAll();
//按商品编号来查询商品类型
@Select("select * from type where id = #{id}")
Type selectById(int id);
}
public interface ProductInfoService {
//分页显示商品
List<ProductInfo> findProductInfo(ProductInfo productInfo, Pager pager);
//商品计数
int count(Map<String, Object> params);
}
@Service("productInfoService")
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class ProductInfoServiceImpl implements ProductInfoService {
@Autowired
public ProductInfoDao productInfoDao;
//分页显示商品
@Override
public List<ProductInfo> findProductInfo(ProductInfo productInfo, Pager pager) {
//创建params对象
Map<String ,Object> params = new HashMap<>();
//将封装查询条件的productInfo对象放入params中
params.put("productInfo",productInfo);
//根据条件计算商品总数
int resordCount = productInfoDao.count(params);
//给pager对象设置rowCount属性值(记录总数)
pager.setRowCount(resordCount);
if (resordCount > 0){
//将page对象放入params
params.put("pager",pager);
}
//分页获取商品信息
return productInfoDao.selectByPage(params);
}
//商品计数
@Override
public int count(Map<String, Object> params) {
return productInfoDao.count(params);
}
}
public interface TypeService {
//获取所有商品类型
List<Type> getAll();
@Service("typeService")
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class TypeServiceImpl implements TypeService {
@Autowired
private TypeDao typeDao;
@Override
public List<Type> getAll() {
return typeDao.selectAll();
}
list方法中有三个参数,一个是ProductInfo类型的参数,用于封装表单传递过来的查询条件;另外两个参数是page和rows,用于接受从Datagrid控件传递过来的页码和每页显示的记录数。
/**
* 商品信息控制器类
*/
@Controller
@RequestMapping("/productinfo")
public class ProductInfoController {
@Autowired
ProductInfoService productInfoService;
//后台商品列表分页显示,@RequestBody注解将数据转换为Json格式
@RequestMapping(value = "/list")
@ResponseBody
public Map<String , Object> list(Integer page, Integer rows, ProductInfo productInfo){
//初始化分页类对象page
Pager pager = new Pager();
pager.setCurPage(page);
pager.setPerPageRows(rows);
//创建params对象,封装查询条件
Map<String ,Object> params = new HashMap<>();
params.put("productInfo",productInfo);
//获取满足条件的商品总数
int totalCount = productInfoService.count(params);
//获取满足条件的商品列表
List<ProductInfo> productInfos = productInfoService.findProductInfo(productInfo,pager);
//创建result对象,保存查询结果数据
Map<String ,Object> result = new HashMap<>();
result.put("total",totalCount);
result.put("rows",productInfos);
//@ResponseBody将结果以json格式发送到前端页面
return result;
}
创建查询工具栏主要内容:
1、显示商品编号、商品名称、商品品牌、价格区间;这里商品类型为组合框。其默认显示为0,其列表内容通过请求:url:‘type/getType/1’"获得。通过创建TypeController控制器,并在其中响应请求方法中通过 typeService.getAll()查找到所有的商品类型,并将其添加到List对象中,返回前要将其转换为JSON格式。
<div id="searchtb_productinfo" style="padding: 2px 5px;">
<form id="searchForm_productinfo" method="post">
<div style="padding: 3px">
商品编号
<input class="easyui-textbox" name="productinfo_search_code" id="productinfo_search_code" style="width: 110px" />
div>
<div style="padding: 3px">
商品名称
<input class="easyui-textbox" name="productinfo_search_name" id="productinfo_search_name" style="width: 110px" />
商品类型
<input style="width: 110px;" id="productinfo_search_tid" class="easyui-combobox" name="productinfo_search_tid"
data-options="valueField:'id',textField:'name',url:'type/getType/1'" value="0">
商品品牌
<input class="easyui-textbox" name="productinfo_search_brand" id="productinfo_search_brand" style="width: 110px" />
价格:
<input class="easyui-numberbox" name="productinfo_search_priceFrom" id="productinfo_search_priceFrom" style="width: 80px;" />
~
<input class="easyui-numberbox" name="productinfo_search_priceTo" id="productinfo_search_priceTo" style="width: 80px;" />
<a href="javascript:void(0)" class="easyui-linkbutton" iconCls="icon-search" plain="true" onclick="searchProduct();">查找a>
div>
form>
div>
// 查询商品
function searchProduct() {
var productinfo_search_code = $('#productinfo_search_code').textbox("getValue");
var productinfo_search_name = $('#productinfo_search_name').textbox("getValue");
var productinfo_search_tid = $('#productinfo_search_tid').combobox("getValue");
var productinfo_search_brand = $('#productinfo_search_brand').textbox("getValue");
var productinfo_search_priceFrom;
if ($("#productinfo_search_priceFrom").val() != null&& $("#productinfo_search_priceFrom").val() != "")
{
productinfo_search_priceFrom = $('#productinfo_search_priceFrom').textbox("getValue");
}
else {
productinfo_search_priceFrom = "0";
}
var productinfo_search_priceTo;
if ($("#productinfo_search_priceTo").val() != null&& $("#productinfo_search_priceTo").val() != "")
{
productinfo_search_priceTo = $('#productinfo_search_priceTo').textbox("getValue");
}
else {
productinfo_search_priceTo = "0";
}
$("#dg_productinfo").datagrid('load', {
"code" : productinfo_search_code,
"name" : productinfo_search_name,
"type.id" : productinfo_search_tid,
"brand" : productinfo_search_brand,
"priceFrom" : productinfo_search_priceFrom,
"priceTo" : productinfo_search_priceTo
});
}
/**
* 商品类型接口
*/
public interface TypeDao {
//查询所有商品类型
@Select("select * from type")
List<Type> selectAll();
public interface TypeService {
//获取所有商品类型
List<Type> getAll();
@Service("typeService")
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT)
public class TypeServiceImpl implements TypeService {
@Autowired
private TypeDao typeDao;
@Override
public List<Type> getAll() {
return typeDao.selectAll();
}
通过@PathVariable(“flag”) Integer flag获取请求type/getType/1中的参数1
通过@ResponseBody注解将返回结果转换为JSON格式
@Controller
@RequestMapping("/type")
public class TypeController {
@Autowired
private TypeService typeService;
@RequestMapping("/getType/{flag}")
@ResponseBody
public List<Type> getType(@PathVariable("flag") Integer flag){
List<Type> typeList = typeService.getAll();
if (flag == 1){
Type type = new Type();
type.setId(0);
type.setName("请选择...");
typeList.add(0,type);
}
return typeList;
}
通过点击添加按钮,在script中的addProduct()函数打开新增商品对话框,通过saveProduct()函数保存商品信息,其中打开id="dlg_productinfo"的div中定义的 添加商品信息对话框。
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-add" plain="true" onclick="addProduct();">添加a>
<div id="dlg_productinfo" class="easyui-dialog" title="添加商品"
closed="true" style="width: 500px;">
<div style="padding: 10px 60px 20px 60px">
<form id="ff_productinfo" method="POST" action="" enctype="multipart/form-data">
<table cellpadding="5">
<tr>
<td>商品状态:td>
<td><select id="status" class="easyui-combobox" name="status" style="width: 150px;">
<option value="1">在售option>
<option value="0">下架option>
select>td>
tr>
<tr>
<td>商品类型:td>
<td><input style="width: 150px;" id="type.id" class="easyui-combobox" name="type.id"
data-options="valueField:'id',textField:'name',url:'type/getType/0'"/>
td>
tr>
<tr>
<td>商品名称:td>
<td><input class="easyui-textbox" type="text" id="name" name="name" data-options="required:true"/>td>
tr>
<tr>
<td>商品编码:td>
<td><input class="easyui-textbox" type="text" id="code" name="code" data-options="required:true"/>td>
tr>
<tr>
<td>商品品牌:td>
<td><input class="easyui-textbox" type="text" id="brand" name="brand" data-options="required:true"/>td>
tr>
<tr>
<td>商品数量:td>
<td><input class="easyui-textbox" type="text" id="num" name="num" data-options="required:true"/>td>
tr>
<tr>
<td>商品价格:td>
<td><input class="easyui-textbox" type="text" id="price" name="price" data-options="required:true"/>td>
tr>
<tr>
<td>商品描述:td>
<td><input class="easyui-textbox" name="intro" id="intro" data-options="multiline:true" style="height: 60px"/>td>
tr>
<tr>
<td>商品图片:td>
<td><input class="easyui-filebox" id="file" name="file" style="width: 200px" value="选择图片"/>td>
tr>
table>
form>
<div style="text-align: center; padding: 5px">
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="saveProduct();">保存a>
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="clearForm();">清空a>
div>
div>
div>
// 打开新增商品对话框
function addProduct() {
$('#dlg_productinfo').dialog('open').dialog('setTitle', '新增商品');//打开id为dlg_productinfo的对话框,并设置标题
$('#dlg_productinfo').form('clear');//清空对话框
urls = 'productinfo/addProduct';//设置参数urls代保存时使用
}
// 保存商品信息
function saveProduct() {
$("#ff_productinfo").form("submit", {//单击ff_productinfo的submit按钮(即保存按钮)时执行本函数
url : urls, //提交内容使用前面增加商品或修改商品中的参数urls
success : function(result) {//回调函数,用于将请求返回的内容保存到result中
var result = eval('(' + result + ')');
if (result.success == 'true') {
$("#dg_productinfo").datagrid("reload");//请求成功时重新加载id为dg_productinfo的datagrid控件,并关闭id为dlg_productinfo的对话框
$("#dlg_productinfo").dialog("close");
}
$.messager.show({
title : "提示信息",
msg : result.message
});
}
});
}
//添加商品信息
@Insert("insert into product_info(code,name,tid,brand,pic,num,price,intro,status) "
+ "values(#{code},#{name},#{type.id},#{brand},#{pic},#{num},#{price},#{intro},#{status})")
@Options(useGeneratedKeys = true,keyProperty = "id")
void save(ProductInfo pi);
//添加商品
void addProductInfo(ProductInfo pi);
//添加商品
@Override
public void addProductInfo(ProductInfo pi) {
productInfoDao.save(pi);
}
addProduct方法中有四个参数,第一个是ProductInfo类型的参数,用于封装新增商品对话框输入的商品信息。第二个参数MultipartFile类型的参数file,通过注解将表单中文件上传控件中选择的图片文件绑定到参数file中,第三个参数是HttpServletRequest类型的对象request,用于封装客户端浏览器发出的请求,第四个参数是ModeMap类型的参数model,用于将数据传递到前端页面。
//添加商品
@RequestMapping(value = "/addProduct",produces = "text/html;charset=UTF-8")
@ResponseBody
public String addProduct(ProductInfo pi, @PathVariable(value = "file",
required = false)MultipartFile file, HttpServletRequest request, ModelMap model){
//服务器端upload文件夹物理路径
String path = request.getSession().getServletContext().getRealPath("product_images");
System.out.println("路径======"+path);
//获取文件名
String filename = file.getOriginalFilename();
System.out.println("文件名======"+filename);
//实例化一个File对象,表示目标文件(含物理路径)
if (filename != null){
File targetFile = new File(path,filename);
System.out.println("目标文件====="+targetFile);
if (!targetFile.exists()){
targetFile.mkdirs();
}try {
//将上传文件写到服务器上指定的文件
file.transferTo(targetFile);
pi.setPic(filename);
} catch (IOException e) {
e.printStackTrace();
}
}try {
//添加商品
productInfoService.addProductInfo(pi);
return "{\"success\":\"true\",\"message\":\"商品添加成功\"}";
} catch (Exception e) {
return "{\"success\":\"false\",\"message\":\"商品添加失败\"}";
}
}
在核心控制器中dispatcherServlet-servlet.xml添加文件上传设置:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/>
<property name="defaultEncoding" value="UTF-8"/>
bean>
在商品列表页的Datagrid控件中,选中某一条记录前的复选框,再单击工具栏中的修改按钮,将执行Javascript函数editProduct方法。修改完商品信息之后,单击保存按钮,发送一个productinfo/updateProduct请求,这将映射到控制器类对应的方法中。
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-edit" plain="true" onclick="editProduct();">修改a>
// 打开修改商品对话框(与新增商品对话框共用)
function editProduct() {
var rows = $("#dg_productinfo").datagrid('getSelections');//选择多行(后面有s)
if (rows.length > 0) {
var row = $("#dg_productinfo").datagrid("getSelected");//选择一行
if (row) {
$("#dlg_productinfo").dialog("open").dialog('setTitle', '修改商品信息');
$("#ff_productinfo").form("load", {//加载对话框,并设置对话框中的内容
"type.id" : row.type.id,
"name" : row.name,
"code" : row.code,
"brand" : row.brand,
"num" : row.num,
"price" : row.price,
"intro" : row.intro,
"status" : row.status,
});
urls = "productinfo/updateProduct?id=" + row.id;
}
} else {
$.messager.alert('提示', '请选择要修改的行', 'info');
}
}
//修改商品
@Update("update product_info set code=#{code},name=#{name},tid=#{type.id},"
+ "brand=#{brand},pic=#{pic},num=#{num},price=#{price},intro=#{intro}," + "status=#{status} where id=#{id}")
void edit(ProductInfo pi);
//修改商品
void modifyProductInfo(ProductInfo pi);
//修改商品
@Override
public void modifyProductInfo(ProductInfo pi) {
productInfoDao.edit(pi);
}
//修改商品
@RequestMapping(value = "/updateProduct",produces = "text/html;charset=UTF-8")
@ResponseBody
public String updateProduct(ProductInfo pi, @PathVariable(value =
"file",required = false) MultipartFile file, HttpServletRequest request,ModelMap model){
//服务端upload文件夹物理路径
String path = request.getSession().getServletContext().getRealPath("product_images");
//获取文件名
String filename = file.getOriginalFilename();
//实例化一个File对象,表示目标文件
if (filename != null){
File targetFile = new File(path,filename);
if ( !targetFile.exists()){
targetFile.mkdirs();
}
try {
//将上传文件写到服务器上指定的文件
file.transferTo(targetFile);
pi.setPic(filename);
} catch (IOException e) {
e.printStackTrace();
}
}
try {
productInfoService.modifyProductInfo(pi);
return "{\"success\":\"true\",\"message\":\"商品修改成功\"}";
} catch (Exception e) {
return "{\"success\":\"false\",\"message\":\"商品修改失败\"}";
}
}
选中一个或多个记录前的复选框,再单击工具栏中的删除按钮,执行对应的removeProduct函数,其会获取Datagrid控件上选中的商品记录,将选中的商品编号保存到变量ids中,并以逗号隔开,然后发送productinfo/deleteProduct请求,映射到对应的控制器类方法中,并向该方法中传递id和flag这两个参数。
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-remove" onclick="removeProduct();" plain="true">删除a>
// 删除商品(商品下架)
function removeProduct() {
var rows = $("#dg_productinfo").datagrid('getSelections');//获取从id为dg_productinfo的datagrid控件中选择的多行(s)内容
if (rows.length > 0) {
$.messager.confirm('Confirm', '确认要删除么?', function(r) {//当选择了内容后显示确认对话框
if (r) {
var ids = "";
for (var i = 0; i < rows.length; i++) {
ids += rows[i].id + ",";//将选择的内容的id保存到ids中,并用逗号分隔
}
$.post('productinfo/deleteProduct', {//以post方式提交productinfo/deleteProduct请求,并传递参数id和flag(=0表示下架)
id : ids,
flag : 0
}, function(result) {//回调函数,请求结果将保存到result中
if (result.success == 'true') {//删除成功时
$("#dg_productinfo").datagrid('reload');//重新加载id为dg_productinfo的datagrid控件,并显示下面信息
$.messager.show({
title : '提示信息',
msg : result.message
});
} else {//删除不成功时显示相关信息
$.messager.show({
title : '提示信息',
msg : result.message
});
}
}, 'json');
}
});
} else {//没有选择内容时给一个提示对话框
$.messager.alert('提示', '请选择要删除的行', 'info');
}
}
//商品下架(改变商品状态)
@Update("update product_info set status=#{flag} where id in (${ids})")
void updateState(@Param("ids") String ids,@Param("flag") int flag);
//修改商品状态
void modifyStatus(String substring, int parseInt);
//商品下架
@Override
public void modifyStatus(String ids, int flag) {
productInfoDao.updateState(ids,flag);
}
在deleteProduct方法中,调用了接口中的modifyStatus方法,根据选中的商品的id号,将其状态设置为0。如果执行成功,则向前段页面发送下架成功的信息。
//商品下架
@RequestMapping(value = "/deleteProduct")
@ResponseBody
public String deleteProduct(@RequestParam(value = "id") String id,
@RequestParam(value = "flag") String flag){
String str = "";
try {
productInfoService.modifyStatus(id.substring(0,id.length()-1),Integer.parseInt(flag));
str = "{\"success\":\"true\",\"message\":\"删除成功\"}";
} catch (Exception e) {
str = "{\"success\":\"false\",\"message\":\"删除失败\"}";
}
return str;//return {"success":"false","message":"删除失败"};
}
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-add" plain="true" onclick="addType();">添加a>
<div id="typeDlg" class="easyui-dialog" title="New Type" closed="true"
style="width:500px;">
<div style="padding:10px 60px 20px 60px">
<form id="typeForm" method="POST" action="">
<table cellpadding="5">
<tr>
<td>产品名称:td>
<td><input class="easyui-textbox" type="text" id="name"
name="name" data-options="required:true">input>td>
tr>
table>
form>
<div style="text-align:center;padding:5px">
<a href="javascript:void(0)" class="easyui-linkbutton"
onclick="saveType();">保存a> <a href="javascript:void(0)"
class="easyui-linkbutton" onclick="clearForm();">清空a>
div>
div>
function addType() {
$('#typeDlg').dialog('open').dialog('setTitle', '新增商品类型');
$('#typeDlg').form('clear');
urls = 'type/addType';
}
function saveType() {
$("#typeForm").form("submit", {
url : urls, //使用参数
success : function(result) {
var result = eval('(' + result + ')');
if (result.success == 'true') {
$("#typeDg").datagrid("reload");
}
$("#typeDlg").dialog("close");
$.messager.show({
title : "提示信息",
msg : result.message
});
}
});
}
//添加商品类型
@Insert("insert into type(name) values(#{name})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void save(Type type);
//添加商品类型
void saveType(Type type);
@Override
public void saveType(Type type) {
typeDao.save(type);
}
//新增商品类型
@RequestMapping(value = "/addType")
@ResponseBody
public String addType(Type type){
try {
typeService.saveType(type);
return "{\"success\":\"true\",\"message\":\"商品类型添加成功\"}";
} catch (Exception e) {
return "{\"success\":\"false\",\"message\":\"商品类型添加失败\"}";
}
}
<a href="javascript:void(0)" class="easyui-linkbutton"
iconCls="icon-edit" plain="true" onclick="editType();">修改a>
function editType() {
var row = $("#typeDg").datagrid("getSelected");
if (row) {
$("#typeDlg").dialog("open").dialog('setTitle', '修改产品信息');
$("#typeForm").form("load", {
"name" : row.name
});
urls = "type/updateType?id=" + row.id;
}
}
//修改商品类型
@Update("update type set name=#{name} where id=#{id}")
void updete(Type type);
//修改商品类型
void updateType(Type type);
@Override
public void updateType(Type type) {
typeDao.updete(type);
}
//修改商品类型
@RequestMapping(value = "/updateType")
@ResponseBody
public String updateType(Type type){
try {
typeService.updateType(type);
return "{\"success\":\"true\",\"message\":\"商品类型修改成功\"}";
} catch (Exception e) {
return "{\"success\":\"false\",\"message\":\"商品类型修改失败\"}";
}
}