1 定义系统返回值VO对象
1.1 业务说明
由于业务处理一般都会通过JSON串的形式告知客户端程序是否完成.所以一般情况下都会通过vo对象来返回回执信息,
一般情况下VO对象需要返回业务是否正确/业务处理信息/业务处理数据.
1.2 封装SysResultVO对象
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult implements Serializable {
private Integer status; //定义状态信息 200业务处理成功, 201业务处理失败.
private String msg; //服务器返回的提示信息.
private Object data; //服务器返回业务数据.
//封装一些静态API 简化用户调用过程.
public static SysResult fail(){
return new SysResult(201,"服务器调用失败",null);
}
public static SysResult success(){
return new SysResult(200, "业务执行成功!!!", null);
}
public static SysResult success(Object data){
return new SysResult(200, "业务执行成功!!!", data);
}
}
2 商品新增
2.1 页面URL分析
1).url请求地址
2).页面提交参数
3).页面AJAX展现形式
<a href="javascript:void(0)" class="easyui-linkbutton" onclick="submitForm()">提交</a>
// ajax参数提交方式1json方式 $.post("/xx/xx",{key:value,key2:value2},回调函数)
// ajax参数提交方式1json方式 $.post("/xx/xx",key=value&key2=value....,回调函数)
// jQuery中提供了函数serialize() 将整个表单的数据封装为key=value&key2=value2的形式..
//alert($("#itemAddForm").serialize());
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}else{
$.messager.alert("提示","新增商品失败!");
}
});
2.2 编辑ItemController
/**
* 业务需求: 完成商品入库操作,返回系统vo对象
* url1: /item/save
* 参数: 整个form表单
* 返回值: SysResult对象
*/
@RequestMapping("save")
public SysResult saveItem(Item item){
//全局异常的处理机制!!!!
try {
itemService.saveItem(item);
return SysResult.success();
}catch (Exception e){
e.printStackTrace();
return SysResult.fail();
}
}
2.3 编辑ItemService
@Transactional //控制事务
@Override
public void saveItem(Item item) {
//1.默认商品为上架状态
item.setStatus(1).setCreated(new Date()).setUpdated(new Date());
itemMapper.insert(item);
}
3 全局异常处理机制
3.1 作用
如果在每个方法中添加异常处理机制,则会导致整个代码的结构混乱.即使将来出现了异常,也不能很好的管理.所以需要一种统一的方式实现异常的处理.
该功能在Spring中利用AOP的方式实现.
3.2 创建全局异常处理
package com.jt.aop;
import com.jt.vo.SysResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice //作用: 标识我是一个通知方法,并且只拦截Controll层的异常.并且返回JSON.
public class SysResultException {
//需要定义一个全局的方法 返回指定的报错信息.
//ExceptionHandler 配置异常的类型,当遇到了某种异常时在执行该方法.
@ExceptionHandler(RuntimeException.class)
public Object exception(Exception e){
e.printStackTrace(); //日志记录/控制台输出. 让程序员知道哪里报错!!!
return SysResult.fail();
}
}
1 商品分类名称回显实现
1.1 需求分析
说明:需要将 商品类目 3 改为具体的名称. 如何实现?
实现步骤:
1.通过选择器动态的获取商品分类ID 3
2.发起Ajax请求,根据3获取商品分类的名称. 电子书.
3.在指定的位置完成赋值操作.`
1.2 页面工具栏说明
工具栏引入
data-options="singleSelect:false,fitColumns:true,collapsible:true,pagination:true,url:'/item/query',method:'get',pageSize:20,toolbar:toolbar">
工具栏实现:
var toolbar = [{
text:'新增',
iconCls:'icon-add',
handler:function(){
$(".tree-title:contains('新增商品')").parent().click();
}
},{
text:'编辑',
iconCls:'icon-edit',
handler:function(){
//获取用户选中的数据
var ids = getSelectionsIds();
if(ids.length == 0){
$.messager.alert('提示','必须选择一个商品才能编辑!');
return ;
}
if(ids.indexOf(',') > 0){
$.messager.alert('提示','只能选择一个商品!');
return ;
}
$("#itemEditWindow").window({
onLoad :function(){
//回显数据
var data = $("#itemList").datagrid("getSelections")[0];
data.priceView = KindEditorUtil.formatPrice(data.price);
$("#itemeEditForm").form("load",data);
// 加载商品描述
//_data = SysResult.ok(itemDesc)
$.getJSON('/item/query/item/desc/'+data.id,function(_data){
if(_data.status == 200){
//UM.getEditor('itemeEditDescEditor').setContent(_data.data.itemDesc, false);
itemEditEditor.html(_data.data.itemDesc);
}
});
//加载商品规格
$.getJSON('/item/param/item/query/'+data.id,function(_data){
if(_data && _data.status == 200 && _data.data && _data.data.paramData){
$("#itemeEditForm .params").show();
$("#itemeEditForm [name=itemParams]").val(_data.data.paramData);
$("#itemeEditForm [name=itemParamId]").val(_data.data.id);
//回显商品规格
var paramData = JSON.parse(_data.data.paramData);
var html = "<ul>";
for(var i in paramData){
var pd = paramData[i];
html+="<li><table>";
html+="<tr><td colspan=\"2\" class=\"group\">"+pd.group+"</td></tr>";
for(var j in pd.params){
var ps = pd.params[j];
html+="<tr><td class=\"param\"><span>"+ps.k+"</span>: </td><td><input autocomplete=\"off\" type=\"text\" value='"+ps.v+"'/></td></tr>";
}
html+="</li></table>";
}
html+= "</ul>";
$("#itemeEditForm .params td").eq(1).html(html);
}
});
KindEditorUtil.init({
"pics" : data.image,
"cid" : data.cid,
fun:function(node){
KindEditorUtil.changeItemParam(node, "itemeEditForm");
}
});
}
}).window("open");
}
},{
text:'删除',
iconCls:'icon-cancel',
handler:function(){
var ids = getSelectionsIds();
if(ids.length == 0){
$.messager.alert('提示','未选中商品!');
return ;
}
$.messager.confirm('确认','确定删除ID为 '+ids+' 的商品吗?',function(r){
if (r){
var params = {"ids":ids};
$.post("/item/delete",params, function(data){
if(data.status == 200){
$.messager.alert('提示','删除商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}else{
$.messager.alert("提示",data.msg);
}
});
}
});
}
},'-',{
text:'下架',
iconCls:'icon-remove',
handler:function(){
//获取选中的ID串中间使用","号分割
var ids = getSelectionsIds();
if(ids.length == 0){
$.messager.alert('提示','未选中商品!');
return ;
}
$.messager.confirm('确认','确定下架ID为 '+ids+' 的商品吗?',function(r){
if (r){
var params = {"ids":ids};
$.post("/item/instock",params, function(data){
if(data.status == 200){
$.messager.alert('提示','下架商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}
});
}
});
}
},{
text:'上架',
iconCls:'icon-remove',
handler:function(){
var ids = getSelectionsIds();
if(ids.length == 0){
$.messager.alert('提示','未选中商品!');
return ;
}
$.messager.confirm('确认','确定上架ID为 '+ids+' 的商品吗?',function(r){
if (r){
var params = {"ids":ids};
$.post("/item/reshelf",params, function(data){
if(data.status == 200){
$.messager.alert('提示','上架商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}
});
}
});
}
}];
1.3 实现页面数据回显
//1.通过data数据返回商品分类id
var cid = data.cid;
//alert("我是商品分类目录id:"+cid);
//2.发起ajax请求,注意请求参数问题 必须与方法接收一致
$.get("/item/cat/queryItemName",{"itemCatId":cid},function(data){
//alert("动态获取数据:"+data);
//3.将数据回显到指定位置.
//$("#itemeEditForm input[name='cid']").siblings("span").text(data);
$("#itemeEditForm input[name='cid']").prev().text(data);
});
1.4 页面效果展现
2 商品修改
2.1 页面分析
2.JS分析
2.2 编辑ItemController
说明:编辑item业务逻辑实现更新操作.
/**
* 业务说明: 商品修改操作
* url: /item/update
* 参数: 整个form表单
* 返回值: SysResult对象
*/
@RequestMapping("/update")
public SysResult updateItem(Item item){
itemService.updateItem(item);
return SysResult.success();
}
2.2 编辑ItemService
@Override
public void updateItem(Item item) {
//更新时需要修改更新时间!!!
item.setUpdated(new Date());
itemMapper.updateById(item);
}
3 序列化时间数据的填充
3.1 业务说明
由于表中需要记录用户的操作时间,所以在业务层,只要用户操作了表就需要添加如下的代码.导致编码繁琐.能否优化??
3.2 添加注解
//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
@TableField(fill = FieldFill.INSERT) //新增有效
private Date created;
@TableField(fill = FieldFill.INSERT_UPDATE) //新增和更新有效
private Date updated;
}
3.3 编辑配置类完成自动赋值操作
package com.jt.auto;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
//完成自动填充功能
@Component //将该对象交给spring容器管理
public class MyMetaObjectHandler implements MetaObjectHandler {
/**
* 在POJO中添加了 新增/更新的注解,但是必须在数据库的字段中完成赋值的操作.
* 所以.必须明确,新增/更新时操作的是哪个字段,及值是多少
* * * @param metaObject
*/
@Override
public void insertFill(MetaObject metaObject) {
this.setInsertFieldValByName("created", new Date(), metaObject);
this.setInsertFieldValByName("updated", new Date(), metaObject);
}
@Override
public void updateFill(MetaObject metaObject) {
this.setUpdateFieldValByName("updated", new Date(), metaObject);
}
}
3.4 代码优化
4 商品删除
4.1 页面分析
$.messager.confirm('确认','确定删除ID为 '+ids+' 的商品吗?',function(r){
if (r){
var params = {"ids":ids};
$.post("/item/delete",params, function(data){
if(data.status == 200){
$.messager.alert('提示','删除商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}else{
$.messager.alert("提示",data.msg);
}
});
}
});
4.2 编辑ItemController
/**
* 商品删除
* url: /item/delete
* 参数: {"ids":"100,101,102"} ids数据类型是字符串!!!
* 返回值: 系统返回值变量
*
* 注意事项: 取值与赋值操作的key必须相同!!!
*/
@RequestMapping("/delete")
public SysResult deleteItems(Long... ids){
itemService.deleteItems(ids);
return SysResult.success();
}
4.3 编辑ItemService
@Override
public void deleteItems(Long[] ids) {
//List<Long> longList = Arrays.asList(ids);
//itemMapper.deleteBatchIds(longList);
//2.手动完成批量删除的操作.... 5分钟
itemMapper.deleteItems(ids);
}
4.4 编辑ItemMapper
public interface ItemMapper extends BaseMapper<Item>{
@Select("select * from tb_item order by updated desc limit #{startIndex},#{rows}")
List<Item> findItemByPage(int startIndex, Integer rows);
//由于数组取值需要进行循环遍历 所以需要通过遍历标签实现
//Mybatis中规范,默认条件下可以进行单值传递 后端用任意的参数接收都可以.
//有时可能进行多值传递.会将多值封装为Map集合进行参数的传递
//旧版本时如果需要封装为单值,则必须添加Param
//新版本时可以自动的添加@Param,前提条件是多值传递.
void deleteItems(Long[] ids);
}
4.4 编辑ItemMapper.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jt.mapper.ItemMapper">
<!--删除Item数据信息
单值: 数组 collection="array"
单值: list集合 collection="list"
多值: 利用Param注解封装 collection="key".
-->
<delete id="deleteItems">
delete from tb_item where id in (
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</delete>
</mapper>
5 商品上架/下架操作
5.1 业务说明
说明: 当用户点击按钮时,需要将其中的状态信息改为对应的值.
5.2 上架/下架URL地址说明
任务: 利用一个方法实现商品的上架/下架操作!!!
原始JS:
$.post("/item/instock",params, function(data){
if(data.status == 200){
$.messager.alert('提示','下架商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}
});
优化后的JS:
$.post("/item/updateStatus/2",params, function(data){
if(data.status == 200){
$.messager.alert('提示','下架商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}
});
5.3 编辑ItemController
/**
* 需求: 利用一个方法实现商品上架/下架操作 restFul风格实现
* url1:/item/updateStatus/2 status=2
* url2:/item/updateStatus/1 status=1
*/
@RequestMapping("/updateStatus/{status}")
public SysResult updateStatus(@PathVariable Integer status,Long... ids){
itemService.updateStatus(status,ids);
return SysResult.success();
}
5.4 编辑ItemService
/**
* update(arg1,arg2)
* arg1: 需要修改的数据
* arg2: 修改的条件构造器
* @param status
* @param ids
*/
@Override
public void updateStatus(Integer status, Long[] ids) {
Item item = new Item();
item.setStatus(status);
UpdateWrapper<Item> updateWrapper = new UpdateWrapper<>();
List<Long> idList = Arrays.asList(ids);
updateWrapper.in("id",idList);
itemMapper.update(item,updateWrapper);
}