• 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: { 
                    validatorfunction(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", "decidedzones"});

            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";
        }
  • 相关阅读:
    【SCOI 2011】 糖果
    【POJ 3159】 Candies
    【POJ 1716】 Integer Intervals
    【POJ 2983】 Is the information reliable?
    【POJ 1364】 King
    【POJ 1201】 Intervals
    【POJ 1804】 Brainman
    6月10日省中提高组题解
    【POJ 3352】 Road Construction
    【POJ 1144】 Network
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9742791.html
Copyright © 2020-2023  润新知