京淘实训Day08-京淘后台项目维护

1.利用MP的方式实现分页

1.1编辑ItemService实现分页操作

@Service
public class ItemServiceImpl implements ItemService {
	
	@Autowired
	private ItemMapper itemMapper;

	/**
	 *编辑代码技巧: 记忆部分关键字,之后根据方法提示,完成任务.
	 * 说明:利用MP的方式实现分页操作
	 * 
	 */
	@Override
	public EasyUITable findItemByPage(Integer current, Integer size) {
		
		//1.定义Page 简单分页对象
		Page<Item> page = new Page<>(current, size);
		//2.按照updated 降序排列
		OrderItem orderItem = new OrderItem();
		orderItem.setColumn("updated")
				 .setAsc(false);
		page.addOrder(orderItem);
		//3.执行分页查询操作
		IPage<Item> iPage = itemMapper.selectPage(page,null);
		//4.封装返回值	long-->int
		return new EasyUITable((int)iPage.getTotal(), iPage.getRecords());
	}
		}

1.2引入MP的分页插件

package com.jt.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize;

@Configuration //标识我是一个配置类  早期通过xml配置文件的方式进行整合,SpringBoot之后用配置类代替xml
public class MPConfig {
	
	//如果需要使用MP的分页机制.则需要配置分页插件即可
	//将分页插件交给Spring容器管理
	@Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

1.3分页效果

在这里插入图片描述

2 展现商品分类目录信息

2.1 问题分析

说明: 叶子类目其实就是商品的分类信息.要求根据商品分类ID信息,查询商品分类的名称
在这里插入图片描述

2.2 业务接口说明

  1. 业务需求: 根据商品分类ID值965,其实需要根据965的ID的值查询商品分类名称. 发起ajax请求获取商品名称.
  2. 页面url请求地址: http://localhost:8091/item/cat/queryItemName
  3. url请求参数: itemCatId: 965
  4. 返回值结果: 要求返回商品分类的名称

2.3编辑ItemCat POJO对象

说明:在jt-common的pojo包中添加ItemCat对象.

//该POJO对象是商品分类信息
@TableName("tb_item_cat")	//标识对象与表关系
@Data
@Accessors(chain=true)
//@NoArgsConstructor
//@AllArgsConstructor
public class ItemCat extends BasePojo{
	
	@TableId(type=IdType.AUTO)
	private Long id;			//主键标识
	private Long parentId;		//定义父级分类id
	private String name;		//商品分类名称
	private Integer status;		//商品分类状态
	private Integer sortOrder;	//商品分类排序号
	private Boolean isParent;	//是否为父级.
	
}

2.4编辑ItemCatController

package com.jt.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.jt.pojo.ItemCat;
import com.jt.service.ItemCatService;
import com.jt.service.ItemService;

//一般要求返回的数据都是JSON
@RestController
@RequestMapping("/item/cat")
public class ItemCatController {
	
	//编码规范: 1.POJO  2.mapper  3.service  4.controller
	
	@Autowired
	private ItemCatService itemCatService;
	/**
	 *  1. 业务需求: 根据商品分类ID值965,其实需要根据965的ID的值查询商品分类名称. 发起ajax请求获取商品名称.
 		2. 页面url请求地址: http://localhost:8091/item/cat/queryItemName
 		3. url请求参数:  itemCatId: 965
 		4. 返回值结果:   要求返回商品分类的名称
	 */
	@RequestMapping("/queryItemName")
	public String findItemCatNameById(Long itemCatId) {
		
		//1.根据id查询商品分类对象信息
		ItemCat itemCat = itemCatService.findItemCatById(itemCatId);
		//2.从对象中获取name属性
		return itemCat.getName();	
	}
}

2.5编辑ItemCatService

package com.jt.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.jt.mapper.ItemCatMapper;
import com.jt.pojo.ItemCat;

@Service
public class ItemCatServiceImpl implements ItemCatService {
	
	@Autowired
	private ItemCatMapper itemCatMapper;

	//根据Id查询商品分类信息
	@Override
	public ItemCat findItemCatById(Long itemCatId) {
		
		return itemCatMapper.selectById(itemCatId);
	}

}

2.6页面效果展现

在这里插入图片描述

3.商品分类目录页面结构

3.1EasyUI中弹出框效果

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EasyUI-3-菜单按钮</title>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css"
	href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<link rel="stylesheet" type="text/css"
	href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<script type="text/javascript">
	//让页面加载完成
	$(function(){
		
		//1.利用jQuery动态获取input中的参数   
		//步骤:   1.利用选择器选中数据    2.利用函数获取数据
		//1.选择器的类型         1.id选择器  #号   2.元素选择器  标签信息    3.类选择器  .
		var value = $("#input1").val();	//根据元素,获取里边的值
		//alert(value);
		//2.修改input中的数据
		$("#input1").val("我是修改后的数据"); //准确的定位元素信息
		
		var num = $("input").length;	//获取标签的个数
		//alert("input标签一共有:"+num);
		
		//3.类选择器
		var value2 = $(".myClass").val();
		//alert("通过class选择器获取数据:"+value2);
		
		
		
		//为btn1添加点击事件,function(){点击完成之后,程序执行的动作}
		$("#btn1").bind("click",function(){
			
			//.windows效果是JS插件EasyUI工具动态提供的.
			$("#win1").window({
				title:"弹出框",
				width:400,
				height:400,
				modal:false   //这是一个模式窗口,只能点击弹出框,不允许点击别处
			})
		})
		
		$("#btn3").click(function(){
			alert("关闭");
			$("#win2").window("close");
		});
		
		/*定义退出消息框  */
		$("#btn4").click(function(){
			//消息提示框架
			$.messager.confirm('abc','你确定要退出吗',function(r){ 
					if (r){ 
						alert("确认退出");
					} else{
						alert("哦!   原来你点错了!!!  下次手不要欠!!!!!")
					}
				});
		})
		
		/*定义消息提示框  */
		$.messager.show({  	
			  title:'My Title',  	
			  msg:'郑哥你都胖成一个球了,圆的',  	
			  timeout:5000,
			  height:200,
			  width:300,
			  showType:'slide'  
			}); 
	})
</script>
</head>
<body>
	用户姓名: <input class="myClass"  type="text" id="input1"  name="input1" value="我是input标签,文本内容"/>
	<h1>Easy-弹出窗口</h1>
	
	
	<!--主要展现弹出框  -->
	<a id="btn1" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-add'">搜索</a>
	<div id="win1"></div>
	
	<!--定义弹出窗口  -->
	<div id="win2" class="easyui-window" title="My Window" style="width:600px;height:400px" data-options="iconCls:'icon-save',modal:true"> 
		我是一个窗口
		<a id="btn3" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-back'">关闭</a>
	</div>
	<div style="float: right">
		<a id="btn4" href="#" class="easyui-linkbutton" data-options="iconCls:'icon-cancel'">退出系统</a>
	</div>

</body>
</html>

3.2EasyUI树形结构

说明:商品分类信息,包含父子级关系. 一般的商品分类结构分为3级菜单 在这里插入图片描述
2).EasyUI中树形结构展现

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>EasyUI-3-菜单按钮</title>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/jquery.easyui.min.js"></script>
<script type="text/javascript"
	src="/js/jquery-easyui-1.4.1/locale/easyui-lang-zh_CN.js"></script>
<link rel="stylesheet" type="text/css"
	href="/js/jquery-easyui-1.4.1/themes/icon.css" />
<link rel="stylesheet" type="text/css"
	href="/js/jquery-easyui-1.4.1/themes/default/easyui.css" />
<script type="text/javascript">
	/*通过js创建树形结构 */
	$(function(){
		
		//.tree EasyUI中提供的函数
		$("#tree").tree({
			url:"tree.json",		//加载远程JSON数据
			method:"get",			//请求方式  get/post
			animate:false,			//表示显示折叠端口动画效果
			checkbox:true,			//表述复选框
			lines:true,				//表示显示连接线
			dnd:true,				//是否拖拽
			onClick:function(node){	//添加点击事件
				alert("用户点击了节点")
				//控制台
				console.info(node);
			}
		});
	})
</script>
</head>
	<body>
		<h1>EasyUI-树形结构</h1>
		
		<ul id="tree"></ul>
	</body>
</html>

在这里插入图片描述

3).EasyUI中树形结构的JSON规则
说明:根据树形结构的规范 如果需要展现树形结构,格式如下

[{"id":"节点编号"  ,"text":"节点名称","state":"closed/open"}]

结论:如果需要展现树形结构,则需要配置三个属性 分别为id/text/state属性.
如果需要展现样式,则必须按照特定的规则编辑.

3.3封装树形结构的VO对象 EasyUITree

说明:按照格式要求,封装树形结构返回值VO对象

package com.jt.vo;

import java.util.List;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
//树形结构的格式要求.
@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
public class EasyUITree {
	
	private Long id;
	private String text;	//文本信息
	private String state;	//节点状态 open/closed
	
}

3.4商品分类信息获取的接口API

业务说明: 当用户点击商品分类按钮时,会进行弹出框操作.并且在弹出框中以树形结构的形式,展现商品分类信息.
url地址: http://localhost:8091/item/cat/list
参数: 初始化时没有参数,但是当展现子节点时,会传递id.
返回值: 返回list集合对象
详细说明:
1). 利用树形结构展现的是商品分类信息.但是树形结构要求返回的数据是EasyUITree VO对象.但是数据库中只有itemCat数据库对象信息.
2).发现返回值VO与数据库对象信息不一致,则需要程序员手动的实现对象数据的转化.
3).用户默认的条件下,只展现一级商品分类信息, 当用户点击某个一级商品分类信息时,才会展现具体的二级商品分类信息.
4).如果成功展现了1级商品分类信息,当通过一级展现二级信息时,会传递当前一级信息的ID.当作参数,发往服务器获取数据.
在这里插入图片描述

3.5商品分类信息查询结构

说明:商品分类信息,包含3级分类,通过1级查询二级信息.同理通过2级id查询3级的信息.

/*一级*/
SELECT * FROM tb_item_cat WHERE parent_id = 0
/*二级*/
SELECT * FROM tb_item_cat WHERE parent_id = 558
/*三级*/
SELECT * FROM tb_item_cat WHERE parent_id = 559

3.6编辑ItemCatController

/**
	 * url:http://localhost:8091/item/cat/list 
	 *   参数: 当展现二三级信息时,会传递父级的Id信息,如果展现1级菜单,则应该设定默认值
	 *   返回值: List<EasyUITree>
	 */
	@RequestMapping("list")
	public List<EasyUITree> findItemCatList
	(@RequestParam(name="id",defaultValue="0")Long parentId){
		
		//1.查询一级商品分类信息,所以
		return itemCatService.findItemCatList(parentId);
	}

3.7编辑ItemCatService

//目的为了简化代码的耦合性.每个方法都应该完成自己独立的任务
	public List<ItemCat> findItemCatListByParentId(Long parentId){
		
		QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<ItemCat>();
		queryWrapper.eq("parent_id", parentId);
		return itemCatMapper.selectList(queryWrapper);
	}
	
	@Override
	public List<EasyUITree> findItemCatList(Long parentId) {
		//1.先获取所有的一级商品分类信息.
		List<ItemCat> itemCatList = findItemCatListByParentId(parentId);
		//2.将CartList转化为VOlist
		List<EasyUITree> treeList = new ArrayList<>(itemCatList.size());
		for (ItemCat itemCat : itemCatList) {
			Long id = itemCat.getId();
			String text = itemCat.getName();
			//如果是父级则默认关闭,如果是子级则默认打开.
			String state = itemCat.getIsParent()?"closed":"open";
			EasyUITree easyUITree = new EasyUITree(id, text, state);
			treeList.add(easyUITree);
		}
		return treeList;
	}

3.8页面效果展现

在这里插入图片描述

3.9EasyUI中树形结构控件说明

树控件读取URL。子节点的加载依赖于父节点的状态。当展开一个封闭的节点,如果节点没有加载子节点,它将会把节点id的值作为http请求参数并命名为’id’,通过URL发送到服务器上面检索子节点。

4. 商品新增操作

4.1 商品新增url分析

在这里插入图片描述

4.2 商品新增参数分析

在这里插入图片描述

4.3 Item对象分析

在这里插入图片描述

4.4 商品新增的Ajax请求

/*
			ajax中的参数提交一般分为2种形式:
				1.json格式      {"id":"1","name":"tomcat猫"}
				2.参数拼接        id=1&name="tomcat猫"

			jQuery专门专对form表单提交指定的函数.serialize(),
			作用:将整个form表单提交时,进行参数的拼接.
		  */
		$.post("/item/save",$("#itemAddForm").serialize(), function(data){
			//当程序执行成功之后,要执行回调函数.
			if(data.status == 200){
				$.messager.alert('提示','新增商品成功!');
			}else{
				$.messager.alert("提示","新增商品失败!");
			}
		});

4.5 封装系统返回值的VO对象

说明:在做业务操作时,定义系统级别的VO对象,当用户完成CURD操作之后.需要返回系统变量.
要素说明:
1.告知用户是否操作正确 判断依据
2.返回系统的提示信息
3.利用公共API封装服务器返回值数据

@Data
@Accessors(chain=true)
@NoArgsConstructor
@AllArgsConstructor
public class SysResult {
	
	private Integer status;		//200 表示成功 201表示失败. 
	private String  msg;		//服务器返回客户端消息
	private Object  data;		//服务器返回客户端数据
	
	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);
	}
	
	public static SysResult success(String msg,Object data) {
		
		return new SysResult(200, msg, data);
	}
}

4.6 编辑ItemController

说明:编辑itemController实现商品新增操作

/**
	 *  url地址: http://localhost:8091/item/save
	 *     参数: 整合form表单提交   item对象接收参数
	 *     返回值: 系统返回值  SysResult对象
	 */
	@RequestMapping("/save")
	public SysResult saveItem(Item item) {
		
		itemService.saveItem(item);
		return SysResult.success(); //用户入库成功!!!!
	}

4.7 编辑ItemService

说明:编辑itemService实现商品新增操作

@Override
	@Transactional	//控制数据库事务  sql插入数据库 代码报错了!!   同时成功/失败
	public void saveItem(Item item) {
		
		item.setCreated(new Date())
			.setUpdated(item.getCreated()); //保证用户入库时间一致
		itemMapper.insert(item);
	}

4.8 全局异常的处理机制

说明: 程序执行过程中,可能会出现异常报错信息.如果在代码中频繁的使用try-catch这样的结构则必然导致代码的结构混乱.所以需要全局异常的处理机制.
原理说明: 全局异常处理机制,是Spring利用AOP(面向切面编程)技术,利用了异常通知,实现该功能.

4.8.1 定义全局异常处理

说明:由于异常处理机制的维护是全局的,所有代码应该写到jt-common中.

//1.标识该类是一个全局异常处理机制
@RestControllerAdvice	//通知
public class SystemExcAOP {

	//该异常处理机制,只对controller抛出的异常有效.
	//爸爸(亿万富翁)  ----自己(富二代)--------儿子(富三代)  亿解决
	
	//只有程序抛出运行时异常时,才会被全局异常处理机制捕获.
	//专业的开发人员:职业操守   自己必须处理的异常称之为检查异常.
	//如果自己不想处理,则将检查异常转化为运行时异常即可.
	@ExceptionHandler(RuntimeException.class)
	public SysResult systeResult() {
		
		return SysResult.fail();
	}
}

作业

1.重新完成 商品列表展现 /商品分类信息回显/商品分类树形结构展现. 必做内容
2.预习 商品修改/删除/上架/下架操作
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_16804847/article/details/106800953
今日推荐