zoukankan      html  css  js  c++  java
  • day54_BOS项目_06

    • 今天内容安排:
      • 1、业务受理环节分析
      • 2、创建业务受理环节对应的数据表(业务通知单、工单、工作单)
      • 3、实现业务受理、自动分单
      • 4、数据网格datagrid的编辑功能的使用
      • 5、基于数据网格datagrid的编辑功能实现工作单快速录入功能
      • 6、演示权限控制demo

    1、业务受理分析

    • 受理环节,是宅急送业务的开始,作为服务前端,客户通过电话、网络等多种方式进行委托,业务受理员通过与客户交流,获取客户的服务需求和具体委托信息,将服务指令输入我司服务系统。
    • 客户通过打电话的方式进行物流委托,一个客户的委托信息对应一个业务通知单
    • 系统通过客户的取件地址,自动匹配到一个取派员,为取派员产生一个任务,这个任务就是一个工单
    • 工作单:描述货物和物流信息的单据。就是我们寄快递的时候,取派员让我们填写的单子。如下图所示:
    • 业务受理如下图所示:

    第一步:根据提供的 业务受理.pdm 文件生成建表文件 bos_qp.sql
    第二步:由于业务受理.pdm 文件中有伪表,所以我们需要修改生成的建表文件,修改如下图所示:


    第三步:我们根据 建表文件 bos_qp.sql使用 Navicat for MySQL 生成对应的表,生成的表为:qp_noticebill(业务通知单)、qp_workbill(工单)、qp_workordermanage(工作单),注意:由于表的数量及表的关系增多,我们要有意识的检查生成的表中外键名是否有重复,有重复的我们需要进行修改。
    第四步:我们使用MyEclipse中Hibernate反转引擎插件生成对应的实体类以及对应的xxx.hbm.xml文件
      详细操作步骤链接:https://www.cnblogs.com/chenmingjun/p/9733326.html
    第六步:对实体类的字段进行注释

    2、实现业务受理、自动分单

    2.1、在crm中扩展提供根据手机号查询客户信息的方法并实现

    CustomerService接口:

    package cn.itcast.crm.service;

    import java.util.List;

    import cn.itcast.crm.domain.Customer;

    // 客户服务接口 
    public interface CustomerService {
        // 未关联定区客户
        public List<Customer> findnoassociationCustomers();

        // 查询已经关联指定定区的客户
        public List<Customer> findhasassociationCustomers(String decidedZoneId);

        // 将未关联定区客户关联到定区上
        public void assignCustomersToDecidedZone(Integer[] customerIds, String decidedZoneId);

        // 根据手机号查询客户信息
        public Customer findCustomerByTelephone(String telephone);
    }

    CustomerServiceImpl实现类:

        public Customer findCustomerByTelephone(String telephone) {
            Session session = HibernateUtils.openSession();
            session.beginTransaction();

            String hql = "from Customer where telephone=?";
            List<Customer> customers = session.createQuery(hql).setParameter(0, telephone).list();

            session.getTransaction().commit();
            session.close();

            if (customers != null && customers.size() > 0) {
                return customers.get(0);
            }
            return null;
        }

    2.2、在bos中实现业务受理、自动分单

    注意:需要将crm中接口扩展的方法复制到bos的接口中
    业务受理页面:WEB-INF/pages/qupai/noticebill_add.jsp
    第一步:为手机号输入框绑定离焦事件,发送ajax请求,提交输入的手机号到Action中,在Action中调用crm的代理对象,访问crm服务,根据手机号查询客户信息,返回json数据

        <td>来电号码:</td>
        <td>
            <input type="text" class="easyui-validatebox" name="telephone" required="true"/>
            <script type="text/javascript">
                $(function() {
                    $("input[name=telephone]").blur(function() {
                        // alert("晓艺微信把我删了,想o(╥﹏╥)o");
                        // 获取输入框的值(手机号)
                        var telephone = this.value; 
                        // 发送ajax请求,带上参数:手机号
                        var url = "${pageContext.request.contextPath}/noticebillAction_findCustomerByTelephone.action";
                        $.post(url, {"telephone":telephone}, function(data{
                            alert(data);
                        }, 'json');
                    });
                });
            
    </script>
        </td>

    浏览器效果截图如下:


    第二步:创建新的NoticebillAction,提供findCustomerByTelephone()方法,加注解、加注释、继承BaseAction<Noticebill>、配置struts.xml
    package com.itheima.bos.web.action;

    import java.io.IOException;

    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;

    import com.itheima.bos.domain.Noticebill;
    import com.itheima.bos.web.action.base.BaseAction;

    import cn.itcast.crm.domain.Customer;

    /**
     * 业务通知单设置
     * @author Bruce
     *
     */

    @Controller
    @Scope("prototype")
    public class NoticebillAction extends BaseAction<Noticebill{

        /**
         * 调用代理对象,根据手机号查询客户信息
         * @return
         * @throws IOException 
         */

        public String findCustomerByTelephone() throws IOException {
            Customer customer = remoteProxy.findCustomerByTelephone(model.getTelephone());
            String[] excludes = new String[] {};
            this.writeObject2Json(customer, excludes);
            return "none"
            // 注意:我们发的是ajax请求,返回的是json数据,解析的也是json数据,所以返回的是"none"
            // 如果返回的是"list",就是说我们查询到的结果变成HTML页面,我用解析json数据的方式根本解析不出来啊!
        }
    }

    第三步:完善页面中ajax方法的回调函数

        <td>来电号码:</td>
        <td>
            <input type="text" class="easyui-validatebox" name="telephone" required="true"/>
            <script type="text/javascript">
                $(function() {
                    $("input[name=telephone]").blur(function() {
                        // alert("晓艺微信把我删了,想o(╥﹏╥)o");
                        // 获取输入框的值(手机号)
                        var telephone = this.value;
                        // 发送ajax请求,带上参数:手机号
                        var url = "${pageContext.request.contextPath}/noticebillAction_findCustomerByTelephone.action";
                        $.post(url, {"telephone":telephone}, function(data{
                            // alert(data);
                            if (data != null) {
                                // 查询到客户,可以进行回显
                                var customerId = data.id;
                                var customerName = data.name;
                                var customerAddress = data.address;
                                $("input[name=customerId]").val(customerId);
                                $("input[name=customerName]").val(customerName);
                                $("input[name=delegater]").val(customerName);
                                $("input[name=pickaddress]").val(customerAddress);
                            } else {
                                // 清除数据
                                var customerId = data.id;
                                var customerName = data.name;
                                var customerAddress = data.address;
                                $("input[name=customerId]").val("");
                                $("input[name=customerName]").val("");
                                $("input[name=delegater]").val("");
                                $("input[name=pickaddress]").val("");
                            }
                        }, 'json');
                    });
                });
            
    </script>
        </td>

    第四步:为“新单”按钮绑定保存事件

        <script type="text/javascript">
            $(function() {
                    $("body").css({
                        visibility : "visible"
                });

                // 对save按钮绑定点击事件
                $('#save').click(function() {
                    // 对form表单进行校验
                    if ($('#noticebillForm').form('validate')) {
                        $('#noticebillForm').submit();
                    }
                });
            });
        
    </script>

    第五步:在NoticebillAction中提供add()方法,保存一个业务通知单数据,并根据取件地址尝试自动分单,注入NoticebillService、加注解、加注释、等等
    NoticebillAction.java

        /**
         * 保存业务通知单,并根据取件地址尝试自动分单
         * @return
         */

        public String add() {
            // 从session中获取当前登录用户,即业务员(业务受理员)
            User user = BOSContext.getLoginUser();
            // 设置用户
            model.setUser(user);
            noticebillService.save(model);
            return "addUI";
        }

    第六步:在crm服务中扩展方法,根据取件地址查询定区id

        public String findDecidedzoneIdByPickaddress(String address) {
            Session session = HibernateUtils.openSession();
            session.beginTransaction();

            String hql = "select decidedzone_id from Customer where address=?";
            List<String> decidedzoneId = session.createQuery(hql).setParameter(0, address).list();

            session.getTransaction().commit();
            session.close();

            if (decidedzoneId != null && decidedzoneId.size() > 0) {
                return decidedzoneId.get(0);
            }
            return null;
        }

    第七步:在NoticebillService中提供save方法
    NoticebillServiceImpl.java

    package com.itheima.bos.service.impl;

    import java.sql.Timestamp;

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import com.itheima.bos.crm.CustomerService;
    import com.itheima.bos.dao.IDecidedzoneDao;
    import com.itheima.bos.dao.INoticebillDao;
    import com.itheima.bos.dao.IWorkbillDao;
    import com.itheima.bos.domain.Decidedzone;
    import com.itheima.bos.domain.Noticebill;
    import com.itheima.bos.domain.Staff;
    import com.itheima.bos.domain.Workbill;
    import com.itheima.bos.service.INoticebillService;

    @Service
    @Transactional
    public class NoticebillServiceImpl implements INoticebillService {

        // 注入业务通知单dao
        @Autowired
        private INoticebillDao noticebillDao;

        // 注入远程访问的代理对象
        @Autowired
        private CustomerService remoteProxy;

        // 注入定区dao
        @Autowired
        private IDecidedzoneDao decidedzoneDao;

        // 注入工单dao
        @Autowired
        private IWorkbillDao workbillDao;

        /**
         * 保存业务通知单,并根据取件地址尝试自动分单
         */

        public void save(Noticebill model) {
            // 先保存业务通知单(多个业务通知单属于一个取派员)
            noticebillDao.save(model);  // 持久化对象

            // 获取取件地址
            String pickaddress = model.getPickaddress();
            // 根据取件地址查找定区id
            String decidedzoneId = remoteProxy.findDecidedzoneIdByPickaddress(pickaddress);
            if (decidedzoneId != null) {
                // 查询到定区id,可以进行自动分单
                Decidedzone decidedzone = decidedzoneDao.findById(decidedzoneId); // 持久化对象
                // 获取取派员
                Staff staff = decidedzone.getStaff();
                // 设置业务通知单关联匹配到的取派员
                model.setStaff(staff);
                // 设置分单类型为“自动分单”
                model.setOrdertype("自动分单");

                // 为取派员创建一个工单并设置值
                Workbill workbill = new Workbill();
                workbill.setNoticebill(model); // 工单关联业务通知单
                workbill.setStaff(staff); // 工单关联取派员
                workbill.setType("新单");
                workbill.setPickstate("未取件");
                workbill.setBuildtime(new Timestamp(System.currentTimeMillis()));
                workbill.setAttachbilltimes(0);
                workbill.setRemark(model.getRemark());

                // 保存工单
                workbillDao.save(workbill);

                // 调用短信平台服务,给取派员发送短信
                // ......
            } else {
                // 没有查询到定区id,设置分单类型为“人工分单”(进入调度环节)
                model.setOrdertype("人工分单");
                // 调度
                // ......
            }
        }
    }

    3、数据网格datagrid 的编辑功能的使用

    • 列(Column)属性:数据网格(DataGrid) 的列(Column)是一个数组对象,它的每个元素也是一个数组。元素数组的元素是一个配置对象,它定义了每个列的字段。

      • 数据网格的编辑功能是以为单位的。
      • 即:通过数据网格的列属性editor开启指定列的编辑功能。如下图所示:
    • 数据网格的方法:

      • 插入一行:insertRow
      • 删除一行:deleteRow
      • 开启编辑状态:beginEdit
      • 结束编辑状态:endEdit
      • 获得选中行的索引:getRowIndex
      • 获得选中的第一行:getSelected
      • 获得选中的所有行:getSelections
    • 数据网格的事件:

      • 结束编辑状态时触发:onAfterEdit

    示例代码如下:

    <%@ page language="java" contentType="text/html; charset=UTF-8"
        pageEncoding="UTF-8"%>

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>datagrid_edit---数据网格的编辑功能</title>
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/js/easyui/themes/default/easyui.css">
    <link rel="stylesheet" type="text/css" href="${pageContext.request.contextPath }/js/easyui/themes/icon.css">
    <script type="text/javascript" src="${pageContext.request.contextPath }/js/jquery-1.8.3.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath }/js/easyui/jquery.easyui.min.js"></script>
    <script type="text/javascript" src="${pageContext.request.contextPath }/js/easyui/locale/easyui-lang-zh_CN.js"></script>
    </head>
    <body>
        <h3>方式三:通过js代码,使用插件提供的API动态创建datagrid,大量使用</h3>
        <table id="grid"></table>
        <script type="text/javascript">
            $(function() {
                // 全局的行索引
                var index;
                $("#grid").datagrid({
                    columns:[[ // 定义标题行所有的列,是一个二维数组
                        {field:'id',title:'编号',checkbox:true}, // 是否复选框
                        {field:'name',title:'姓名',editor:{ // 指定当前列具有编辑功能
                            type:'validatebox',
                            options:{
                            }
                        }},
                        {field:'age',title:'年龄',editor:{ // 指定当前列具有编辑功能
                            type:'validatebox',
                            options:{
                            }
                        }}
                    ]],
                    url:'/bos19/json/data.json'// 指定URL地址,datagrid控件会自动发送ajax请求获取数据
                    onAfterEdit:function(rowIndex,rowData,changes// 数据网格的事件:当前行结束编辑状态时触发
                        alert("更新后的姓名为:" + rowData.name);
                    },
                    toolbar:[ // 工具栏按钮
                        {text:'保存',iconCls:'icon-save',handler:function() {
                            // 结束当前行的编辑状态
                             $("#grid").datagrid("endEdit",index);
                        }},
                        {text:'添加',iconCls:'icon-add',handler:function() {
                            // 动态添加一行
                            $("#grid").datagrid("insertRow",{
                                index:0// 在索引为0的位置插入,即在第一行插入
                                row:{}   // 空的json表示空行
                            });
                            // 让第一行开启编辑状态
                            index = 0;
                            $("#grid").datagrid("beginEdit",index);
                        }},
                        {text:'删除',iconCls:'icon-remove',handler:function() {
                            // 获得当前选中的行
                            var row = $("#grid").datagrid("getSelected");
                            // 获取当前选中的行的索引
                            index = $("#grid").datagrid("getRowIndex",row);
                            // 删除当前行
                            $("#grid").datagrid("deleteRow",index);
                        }},
                        {text:'修改',iconCls:'icon-edit',handler:function() {
                            // 获得当前选中的所有行
                            // $("#grid").datagrid("getSelections");
                            // 获得当前选中的行
                            var row = $("#grid").datagrid("getSelected");
                            // 获取当前选中的行的索引
                            index = $("#grid").datagrid("getRowIndex",row);
                            // 开启当前选中行的编辑状态
                            $("#grid").datagrid("beginEdit",index);
                        }}
                    ],
                    singleSelect:true,    // 是否可以单选
                    pagination:true,    // 分页条
                    pageList:[3,5,7]     // 自定义分页条中的下拉框选项
                });
            });
        
    </script>
    </body>
    </html>

    示例动图如下:

    4、基于数据网格datagrid 的编辑功能实现工作单快速录入功能

    第一步:在quickworkorder.jsp页面中增加发送ajax请求,提交当前结束编辑行的数据到服务器,完成保存操作的代码,如下:
    位置:/bos19/WebContent/WEB-INF/pages/qupai/quickworkorder.jsp

        // 发送ajax请求,提交当前结束编辑行的数据到服务器,完成保存操作
        var url = "${pageContext.request.contextPath}/workordermanageAction_add.action";
        $.post(url,rowData,function(data{
            if (data == 1) {
                // 工作单信息录入成功
                $.messager.alert("提示信息","工作单信息录入成功!","warning");
            } else {
                // 工作单信息录入失败
                $.messager.alert("提示信息","工作单信息录入失败!","warning");
            }
        });

    第二步:创建新的WorkordermanageAction,提供add()方法,加注解、加注释、继承BaseAction<Workordermanage>、配置struts.xml、等等

    package com.itheima.bos.web.action;

    import java.io.IOException;

    import org.apache.struts2.ServletActionContext;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Controller;

    import com.itheima.bos.domain.Workordermanage;
    import com.itheima.bos.web.action.base.BaseAction;

    /**
     * 工作单设置
     * @author Bruce
     *
     */

    @Controller
    @Scope("prototype")
    public class WorkordermanageAction extends BaseAction<Workordermanage{

        public String add() throws IOException {
            String flag = "1";
            try {
                // 工作单信息录入成功
                workordermanageService.save(model);
            } catch (Exception e) {
                // 工作单信息录入失败
                flag = "0";
            }
            // 响应给浏览器一个状态码,这种手法常用
            ServletActionContext.getResponse().setContentType("text/html;charset=UTF-8");
            ServletActionContext.getResponse().getWriter().print(flag);
            return "none";
        }
    }
  • 相关阅读:
    LOJ#10106. 「一本通 3.7 例 2」单词游戏
    小木棍(爆搜减枝)
    倍增求lca(模板)
    2018年第九届蓝桥杯C/C++A组省赛(最后一题)
    LOJ#10172. 「一本通 5.4 练习 1」涂抹果酱
    【[APIO/CTSC2007]动物园】状压DP
    c++滚动数组
    状态压缩入门(附经典题目和题解)
    小 M 的算式(dfs)
    P与NP问题详解
  • 原文地址:https://www.cnblogs.com/chenmingjun/p/9765473.html
Copyright © 2011-2022 走看看