将上面的js文件引入所需要的jsp页面中,本例以index.jsp为例 /bos19/WebContent/WEB-INF/pages/common/index.jsp
<!-- 引入 防止window拖拽出边界的js代码-->
<script
src="${pageContext.request.contextPath }/js/outOfBounds.js"
type="text/javascript">
</script>
整个基础设置部分对应需求文档2.6章节。如下图所示:
功能概述:
在其他的系统中通常称为“数据字典”。`提供基础数据,供其他模块使用`。
主要是针对本系统中的一些自定义项,需要参照录入,并作为统计分析和计算的维度,用户根据自己的需要动态设置的基础档案;对于自定义的档案支持多级定义;
系统会事先预置一些系统级别的基础档案,如线路类型、保险类型等;客户根据自己的需要动态增加,主要是应用在`参照录入`;
此功能主要是为`系统的可扩张性`而设置的;
此功能主要应用角色是`“系统管理员”`;
目前需要在此设置的基础档案包括:线路类型、取派员类型、签收类型、保险类型、受理备注说明、配载信息、返货原因、消单原因、取消签收类型、返货拒绝类型、大物流类型。
功能概述:
将承接的货物,按照重量和体积两个标准,双纬度定义货物的标准。以便将不同标准的货物分给不同收取和派送能力的人员。由运营部门制定。
功能概述:
班车设置表,线路设置表。
将设置的线路和车辆建立对应关系。
功能概述:
小件员设置主要是设置小件员和快递员的资源信息,主要是为了自动下单和取派任务件使用;包括增加小件员的交通工具和通讯设备,以及取派的重量和体积标准。
使用角色为各级组织机构的系统管理人员在添加。
取派设置中包括小件员的替班信息设置。
以及被替班人信息的查询功能。
功能概述:
区域为国家划分的行政区域。
功能概述:
区域范围很大,不规则,不便于直接进行人员分配,需要对区域进行细分 --> 分区。
功能概述:
`定区是物流分配的基本单位`。定区可以将分区、取派员、客户信息进行关联,为自动分单提供数据支持。使用hessian技术,远程调用技术。
功能概述:
上班时间的管理,根据取派人员的可上班时间,将区域取派任务在不同时限分配给不同的取派人员。建议时间管理由总公司部门管理,固化出各种上班时间点。下级厅点只有调用权限,没有修改权限。
页面位置:/WEB-INF/pages/base/staff.jsp
为了便于处理,我们先将取派员编号选项框
删掉,该编号我们让其自动生成。
我们在Staff.hbm.xml中更改主键生成策略,代码如下:
<id name="id" type="java.lang.String">
<column name="id" length="32" />
<!-- generator:主键生成策略,uuid:生成32位的不重复随机字符串当做主键 -->
<generator class="uuid" />
</id>
修改后的界面,如下图所示:
第一步:由于默认自带的检验规则较少,所以我们需要扩展校验规则,对手机号进行校验
<script type="text/javascript">
// 扩展校验规则
$(function() {
var reg = /^1[3|4|5|7|8|9][0-9]{9}$/;
$.extend($.fn.validatebox.defaults.rules, {
phonenumber: {
validator: function(value, param) {
return reg.test(value);
},
message: '手机号输入有误!'
}
});
});
</script>
第二步:在对应手机号输入框上,应用上面的校验规则
<tr>
<td>手机号</td>
<td><input type="text" name="telephone" class="easyui-validatebox" required="true"
data-options="validType:'phonenumber'"
/></td>
</tr>
第三步:为添加窗口中的“保存按钮”绑定事件
<div class="datagrid-toolbar">
<a id="save" icon="icon-save" href="#" class="easyui-linkbutton" plain="true" >保存</a>
<script type="text/javascript">
$(function() {
// 绑定事件
$("#save").click(function() {
// 先校验表单输入项
var v = $("#addStaffForm").form("validate");
if (v) {
// 说明校验通过,提交增加收派员的表单
$("#addStaffForm").submit();
}
});
});
</script>
</div>
第四步:创建StaffAction类,提供add方法,处理取派员添加动作 StaffAction.java
package com.itheima.bos.web.action;
import javax.annotation.Resource;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import com.itheima.bos.domain.Staff;
import com.itheima.bos.service.IStaffService;
import com.itheima.bos.web.action.base.BaseAction;
/**
* 取派员设置
* @author Bruce
*
*/
@Controller
@Scope("prototype")
public class StaffAction extends BaseAction<Staff> {
// 注入service
@Resource
private IStaffService staffService;
/**
* 添加取派员
* @return
*/
public String add() {
staffService.save(model);
return "list";
}
}
IStaffService.java
package com.itheima.bos.service;
import com.itheima.bos.domain.Staff;
public interface IStaffService {
public void save(Staff model);
}
StaffServiceImpl.java
package com.itheima.bos.service.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.itheima.bos.dao.IStaffDao;
import com.itheima.bos.domain.Staff;
import com.itheima.bos.service.IStaffService;
@Service
@Transactional
public class StaffServiceImpl implements IStaffService {
// 注入dao
@Autowired
private IStaffDao staffDao;
public void save(Staff model) {
staffDao.save(model);
}
}
IStaffDao.java
package com.itheima.bos.dao;
import com.itheima.bos.dao.base.IBaseDao;
import com.itheima.bos.domain.Staff;
public interface IStaffDao extends IBaseDao<Staff> {
}
StaffDaoImpl.java
package com.itheima.bos.dao.impl;
import org.springframework.stereotype.Repository;
import com.itheima.bos.dao.IStaffDao;
import com.itheima.bos.dao.base.impl.BaseDaoImpl;
import com.itheima.bos.domain.Staff;
@Repository
public class StaffDaoImpl extends BaseDaoImpl<Staff> implements IStaffDao {
}
第五步:配置struts.xml
<!-- 配置staffAction-->
<action name="staffAction_*" class="staffAction" method="{1}">
<result name="list">/WEB-INF/pages/base/staff.jsp</result>
</action>
数据网格(datagrid)以表格格式显示数据,并为选择、排序、分组和编辑数据提供了丰富的支持。数据网格(datagrid)的设计目的是为了减少开发时间,且不要求开发人员具备指定的知识。它是轻量级的,但是功能丰富。它的特性包括单元格合并,多列页眉,冻结列和页脚,等等。
<h3>方式一:将静态的HTML代码渲染成datagrid样式,不常用</h3>
<table class="easyui-datagrid">
<thead>
<tr>
<th data-options="field:'id'">编号</th>
<th data-options="field:'name'">姓名</th>
<th data-options="field:'age'">年龄</th>
</tr>
</thead>
<tbody>
<tr>
<td>001</td>
<td>张三</td>
<td>20</td>
</tr>
<tr>
<td>002</td>
<td>李四</td>
<td>30</td>
</tr>
</tbody>
</table>
<h3>方式二:发送ajax请求获取json数据,并显示,常用,该数据网格可以自己发送ajax请求</h3>
<table class="easyui-datagrid" data-options="url:'/bos19/json/data.json'">
<thead>
<tr>
<th data-options="field:'id'">编号</th>
<th data-options="field:'name'">姓名</th>
<th data-options="field:'age'">年龄</th>
</tr>
</thead>
</table>
要求服务端返回的json数据的格式满足:
该数据可以有多项,但是上述代码我们只取前三项。
<h3>方式三:通过js代码,使用插件提供的API动态创建datagrid,大量使用</h3>
<table id="grid">
</table>
<script type="text/javascript">
$(function() {
$("#grid").datagrid({
columns:[[ // 定义标题行所有的列,是一个二维数组
{field:'id',title:'编号',checkbox:true}, // 是否复选框
{field:'name',title:'姓名'},
{field:'age',title:'年龄'}
]],
url:'/bos19/json/data.json', // 指定URL地址,datagrid控件会自动发送ajax请求获取数据
toolbar:[ // 工具栏按钮
{text:'添加',iconCls:'icon-add'},
{text:'删除',iconCls:'icon-remove',
handler:function() {
// 获得选中的行
var rows = $("#grid").datagrid("getSelections");
for(var i=0; i < rows.length; i++) {
var id = rows[i].id; // 获取id字段的值
alert(id);
}
}},
{text:'修改',iconCls:'icon-edit'}
],
singleSelect:true, // 是否可以单选
pagination:true, // 分页条
pageList:[3,5,7] // 自定义分页条中的下拉框选项
});
});
</script>
要求服务端返回的json数据的格式满足:
该数据可以有多项,但是上述代码我们只取前三项。 注意两个rows的区别:
三种方式的效果如下图所示:
第一步:修改staff.jsp页面中datagrid的URL地址,访问action
// 取派员信息表格
$('#grid').datagrid( {
iconCls : 'icon-forward',
fit : true, // 自适应
border : false,
rownumbers : true, // 显示行号
striped : true,
pageList: [3,5,10],
pagination : true,
toolbar : toolbar, // 工具栏
url : "${pageContext.request.contextPath}/staffAction_pageQuery.action", // 服务器响应回来的是json数据,通过jQuery EasyUI的datagrid数据网格显示出来
idField : 'id',
columns : columns,
onDblClickRow : doDblClickRow // 双击表格数据
});
效果如下:
第二步:创建一个PageBean类,用于封装分页信息
package com.itheima.bos.utils;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
/**
* 封装分页信息
* @author Bruce
*
*/
public class PageBean {
private int currentPage; // 当前页码
private int pageSize; // 每页显示记录数
private int total; // 总记录数
private DetachedCriteria detachedCriteria; // 离线条件查询对象,封装查询条件
// List<?> 表示集合里的对象类型不确定,未指定
private List<?> rows; // 当前页需要展示的数据集合
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public DetachedCriteria getDetachedCriteria() {
return detachedCriteria;
}
public void setDetachedCriteria(DetachedCriteria detachedCriteria) {
this.detachedCriteria = detachedCriteria;
}
public List<?> getRows() {
return rows;
}
public void setRows(List<?> rows) {
this.rows = rows;
}
}
第三步:在StaffAction类中提供pageQuery()方法 由于浏览器发送过来的请求中带了2个参数(page和rows),我们需要采用属性驱动的方式,提供两个setPage和setRows方法,接收页面提交过来的参数
// 采用属性驱动的方式,接收页面提交过来的参数
private int page; // 当前页码
private int rows; // 每页显示的记录数
public void setPage(int page) {
this.page = page;
}
public void setRows(int rows) {
this.rows = rows;
}
/**
* 分页查询
* @throws IOException
*/
public String pageQuery() throws IOException {
PageBean pageBean = new PageBean();
// 设置当前页码
pageBean.setCurrentPage(page);
// 设置每页显示记录数
pageBean.setPageSize(rows);
// 设置离线条件查询对象,封装查询条件
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Staff.class); // 创建离线条件查询对象
pageBean.setDetachedCriteria(detachedCriteria);
// 调用该方法,设置PageBean对象的其他属性
staffService.pageBean(pageBean);
// 步骤:先导入json-lib的jar包+依赖包,步骤链接:https://www.cnblogs.com/chenmingjun/p/9513143.html
// 将PageBean对象转为JSON格式的数据响应给客户端浏览器进行显示
// 排除不需要的数据和排除关联对象
JsonConfig jsonConfig = new JsonConfig();
jsonConfig.setExcludes(new String[] {"currentPage", "pageSize", "detachedCriteria"});
JSONObject jsonObject = JSONObject.fromObject(pageBean, jsonConfig);
String json = jsonObject.toString();
ServletActionContext.getResponse().setContentType("text/json;charset=UTF-8");
ServletActionContext.getResponse().getWriter().print(json);
return "none";
}
第四步:在BaseDao中提供通用分页查询方法
/**
* 通用分页查询方法
*/
public void pageBean(PageBean pageBean) {
// 我们先把在StaffAction类中已经对PageBean类赋值好的3个值取出来
int currentPage = pageBean.getCurrentPage();
int pageSize = pageBean.getPageSize();
DetachedCriteria detachedCriteria = pageBean.getDetachedCriteria();
// 我们的PageBean还差两个属性没有赋值
// 总记录数 --> select count(*) from bc_staff
// 人为改变Hibernate框架默认发出SQL的形式,默认发出的是:select * from bc_staff
detachedCriteria.setProjection(Projections.rowCount()); // 发:select count(*) from bc_staff
List<Long> list = this.getHibernateTemplate().findByCriteria(detachedCriteria);
Long total = list.get(0);
// 设置总记录数
pageBean.setTotal(total.intValue());
// 将Hibernate框架发出SQL的形式还原成默认的形式:select * from bc_staff
detachedCriteria.setProjection(null);
// 重置表和类的映射关系
detachedCriteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY);
// 当前页需要展示的数据集合
int firstResult = (currentPage - 1) * pageSize;
int maxResult = pageSize;
List<?> rows = this.getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResult);
// 设置当前页需要展示的数据集合
pageBean.setRows(rows);
}
效果截图:
逻辑删除取派员,将取派员的deltag改为“1” 第一步:为“作废”按钮绑定事件
// 批量删除取派员
function doDelete() {
// 获得选中的行
var rows = $("#grid").datagrid("getSelections");
if (rows.length == 0) {
// 没有选中,提示
$.messager.alert("提示信息","请选择需要删除的记录!","warning");
} else {
var array = new Array();
// 选中了记录,获取选中行的id
for(var i=0; i<rows.length; i++) {
var id = rows[i].id; // 获取属性id的值
array.push(id);
}
var ids = array.join(","); // 1,2,3,4
// 发送同步请求,传递ids参数
window.location.href = '${pageContext.request.contextPath}/staffAction_delete.action?ids=' + ids;
}
}
第二步:在StaffAction中提供ids属性和对应的set方法,创建delete()方法,用于批量删除取派员
// 采用属性驱动的方式,接收页面提交过来的参数ids
private String ids;
public void setIds(String ids) {
this.ids = ids;
}
/**
* 批量删除(逻辑删除)
* @return
*/
public String delete() {
staffService.deleteBatch(ids);
return "list";
}
第三步:在Service中提供批量删除方法
/**
* 批量删除(逻辑删除)
*/
public void deleteBatch(String ids) {
String[] staffIds = ids.split(",");
for (String staffId : staffIds) {
staffDao.executeUpdate("staff.delete", staffId);
}
}
第四步:在Staff.hbm.xml中定义命名查询语句
<!-- 命名查询语句 -->
<query name="staff.delete">
update Staff set deltag='1' where id=?
</query>
列(Column)属性中,单元格的格式化函数:formatter
// 定义列
var columns = [ [ {
field : 'id',
checkbox : true,
},{
field : 'name',
title : '姓名',
width : 120,
align : 'center'
}, {
field : 'telephone',
title : '手机号',
width : 120,
align : 'center'
}, {
field : 'haspda',
title : '是否有PDA',
width : 120,
align : 'center',
formatter : function(data,row, index) { // formatter 单元格的格式化函数
if (data=="1") {
return "有";
} else {
return "无";
}
}
}, {
field : 'deltag',
title : '是否作废',
width : 120,
align : 'center',
formatter : function(data,row, index) { // formatter 单元格的格式化函数
if (data=="0") {
return "正常使用"
} else {
return "已作废";
}
}
}, {
field : 'standard',
title : '取派标准',
width : 120,
align : 'center'
}, {
field : 'station',
title : '所谓单位',
width : 200,
align : 'center'
} ] ];
第一步:复制添加取派员窗口,获得修改取派员窗口,注意:要修改取派员窗口的格式,并添加隐藏域
<!-- 修改取派员窗口 -->
<div class="easyui-window" title="对收派员进行添加或者修改" id="editStaffWindow" collapsible="false" minimizable="false" maximizable="false" style="top:20px;left:200px">
<div region="north" style="height:31px;overflow:hidden;" split="false" border="false" >
<div class="datagrid-toolbar">
<!-- 为添加窗口中的“保存按钮”绑定事件 -->
<a id="edit" icon="icon-save" href="#" class="easyui-linkbutton" plain="true" >保存</a>
<script type="text/javascript">
$(function() {
// 绑定事件
$("#edit").click(function() {
// 先校验表单输入项
var v = $("#editStaffForm").form("validate");
if (v) {
// 说明校验通过,提交增加收派员的表单
$("#editStaffForm").submit();
}
});
});
</script>
</div>
</div>
<div region="center" style="overflow:auto;padding:5px;" border="false">
<form id="editStaffForm" action="${pageContext.request.contextPath}/staffAction_edit.action" method="post">
<!-- 提供隐藏域 -->
<!-- <input type="text" name="id"> -->
<input type="hidden" name="id">
<table class="table-edit" width="80%" align="center">
<tr class="title">
<td colspan="2">取派员信息</td>
</tr>
<!-- TODO 这里完善收派员添加 table -->
<!--
<tr>
<td>取派员编号</td>
<td><input type="text" name="id" class="easyui-validatebox" required="true"/></td>
</tr>
-->
<tr>
<td>姓名</td>
<td><input type="text" name="name" class="easyui-validatebox" required="true"/></td>
</tr>
<tr>
<td>手机号</td>
<td><input type="text" name="telephone" class="easyui-validatebox" required="true"
data-options="validType:'phonenumber'"
/></td>
</tr>
<tr>
<td>单位</td>
<td><input type="text" name="station" class="easyui-validatebox" required="true"/></td>
</tr>
<tr>
<td colspan="2">
<input type="checkbox" name="haspda" value="1" />
是否有PDA</td>
</tr>
<tr>
<td>取派标准</td>
<td>
<input type="text" name="standard" class="easyui-validatebox" required="true"/>
</td>
</tr>
</table>
</form>
</div>
</div>
第二步:修改datagrid的双击行事件的处理函数 onDblClickRow 当用户双击一行时触发,参数包括: rowIndex:被双击行的索引,从 0 开始 rowData:被双击行对应的记录
// 当用户双击一行时触发该事件
function doDblClickRow(rowIndex, rowData) { // rowData => id:xxx,name:xxx,...
// 打开修改取派员窗口
$('#editStaffWindow').window("open");
// 回显数据
// $("input[name=name]").val(rowData.name); // 显示姓名
$('#editStaffForm').form("load", rowData); // 显示整个表格的数据
}
第三步:提交修改的表单
第四步:在StaffAction中提供edit()方法,修改取派员信息
/**
* 取派员信息修改
* @return
*/
public String edit() {
// 这样直接更新是不正确的,因为Staff这个表不是独立的,它有很多引用和被引用。
// staffService.update(model);
// 先查询数据库中的原始数据
Staff staff = staffService.findById(model.getId());
// 再按照页面提交过来的参数进行对应的覆盖
staff.setName(model.getName());
staff.setTelephone(model.getTelephone());
staff.setStation(model.getStation());
staff.setHaspda(model.getHaspda());
staff.setStandard(model.getStandard());
// 更新数据
staffService.update(staff);
return "list";
}