京淘day07-京淘项目商品详情及文件上传

AlgoCraft
• 阅读 932

1.实现商品详情展现

1.1 业务说明

一般用户查询商品时,只需要展现商品相关信息即可,如果用户点击某个商品时才会展现商品详情信息,因为商品详情是大字段信息,所以检索相对较慢,浪费性能.
表设计说明:
1.tb_item 商品表
2.tb_item_desc 商品详情表
一个商品只有一个详情信息,所以item表与itemDesc一对一.

1.2 商品详情表设计

京淘day07-京淘项目商品详情及文件上传

1.3 编辑ItemDesc

package com.jt.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@TableName("tb_item_desc")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class ItemDesc extends BasePojo{
    @TableId
 private Long itemId;        //商品ID 与item表中的数据一致.
 private String itemDesc;    //商品详情
}

1.4 富文本编辑器介绍

1.4.1 入门案例

京淘day07-京淘项目商品详情及文件上传

1.5 重构商品新增

1.5.1 业务说明

由于商品新增是将Item/ItemDesc对象一起新增,所以需要完成2张表的入库操作.

1.5.2 编辑ItemController

/**
 * 业务需求: 完成商品新增操作
 * url:    http://localhost:8091/item/save
 * 参数: 整个表单进行提交  使用对象接收
 * 返回值: 系统返回值对象
 */
 @RequestMapping("/save")
   @Transactional
 public SysResult saveItem(Item item, ItemDesc itemDesc) {
      itemService.saveItem(item,itemDesc);
      return SysResult.success();
 }

1.5.3 编辑ItemService

@Override
@Transactional//开启事务控制
public void saveItem(Item item, ItemDesc itemDesc) {
 //MP用法:如果完成主键自增,则自动的实现数据的回显!!!
 itemMapper.insert(item);
 //获取主键信息
 itemDesc.setItemId(item.getId());
 itemDescMapper.insert(itemDesc); 
}

1.6 商品详情展现

1.6.1 页面分析

京淘day07-京淘项目商品详情及文件上传

1.6.2 页面JS分析

京淘day07-京淘项目商品详情及文件上传

1.6.3 编辑ItemController

@RequestMapping("/query/item/desc/{itemId}")
public SysResult findItemDescById(@PathVariable Long itemId){
   ItemDesc itemDesc=itemService.findItemDescById(itemId);
   return SysResult.success(itemDesc);
}

1.6.4 编辑ItemService

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

1.6.5 页面效果展现

京淘day07-京淘项目商品详情及文件上传

1.7 重构商品更新

1.7.1 业务说明

当用户点击商品更新时,应该实现2张表的数据更新操作. 更新Item/更新ItemDesc对象

1.7.2 编辑ItemController

/**
 * 实现商品编辑
 * url地址: /item/update
 * 请求参数: 整个form表单提交
 * 返回值:    sysResult对象
 */
@RequestMapping("/update")
public SysResult updateItem(Item item,ItemDesc itemDesc) {
   itemService.updateItem(item,itemDesc);
   return SysResult.success();
}

1.7.3 编辑ItemService

@Override
@Transactional //控制事务
public void updateItem(Item item, ItemDesc itemDesc) {
   itemMapper.updateById(item);
   //补全数据
   itemDesc.setItemId(item.getId());
   itemDescMapper.updateById(itemDesc);
}

1.8 商品删除操作

1.8.1 编辑ItemController

/**
 * 实现商品的删除
 * url:/item/delete
 * 参数:ids
 * 返回类型:SysResult
 */@RequestMapping("/delete")
public SysResult deleteItems(Long[] ids) {
   itemService.deleteItems(ids);
   return SysResult.success();
}

1.8.2 编辑ItemService

@Override
@Transactional
public void deleteItems(Long[] ids) {
 //方式2手写sql方式实现删除
 itemMapper.deleteItems(ids);
 //商品详情信息
 List<Long> longIds= Arrays.asList(ids);
 itemDescMapper.deleteBatchIds(longIds);
}

2 文件上传

2.1 文件上传入门案例

2.1.1 页面标识

京淘day07-京淘项目商品详情及文件上传

2.1.2 文件上传入门案例

package com.jt.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
@RestController
public class FileController {
    /**
     * url地址:  http://localhost:8091/file
     * 参数:     文件信息 fileImage
     * 返回值:   String
     */
    @RequestMapping("/file")
    public String file(MultipartFile fileImage) throws IOException {
        //1.获取图片名称
        String name = fileImage.getOriginalFilename();
        //2.定义文件目录
        String fileDirPath = "D:/JT-SOFT/images";
        //3.创建目录
        File fileDir = new File(fileDirPath);
        if(!fileDir.exists()){
            fileDir.mkdirs();
        }
        //4.生成文件的全路径
        String filePath = fileDirPath+"/"+name;
        File imageFile = new File(filePath);
        //5.实现文件上传
        fileImage.transferTo(imageFile);
        return "文件上传成功!!!";
    }
} 

2.2 实现文件上传

2.2.1 页面URL分析

京淘day07-京淘项目商品详情及文件上传

2.2.2 请求参数

京淘day07-京淘项目商品详情及文件上传

2.2.3 编辑VO对象

{“error”:0,“url”:“图片的保存路径”,“width”:图片的宽度,“height”:图片的高度}

package com.jt.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class ImageVO {
    //{"error":0,"url":"图片的保存路径","width":图片的宽度,"height":图片的高度}
    private Integer error;  // 0 表示文件上传正确    1.上传有误
    private String  url;    //图片浏览的网络地址(虚拟地址)
    private Integer width;  //宽度
    private Integer height; //高度
    public static ImageVO fail(){
        return new ImageVO(1, null, null, null);
    }
    public static ImageVO success(String url,Integer width,Integer height){
       return new ImageVO(0, url,width, height);
    }
} 

2.2.4 编辑FileController

 /**
     * 业务需求: 实现文件上传操作
     *  url:http://localhost:8091/pic/upload?dir=image
     *  参数:uploadFile
     *  返回值: ImageVO对象
     */
     @RequestMapping("/pic/upload")
     public ImageVO upload(MultipartFile uploadFile){
         return fileService.upload(uploadFile);
     } 

2.2.5 编辑pro配置文件

#配置本地磁盘根目录
image.fileDir=E:/images
#配置图片服务器地址
image.urlPath=http://image.ji.com

2.2.6 编辑FileService

package com.jt.service;
import com.jt.vo.ImageVO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
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;
@Service
@PropertySource(value="classpath:/properties/image.properties",encoding="UTF-8")
public class FileServiceImpl implements FileService {
    @Value("${image.fileDir}")
    private String fileDir;//"E:/images"
 @Value("${image.urlPath}")
    private String urlPath;//设定域名网址
 private static Set<String> typeSet = new HashSet<>();
    static {
        typeSet.add(".jpg");
        typeSet.add(".png");
        typeSet.add(".gif");
    }
 /**
 * 业务逻辑:实现文件上传@Override
 * 步骤:
 * 1.校验图片的类型 jpg|png|gif.......
 * 2.校验文件是否为恶意程序...
 * 3.采用分目录的结构进行存储
 * 4.避免文件重名 UUID
 * @param uploadFile
 * @return
 */
 @Override
 public ImageVO upload(MultipartFile uploadFile) {
        //一. 校验图片类型 1.利用集合校验 2.正则表达式
        //1.1 获取文件名称 1.jpg  1.JPG} 
        String fileName = uploadFile.getOriginalFilename();
        //全部转化为小写
        fileName = fileName.toLowerCase();
        //1.2 获取文件后缀类型
        int index = fileName.lastIndexOf(".");
        //1.3  .jpg   
        String fileType = fileName.substring(index);
        //1.4 判断是否为图片类型
        if (!typeSet.contains(fileType)) {
              return ImageVO.fail();
        }
        //二.如果是图片,高度、宽度
        //2.1将数据转化图片对象
        try {
            BufferedImage bufferedImage=ImageIO.read(uploadFile.getInputStream());
            int width=bufferedImage.getWidth();
            int height=bufferedImage.getHeight();
            if (width==0||height==0){
                return ImageVO.fail();
            }
        //三.实现分目录储存
        //3.1按照/yyyy/MM/dd/的方式进行目录划分
        String dateDir=new SimpleDateFormat("/yyyy/MM/dd/").format(new Date());
        //E:/images/2020/12/01
        String fileDirPath=fileDir+dateDir;
        File dirFile=new File(fileDirPath);
        //3.2创建目录
        if (!dirFile.exists()){
            dirFile.mkdirs();
        }
        //四.实现文件上传
        //4.1准备文件名称 UUID 
        String uuid= UUID.randomUUID().toString().replace("-","");
        //4.2动态生成文件名称
        String uuidName=uuid+fileType;
        //4.3实现文件上传 E:images20201202a.jpg 
        File realFile=new File(fileDirPath+uuidName) ;
        uploadFile.transferTo(realFile);
        //本地磁盘地址:E:images20201202a.jpg
        //网络访问虚拟地址:http://image.ji.com20201202a.jpg
        String url=urlPath+dateDir+uuidName;
        return ImageVO.success(url,width,height);
        } catch (IOException e) {
            e.printStackTrace();
        }
       return null;
    }
}

2.2.7 代码测试

1.上传图片之后 文件上传的路径.
京淘day07-京淘项目商品详情及文件上传
2.将请求的前缀修改为具体磁盘地址
切换前缀,检查文件是否正常
京淘day07-京淘项目商品详情及文件上传

点赞
收藏
评论区
推荐文章
CuterCorley CuterCorley
4年前
Django+Vue开发生鲜电商平台之8.商品详情页功能实现
不走康庄大道,我自己喜欢做什么要比别人怎么看我更重要。——李彦宏Github和Gitee代码同步更新:;。一、viewsets实现商品详情页商品详情页效果如下:可以看到,左侧有商品轮播图,右侧是商品的详情信息,包括商品名称、商品描述、是否包邮、市场价、本店价、销量、库存量、购物车按钮、收藏按钮,还包括富文本详情和热卖商品等。apps/go
淘宝天猫店铺所有商品接口(整店商品采集接口)代码展示
淘宝店铺所有商品接口,淘宝整店商品接口,天猫店铺所有商品接口,天猫店铺商品接口,淘宝商品详情接口,天猫商品详情接口,淘宝店铺详情接口,天猫店铺详情接口,淘宝店铺详情接口,天猫店铺详情接口
淘宝天猫平台商品详情接口(商品销量接口,商品优惠券查询接口,商品到手价接口)代码分享
淘宝商品详情接口,淘宝商品销量接口,淘宝商品优惠券查询接口,天猫商品详情接口,天猫商品销量接口,淘宝商品列表接口,天猫商品列表接口,淘宝商品属性接口,淘宝商品sku信息查询接口,淘宝API接口
天猫APP商品详情接口(商品销量接口,商品优惠券接口,商品价格接口)代码展示
天猫商品详情接口,天猫商品销量接口,天猫商品优惠券接口,天猫商品价格接口,天猫商品sku属性查询接口,天猫商品sku信息接口,淘宝商品详情接口,淘宝商品销量接口,淘宝商品优惠券接口,淘宝商品列表接口,天猫商品列表接口
淘宝天猫商品详情接口代码展示(商品销量接口,商品列表接口,商品视频接口,商品优惠券接口)
淘宝商品详情接口,淘宝商品销量接口,淘宝商品列表接口,淘宝商品视频接口,淘宝商品优惠券接口,天猫商品详情接口,天猫商品销量接口,天猫商品列表接口,天猫商品视频接口,天猫商品优惠券接口,淘宝api接口,天猫API接口
lazada选品:lazada商品评论数据采集接口代码展示
lazada商品评论接口,lazada商品评论数据接口,lazada商品评价接口,lazada商品详情接口,lazada商品列表接口,lazada商品数据接口,lazada商品API接口,lazada商品评论内容接口,lazada商品属性接口,lazada商品sku信息接口,lazada店铺商品接口,lazada商品API接口,lazada商品数据采集接口
lazada选品:lazada商品详情数据接口采集代码展示
lazada商品详情接口,lazada商品列表接口,lazada商品评论接口,lazada店铺商品接口,lazada商品API接口,lazada商品数据接口,lazada商品优惠券接口,lazada商品属性接口,lazada商品sku信息接口,lazada整店商品接口,lazada店铺商品接口,lazada商品描述接口,lazada评论内容接口,lazada商品销量接口
shopee商品详情接口,店铺商品接口,商品评论接口代码封装教程
shopee商品详情接口,shopee商品列表接口,shopee商品数据接口,shopee店铺商品接口,关键词搜索shopee商品接口,关键词搜索shopee商品列表接口,shopee商品API接口,shopee商品详情属性接口,shopee详情sku数据,shopee店铺详情接口,shopee规格数据接口,shopee商品销量接口,shopee商品sku接口,shopee尺寸接口,shopee重量接口
鸿蒙小林 鸿蒙小林
8个月前
《仿盒马》app开发技术分享-- 商品详情页(10)
技术栈Appgalleryconnect开发准备上一节我们实现了自定义标题栏和商品详情的数据接收,我们已经拿到了想要的数据,这一节我们要丰富商品详情页的内容。商品详情页面我们需要展示的是商品的各个属性参数、商品的图片、商品规格、活动详情等功能分析商品详情页
鸿蒙小林 鸿蒙小林
8个月前
《仿盒马》app开发技术分享-- 商品规格弹窗(11)
技术栈Appgalleryconnect开发准备上一节我们实现了商品详情页面,并且成功在页面上展示了商品的图片、商品规格、活动详情等信息,要知道同一种商品大多数都是有多种型号跟规格的,所以这一节我们来实现商品的规格弹窗。这节的要点是自定义弹窗的运用。功能分
鸿蒙小林 鸿蒙小林
8个月前
《仿盒马》app开发技术分享-- 商品兑换校验(70)
技术栈Appgalleryconnect开发准备上一节我们实现了可兑换商品的详情,我们能够查看到商品更多的信息,这一节我们来实现商品兑换相关的功能,在进行商品兑换之前,我们在兑换详情页面,点击立即兑换按钮之后我们需要跳转到兑换详情页,但是用户的积分可能达不