1. 商品模块实现
1.1 商品路由跳转
1.编辑路由机制
2.页面效果展现
1.2 商品列表展现
1.2.1 业务接口文档说明
- 请求路径: /item/getItemListquery=&pageNum=1&pageSize=10
- 请求类型: get
- 请求参数: 使用pageResult对象接收
参数名称
参数说明
备注信息
query
用户查询的数据
可以为null
pageNum
分页查询的页数
必须赋值不能为null
pageSize
分页查询的条数
必须赋值不能为null
- 返回值结果:
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
商品分页对象
1.2.2 编辑ItemController
@RestController
@CrossOrigin
@RequestMapping("/item")
public class ItemController {
@Autowired
private ItemService itemService;
/**
* 业务说明: 完成商品查询操作
* URL: /item/getItemList?query=&pageNum=1&pageSize=10
* 参数: pageResult
* 类型: get/delete post/put
* 返回值: SysResult对象
*/
@GetMapping("/getItemList")
public SysResult getItemList(PageResult pageResult){//3
pageResult = itemService.getItemList(pageResult);//+2
return SysResult.success(pageResult); //返回5条记录
}
}
1.2.3 编辑ItemService
package com.jt.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.jt.mapper.ItemMapper;
import com.jt.pojo.Item;
import com.jt.vo.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class ItemServiceImpl implements ItemService{
@Autowired
private ItemMapper itemMapper;
/**
* 1.获取满足条件的记录总数
* 2.进行分页操作
* 原则:
* 1.手写Sql 业务层级简单,Sql高效直观.
* 2.利用MP实现 业务层复杂, Sql不写
* Sql: select * from item limit 起始位置,条数
* @param pageResult
* @return
*/
@Override
public PageResult getItemList(PageResult pageResult) {
QueryWrapper<Item> queryWrapper = new QueryWrapper<>();
queryWrapper.like("title", pageResult.getQuery());
//2.完成分页操作
//2.1 准备一个分页对象,MP基于初始化条件,获取分页其它数据
IPage<Item> page = new Page<>(pageResult.getPageNum(),
pageResult.getPageSize());
page = itemMapper.selectPage(page,queryWrapper);
//2.2 获取总数,获取记录数
long total = page.getTotal();
List<Item> list = page.getRecords();
return pageResult.setTotal(total).setRows(list);
}
}
1.2.4 编辑配置类
@Configuration //标识配置类
public class MybatisPlusConfig {
//MybatisPlusInterceptor MP拦截器 负责指定数据库类型
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));
return interceptor;
}
}
1.3 商品状态修改
1.3.1 编辑业务接口
- 请求路径: /item/updateItemStatus
- 请求类型: put
- 请求参数: 使用对象接收
参数名称
参数说明
备注
id
商品id
不能为null
status
状态信息
不能为null
- 返回值结果:
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
1.3.2 编辑ItemController
/**
* 实现商品状态的修改
* URL地址: /item/updateItemStatus
* 参数: js对象 json串 java对象
* 返回值: SysResult对象
*/
@PutMapping("/updateItemStatus")
public SysResult updateItemStatus(@RequestBody Item item){
itemService.updateItemStatus(item);
return SysResult.success();
}
1.3.3 编辑ItemService
//update item set status=#{status},updated=#{updated} where id=#{id}
@Override
@Transactional
public void updateItemStatus(Item item) {
//根据对象中不为null的元素,进行操作
item.setUpdated(new Date());
itemMapper.updateById(item);
}
1.4 商品信息数据结构说明
说明: 为了让前端用户检索商品的速度更快,采用2张表进行设计.
表1: 商品表 item
表2: 商品详情信息item_desc
3. 修改数据表字段
4. 一个商品对应一个商品详情 要求: item.id = item_desc.id
5. 清空详情表的数据信息
1.5 商品新增实现
1.5.1 ItemDesc与表关联
/**
* @author 刘昱江
* 时间 2021/4/7
*/
@Data
@Accessors(chain = true)
@TableName("item_desc")
public class ItemDesc extends BasePojo{
@TableId
private Integer id; //item.id一致
private String itemDesc; //html代码片段
}
1.5.2 创建ItemDescMapper
1.5.3 商品新增业务接口
-
请求路径: http://localhost:8091/item/saveItem
-
请求类型: post
-
前端传递参数分析
{ item: { images: "/2021/05/20/da0c1d4781c1499399f090da8b60f359.jpg,/2021/05/20/2ac1c34776a7465887eb019655354c3c.jpg" itemCatId: 560 num: "100" price: 718800 sellPoint: "【华为官方直供,至高12期免息0首付,原装正品】送华为原装无线充+运动蓝牙耳机+蓝牙音箱+三合一多功能数据线+钢化膜等!" title: "华为P40 Pro 5G手机【12期免息可选送豪礼】全网通智能手机" }, itemDesc: { itemDesc: "<ul><li>品牌: <a href=https://list.jd.com/list.html"....... " } }
-
请求参数: 使用ItemVO对象接收
参数名称
参数类型
参数说明
备注
item
Item
商品基本信息对象封装
不能为null
itemDesc
ItemDesc
商品详情信息
不能为null
- ItemVO参数详解:
- Item对象
参数名称
参数类型
参数说明
备注
title
String
商品标题信息
不能为null
sellPoint
String
商品卖点信息
不能为null
price
Integer
商品价格信息
不能为null 需要将数据扩大100倍
num
Integer
商品数量信息
不能为null
images
String
商品图片地址信息
不能为null
itemCatId
Integer
商品父级分类ID
不能为null
status
Boolean
商品状态信息
不能为null
- itemDesc 对象
-
为了降低商品提交代码的耦合性,将大字段信息详情,采用ItemDesc对象进行封装
参数名称
参数类型
参数说明
备注
id
Integer
商品Id信息
因为Item和ItemDesc是一对一关系 所以需要依赖Item对象的Id值
itemDesc
String
商品详情信息
内部包含了大量的html语句
- 返回值结果:
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
1.5.4 编辑ItemController
/**
* 业务说明: 完成商品入库操作 item item_desc表
* URL: http://localhost:8091/item/saveItem
* 参数: ItemVO
* 返回值: SysResult对象
*/
@PostMapping("/saveItem")
public SysResult saveItem(@RequestBody ItemVO itemVO){
itemService.saveItem(itemVO);
return SysResult.success();
}
1.5.5 编辑ItemService
/**
* 入库操作维护:
* 1.状态
* 2.创建/修改时间
* @param itemVO
*/
@Override
@Transactional
public void saveItem(ItemVO itemVO) {
Date date = new Date();
Item item = itemVO.getItem();
item.setStatus(true).setCreated(date).setUpdated(date);
itemMapper.insert(item);
//入库详情表 item.id = itemDesc.id
ItemDesc itemDesc = itemVO.getItemDesc();
itemDesc.setId(item.getId()).setCreated(date).setUpdated(date);
itemDescMapper.insert(itemDesc);
}
1.6 商品删除操作
1.6.1 业务接口
- 请求路径: /item/deleteItemById
- 请求类型: delete
- 请求参数:
参数名称
参数说明
备注
id
商品id
不能为null
- 返回值结果:
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
1.6.2 编辑ItemController
/**
* 完成商品删除操作
* URL: /item/deleteItemById?id=xx
* 参数: id
* 返回值: SysResult对象
*/
@DeleteMapping("/deleteItemById")
public SysResult deleteItemById(Integer id){
itemService.deleteItemById(id);
return SysResult.success();
}
1.6.3 编辑ItemService
/**
* 1.删除商品信息
* 2.删除商品详情信息
* @param id
*/
@Override
@Transactional
public void deleteItemById(Integer id) {
itemMapper.deleteById(id);
itemDescMapper.deleteById(id);
}
1.7 文件上传实现
1.7.1 接口文档说明
- 请求路径: http://localhost:8091/file/upload
- 请求类型: post
- 请求参数:
参数名称
参数说明
备注
file
文件上传的参数名称
file中携带的是二进制信息
- 返回值结果:
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
返回ImageVO对象
- ImageVO对象说明
参数名称
参数类型
参数说明
备注
virtualPath
String
图片实际路径 不包含磁盘信息
例如: 2021/11/11/a.jpg 不需要写磁盘地址
urlPath
String
图片url访问地址
http://image.jt.com/2021/11/11/a.jpg 需要指定域名地址
fileName
String
文件上传后的文件名称
UUID.type
1.7.2 编辑FileController
@RestController
@CrossOrigin
@RequestMapping("/file")
public class FileController {
@Autowired
private FileService fileService;
/**
* 业务说明:
* 1.URL地址: http://localhost:8091/file/upload
* 2.请求参数: file
* 3.返回值: SysResult(ImageVO)
*/
@PostMapping("/upload")
public SysResult upload(MultipartFile file){
ImageVO imageVO = fileService.upload(file);
if(imageVO == null){
return SysResult.fail();
}
return SysResult.success(imageVO);
}
}
1.7.3 编辑FileService
@Service
public class FileServiceImpl implements FileService{
private String localDir = "F:/JT_SOFT/images";
/**
* 业务说明:
* 1.校验图片的类型 是否为 jpg|png|gif
* 2.校验文件是否为恶意程序 防止木马病毒.
* 3.按照分目录结构 存储图片
* 4.应该让文件名称不重复
*
* @param file
* @return
*/
@Override
public ImageVO upload(MultipartFile file) {
//1.校验图片的类型
//1.1 获取图片名称 abc.gif ABC.GIF
String fileName = file.getOriginalFilename();
//1.2 将字母转化为小写
fileName = fileName.toLowerCase();
//1.3 正则表达式写法
if(!fileName.matches("^.+\.(jpg|png|gif)$")){
return null;
}
//2.防止木马病毒 图片宽度和高度
try {
BufferedImage bufferedImage =
ImageIO.read(file.getInputStream());
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
if(width==0 || height==0){
//说明 不是正经图片
return null;
}
//3.分目录存储 提交的时间|名称hash abasedhh|type 进行存户
String datePath = new SimpleDateFormat("/yyyy/MM/dd/")
.format(new Date());
//3.1 创建图片目录
String dirPath = localDir + datePath;
//3.2 创建目录
File dirFile = new File(dirPath);
if(!dirFile.exists()){
dirFile.mkdirs();
}
//4.要求文件名称不重名 uuid.type
String uuid = UUID.randomUUID().toString();
int index = fileName.lastIndexOf(".");
//.jpg
String type = fileName.substring(index);
fileName = uuid + type;
//5.实现文件上传
String realFilePath = dirPath + fileName;
file.transferTo(new File(realFilePath));
} catch (IOException e) {
e.printStackTrace();
//如果出现了异常信息,则返回null即可
return null;
}
return null;
}
/**
* 实现文件上传操作:
* 1.获取文件上传名称
* 2.准备文件上传的目录
* 3.实现文件上传操作
*
* 注意事项:
* 1.图片选择京东的图片
* 2.图片大小不要超过1M
* @param file
* @return
*/
/*@Override
public ImageVO upload(MultipartFile file) {
//1.获取文件名称 abc.jpg
String fileName = file.getOriginalFilename();
//2.指定磁盘路径信息
String filePath = "F:/JT_SOFT/images";
//3.校验目录是否存在
File dirFile = new File(filePath);
if(!dirFile.exists()){
dirFile.mkdirs(); //创建多级目录
}
//4.准备文件的全路径 F:/JT_SOFT/images/abc.jpg
String path = filePath + "/" +fileName;
//5.将路径包装为File对象
File imageFile = new File(path);
//6.实现文件上传
try {
file.transferTo(imageFile);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}*/
}
作业
- 下载nginx 软件
- 启动nginx服务
- 检查服务是否启动
- 访问服务
- 注意事项:
nginx服务启动会占用80端口,所以80端口不能被其它软件占用.
关于京淘项目问题集: 关于Nginx 不能启动说明
虚拟机安装和使用
B站视频: VMware配置说明
URL: https://www.bilibili.com/video/BV1iy4y1L7tpfrom=search&seid=7776107191945920113&spm_id_from=333.337.0.0