day51_BOS项目_03

  • 今天内容安排:
    • 1、解决window窗口bug
    • 2、bos项目整体需求分析(基础设置、取派、中转、路由、报表)
    • 3、取派员添加功能
    • 4、jQuery easyUI 数据网格控件 datagrid 的使用方式
    • 5、基于datagrid实现取派员分页查询
    • 6、取派员批量删除功能
    • 7、取派员信息修改功能

1、解决window窗口bug

将上面的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、bos项目整体需求分析之部分需求分析

整个基础设置部分对应需求文档2.6章节。如下图所示:

2.1、基础档案设置

功能概述:
    在其他的系统中通常称为“数据字典”。`提供基础数据,供其他模块使用`。
    主要是针对本系统中的一些自定义项,需要参照录入,并作为统计分析和计算的维度,用户根据自己的需要动态设置的基础档案;对于自定义的档案支持多级定义;
    系统会事先预置一些系统级别的基础档案,如线路类型、保险类型等;客户根据自己的需要动态增加,主要是应用在`参照录入`;
    此功能主要是为`系统的可扩张性`而设置的;
    此功能主要应用角色是`“系统管理员”`;
    目前需要在此设置的基础档案包括:线路类型、取派员类型、签收类型、保险类型、受理备注说明、配载信息、返货原因、消单原因、取消签收类型、返货拒绝类型、大物流类型。

2.2、收派标准

功能概述:
    将承接的货物,按照重量和体积两个标准,双纬度定义货物的标准。以便将不同标准的货物分给不同收取和派送能力的人员。由运营部门制定。

2.3、班车设置

功能概述:
    班车设置表,线路设置表。
    将设置的线路和车辆建立对应关系。

2.4、取派员设置/替班

功能概述:
    小件员设置主要是设置小件员和快递员的资源信息,主要是为了自动下单和取派任务件使用;包括增加小件员的交通工具和通讯设备,以及取派的重量和体积标准。
    使用角色为各级组织机构的系统管理人员在添加。
    取派设置中包括小件员的替班信息设置。
    以及被替班人信息的查询功能。

2.5、区域设置

功能概述:
    区域为国家划分的行政区域。

2.6、管理分区

功能概述:
    区域范围很大,不规则,不便于直接进行人员分配,需要对区域进行细分 --> 分区。

2.7、管理定区/调度排版

功能概述:
    `定区是物流分配的基本单位`。定区可以将分区、取派员、客户信息进行关联,为自动分单提供数据支持。使用hessian技术,远程调用技术。

2.8、收派时间管理

功能概述:
    上班时间的管理,根据取派人员的可上班时间,将区域取派任务在不同时限分配给不同的取派人员。建议时间管理由总公司部门管理,固化出各种上班时间点。下级厅点只有调用权限,没有修改权限。

3、取派员添加功能

页面位置:/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>

4、jQuery easyUI 数据网格控件 datagrid 的使用方式

数据网格(datagrid)以表格格式显示数据,并为选择、排序、分组和编辑数据提供了丰富的支持。数据网格(datagrid)的设计目的是为了减少开发时间,且不要求开发人员具备指定的知识。它是轻量级的,但是功能丰富。它的特性包括单元格合并,多列页眉,冻结列和页脚,等等。

4.1、方式一:将HTML代码渲染成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>

4.2、方式二:发送ajax请求获取json数据,并显示,常用,该数据网格可以自己发送ajax请求

    <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数据的格式满足:

该数据可以有多项,但是上述代码我们只取前三项。

4.3、方式三:通过js代码,使用插件提供的API动态创建datagrid,大量使用

    <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的区别:

三种方式的效果如下图所示:

5、基于datagrid实现取派员分页查询

第一步:修改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);
    }

效果截图:

6、取派员批量删除功能

逻辑删除取派员,将取派员的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'
    } ] ];

7、取派员信息修改功能

第一步:复制添加取派员窗口,获得修改取派员窗口,注意:要修改取派员窗口的格式,并添加隐藏域

    <!-- 修改取派员窗口 -->
    <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";
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏有趣的Python

程序员装机必备爆款软件推荐与配置(windows版)

做机也要做一只全能的机哦 值此新年来临之即,面对两百多个G的c盘。忍痛割爱将电脑系统重装,版本为(win10:1079)之后的所有电脑环境更新,专业软件安装均会...

4253
来自专栏進无尽的文章

兼容-iOS9 适配 添加应用白名单及解除对http的访问限制

       iOS 9系统更新后限制了http协议的访问,此外第三方应用需要在“Info.plist”中列为白名单,才可正常检查其应用是否安装。受此影响,当你...

2293
来自专栏码洞

如何优雅的关闭Go Channel【译】

不要在消费端关闭channel,不要在有多个并行的生产者时对channel执行关闭操作。

2304
来自专栏比原链

剥开比原看代码05:如何从比原节点拿到区块数据?

Gitee地址:https://gitee.com/BytomBlockchain/bytom

711
来自专栏Thinks

你的第一个渐进式网站应用(5)

渐进式网站应用会很快启动并马上可用。在目前的状态中(step-04),我们的天气app启动很快,但是不可用。因为还木有数据。 我们要使用一个AJAX请求去获取数...

793
来自专栏李蔚蓬的专栏

VMware Workstation14.1.3 & Ubuntu18.04从安装到实用的填坑之路

本机VMware Workstation环境是上学期安装的,拿的老师给的安装包,版本10.0.1。顺便装了个Ubuntu15.10。

1341
来自专栏菩提树下的杨过

老生常谈:利用Membership实现SSO(单点登录)

虽然有一些现成的第三方解决方案比如:OpenID,Passport,SpaceCard等都还不错,但是要么就是收费的(passport),要么就是有点用不习惯(...

2005
来自专栏小白课代表

Ansoft maxwell(Ansoft maxwell EM)16 安装教程。

2932
来自专栏wujianqinjian的云

腾讯云API弹性公网IP踩坑

由于自己管理的云服务器数量比较多,时不时需要更换IP,在管理台上一下下点击,实在浪费时间,于是就想到了通过API调用的方式,将更换IP一系列动作,全部集成到Py...

3.7K0
来自专栏葡萄城控件技术团队

Asp.Net MVC4入门指南(7):给电影表和模型添加新字段

在本节中,您将使用Entity Framework Code First来实现模型类上的操作。从而使得这些操作和变更,可以应用到数据库中。 默认情况下,就像您在...

19110

扫码关注云+社区