文章目录
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
表结构说明:
- 商品的基本信息 保存到item表
- 商品的详细信息 保存到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>品牌: <a href=https://list.jd.com/list.html"....... "
}
}
- 请求参数: 使用ItemVO对象接收
参数名称 参数类型 参数说明 备注
item Item 商品基本信息对象封装 不能为null
itemDesc ItemDesc 商品详情信息 不能为null
扫描二维码关注公众号,回复:
13226592 查看本文章
- 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 引入步骤
- 引入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)
- 使用富文本编辑器
<!-- 定义富文本编辑器-->
<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 修改表类型.
说明: 为了存储大字段.修改数据库类型