1、回顾昨天
1.2上架下架代码(优化)
说明:商品上架/下架操作修改的是status属性,updated时间.
分析:
- 下架操作 /item/instock status=2
- 上架操作 /item/reshelf status=1
restFul优化:
- 下架操作 /item/updateStatus/2
- 上架操作 /item/updateStatus/1
{
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/updatestatus/2",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/updatestatus/1",params, function(data){
if(data.status == 200){
$.messager.alert('提示','上架商品成功!',undefined,function(){
$("#itemList").datagrid("reload");
});
}
});
}
});
}
}
1.2编辑ItemController
@RequestMapping("/updatestatus/{status}") //合并1
public SysResult updatestatus(Long[] ids,@PathVariable Integer status) {
itemService.updatestatus(ids,status);
return SysResult.success();
}
1.3编辑ItemServiceImpl
/**
/**
* MP的更新操作
* 1.entity 要修改的记录
* 2.updateWrapper 要修改条件构造器
*/
@Override
@Transactional //控制数据库事务
public void updatestatus(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.4修改状态字体颜色
formatItemStatus : function formatStatus(val,row){
if (val == 1){
return '正常';
} else if(val == 2){
return '<span style="color:red;">下架</span>';
} else {
return '未知';
}
},
2、富文本编辑器介绍
2.1说明
核心理念: 所见即所得编辑效果
KindEditor是一套开源的HTML可视化编辑器,主要用于让用户在网站上获得所见即所得编辑效果,兼容IE、Firefox、Chrome、Safari、Opera等主流浏览器。
2.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>
3、 重构商品入库操作
实现2张表同时入库操作.
说明:当用户点击商品提交时,会将2张表的数据通过/item/save的请求一起打包提交.
3.1建立ItemDesc
package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true) //开启链式加载结构
@TableName("tb_item_desc") //表名
public class ItemDesc extends BasePojo{
@TableId //主键
private Long itemId; //'商品ID', 既是item表的主键,也是itemDesc表的主键值相同
private String itemDesc; // 商品详情信息
}
3.2建立ItemDescMapper
package com.jt.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jt.pojo.ItemDesc;
public interface ItemDescMapper extends BaseMapper<ItemDesc> {
}
3.3修改ItemController
@RequestMapping("/save")
public SysResult saveItem(Item item,ItemDesc itemDesc) {
//两张表同时入库
itemService.saveItem(item,itemDesc);
return SysResult.success();
//定义全局异常处理机制!!!
}
3.4修改ItemServiceImpl
@Transactional //控制数据库事务
@Override
public void saveItem(Item item,ItemDesc itemDesc) {
//1.商品入库
item.setStatus(1)
.setCreated(new Date())
.setUpdated(item.getCreated());
itemMapper.insert(item);
//由于主键自增的原因,所以程序入库之后才会有主键信息
//MP提供业务支持实现数据回显功能!!! 入库操作之后,会将所有的数据库记录进行映射给对象
//2.商品详情入库
itemDesc.setItemId(item.getId())
.setCreated(item.getCreated())
.setUpdated(item.getCreated());
itemDescMapper.insert(itemDesc);
}
4、商品详情
- url地址
页面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);
//console.log(_data.data.itemDesc);
//在指定位置,显示页面html信息
itemEditEditor.html(_data.data.itemDesc);
}
});
4.1回显
4.1.1编辑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);
}
4.1.2编辑ItemService
@Override
public ItemDesc findItemDescById(Long itemId) {
return itemDescMapper.selectById(itemId);
}
4.2修改(updateItem值添加ItemDesc )
4.2.1编辑ItemController
/**
* 业务:商品的修改操作
* url:/item/update
* 参数:from表单数据
* 返回值结果:SysResult对象
*/
@RequestMapping("/update")
public SysResult updateItem(Item item,ItemDesc itemDesc) {
itemService.updateItem(item,itemDesc);
return SysResult.success();
}
4.2.2编辑ItemService
@Transactional //控制数据库事务
@Override
public void updateItem(Item item, ItemDesc itemDesc) {
//更新商品信息
item.setUpdated(new Date());
itemMapper.updateById(item);
//更新商品详情信息
itemDesc.setItemId(item.getId())
.setUpdated(item.getUpdated());
itemDescMapper.updateById(itemDesc);
}
4.3删除
4.3.1编辑ItemService
@Transactional //控制数据库事务
@Override
public void deleteItem(Long[] ids) {
//删除商品
//Arrays.asList(ids)- - ->将数组转化为集合
List<Long> idList=Arrays.asList(ids);
itemMapper.deleteBatchIds(Arrays.asList(ids));
//删除商品详情信息
itemDescMapper.deleteBatchIds(idList);
}
5、文件上传入门案例
- 入门测试网址
http://localhost:8091/file.jsp
<%@ 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>
5.1添加FileController
说明:编辑FileController使用SpringMVC框架的文件上传API.
package com.jt.controller;
import java.io.File;
import java.io.IOException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.jt.service.FileService;
import com.jt.vo.ImageVO;
@RestController //返回json数据
public class FileController {
@Autowired
private FileService fileService;
/**
* url地址: http://localhost:8091/file
* 参数: File=fileImage
* 返回值: 字符串
*
* 参数说明:MultipartFile 接口, 主要负责实现文件接收
* 常识:
* 1.必须指定文件上传的路径信息 D:\JT-SOFT\images\文件名称.jpg
* 2.将字节信息利用outPutStream进行输出操作
*
* 说明:文件上传默认大小1M=1024*1024
* 具体参见CommonsFileUploadSupport类
*
* InputStream
* @throws IOException
* @throws IllegalStateException
*
*/
@RequestMapping("/file")
public String file(MultipartFile fileImage) throws IllegalStateException, IOException {
//1.定义文件目录信息
String dirPath ="***自己的路径****";
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);
// FileOutputStream stream=new FileOutputStream(new File("XXXXX"));
// stream.close();
// System.out.println(fileImage);
return "恭喜你,文件上传成功";
}
}
5.2文件上传业务实现
1).页面url分析
2).参数提交
3).数据回传的格式要求
查阅富文本的API获取相关信息.
{"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
参数1.error: 正常错误0 ,上传有误1
参数2: 图片的虚拟地址信息
width/height 如果设定则使用用户的,如果不设定这使用默认的. 一般不用修改.
5.3封装文件上传VO–ImageVO
package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true) //开启链式加载结构
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(1,url,width,height);
}
}
5.4编辑FileController
/**
* 业务分析:实现文件上传.
* 1.url地址: http://localhost:8091/pic/upload
* 2.参数: uploadFile 文件上传对象
* 3.返回值: ImageVO对象
*/
@RequestMapping("/pic/upload")
public ImageVO upLoadFil(MultipartFile uploadFile) {
return fileService.uploadFile(uploadFile);
}
5.5编辑FileService
package com.jt.service;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
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:\\java\\CGB-04\\jt\\jt-manage\\src\\main\\webapp\\easy-ui\\images";
//bug: 漏洞--一般情况没错 特殊情况:传递特殊参数时报错
//error:错误
/**
* 1.如何校验上传的信息是图片
* 通过后缀进行校验: 。jpg, .png, .gif, jpge......
* 2.如何保证检索的速度更快
* 分目录储存 1).hash 2).时间
* 3.如何防止文件重名
* 重定义文件名 uuid
*/
@Override
public ImageVO uploadFile(MultipartFile uploadFile) {
//校验上传的信息 是否为图片
//1.1初始化图片集合类型
Set<String> typeSet =new HashSet<>();
typeSet.add(".jpg");
typeSet.add(".png");
typeSet.add(".gif");
typeSet.add(".jpeg");
//1.2动态获取用户上传的图片类型
String fileName = uploadFile.getOriginalFilename();
fileName = fileName.toLowerCase(); //将所有的字符转化为小写
//动态获取.后面的 - - -> .jpg
int index = fileName.lastIndexOf(".");
String fileType = fileName.substring(index);
//1.2校验图片类型是否有效
if(!typeSet.contains(fileType)) {
//表示类型不属于图片信息 则终止程序
return ImageVO.fail();
}
//2.准备文件上传的目录结构 文件上传根目录+动态变化目录
//D:\\java\\CGB-04\\jt\\jt-manage\\src\\main\\webapp\\easy-ui\\images + 2020/7/10
String dataDir =new SimpleDateFormat("/yyyy/MM/dd").format(new Date());
String dirPath = localDir+dataDir;
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 ="http://img5.imgtn.bdimg.com/it/u=2548331075,3510282070&fm=26&gp=0.jpg";
return ImageVO.success(url);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
return ImageVO.fail();
}
return null;
}
}