1. 取派模块业务分析

已经完成基础设置模块 : 收派标准管理、 取派员管理、 区域管理、分区管理、定区管理
基础设置模块的数据,实际上为后期业务模块提供支持

重点开发任务,业务受理模块

业务受理功能
受理环节,是宅急送业务的开始,作为服务前端,客户通过电话、网络等多种方式进行委托,业务受理员通过与客户交流,获取客户的服务需求和具体委托信息,将服务指令输入我司服务系统。

业务受理后,业务人员需要将客户信息,录入为 “业务通知单”(代表客户一份快递需要) ,系统进行自动分单,产生“工单” , 系统自动识别客户对应定区的负责人员, 由指定取派员到客户家取货

工作单功能 “工作单”
工作单基础信息的录入是信息的入口,并且也是本系统中人机交互最多的环节;基础信息录入的及时、准确、完整会直接影响后续的实物的运转配载、小件员交款、财务收入确认、成本垫付分摊,所以对数据的准确性、及时性、完整性要求比较高。

业务通知单: 客户快递申请
工单: 取派员取件任务
工作单 : 面向物流的数据,真实货物信息

查台转单
当自动下单成功,但是由于基础信息错误,而导致分配的取货人员错误,通过查台转单来解决此类失误。 (分错取派员,更换取派员 )

人工调度
在自动下单的时候,由于取件地址无法匹配取件人员,就转入人工调度。 (业务人员,手动为客户,指定取派员 )

2. 取派业务模块— 数据库设计

根据 “业务受理数据表.xls” 设计PowerDesigner PDM 物理数据模型
参考 “业务受理.pdm”

根据PDM生成SQL 脚本,将脚本导入 数据库

qp_noticebill 业务通知单
qp_workbill 工单
qp_workordermanage 工作单

根据数据表,使用MyEclipse 反转生成PO类和hbm映射

修改生成的类名

3. 业务受理功能

客户提交快递申请 ,业务人员将客户业务信息,录入到系统

3.1. 业务通知单页面编写

业务通知单录入页面 : /WEB-INF/pages/qupai/noticebill_add.jsp
页面存在大form 表单 ,使用EasyUI form 控件

validatebox (验证框) :非空、长度
<input type="text" class="easyui-validatebox" required="true" />numberbox (数字框) :对validatebox扩展,只允许输入数字
<input type="text" class="easyui-numberbox" required="true" />combobox (下拉框) : 可以对 <input> 元素,生成下拉列表 datebox (日历控件) : 选择日期
<input type="text" class="easyui-datebox" data-options="required:true,editable:false"/>

检查业务受理form表单,元素name属性和 NoticeBill 实体类是否一致
为form添加 点击提交事件

// 点击新单按钮,将业务通知单 保存
$('#save').click(function(){if($("#noticebillForm").form('validate')){$('#noticebillForm').submit();}else{$.messager.alert('警告','表单存在非法数据项!','warning');}
});

3.2. 编写业务受理服务器代码

3.2.1. 完成基本代码结构

public class NoticeBillAction extends BaseAction implements ModelDriven<NoticeBill> {}
public interface NoticeBillService {}
public class NoticeBillServiceImpl extends BaseService implements NoticeBillService {}

将DAO 注入Service
将Service 注入 Action

在业务受理时,产生业务通知单的数据,在保存到数据库的时候,需要进行自动分单的操作

1、 用客户取货地址通过远程调用,访问CRM,比较CRM系统中客户地址 ,查找客户对应定区,再通过定区获得 取派员信息
2、 如果不能在CRM中找到客户对应定区,使用当前发件人地址去匹配分区地址 ,就可以通过分区去管理定区,匹配到取派员

如果自动分单成功,需要在数据表 qp_workbill 生成一条工单记录 !
如果自动分单失败,进入人工调度环节

3.2.2. 自动分单 — 去CRM匹配客户的地址

修改CRM业务接口 CustomerService

// 根据 客户地址 查询 定区编码
public String findDecidedZoneIdByCustomerAddress(String address);

将修改后的CustomerService 接口,复制BOS系统 !!!
编写 CustomerServiceTest测试用例 ,完成接口调试

3.2.3. 自动分单 —- 匹配分区的关键字

<query name="Subarea.findByAddresskey"><![CDATA[from Subarea where addresskey = ?]]>
</query>
public void saveNoticeBill(NoticeBill noticeBill) {// 将业务通知单数据保存到数据库noticeBillDAO.save(noticeBill);// 自动分单// 1 、使用当前取件地址,去查询CRM系统 定区编码String decidedZoneId = customerService.findDecidedZoneIdByCustomerAddress(noticeBill.getPickaddress());if (decidedZoneId == null) {// 未查到// 2、匹配分区 关键字String[] addressArray = noticeBill.getPickaddress().split(" "); // 北京市海淀区 xxx路 1号楼if (addressArray.length >= 2) {String addresskey = addressArray[1]; // 取第二个元素 作为关键字List<Subarea> list = subareaDAO.findByNamedQuery("Subarea.findByAddresskey",addresskey);// 只匹配到唯一的一个分区,而且这个分区已经关联到定区if (list.size() == 1 && list.get(0).getDecidedZone() != null) {// 自动分单成功// 查到 (自动分单成功)DecidedZone decidedZone = list.get(0).getDecidedZone();// 通知单noticeBill.setStaff(decidedZone.getStaff());noticeBill.setOrdertype("自动");// 工单信息WorkBill workBill = new WorkBill();workBill.setNoticeBill(noticeBill);workBill.setStaff(decidedZone.getStaff());workBill.setType("新");workBill.setPickstate("新单");workBill.setBuildtime(new Timestamp(System.currentTimeMillis()));workBill.setAttachbilltimes(0);workBill.setRemark(noticeBill.getRemark());workBillDAO.save(workBill);} else {// 人工调度noticeBill.setOrdertype("人工");}} else {// 人工调度noticeBill.setOrdertype("人工");}} else {// 查到 (自动分单成功)DecidedZone decidedZone = decidedZoneDAO.findById(decidedZoneId);// 通知单noticeBill.setStaff(decidedZone.getStaff());noticeBill.setOrdertype("自动");// 工单信息WorkBill workBill = new WorkBill();workBill.setNoticeBill(noticeBill);workBill.setStaff(decidedZone.getStaff());workBill.setType("新");workBill.setPickstate("新单");workBill.setBuildtime(new Timestamp(System.currentTimeMillis()));workBill.setAttachbilltimes(0);workBill.setRemark(noticeBill.getRemark());workBillDAO.save(workBill);}
}

3.2.4. 配置添加通知单Action

<!-- 业务通知单受理 -->
<action name="noticebill_*" class="noticeBillAction" method="{1}"><result name="saveSUCCESS">/WEB-INF/pages/qupai/noticebill_add.jsp</result>
</action

>

4. 业务受理 未实现的功能

工单操作

查询出系统的所有工单 qp_workbill

追单 : 客户已经提交业务申请,取派员很多都没有去客户家中取件,再次进行追单操作, 系统只需要在 workbill表中 attachbilltimes 追单次数+1 (实际业务中,需要通过短信平台,催促取派员 )

销单 : 在取派员去取件的过程中,客户选择进行销单,不进行快递业务 ,在workbill 表type 设置 “销”, pickstack 设置为 “已取消”

查台转单
业务通知单 自动分单 成功 ,但是分错人了, 需要为通知单 重新手动更换 取派员 !

人工调度
业务通知单 自动分单失败,进入人工调度,需要手动为通知单指定取派员,生成工单!

结果: 已经将客户的货物,取回了物流公司!!!

5. 工作单管理

工作单基础信息的录入是信息的入口,并且也是本系统中人机交互最多的环节;基础信息录入的及时、准确、完整会直接影响后续的实物的运转配载、小件员交款、财务收入确认、成本垫付分摊,所以对数据的准确性、及时性、完整性要求比较高。

5.1. 工作单快速录入

提供操作人员在货量大单子多时简洁快速录入工作单的途径,快速录入中的信息主要是为了满足配载而设置的功能界面。
当业务高峰期,业务人员,只需要录入工作单基本信息(为了满足物流),就可以开始物流配送, 在业务闲暇时,再手动完善工作单信息。

5.1.1. easy ui 提供 datagrid的 行编辑效果

使用 datagrid 的列属性

步骤一: 在可编辑 列信息上,添加editor 属性

步骤二: 如果想编辑数据,开启某行数据编辑的状态

开启编辑

$('#grid').datagrid('beginEdit',1);// 索引1 代表第二行 

结束编辑

$('#grid').datagrid('endEdit',1);// 索引1 代表第二行

取消编辑 (将该行数据,还原到编辑之前的效果 )

$('#grid').datagrid('cancelEdit',1);// 索引1 代表第二行

步骤三: 如何向表格插入新的一行
Easy ui 提供 appendRow 和 insertRow 用于表格数据插入
appendRow 在表格末尾追加一行
insertRow 在指定位置插入一行

在表格第一行,插入一个空白行 :

$('#grid').datagrid('insertRow',{index : 0 , // 在第一行进行插入row : {}
});

步骤四: 在编辑结束后 或者 取消编辑后,执行事件函数

在行编辑后,onAfterEditor 事件函数就会执行,在取消编辑后 onCancelEdit 会执行

onAfterEdit : function(rowIndex, rowData, changes){alert('编辑完成');
}

5.1.2. 工作单快速录入页面

/WEB-INF/pages/qupai/quickworkorder.jsp
// 点击新增一行
function doAdd(){// 判断当前是否正在编辑 if(editIndex != undefined){$("#grid").datagrid('endEdit',editIndex); // 结束当前行编辑// 触发onAfterEdit 函数}// 判断当前已经没有编辑行if(editIndex==undefined){ // 在数据表格第一行 ,插入一个空行$("#grid").datagrid('insertRow',{index : 0,row : {}});// 打开第一行编辑状态$("#grid").datagrid('beginEdit',0);// 将编辑的行号,保存成员变量editIndex = 0;}
}

datagrid 行编辑,如果该行数据项不符合form的校验,无法执行 endEdit方法

在datagrid的每行结束编辑时,触发doAfterEdit 事件,在事件中提交ajax请求,提交结束编辑行数据给服务器端,完成数据保存

onAfterEdit : function(rowIndex, rowData, changes){editIndex = undefined; // 将当前正在编辑行 设置undefined
// 提交ajax请求,将编辑行数据,以ajax方式,发送到服务器,完成保   
$.post("${pageContext.request.contextPath}/workordermanage_saveOrUpdate.action",rowData , function(data){});
}

编写服务器代码

public class WorkOrderManageAction extends BaseAction implements ModelDriven<WorkOrderManage> {}
public interface WorkOrderManageService {}
public class WorkOrderManageServiceImpl extends BaseService implements WorkOrderManageService {}

将DAO 注入 BaseService
将Service 注入BaseAction

Action 处理ajax返回结果

配置struts.xml 拆分

<include file="struts-user.xml"></include>
<include file="struts-bc.xml"></include>
<include file="struts-qp.xml"></include>

在 struts-qp.xml 配置工作单

<!-- 工作单管理 -->
<action name="workordermanage_*" class="workOrderManageAction" method="{1}"><!-- 保存 --><result name="saveOrUpdateSUCCESS" type="json"><param name="root">map</param></result>
</action>

5.2. 工作单快速录入 分页列表查询

为datagrid 添加url

url :  "${pageContext.request.contextPath}/workordermanage_pageQuery.action",

在服务器 WorkOrderManageAction 添加 pageQuery 方法

<!-- 分页查询 -->
<result name="pageQuerySUCCESS" type="json"><param name="root">pageResponseBean</param><param name="includeProperties">total,rows\[\d+\]\.id,rows\[\d+\]\.arrivecity,rows\[\d+\]\.product,rows\[\d+\]\.num,rows\[\d+\]\.weight,rows\[\d+\]\.floadreqr</param>
</result>

5.3. 工作单搜索功能

对工作单使用 like模糊查询时,实际上 数据库内部索引无法使用 ,需要逐条比较查询内容,效率比较低
在数据量很多情况下, 提供模糊查询性能,使用lucene全文索引库技术
—- 最适合 场景 : 论坛和贴吧

Lucene检索原理, 会针对目标内容,先进行分词建立全文索引 ,在用户查找时,先查询索引库中词条,根据词条找到数据记录id ,再根据id 查找数据库记录 !

5.3.1. 在添加工作单,为工作单数据建立索引

直接引入框架 Hibernate Search (用来整合 Hibernate + Lucene)

HibernateSearch是在apacheLucene的基础上建立的主要用于Hibernate的持久化模型的全文检索工具。

1、 在项目导入jar包
导入 hibernate 的jar 、 导入 lucene的jar 、导入hibernate search的jar

dist 存放jar包
docs 文档

project 项目源码
hibernate-search-3.4.2.Final.jar : hibernate Search 核心jar包
hibernate-core-3.6.10.Final.jar : hibernate 核心jar包
lucene-core-3.1.0.jar : lucene核心jar包

使用maven坐标 导入 hibernate search

<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-search</artifactId><version>3.4.2.Final</version>
</dependency>

2、 导入 IK 分词器
将 IKAnalyzer2012_u6.jar 导入项目
将 IKAnalyzer.cfg.xml、stopword.dic 两个文件 复制 classpath

将jar复制到 项目src/main/webapp/WEB-INF/lib 下

<!-- 导入 IK分词器 -->
<dependency><groupId>ik</groupId><artifactId>ik</artifactId><version>1.0</version>      <systemPath>D:\work\sh_javaee20130731\mavenbos\src\main\webapp\WEB-INF\lib\IKAnalyzer2012_u6.jar</systemPath><scope>system</scope>
</dependency>

3、 配置hibernate search
在applicationContext-common.xml 中配置 索引库位置

<prop key="hibernate.search.default.indexBase">d:/index</prop>

在实体类上面使用注解配置对哪些数据建立索引(只支持注解)

自动完成索引库 创建、 更新、删除 !!!!

使用 Luke 工具,查询索引文件内容 !!

5.3.2. 结合lucene索引库完成模糊查找功能

使用 EasyUI 提供 searchbox 完成搜索框制作

<!--prompt 默认提示内容menu 搜索条件下拉选项 searcher 点击搜索按钮执行js函数名称-->
<input id="ss" class="easyui-searchbox" style="width:300px" data-options="prompt:'请输入您的查询内容',menu:'#mm',searcher:doSearch"/><div id="mm"><div data-options="name:'arrivecity'">按照到达地搜索</div><div data-options="name:'product'">按照货物名称搜索</div>
</div>// 搜索函数
function doSearch(value,name){
alert("搜索项:"+name + ", 搜索内容:" + value);
}

将搜索内容,提交给服务器

// 将查询条件 缓存到 datagrid
$('#grid').datagrid('load',{conditionName : name,conditionValue : value
});

修改 WorkOrderManageAction的 pageQuery 方法,结合条件查询

在GenericDAO 添加查询lucene索引库的方法

/*** 结合lucene索引库 进行分页查询* * @param conditionName* @param conditionValue* @param page* @param rows* @return*/
public PageResponseBean queryByLucene(String conditionName, String conditionValue, int page, int rows);

其它

课前资料

hibernate search使用

课后资料

课程视频内容

宅急送 项目第七天 取派业务模块相关推荐

  1. 宅急送 项目第四天 取派员和区域管理

    在第三天课程中,重点 Easy UI的 datagrid , UI框架自带数据表格插件 Datagrid : 主要功能显示,自带分页查询. 条件查询. 排序 EasyUI .ExtJs.Flex 通常 ...

  2. SSH综合项目实战(快递) -- day09 收派业务、客户在线下单

    一.取派业务 1.创建取派业务模块,导入实体类 package com.itheima.bos.domain.take_delivery;import java.util.Date; import j ...

  3. 宅急送项目的第七天笔记!(JBPM工作流)

    宅急送项目的第七天  三个主要功能模块: 基础设置. 取派业务.中转配送业务 基础设置: 标准管理.取派员管理.区域设置.分区设置.定区管理 取派业务: 业务受理.工作单快速录入(追单.销单). 工作 ...

  4. 宅急送项目第六天笔记!

    宅急送项目第六天  一. 回顾前5天 1. 项目前端 easyui  (为什么使用? 收费? ) .服务器SSH三大框架  2. 数据层 GenericDAO 抽取  3. 业务层 分页查询 制作为通 ...

  5. 宅急送项目第五天笔记!

    修复bug 1.RegionAction 添加区域时,条件书写错误 if(region.getId()==null || region.getId().equals("")){ } ...

  6. 宅急送项目的第九天笔记!( 角色--权限管理)

    项目进度 : 1. 用户管理 (设置密码.登陆. 用户增删改查) 2. 基础设置业务 (取派标准.取派员.区域表.分区表.定区排班) 3. 取派业务 (业务受理.工作单快速录入.工作单批量导入 ) - ...

  7. 宅急送项目的第七天笔记!(JBPM工作流和介绍 -- 权限管理模型)

    一.回顾第一天核心内容  1. JBPM是什么? 为我的项目带来什么?  工作流, 就是将业务流程实现自动化,非人工方式,控制任务的执行 -------- 所有业务流程 执行信息 都可以存放到数据库 ...

  8. 宅急送项目开发过程及问题?

    一. 需求和文档  1. 项目类型  OA : 办公自动化(Office Automation,简称OA)是将现代化办公和计算机网络功能结合起来的一种新型的办公方式  CRM : CRM(Custom ...

  9. 宅急送项目第三天笔记!(SVN插件和反编译插件)

    宅急送 第三天  * 第一天 SSH整合,项目中常见问题解决  * 第二天 easyui控件简单使用 .完整的用户管理模块 (登陆.设置密码.增删改查 ) 一.SVN的使用  需要服务器和客户端 两个 ...

最新文章

  1. IDEA新建一个多maven模块工程(有图)
  2. 零基础该如何学习Web前端知识?
  3. 希尔伯特著名的第六问题 – 原来麦克斯韦早就有解?
  4. iOSAPP配置多环境
  5. 架空输电线路运行规程_架空输电线路杆塔金具的种类
  6. C++ Templates 中的一个例子
  7. 基于JFinal框架开发的企业办公系统-JFinalOA v1.1源码
  8. windows linux mysql_linux/windows环境mysql数据库安装与使用
  9. 常见几种编码格式及比较
  10. 爱了爱了!从草根到百万年薪程序员的十年风雨之路,小白也能看明白
  11. API是什么意思,具体是什么?
  12. Boost编译一步步来
  13. 【python爬虫实战】 001 技术路线图
  14. 国内开源镜像网站汇总
  15. OOALV的基本实现步骤
  16. Spark Streaming控制每秒消费数据的速度
  17. ThreadLocalMap中为什么valu是强引用,不是弱引用
  18. 勤哲Excel服务器分类问题解答
  19. Generalized-ICP(GICP)論文研讀
  20. PyCharm报错:Please specify a different SDK name解决方法

热门文章

  1. 金蝶k3服务器老是自动重新启动,金蝶K3:常见问题分析及解决方法
  2. 试题 算法训练 一元三次方程求解---蓝桥杯
  3. 有状态软件如何在 k8s 上快速扩容甚至自动扩容
  4. Salesforce开发教程(上下)
  5. 【mmsegmentation】bug解决:Error: [Errno 95] Operation not supported: ‘epoch_1.pth‘ -> ‘lastest.pth‘
  6. js实现点击一键复制文本
  7. java判断是平年还是闰年
  8. 一维向量转换为n维向量_如何在N维上固定万向节锁
  9. html 修改下拉框样式,select下拉框option的样式修改
  10. Java项目:SSH校园报修管理系统