京淘后端商品管理-Day05

不羁岁月 提交于 2020-08-17 00:04:31

1.京淘后端业务实现(二)

1.1 商品删除

1.1.1 业务分析

说明:当用户点击删除按钮时,提交多个ID数据信息,之后删除后端服务器数据.
1).页面ajax请求
在这里插入图片描述

1.1.2 编辑ItemController

	/**
	 * 补充1:  SpringMVC框架 不熟!
	 * 页面中传递什么样的数据,后端才能接收什么样的数据.
	 * 要求1: name属性名称必须与参数名称一致.
	 * 要求2: name属性名称必须与属性名称一致
	 * 例子1: 
	 * 		页面信息  <input type="text" name="id"  value="100"  />
	 * 		页面信息  <input type="text" name="age"  value="19"  />
	 * 		页面信息  <input type="text" name="sex"  value="男"  />
	 * 
	 * 补充2: SpringMVC底层实现Servlet,数据传输协议https/http 一般传递的数据都是String结构.
	 * 案例:  页面信息  <input type="text" name="sex"  value="男"  />
	 *       页面信息  <input type="text" name="sex"  value="男"  />
	 *       页面信息  <input type="text" name="sex"  value="男"  />
	 *       如果遇到重名属性提交,则浏览器会自己解析将value进行拼接     sex="男,男,男"
	 *       
	 * springMVC优化: 
	 * 			1.可以自动的根据参数类型进行转化  string转化为具体类型
	 * 			2.如果遇到了重名属性提交,则会自动的转化为数组类型接收. 
	 * 
	 * url:/item/delete
	 * 参数: ids=id,id,id,id
	 * 返回值结果: SysResult对象
	 */
	@RequestMapping("/delete")
	public SysResult  deleteItems(Long[] ids) {
		
		itemService.deleteItems(ids);
		return SysResult.success();
	}

1.1.3 编辑ItemService

	//参数是数组类型 有多个
	@Override
	public void deleteItems(Long[] ids) {
		//将数组转化为集合类型
		List<Long> idList = Arrays.asList(ids);
		itemMapper.deleteBatchIds(idList);
		//或者自己写sql.
	}

1.2 商品上架/下架操作

1.2.1 业务需求说明

说明:商品上架/下架操作修改的是status属性,updated时间.
分析:
1. 下架操作 /item/instock status=2
2. 上架操作 /item/reshelf status=1


restFul优化:
1. 下架操作 /item/updateStatus/2
2. 上架操作 /item/updateStatus/1

1.2.2 修改url地址

优化后的代码

	$.messager.confirm('确认','确定下架ID为 '+ids+' 的商品吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/item/updateStatus/2",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','下架商品成功!',undefined,function(){
            					$("#itemList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});
        }

		$.messager.confirm('确认','确定上架ID为 '+ids+' 的商品吗?',function(r){
        	    if (r){
        	    	var params = {"ids":ids};
                	$.post("/item/updateStatus/1",params, function(data){
            			if(data.status == 200){
            				$.messager.alert('提示','上架商品成功!',undefined,function(){
            					$("#itemList").datagrid("reload");
            				});
            			}
            		});
        	    }
        	});

		

1.2.3 编辑ItemController

	/**
	 * url地址:   /item/updateStatus/2   /item/updateStatus/1
	 * 参数:  1.url中  2.ids
	 * 返回值:  SysResult对象
	 */
	@RequestMapping("/updateStatus/{status}")
	public SysResult updateItemStatus(Long[] ids,@PathVariable Integer status) {
		
		//实现商品状态修改
		itemService.updateItemStatus(ids,status);
		return SysResult.success();
	}

1.2.4 编辑ItemService

	/**
	 *  MP的更新操作  
	 *  1.entity  要修改的记录
	 *  2.updateWrapper   修改条件构造器
	 *  Sql: update tb_item set status=#{status},updated = #{updated}
	 *  	 where id in (id1,id2,id3.....);
	 *  单表操作 性能损耗可以忽略.
	 */
	@Override
	public void updateItemStatus(Long[] ids, Integer status) {
		//1.定义修改数据
		Item item = new Item();
		item.setStatus(status).setUpdated(new Date());
		//2.定义修改的条件
		List<Long> idList = Arrays.asList(ids);
		UpdateWrapper<Item> updateWrapper = new UpdateWrapper<>();
		updateWrapper.in("id", idList);
		itemMapper.update(item, updateWrapper);
	}

1.2.5 修改成功颜色

在这里插入图片描述

1.3 富文本编辑器介绍

1.3.1 富文本入门案例

核心理念: 所见即所得编辑效果
KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。

1.3.2 富文本页面JS

	<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="/js/kindeditor-4.1.10/themes/default/default.css" type="text/css" rel="stylesheet">
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/kindeditor-all-min.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/kindeditor-4.1.10/lang/zh_CN.js"></script>
<script type="text/javascript" charset="utf-8" src="/js/jquery-easyui-1.4.1/jquery.min.js"></script>

<script type="text/javascript">
	$(function(){
		KindEditor.ready(function(){
			KindEditor.create("#editor")
		})
	})
</script>
</head>
<body>
<h1>富文本编辑器</h1>
<textarea style="width:700px;height:350px" id="editor"></textarea>
</body>
</html>

1.4 商品详情业务说明

1.4.1 表设计

在这里插入图片描述

1.4.2 编辑ItemDesc POJO对象

	@TableName("tb_item_desc")
@Data
@Accessors(chain = true)
public class ItemDesc extends BasePojo{
	
	@TableId 	                //主键 
	private Long itemId;		//商品id号   itemId既是item表主键,也是itemDesc表的主键 值相同
	private String itemDesc;	//商品详情信息
	
}

1.4.3 编辑ItemDescMapper 接口

在这里插入图片描述

1.4.3 业务层Service注入Mapper接口

在这里插入图片描述

1.5 重构商品入库操作

1.5.1 业务介绍

实现2张表同时入库操作.
在这里插入图片描述

1.5.2 页面结构分析

说明:当用户点击商品提交时,会将2张表的数据通过/item/save的请求一起打包提交.
在这里插入图片描述

1.5.3 重构ItemController

		/**
	 * 商品新增操作
	 * url: /item/save
	 * 参数: form表单数据
	 * 返回值结果: SysResult对象
	 */
	@RequestMapping("/save")
	public SysResult saveItem(Item item,ItemDesc itemDesc) {
		
		//2张表同时入库
		itemService.saveItem(item,itemDesc);
		return SysResult.success();
	}

1.5.4 重构ItemService

		//控制数据库事务
	@Transactional
	@Override
	public void saveItem(Item item,ItemDesc itemDesc) {
		//1.商品入库
		item.setStatus(1)   //
			.setCreated(new Date())
			.setUpdated(item.getCreated());
		itemMapper.insert(item);
		//由于主键自增的原因,所以程序入库之后才会有主键信息.
		//MP提供业务支持实现数据自动的回显功能!!!!  入库操作之后,会将所有的数据库记录进行映射给对象
		//底层实现是Mybatis的主键自动回显功能
		
		//2.商品详情入库   item/itemDesc中的ID的值一致.
		itemDesc.setItemId(item.getId())
				.setCreated(item.getCreated())
				.setUpdated(item.getCreated());
		itemDescMapper.insert(itemDesc);
	}

1.5 商品详情回显

1.5.1 页面分析

1).url地址
在这里插入图片描述

2).页面JS

	// 加载商品描述
        			//_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);
        					//在指定的位置,显示页面html标记信息.
        					itemEditEditor.html(_data.data.itemDesc);
        				}
        			});

1.5.2 编辑ItemController

	/**
	 * 业务需求:  根据itemId查询商品详情信息
	 * url地址:  http://localhost:8091/item/query/item/desc/1474391972
	 * 参数:		使用restFul方式使用传输传递
	 * 返回值:    SysResult对象,并且需要携带itemDesc数据信息.
	 */
	@RequestMapping("/query/item/desc/{itemId}")
	public SysResult findItemDescById(@PathVariable Long itemId) {
		
		ItemDesc itemDesc = itemService.findItemDescById(itemId);
		return SysResult.success(itemDesc);
	}

1.5.3 编辑ItemService

	@Override
	public ItemDesc findItemDescById(Long itemId) {
		
		return itemDescMapper.selectById(itemId);
	}

1.5.4 页面效果展现

在这里插入图片描述

1.6 商品详情修改

1.6.1编辑ItemController

	/**
	 * 商品修改操作
	 * url: /item/update
	 * 参数: form表单数据
	 * 返回值结果: SysResult对象
	 */
	@RequestMapping("/update")
	public SysResult updateItem(Item item,ItemDesc itemDesc) {
		
		itemService.updateItem(item,itemDesc);
		return SysResult.success();
	}

1.6.2 编辑ItemService

	@Override
	@Transactional
	public void updateItem(Item item,ItemDesc itemDesc) {
		//1.更新商品信息
		item.setUpdated(new Date());
		itemMapper.updateById(item);
		
		//2.更新商品详情信息
		itemDesc.setItemId(item.getId())
				.setUpdated(item.getUpdated());
		itemDescMapper.updateById(itemDesc);
	}

1.7 商品关联删除

1.7.1编辑ItemService

说明:实现商品关联删除

	//参数是数组类型 有多个
	@Override
	@Transactional
	public void deleteItems(Long[] ids) {
		//1.删除商品信息
		//将数组转化为集合类型
		List<Long> idList = Arrays.asList(ids);
		itemMapper.deleteBatchIds(idList);
		
		//2.删除商品详情信息
		itemDescMapper.deleteBatchIds(idList);
	}

1.8 文件上传入门案例

1.8.1 入门测试网址

在这里插入图片描述

1.8.2 编辑页面html

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	<h1>实现文件长传</h1>
	<!--enctype="开启多媒体标签" 字节信息 -->
	<form action="http://localhost:8091/file" method="post" 
	enctype="multipart/form-data">
		<input name="fileImage" type="file" />
		<input type="submit" value="提交"/>
	</form>
</body>

</html>

1.8.3 编辑FileController

说明:编辑FileController使用SpringMVC框架的文件上传API.

	package com.jt.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

@RestController		//返回json数据
public class FileController {
	
	
	/**
	 * url地址: http://localhost:8091/file
	 * 参数:    File=fileImage
	 * 返回值:   字符串
	 * 
	 * 参数说明:MultipartFile 接口, 主要负责实现文件接收
	 * 常识: 
	 * 		1.必须指定文件上传的路径信息   D:\JT-SOFT\images\文件名称.jpg
	 * 		2.将字节信息利用outPutStream进行输出操作
	 * 
	 * 说明:文件上传默认大小1M=1024*1024   
	 * 具体参见CommonsFileUploadSupport类
	 * 
	 * @throws IOException 
	 * @throws IllegalStateException 
	 */
	@RequestMapping("/file")
	public String file(MultipartFile fileImage) throws IllegalStateException, IOException {
		//1.定义文件目录信息
		String dirPath = "D:/JT-SOFT/images";
		File  fileDir = new File(dirPath);
		
		//2.校验图片目录是否存在.
		if(!fileDir.exists()) {	//如果文件目录不存在,应该创建目录
			
			fileDir.mkdirs();   //创建多级目录
		}
		
		//3.获取文件信息. 一般都在上传提交的参数中     a.jpg
		String fileName = fileImage.getOriginalFilename();
		
		//4.实现文件上传. 指定文件真实路径
		File file = new File(dirPath+"/"+fileName);
		//5.利用api实现文件输出.
		fileImage.transferTo(file);
		
		return "恭喜你,文件上传成功!!!";
	}
}

1.9 文件上传业务实现

1.9.1 文件上传页面分析

1).页面url分析
在这里插入图片描述
2).参数提交
在这里插入图片描述
3).数据回传的格式要求
查阅富文本的API获取相关信息.




 {"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
 
 参数1.error: 正常错误0   ,上传有误1
 参数2: 图片的虚拟地址信息
 width/height 如果设定则使用用户的,如果不设定这使用默认的.  一般不用修改.

1.9.2 封装文件上传VO–ImageVO

	@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {
	private Integer error;	//错误信息   0正确    1错误
	private String  url;	//url地址
	private Integer width;	//宽度
	private Integer height;	//高度

	
	//1.封装失败的方法
	public static ImageVO fail() {
		
		return new ImageVO(1, null, null, null);
	}
	
	//2.封装成功的方法
	public static ImageVO success(String url) {
		
		return new ImageVO(0, url, null, null);
	}
	
	public static ImageVO success(String url,Integer width,Integer height) {
		
		return new ImageVO(0, url, width, height);
	}
	
}	

1.9.3 编辑FileController

	/**
	 * 业务分析:实现文件上传.
	 * 1.url地址: http://localhost:8091/pic/upload
	 * 2.参数:   uploadFile  文件上传对象
	 * 3.返回值:  ImageVO对象
	 */
	@RequestMapping("/pic/upload")
	public ImageVO uploadFile(MultipartFile uploadFile) {
		
		
		return fileService.uploadFile(uploadFile);
	}

1.9.4 编辑FileService

	package com.jt.service;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.jt.vo.ImageVO;

@Service
public class FileServiceImpl implements FileService {
	
	private String localDir = "D:/JT-SOFT/images";
	

	//bug:漏洞 一般没错  二般情况才会出错  传递特殊参数时报错     
	//error: 错误
	
	/**
	 * 1.如何校验上传的信息是图片??????
	 * 		通过后缀进行校验:  .jpg,.png,.gif........
	 * 2.如何保证检索速度更快 ????
	 * 		分目录存储		1).hash   2).时间
	 * 3.如何防止文件重名???
	 * 		重定义文件名称    uuid.jpg
	 */
	@Override
	public ImageVO uploadFile(MultipartFile uploadFile) {
		//1.校验上传的信息 是否为图片
		//1.1初始化图片类型集合
		Set<String>  typeSet = new HashSet<>();
		typeSet.add(".jpg");
		typeSet.add(".png");
		typeSet.add(".gif");
		
		//1.2动态获取用户上传的图片类型          abc.jpg|ABC.JPG
		String fileName = uploadFile.getOriginalFilename();
		fileName = fileName.toLowerCase();	//将所有的字符转化为小写.
		int index = fileName.lastIndexOf(".");
		//.jpg
		String fileType = fileName.substring(index);
		//1.2校验图片类型是否有效
		if(!typeSet.contains(fileType)) {
			//表示类型不属于图片信息  则终止程序
			return ImageVO.fail();
		}
		
		
		//2.准备文件上传的目录结构.   文件上传根目录+动态变化的目录    
		String dateDir = new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
		//D:/JT-SOFT/images/2020/7/10/
		String dirPath = localDir + dateDir;
		File dirFile = new File(dirPath);
		if(!dirFile.exists()) {
			
			dirFile.mkdirs();  //如果目录不存在则新建目录.
		}
		
		//3.重新指定文件名称
		String uuid = UUID.randomUUID().toString();
		String realFileName = uuid + fileType;
		
		//4.执行文件上传代码    目录+文件名称
		File imageFile = new File(dirPath+realFileName);
		try {
			uploadFile.transferTo(imageFile);
			String url = "https://img14.360buyimg.com/n0/jfs/t1/71310/32/5640/402976/5d3a654eE0489baf9/fd8eafe74ef8779c.jpg";
			return ImageVO.success(url);
		} catch (IllegalStateException | IOException e) {
			e.printStackTrace();
			return ImageVO.fail();
		}
	}
}

1.9.5 页面效果展现

在这里插入图片描述

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!