1.商品的CRUD操作
1.1关于JS的数据校验说明
1.1.1.必填项
<td><input class="easyui-textbox" type="text" name="title" data-options="required:true" style="width: 280px;"></input></td>
1.1.2价格校验
<input class="easyui-numberbox" type="text" name="priceView" data-options="min:1,max:99999999,precision:2,required:true" />
1.1.3长度校验
<input class="easyui-textbox" name="sellPoint" data-options="multiline:true,validType:'length[0,150]'" style="height:60px;width: 280px;">
1.1.4 价格的处理:
1.2完成商品入库
1.2.1页面分析
1.url地址
2.提交参数说明
1.2.2页面JS分析
$.post("/item/save",$("#itemAddForm").serialize(), function(data){
if(data.status == 200){
$.messager.alert('提示','新增商品成功!');
}else{
$.messager.alert("提示","新增商品失败!");
}
});
1.2.3系统级别的VO对象
说明:由于该VO对象是系统的全局的VO对象,所以放到jt-common中更好.
SysResult:
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
/**
* 该对象是系统返回值VO对象,主要包含3个属性
* 1.设定状态码 200表示执行成功 201执行失败 人为定义的(和浏览器没有关系)
* 2.定义返回值信息 服务器可能会给用户一些提示信息 例如 执行成功,用户名或密码错误等
* 3.定义返回值对象 服务器在后端处理完成业务之后,将对象返回给前端
* */
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult {
private Integer status;//200成功 201失败
private String msg;//服务器提示信息
private Object data;//服务器返回前端的业务数据
//准备工具API,方便用户使用
//用户关注点: 1.执行成功 2.执行失败
public static SysResult fail(){
return new SysResult(201,"业务调用失败",null);
}
//成功方式1:只返回状态码
public static SysResult success(){
return new SysResult(200,"业务调用成功",null);//只标识成功,不返回数据
}
//成功方式2:需要返回服务器数据
public static SysResult success(Object data){
return new SysResult(200,"业务调用成功",data);//标识成功并返回数据
}
//成功方式3:可能告知服务器信息及服务器数据
public static SysResult success(String msg,Object data){
return new SysResult(200,msg,data);
}
//bug: 将String当作响应数据,回传给客户端
//注意事项:在写工具API时,方法千万不要耦合
// public static SysResult success(String msg)和public static SysResult success(Object data)出现耦合
}
1.2.4编辑ItemController
/**
* 1.url地址: http://localhost:8091/item/save
* 2.请求参数: 整个form表单
* 3.返回值结果: SysResult对象
*
* 复习: 页面中的参数是如何通过SpringMVC为属性赋值???
* 分析: 页面参数提交 一般方式3种 1.form表单提交 2.ajax页面提交 3.a标签 参数提交
* 页面参数提交一般都会遵守协议规范 key=value
* 分析2: SpringMVC的底层实现servlet. 包含了2大请求对象 request对象/response对象
* servlet如何获取数据?????
* 规则: 参数提交的名称与mvc中接受参数的名称必须一致!!!!
*/
@RequestMapping("/save")
public SysResult saveItem(Item item){
//1.利用对象的get方法,获取对象的属性的信息
//item.getId()---->get去除------获取id的属性(大小写忽略);
//之后将获取到的值利用对象的set方法为属性赋值.
//request.getParameter("id")
try {
itemService.saveItem(item);
return SysResult.success();
}catch (Exception e){
e.printStackTrace();
return SysResult.fail();
}
}
1.2.5编辑ItemService
/**
* 1.url:http://localhost:8091/item/save
* 2.参数:整个form表单
* 3.返回值类型:SysResult对象
*复习:页面中的参数是如何通过SpringMVC为属性赋值的
* 分析:页面参数的提交:一般方式两种:1.form表单的提交 2.ajax页面提交 3.a标签 参数提交
* 页面参数提交一般都会遵守协议规范 key=value
* 分析2: SpringMVC的底层实现servlet,包含了两大请求对象request和response对象
* servlet如何获取对象????
* request.getParameter(xxxx)
* 规则:参数提交的名称与mvc中接收参数名称必须要一致
*
* * */
@Override
@Transactional
public void saveItem(Item item) {
//保证入库的时间一致
item.setStatus(1).setCreated(new Date()).setUpdated(item.getCreated());
itemMapper.insert(item);
}
1.3定义全局异常处理机制
1.3.1 编辑全局异常处理
package com.jt.aop;
import com.jt.vo.SysResult;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice //定义异常处理的通知. 只拦截Controller层抛出的异常. 并且返回值JSON串
public class SystemExceptionAOP {
@ExceptionHandler(RuntimeException.class)
public Object fail(Exception e){
//打印异常信息
e.printStackTrace();
return SysResult.fail();
}
}
1.3.2 全局异常处理引入简化代码
1.4商品的修改
1.4.1编辑按钮弹出框调用流程
1.工具栏
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.4.1 实现商品分类数据的回显
查看页面数据信息
console日志.
1.4.2实现商品分类数据回显
item-list.jsp
/*
实现商品分类信息数据的ajax回显
1.想办法获取商品分类的id
2.利用ajax请求获取商品分类的名称
3.在指定的位置显示分类名称
*/
var cid=data.cid;
$.get("/item/cat/queryItemName",{"itemCatId":cid},function(name){
$("input[name='cid']").prev("span").html(name);
// $("input[name='cid']").siblings("span").text(name);
});
$("input[name='cid']").prev("span").text(KindEditorUtil.findItemCatName(data.cid));
商品修改JS
商品修改的URL说明
请求url地址:
提交参数:
1.4.3编辑ItemController
/**
* 完成商品信息修改
* url:http://localhost:8091/item/update
* 参数: 整个商品表单
* 返回值: SysResult对象
*/
@RequestMapping("/update")
public SysResult updateItem(Item item){
itemService.updateItem(item);
return SysResult.success();
}
1.4.4编辑ItemService
@Override
@Transactional
public void updateItem(Item item) {
item.setUpdated(new Date());
//根据对象中不为null的元素充当set条件. 主键充当where条件.
itemMapper.updateById(item);
}
1.5 利用MP机制简化时间操作.
1.5.1编辑公共的pojo对象
1.5.2编辑自动赋值处理器
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@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.setInsertFieldValByName("updated",new Date(),metaObject);
}
}
1.6商品页面的删除操作
1.6.1 页面分析
2.页面参数
3.页面JS
1.6.2 编辑ItemController实现删除任务.
/**
* 业务需求: 完成商品删除操作
* url请求地址: /item/delete
* 参数: ids= id1,id2 串
* 返回值结果: SysResult对象
* SpringMVC知识点: 可以根据制定的类型动态的实现参数类型的转化.
* 如果字符串使用","号分隔,则可以使用数组的方式接参.
*/
@RequestMapping("/delete")
public SysResult deleteItems(Long[] ids){
itemService.deleteItems(ids);
return SysResult.success();
}
1.6.3 编辑ItemService
//1.利用MP方式完成.
//2.利用Sql方式动态拼接完成.
//利用批量执行的方式进行操作.
//sql: delete from tb_item where id in (id1,id2,id3...)
@Override
public void deleteItems(Long[] ids) {
//方式1:将数组转化为list集合
//List<Long> idList = Arrays.asList(ids);
//itemMapper.deleteBatchIds(idList);
//方式2:利用手写sql完成.
itemMapper.deleteItems(ids);
}
1.6.4 编辑ItemMapper接口和实现类
1.编辑Mapper
/**
* 问题:为什么Mybatis需要将参数封装为Map??????
* 答案:Mybatis 规定 一般的参数只能进行单值传参,不能多值传参.
* 但是有时业务需要必须进行多值传递.那么这时需要将多值,封装为单值.
* 为了解决多值传参的问题,则Mybatis提供了@Param注解,其作用将参数封装为Map集合.
*
* @Param("ids") Long[] ids 将参数封装为Map集合. 其中@Params中的ids当做key.参数当做value
*
* @param ids
*/
void deleteItems(Long[] ids);
2.编辑Mapper配置文件
<mapper namespace="com.jt.mapper.ItemMapper">
<!--完成商品的删除
void deleteItems(Long[] ids); 接口方法
sql: delete from tb_item where id in (id1,id2,id3...)
collection:
分类1: List集合 collection="list"
分类2: Array数组 collection="array"
分类3: Map集合 collection="map中的key" 规范
-->
<delete id="deleteItems">
delete from tb_item where id in (
<!--循环遍历数组,之后获取其中的数据,完成删除.-->
<foreach collection="array" item="id" separator=",">
#{id}
</foreach>
)
</delete>
</mapper>