宅急送 项目第四天 取派员和区域管理

时间:2022-03-11 20:55:42
在第三天课程中,重点 Easy UI的 datagrid , UI框架自带数据表格插件 

Datagrid : 主要功能显示,自带分页查询、 条件查询、 排序 

EasyUI 、ExtJs、Flex 通常基于json格式数据,强大表格控件,支持xml格式的数据 

PS : Jquery 插件 jqGrid  (自学一下,效果EasyUI datagrid完成类似 )

1. 取派员管理

主要管理,取派货物快递人员信息

1.1. 取派员添加操作

为取派员选择 使用标准 (多表关联 )
/WEB-INF/pages/base/staff.jsp 取派员管理页面

宅急送 项目第四天 取派员和区域管理

1.1.1. 添加取派员时,选择已经存在取派标准

Struts2 学习 <s:select> 生成下拉列表

通用解决方案: Ajax 获取收派标准列表, 显示select下拉列表
步骤:
1、 客户端 发起Ajax请求

$.post("${pageContext.request.contextPath}/standard_ajaxlist.action",function(data){
});

2、 服务器处理数据,获得结果

在StandardAction 添加 ajaxlist 方法
业务查询所有正常使用标准 deltag = 0 ,带有条件查询 ,使用NamedQuery

<query name="Standard.ajaxlist">
        <![CDATA[from Standard where deltag = '0']]>
</query>

3、 服务器将处理结果 转换jso// 将处理结果 转换json返回

ActionContext.getContext().put(“standards”, standards);struts.xml

<!-- 收派标准 ajax列表 -->
<result name="ajaxlistSUCCESS" type="json">
    <param name="root">standards</param>
    <param name="includeProperties">
        \[\d+\]\.id,
        \[\d+\]\.name
    </param>
</result>

通过 FireBug 进行抓包调试

4、 服务器返回数据后,执行Ajax 回调函数

// jquery
$(data).each(function(){
    var option = $("<option value='"+this.id+"'>"+this.name+"</option>");
    $("#standardList").append(option);
});

以上代码 被EasyUI combobox控件简化

<input class="easyui-combobox"  data-options="url:'${pageContext.request.contextPath}/standard_ajaxlist.action'
,valueField:'id',textField:'name'" />

url : 获得json数据路径, valueField 就是返回json中哪个属性生成option的value属性,textField 返回json中哪个属性生成option的文本信息 !

1.1.2. 添加收派标准功能

<!-- 目标model 是 Staff, 提供 setStandard 方法, 在Standard中提供 setId 的方法 -->
<input class="easyui-combobox" name="standard.id" data-options="url:'${pageContext.request.contextPath}/standard_ajaxlist.action',valueField:'id',textField:'name'" />

standard.id 属性意义,封装 model 中 standard属性 的 id属性
model 提供 setStandard 方法
standard 类提供 setId 方法

// 为保存按钮添加 点击事件
$('#save').click(function(){
    // 进行form 校验
    if($('#staffForm').form('validate')){
        // 通过校验
        $('#staffForm').submit();
    }else{
        // 校验失败 
        $.messager.alert('警告','表单存在非法数据项,请重新输入','warning');
    }
});

服务器编写,对应每个数据表 (相同model) 编写一个单独Action : StaffAction

public class StaffAction extends BaseAction implements ModelDriven<Staff> {
}
public interface StaffService {
}
public class StaffServiceImpl extends BaseService implements StaffService {
}

将StaffDAO 注入 BaseService
将StaffService 注入 BaseAction

@Override
public void saveOrUpdate(Staff staff) {
    staffDAO.saveOrUpdate(staff);
}

统一配置 struts.xml applicationContext-action –service –dao.xml

1.2. 取派员列表分页查询

使用通用分页组件 PageRequestBean 和 PageResponseBean
将datagrid的 url换掉,服务器返回 特定格式json数据

{ total : 总记录数, rows: [当前页数据] }
$('#grid').datagrid( {
            url : "${pageContext.request.contextPath}/staff_pageQuery.action",
});

在服务器StaffAction 提供pageQuery的方法 — 实现分页查询

宅急送 项目第四天 取派员和区域管理

<!-- 分页列表查询 -->
<result name="pageQuerySUCCESS" type="json">
    <param name="root">pageResponseBean</param>         
    <param name="includeProperties">
        total,
        rows\[\d+\]\.id,
        rows\[\d+\]\.name,
        rows\[\d+\]\.telephone,
        rows\[\d+\]\.station,
        rows\[\d+\]\.haspda,
        rows\[\d+\]\.deltag,
        rows\[\d+\]\.standard\.name
    </param>
</result>

1.3. 取派员分页查询代码 重构优化

优化法则: 将重复代码进行抽取, 不同代码部分可以作为方法参数 (获得回调函数传入方法的 )

优化步骤 :

第一步: 将分页查询代码抽取
StandardServiceImpl 和 StaffServiceImpl的 pageQuery代码很相似 ,抽取将重复代码放入 BaseService

宅急送 项目第四天 取派员和区域管理

实现类代码简化


@Override
public PageResponseBean pageQuery(PageRequestBean pageRequestBean) {
    return pageQuery(pageRequestBean, staffDAO);
}

第二步 : 接口分离

宅急送 项目第四天 取派员和区域管理

public interface StaffService extends PageQuery {
}

第三步 :Action将请求参数 封装PageRequestBean
BaseAction 代码抽取

宅急送 项目第四天 取派员和区域管理

Action 子类

// 条件对象
DetachedCriteria detachedCriteria = 
    DetachedCriteria.forClass(Staff.class);
PageRequestBean pageRequestBean = 
    initPageRequestBean(detachedCriteria);

1.4. 取派员修改操作

双击修改 ,为表格数据行,添加双击事件

宅急送 项目第四天 取派员和区域管理

基于datagrid 修改,直接使用 数据表格内部缓存数据,进行form 回显

为了select 下拉框回显
修改 查询列表result

宅急送 项目第四天 取派员和区域管理

在页面 回显form数据

宅急送 项目第四天 取派员和区域管理

修改操作,可以使用 saveOrUpdate 方法 !!!

昨天: 修改标准时, 主键策略 uuid (自动生成策略),如果id 不为null,默认执行update操作
今天: 修改取派员,主键策略 assigned (委派策略), 服务器会生成查询语句,先根据id 查询,如果存在 update,如果不存在 save

问题: 使用生成策略,能否在update修改前 执行

sele<class name="cn.itcast.bos.domain.bc.Staff" table="bc_staff" catalog="bos" select-before-update="true">

管理,作废功能
在checkbox 两端,添加form, 提交form 所有勾选checkbox 自动提交

<form action="${pageContext.request.contextPath }/staff_delBatch.action" method="post">
    <div region="center" border="false">
        <table id="grid"></table>
    </div>
</form>

页面控制选中提交

// 作废操作 
function doDelete(){
    // 先判断 用户是否选择
    var array = $('#grid').datagrid('getSelections'); 
    if(array.length == 0){
        $.messager.alert('警告','删除前必须选择!','warning');
    }else{
        $('#delForm').submit();
    }
}

在服务器 StaffAction 添加 delBatch 方法

@Override
public void delBatch(String[] ids) {
    // 修改每个id 对应 取派员 deltag 为 1
    for (String id : ids) {
        Staff staff = staffDAO.findById(id);
        staff.setDeltag("1");
    }
}

2. 区域管理模块

区域管理, 自然行政区域信息管理,不依赖任何数据, 区域信息在分区管理模块使用 !
分析区域信息 Region 类

宅急送 项目第四天 取派员和区域管理

区域管理 增加、 修改、 删除 —- 留作作业 !!

重点学习: 区域信息批量导入
(文件上传、 Excel解析 技术点 )

2.1. Excel读写操作

2.1.1. 简介 Apache POI

使用Apache POI 完成Excel读写操作

Apache POI 是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能。

http://poi.apache.org/ 下载POI的jar包 ,包括以下内容

宅急送 项目第四天 取派员和区域管理

Excel 2003之前 xls 格式文件, Excel2007 文件格式 xlsx ,如果解析Excel,先分清Excel文件版本 ,如果2003之前, 使用HSSF API进行解析 、 如果 2007 Excel 使用 XSSF 进行解析

今天重点学习: HSSF 的 Excel解析 (针对Excel 2003 之前版本 )
下载 POI 3.9 的jar 包,完成Excel 读写操作

宅急送 项目第四天 取派员和区域管理

docs POI使用文档 (javadoc文档、 规范文档)
学习API : 推荐 POI3.5_HSSF_和XSSF_Excel操作快速入门手册.pdf

lib :相关jar包
ooxml-lib : 解析2007 Office版本文件jar 包

开发POI 最简单方式,导入 poi-3.9-20121203.jar 一个jar包就可以了

2.1.2. 将POI 导入项目

在pom.xml 导入 坐标

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.9</version>
</dependency>

2.1.3. 使用POI 读写Excel

参考: “POI整理.doc” 进行企业开发
编写代码,完成Excel解析和生成

解析步骤:

Excel文件 ---- HSSFWorkbook 工作薄对象 ---- Sheet --- Row 行--- Cell 单元格 

解析时要注意,如果Excel单元格的数据,使用numeric 格式保存,不能使用 getStringCellValue 进行读取 , 使用 getNumericCellValue 进行读取

可以在Excel 设置单元格 数据保存格式 为文本类型,使用 getStringCellValue 进行读取

宅急送 项目第四天 取派员和区域管理

// 1、 获得 HSSFWorkbook (针对 xls格式文件 )
HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream("info.xls"));

// 2、获得要解析sheet
HSSFSheet sheet = hssfWorkbook.getSheet("Sheet1"); // 通过名称获得Sheet
HSSFSheet sheet2 = hssfWorkbook.getSheetAt(0);// 获得第一个Sheet,通过下标获得

// 3、解析Sheet中每一行
for (Row row : sheet) {
    // 遍历 sheet中每一行
    // 4、 打印行 中单元格数据
    for (Cell cell : row) {
        // 判断单元格数据类型
        if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
            System.out.println(cell.getStringCellValue());
        } else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
            System.out.println(cell.getNumericCellValue());
        }
    }

    // 打印指定单元格的值
    System.out.println(row.getCell(1).getStringCellValue());// 打印每行第二个单元格的内容
}

生成一个Excel文件 :

写Workbook 工作薄 — 写Sheet — 写Row 行 — 写Cell 单元格

// 1、 创建 一个空的工作薄
HSSFWorkbook hssfWorkbook = new HSSFWorkbook();

// 2、 在工作薄建立 Sheet
HSSFSheet sheet = hssfWorkbook.createSheet("数据信息");

// 3、 向sheet写入行数据
HSSFRow row = sheet.createRow(0);// 创建第一行数据

// 4、 向row中单元格进行数据输出
row.createCell(0).setCellValue("产品");
row.createCell(1).setCellValue("价格");

// 5、 将Excel 数据输出到硬盘上
hssfWorkbook.write(new FileOutputStream("c:/test.xls"));

宅急送 项目第四天 取派员和区域管理

其它

课前资料

宅急送 项目第四天 取派员和区域管理

里面有各个工具的使用手册

pinyin4j

宅急送 项目第四天 取派员和区域管理

POI

宅急送 项目第四天 取派员和区域管理

一键上传

宅急送 项目第四天 取派员和区域管理

回调函数的由来

宅急送 项目第四天 取派员和区域管理

课程视频内容

宅急送 项目第四天 取派员和区域管理