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