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";
    }
}

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏张善友的专栏

领悟Web设计模式

摘要 本文介绍了在.NET框架下应用Web设计模式改进WebForm程序设计的一些基本方法及要点。 关键字 设计模式,ASP.NET,WebForm,MVC,P...

2125
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十三天 Web商城实战三【悟空教程】

<a href="${pageContext.request.contextPath}/OrderServlet?method=findByUid">我的订单<...

1821
来自专栏社区的朋友们

Node 架构从三层到 N 层,实现代码重用和解耦

三层架构通常意义上是将整个业务应用划分为:控制层、业务逻辑层以及数据访问层,三层架构在 Java Web 项目中很常见,那么这种架构能否运用在 Node 项目中...

2.2K2
来自专栏草根专栏

从头编写 asp.net core 2.0 web api 基础框架 (3)

Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-...

4977
来自专栏FreeBuf

远程RPC溢出EXP编写实战之MS06-040

0x01 前言 MS06-040算是个比较老的洞了,在当年影响十分之广,基本上Microsoft大部分操作系统都受到了影响,威力不亚于17年爆出的”永恒之蓝”漏...

30410
来自专栏大魏分享(微信公众号:david-share)

通过Swagger管理API:API Management学习第一篇

3 Scale有个很好的功能,它提供ActiveDocs实时文档。它基于Swagger框架,提供了一种记录API的方法,并包含在Developer Portal...

1313
来自专栏Google Dart

Flutter 构建完整应用手册-联网 顶

从大多数应用程序获取互联网上的数据是必要的。 幸运的是,Dart和Flutter为这类工作提供了工具!

1322
来自专栏辣子鸡的技术分享

Mybatis自动代码生成器的实现

原博地址https://laboo.top/2018/11/26/a-db/#more

1266
来自专栏安恒网络空间安全讲武堂

赛前福利①最新2018HITB国际赛writeup

FIRST 距离“西湖论剑杯”全国大学生网络空间安全技能大赛只有10天啦! 要拿大奖、赢offer,那必须得来点赛前练习定定心啊~这不,讲武堂就拿到了2018H...

4705
来自专栏Java帮帮-微信公众号-技术文章全总结

Web-第二十一天 Web商城实战一【悟空教程】

public class BaseServlet extends HttpServlet {

2054

扫码关注云+社区

领取腾讯云代金券