完整项目学习-6

1. 商品模块业务实现

1.1 商品页面跳转

编辑index.js的路由文件

import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import ElementUI from '../components/ElementUI.vue'
import Home from '../components/Home.vue'
import User from '../components/user/user.vue'
import ItemCat from '../components/items/ItemCat.vue'
import Item from '../components/items/Item.vue'
//使用路由机制
Vue.use(VueRouter)
const routes = [
  {
    
    path: '/', redirect: '/login'},
  {
    
    path: '/login', component: Login},
  {
    
    path: '/elementUI', component: ElementUI},
  {
    
    path: '/home', component: Home, children: [
     {
    
    path: '/user', component: User},
     {
    
    path: '/itemCat', component: ItemCat},
     {
    
    path: '/item', component: Item}
  ]}
]

1.2 页面效果

在这里插入图片描述

1.2 数据自动填充

1.2.1 业务分析

说明: 如果每次新增/更新时 都需要添加创建时间/修改时间 这样做比较繁琐.能否通过框架自动的实现数据填充.
在这里插入图片描述

1.2.2 添加自动填充注解

//pojo基类,完成2个任务,2个日期,实现序列化
@Data
@Accessors(chain=true)
public class BasePojo implements Serializable{
    
    
	@TableField(fill = FieldFill.INSERT) 		//新增操作时,实现自动填充
	private Date created;	//表示入库时需要赋值
	@TableField(fill = FieldFill.INSERT_UPDATE) //新增/修改操作时,自动填充
	private Date updated;	//表示入库/更新时赋值.
}

1.2.3 配置自动填充类

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
    
    

    //框架用法说明: MP根据实现类,自动的完成数据的注入. MP框架自动调用
    //metaObject: 指定默认的规则
    @Override
    public void insertFill(MetaObject metaObject) {
    
    
        Date date = new Date();
        this.setFieldValByName("created", date, metaObject);
        this.setFieldValByName("updated", date, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
    
    

        this.setFieldValByName("updated", new Date(), metaObject);
    }
}

1.3 构建商品层级代码

1.3.1 item 表设计

在这里插入图片描述

1.3.2 编辑Item POJO

/**
 * @author 刘昱江
 * 时间 2021/4/7
 */
@Data
@Accessors(chain = true)
@TableName("item")
public class Item extends BasePojo{
    
    
    @TableId(type= IdType.AUTO) 
    private Integer id;         //商品Id号
    private String title;       //商品标题信息
    private String sellPoint;   //卖点信息
    private Integer price;      //商品价格
    private Integer num;        //商品数量
    private String images;       //商品图片
    private Integer itemCatId;  //商品分类ID号
    private Boolean status;     //状态信息    0 下架 1 上架
}

1.3.3 编辑层级代码结构

在这里插入图片描述

1.4 完成商品列表展现

1.4.1 页面分析

//1. 生命周期函数
 created() {
    
    
      //1.获取商品列表数据
      this.getItemList()
    },

//2. 调用 this.getItemList()
      async getItemList() {
    
    
        const {
    
    data: result} =
            await this.$http.get("/item/getItemList", {
    
    
          params: this.queryItemInfo
        })
        if (result.status !== 200) return this.$message.error("商品列表查询失败")
        this.itemList = result.data.rows
        this.total = result.data.total
      },

1.4.2 接口文档说明

  • 请求路径: /item/getItemList?query=&pageNum=1&pageSize=10
  • 请求类型: get
  • 请求参数: 使用pageResult对象接收
参数名称 参数说明 备注信息
query 用户查询的数据 可以为null
pageNum 分页查询的页数 必须赋值不能为null
pageSize 分页查询的条数 必须赋值不能为null
  • 返回值结果:
参数名称 参数说明 备注
status 状态信息 200表示服务器请求成功
msg 服务器返回的提示信息 可以为null
data 服务器返回的业务数据 商品分页对象

1.4.3 编辑ItemController

@RestController
@CrossOrigin
@RequestMapping("/item")
public class ItemController {
    
    

    @Autowired
    private ItemService itemService;

    /**
     * 业务: 实现商品的分页查询
     * URL: /item/getItemList?query=&pageNum=1&pageSize=10
     * 参数: query=&pageNum=1&pageSize=10
     * 返回值: SysResult(PageResult)
     */
    @GetMapping("/getItemList")
    public SysResult getItemList(PageResult pageResult){
    
    //3
        //3+2(总记录数,分页结果)
        pageResult  = itemService.getItemList(pageResult);
        return SysResult.success(pageResult);//5
    }
}

1.4.4 编辑ItemService

@Service
public class ItemServiceImpl implements ItemService{
    
    

    @Autowired
    private ItemMapper itemMapper;

    /**
     *  要求: 3+2(总记录数,分页结果)
     *  关于selectPage(参数说明)
     *   参数1: page MP提供的分页对象
     *   参数2: 条件构造器
     * @param pageResult
     * @return
     */
    @Override
    public PageResult getItemList(PageResult pageResult) {
    
    
        //1.构建分页对象  参数1: 第几页   参数2: 多少条
        Page<Item> page = new Page<>(pageResult.getPageNum(),pageResult.getPageSize());
        //2.准备条件构造器 构建模糊查询
        QueryWrapper queryWrapper = new QueryWrapper();
        String query = pageResult.getQuery();
        boolean flag = StringUtils.hasLength(query);
        queryWrapper.like(flag,"title",query);

        //3.根据MP查询 实现分页数据的自动封装
        page = itemMapper.selectPage(page,queryWrapper);

        //4.获取数据,返回分页对象
        long total = page.getTotal();
        //获取分页结果
        List<Item> rows = page.getRecords();
        return pageResult.setTotal(total).setRows(rows);
    }
}

1.4.5 编辑分页配置类

@Configuration  //这是配置类
public class MybatisConfig {
    
    

    //需要通过配置文件 指定数据库类型.
    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
    
    
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MARIADB));
        return interceptor;
    }
}

1.4.6 页面效果展现

在这里插入图片描述

1.5 商品状态的修改

1.5.1 页面JS分析

		<template slot-scope="scope">
            <el-switch v-model="scope.row.status" active-color="#13ce66" inactive-color="#ff4949"
              @change="updateStatus(scope.row)"></el-switch>
        </template>
		
		async updateStatus(item) {
    
    
        const {
    
     data: result} =
        await this.$http.put("/item/updateItemStatus", {
    
    
          id: item.id,
          status: item.status
        })
        if (result.status !== 200) return this.$message.error("更新状态失败")
        this.$message.success("更新状态成功")
      },

1.5.2 业务接口文档

  • 请求路径: /item/updateItemStatus
  • 请求类型: put
  • 请求参数: 使用对象接收
参数名称 参数说明 备注
id 商品id 不能为null
status 状态信息
  • 返回值结果:
参数名称 参数说明 备注
status 状态信息 200表示服务器请求成功
msg 服务器返回的提示信息 可以为null
data 服务器返回的业务数据 可以为null

1.5.3 编辑ItemController

 /**
     * 修改商品的状态信息
     * URL: /item/updateItemStatus
     * 参数: JSON串 {id:xx,status:xx}
     * 返回值: SysResult对象
     */
    @PutMapping("/updateItemStatus")
    public SysResult updateItemStatus(@RequestBody Item item){
    
    

        itemService.updateItemStatus(item);
        return SysResult.success();
    }

1.5.4 编辑ItemService

 @Override
    @Transactional //控制事务
    public void updateItemStatus(Item item) {
    
    

        itemMapper.updateById(item);
    }

1.6 商品删除操作

1.6.1 页面分析

//根据id删除数据
          const {
    
    data: result} = await this.$http.delete("/item/deleteItemById", {
    
    
            params: {
    
    
              id: item.id
            }
          })
          if (result.status !== 200) return this.$message.error("商品删除失败")
          this.$message.success("商品删除成功")
          //重新获取商品列表信息
          this.getItemList()

1.6.2 业务接口文档

  • 请求路径: /item/deleteItemById
  • 请求类型: delete
  • 请求参数:
参数名称 参数说明 备注
id 商品id 不能为null
  • 返回值结果:
参数名称 参数说明 备注
status 状态信息 200表示服务器请求成功
msg 服务器返回的提示信息 可以为null
data 服务器返回的业务数据 可以为null

1.6.3 编辑ItemController

 /**
     * 业务需求: 根据Id 删除数据
     * URL: /item/deleteItemById
     * 参数: id
     * 返回值: SysResult对象
     */
    @DeleteMapping("/deleteItemById")
    public SysResult deleteItemById(Integer id){
    
    

        itemService.deleteItemById(id);
        return SysResult.success();
    }

1.6.4 编辑ItemService

 	@Override
    @Transactional
    public void deleteItemById(Integer id) {
    
    
    
        itemMapper.deleteById(id);
    }

1.7 商品新增操作

1.7.1 实现页面跳转

const routes = [
  {
    
    path: '/', redirect: '/login'},
  {
    
    path: '/login', component: Login},
  {
    
    path: '/elementUI', component: ElementUI},
  {
    
    path: '/home', component: Home, children: [
     {
    
    path: '/user', component: User},
     {
    
    path: '/itemCat', component: ItemCat},
     {
    
    path: '/item', component: Item},
     {
    
    path: '/item/addItem', component: AddItem}
  ]}
]

页面效果:
在这里插入图片描述

1.7.2 新增页面JS

表结构说明:

  1. 商品的基本信息 保存到item表
  2. 商品的详细信息 保存到item_desc表中.
 /* 添加商品按钮 */
      async addItemBtn(){
    
    
        //console.log(this.addItemForm)

        //1.完成表单校验
        this.$refs.addItemFormRef.validate( valid => {
    
    
          if(!valid) return this.$message.error("请输入商品必填项")
        })

        //2.完成商品参数的封装
        //2.0 将商品价格扩大100倍
        this.addItemForm.price = this.addItemForm.price * 100
        //2.1 将商品图片的数据转化为字符串
        this.addItemForm.images = this.addItemForm.images.join(",")

        //2.5 实现商品数据提交 用一个大对象 包裹2个小对象
        let submitAddItem = {
    
    
          item : this.addItemForm,
          itemDesc: this.itemDesc
        }
        //console.log(submitAddItem)
        let {
    
    data: result} = await this.$http.post("/item/saveItem",submitAddItem)
        if(result.status !== 200) return this.$message.error("商品添加失败")
        this.$message.success("商品添加成功")

        //2.5添加完成之后,将数据重定向到商品展现页面
        this.$router.push("/item")
      }

1.7.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>品牌:&nbsp;<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.7.4 编辑ItemController

 /**
     * 完成商品新增操作
     * 1.URL地址  http://localhost:8091/item/saveItem
     * 2.参数     post   itemVO JSON串
     * 3.返回值   SysResult对象
     */
    @PostMapping("/saveItem")
    public SysResult saveItem(@RequestBody ItemVO itemVO){
    
    

        itemService.saveItem(itemVO);
        return SysResult.success();
    }

1.7.5 编辑ItemService

 @Override
    @Transactional
    public void saveItem(ItemVO itemVO) {
    
    
        Item item = itemVO.getItem();
        //设定状态
        item.setStatus(true);
        itemMapper.insert(item);
    }

1.8 商品详情入库

1.8.1 富文本编辑器

说明: 富文本可以在页面中,实现 “所见即所得” 的效果
在这里插入图片描述

1.8.2 引入步骤

  1. 引入js
/* 导入富文本编辑器 */
import VueQuillEditor from 'vue-quill-editor'

/* 导入富文本编辑器对应的样式 */
import 'quill/dist/quill.core.css' // import styles
import 'quill/dist/quill.snow.css' // for snow theme
import 'quill/dist/quill.bubble.css' // for bubble theme

/* 将富文本编辑器注册为全局可用的组件 */
Vue.use(VueQuillEditor)
  1. 使用富文本编辑器
 <!-- 定义富文本编辑器-->
 <quill-editor ref="myQuillEditor" v-model="itemDesc.itemDesc">
 </quill-editor>

1.8.3 关于ItemDesc 的说明

说明: 由于Item和ItemDesc 是典型的一对一. 所以要求 item.id = itemDesc.id

@Data
@Accessors(chain = true)
@TableName("item_desc")
public class ItemDesc extends BasePojo{
    
    
    @TableId
    private Integer id;
    private String itemDesc;
}

1.8.4 编辑ItemDescMapper

public interface ItemDescMapper extends BaseMapper<ItemDesc>{
    
    


}

1.8.5 编辑ItemService

 /**
     * 问题: id是主键自增. 入库之后才有主键所以
     *      应该让主键动态回显
     * 1.Mybatis 动态实现回显
     *      <insert id="xxxx" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
     *         insertinto xxxx
     *     </insert>
     * 2.MP是mybatis的增强版本.所以可以实现自动的主键回显!!!
     * @param itemVO
     */
    @Override
    @Transactional
    public void saveItem(ItemVO itemVO) {
    
    
        Item item = itemVO.getItem();
        //设定状态
        item.setStatus(true);
        itemMapper.insert(item);
        //获取商品详情
        ItemDesc itemDesc = itemVO.getItemDesc();
        itemDesc.setId(item.getId());
        itemDescMapper.insert(itemDesc);
    }

1.8.6 修改表类型.

说明: 为了存储大字段.修改数据库类型
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43770110/article/details/121294056