SSH框架就是Spring + Struts + Hibernate
话不多说先上图,业务需求就是这个样子
手动撸了个前端页面,能用就行,UI请勿吐槽
实现效果:
首先点击look up查到MySQL数据库里的数据,这里有个小知识点,**
最右边的修改状态框下面是动态生成一个可以修改的订单状态的下拉框,并且只能往该订单状态前面修改,不能往后修改
**(意思就是出了状况可以更改,但不能还没做就直接修改到后面的状态去!!!)
然后点击修改状态下拉框,选择你要修改的状态
点击提交,确认后传给后台,修改成功后前台提示修改成功
前端js显示修改成功,那么我们看看到底修改成功了没呢,来 一起看看数据库:
再次在前台look up(查询)一次试试到底有没有改:
上面保存本次记录是保存的cn值,后来需求改变,要求保存状态的key值,因此用英文保存,这个功能到此可以说是完成了,整个需求就是这样子,我们来试试要怎么做,做到这个效果吧_
先讲讲实现此功能的一些技术和工具:
eclipse(初来乍到,没有安装idea,贼不习惯,写完这个需求就装它个idea)+ MySQL8.0 + tomcat 9.0++Sqlyog可视化工具+ SSH框架(有点老的框架了,项目历史遗留问题就不多说了) + jQuery + Ajax +Json + 前端三件套(H5,JS,CSS)
首先,当然是先撸一个前台界面了,由于这个小功能是楼主本人全部操刀的,因此前台就直接简单粗暴的用jsp撸了一套界面
首先我先用一个table显示这些表头,然后再声明一个table来存jQuery post收到后台下发的数据动态显示到界面上,在同一个表里会将表头遮掉(本人前端太扣脚了),只能想出此拙计,你们仔细看会发现上面的界面上明显上下分层,不是一张表。。。
第三张table用来显示下面要输入的原因,感觉一张表能做的事硬是被我搞成三张表,写到这里我自己都有点羞愧了。。。
接下来这个是前端的look up搜索订单操作的onclick事件,和提交操作的onclick事件,这个事件在下面的jQuery function中调用
第一个功能:
搜索,jQuery实现,接收后台下发的json值,添加到对应的表格中去:这里贴上源码:
function searchByReportNumber(){
console.log('click');
var reportNo = document.querySelector("#reportNo").value;
var url = "FIUpdateOrderState.action?reportNo=" + reportNo;
if(reportNo=="")
{
alert("不能为空哦!请输入报告号^_^");
return false;
}
$.post(url, function(json) {
console.log(json);
console.log('operation',json.data.operation.length)
$("#searchResult tr").remove(); //删除首行,每次都是显示当前订单信息
var operationItem = json.data.operation;
var str = '';
$.each(operationItem, function (i, item) {
str +="<option value="+i+">"+item.text.cn+"</option>"});
var search ='<td style="width: 16%;">' + json.data.poNo + '</td><td style="width: 18%;">' + json.data.reportNo + '</td><td style="width: 20%;">' + json.data.productName + '</td>'
+ '<td style="width: 20%;">' + json.data.color + '</td><td style="width: 13%;">' + json.data.state.text.cn + '</td>'
+'<td style="width: 13%;"align="center">'
+'<select id="selection" style="background: #EDEDED;border-radius:1px;padding:1px;height: 29px;width:auto;">'
+'<option>Please select</option>'+ str +'</select>'
+'</td>';
$('#searchResult').append('<tbody><tr align="center">'+ search +'</tr></tbody>');
var searchdata = json.data
if(searchdata.reportNo==""){
alert("Check carefully~,请输入正确的报告号并确认solr是否启动 ^_^");
return false;
}
jsonString = JSON.stringify(json); // 将post请求获取到的json数据转成字符串
return jsonString; //传给下面的function使用
}, "json");
}
采用的拼接字符串的方法,将接收到的json中data对应的value添加到表格中,json数据如下图:
接下来说一下,后台怎么实现在文本框输入报告号,也就是reportNo后,查到这一单的订单信息的
首先创建一个action控制类-FIUpdateOrderState.java
然后在struts2配置文件里配置响应成功后下发的跳转路径,如:
注意这里成功跳转到json…jsp界面然后下发数据
结合这个look up搜索按钮的响应事件跳转:
由此当点击查询时,直接跳转到后台action中对应的类FIUpdateOrderState.java
然后FIUpdateOrderState.java中用request.getParameter(“reportNo”)方法得到前台传来的reportNo值
然后到这里就很简单了,我们可以写sql直接一个查询语句查询数据库里得到这个订单的你想要获得的信息,我们这里只需要五个信息,(PO号,报告号,产品名称,颜色,订单状态)
select poNo,reportNo,productName,color,state from orderItem where reportNo = ?reportNo;
我这里采用的方法是使用企业级搜索引擎 solr,这个东西很好用,但是又不太好用,看项目的大小,当业务达到一定的量级,且数据量越来越大时,这时候solr的好处就很明显了,它对复杂关联数据的搜索很快,比用sql语句要好用很多,但数据量的时候就没什么必要了,用sql语句查询也很快
不清楚的小伙伴找度娘–>什么是solr
代码实现:
String reportId = request.getParameter("reportNo"); //获取前端输入的报告号
String reportNo = null;
System.out.println(reportId);
if (reportId != null && !reportId.equals("")) {
reportNo = reportId.trim();
}
List<FITaskBean> tasks = new ArrayList<>(); //solr查询订单是否存在
String searchType=CommonConstant.SOLR_SEARCH_TYPE_WEB;
if(reportNo!=null){
List<SolrSearchInfo> searchList = new ArrayList<>();
List<Object> searchIndexList = new ArrayList<>();
searchIndexList.add((String)reportNo);
SolrSearchInfo info = new SolrSearchInfo("reportNumber", false, searchIndexList);
searchList.add(info);
tasks = SearchSvc.search(searchList, searchType, 1, 10);
}
if(tasks == null) { //搜索不到
Log.syslog(TAG, "error tasks.size() is don't exit.");
ResultInfo.toJson(requestAttribute, ProtocolConstant.CODE_FAIL, "There is an error tasks.size() is null",
null);
return ActionResult.FAILED;
}
if (tasks != null && tasks.size() > 1) { // 报告号搜索结果不止一条,返回报错
Log.syslog(TAG, "error tasks.size() is more then one");
ResultInfo.toJson(requestAttribute, ProtocolConstant.CODE_FAIL, "There is an error tasks.size() is more then one",
null);
return ActionResult.FAILED;
}
然后我们获得了要修改状态的这一条订单信息,接着我们要下发数据给前台了,怎么下发呢?创建一个info类–FIUpdateOrderStateInfo.java,用来封装数据
package com.icefire.life.json;
import java.util.ArrayList;
import java.util.List;
import com.daren.fabricinspect.service.protocol.members.MenuItem;
public class FIUpdateOrderStateInfo {
private String taskId;
private String poNo=""; //订单PO号
private String reportNo=""; //订单报告号
private String productName=""; //订单产品名称
private String color=""; //订单颜色
private MenuItem state=new MenuItem(); //查询订单的状态
private MenuItem changeState=new MenuItem(); //修改后的状态
private List<MenuItem> operation=new ArrayList<>(); //要进行的操作
private String reason=""; //修改原因
public String getPoNo() {
return poNo;
}
public void setPoNo(String poNo) {
this.poNo = poNo;
}
public String getReportNo() {
return reportNo;
}
public void setReportNo(String reportNo) {
this.reportNo = reportNo;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public MenuItem getState() {
return state;
}
public void setState(MenuItem state) {
this.state = state;
}
public MenuItem getChangeState() {
return changeState;
}
public void setChangeState(MenuItem changeState) {
this.changeState = changeState;
}
public List<MenuItem> getOperation() {
return operation;
}
public void setOperation(List<MenuItem> operation) {
this.operation = operation;
}
public String getReason() {
return reason;
}
public void setReason(String reason) {
this.reason = reason;
}
public String getTaskId() {
return taskId;
}
public void setTaskId(String taskId) {
this.taskId = taskId;
}
}
然后紧接着上面action类里面,创建一个info对象set数据
FIUpdateOrderStateInfo fiupdateOrderState = new FIUpdateOrderStateInfo();
然后得到要修改的订单,赋值完数据后,返回SUCCESS,然后根据struts里的配置跳转到前台jsp界面
FIUpdateOrderStateInfo fiupdateOrderState = new FIUpdateOrderStateInfo();
if(tasks != null && tasks.size()==1){
FITaskBean task = tasks.get(0); //获得要修改的订单
if(task==null){
Log.syslog(TAG, "search result is null");
ResultInfo.toJson(requestAttribute, ProtocolConstant.CODE_FAIL, "search result is null", null);
return ActionResult.FAILED;
}
try{ //利用fiupdateOrderState对象下发数据给前台
fiupdateOrderState.setTaskId(task.getId().toString());
fiupdateOrderState.setPoNo(task.getPoNumber());
fiupdateOrderState.setReportNo(task.getReportNumber());
fiupdateOrderState.setProductName(task.getProductName());
fiupdateOrderState.setColor(task.getColor());
fiupdateOrderState.setState(FITaskStateOperationSvc.inst().getRoleStateStepNameMenuItem(task.getState(), fu.getCurrentRole()));
fiupdateOrderState.setOperation(FITaskStateOperationSvc.inst().getRoleTaskStateListMenuItem(task.getState(), fu.getCurrentRole()));
}catch(Exception e){
Log.syslog(TAG, "search result is wrong");
ResultInfo.toJson(requestAttribute, ProtocolConstant.CODE_FAIL, "search result is wrong", null);
return ActionResult.FAILED;
}
}
ResultInfo.toJson(requestAttribute, ProtocolConstant.CODE_SUCCESS, "success", fiupdateOrderState);
return ActionResult.SUCCESS;
}
}
跳转到此界面,封装好的json方法
前台用jquery接收,上面有传源码:仔细看 拼接字符串接收,这里还有个小细节忘记说了,我们还要动态接收operation操作,并下发一个map数据结构的集合传给下拉框,然后下拉框可以动态生成:
然后点击选中的状态,填好备注,点击提交,则struts 拦截器拦截请求,根据配置跳转到对应的FIForceUpdateState.action
这个类做的操作基本上就是将提交上来的json数据转成GSON接收,然后取得报告号,load solr中的数据,找到后,确认权限是管理人员权限,然后将传上来的要修改的状态
替换掉之前的状态,至此完成,修改状态操作。
JSON:前后端联调开发:
定完数据结构,也就是json接口数据:
对着json接口数据进行后台单线开发
一个json对象就要新增一个类,把所有结构给包起来