商品管理模块开发
下面用到的表:
属性表:
属性值表:
分类一表:
分类二表:
分类三表:
1.1在service 模块下搭建service-product
搭建过程同common-util
添加配置文件application.yml
spring:
application:
name: service-product
profiles:
active: dev
cloud:
nacos:
discovery:
server-addr: 192.168.254.165:8848
添加配置文件application-dev.yml
server:
port: 8206
mybatis-plus:
mapper-locations: classpath:mapper/*Mapper.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
url: jdbc:mysql://192.168.254.165:3306/gmall_product
redis:
host: 192.168.200.129
password:
database: 0
port: 6379
zipkin:
base-url: http://192.168.254.165:9411
rabbitmq:
host: 192.168.254.165
port: 5672
username: guest
password: guest
创建启动类
包名:com.atguigu.gmall.product
@SpringBootApplication
@ComponentScan({"com.atguigu.gmall"})
@EnableDiscoveryClient
public class ServiceProductApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceProductApplication.class, args);
}
}
1.2搭建后台页面
- 拷贝资料中的前端项目页面,放入一个没有中文目录的文件下
- 在gmall-admin当前目录下cmd 回车
- npm install [安装依赖 node_modules] 项目库中有node_modules 就不需要执行npm install
- npm run dev
- 直接访问浏览器
- 将两个配置文件
- dev.env.js http://localhost
- index.js host: 'localhost', port: 8888
注:第一个为网关地址,第二个为项目访问地址
注意:如果出现未找到node-sass模块,只需要在窗口中运行
npm install node-sass 即可,然后重新npm install,npm run dev
运行项目的时候,没有提示node-sass 模块为找到,需要看一下当前的nodejs 版本
node -v : 建议v10.15.3
后端前端结构:
配置目录:
api:定义请求的路径
index:可以修改项目启动的端口
dev.env.js:有请求的基础路径:
npm run dev:启动项目:
改变了数据库的结果,我们需要往ES中推送数据,为了更好的在两个服务建解耦,无论是依赖它调用还是Feign调用,都有依赖性,最终要保证原子性,保证原子性,如果一个不成功会影响其他的操作,这个是不允许的,我们会用到一种方式消息队列,完成数据修改,发送消息到消息队列,ES中的索引库会监听消息对列,进而操作索引库,达到数据同步。
1.3属性管理功能
三级分类组件封装:
一级分类组件:CategorySelector.vue
<template>
<!--查询表单-->
<el-form :inline="true" class="demo-form-inline">
<!-- 一级分类 -->
<el-form-item label="一级分类">
<el-select
v-model="category1Id"
placeholder="请选择"
@change="category1Changed">
<el-option
v-for="category in categoryList1"
:key="category.id"
:label="category.name"
:value="category.id"/>
</el-select>
</el-form-item>
<!-- 二级分类 -->
<el-form-item label="二级分类">
<el-select
v-model="category2Id"
placeholder="请选择"
@change="category2Changed">
<el-option
v-for="category in categoryList2"
:key="category.id"
:label="category.name"
:value="category.id"/>
</el-select>
</el-form-item>
<!-- 三级分类 -->
<el-form-item label="三级分类">
<el-select
v-model="category3Id"
placeholder="请选择"
@change="category3Changed">
<el-option
v-for="category in categoryList3"
:key="category.id"
:label="category.name"
:value="category.id"/>
</el-select>
</el-form-item>
</el-form>
</template>
<script>
import prop from '@/api/components/CategorySelector'
export default {
data() {
return {
// 查询表单数据
category1Id: null,
category2Id: null,
category3Id: null,
categoryList1: [],
categoryList2: [],
categoryList3: []
}
},
// 初始化一级类别
created() {
prop.getCategory1().then(response => {
this.categoryList1 = response.data
})
},
methods: {
// 切换二级类别
category1Changed() {
prop.getCategory2(this.category1Id).then(response => {
this.category2Id = null
this.category3Id = null
this.categoryList2 = response.data
this.$emit('listenOnSelect', this.category1Id, 1)
})
// 清空属性列表
this.attrInfoList = null
},
// 切换三级类别
category2Changed() {
prop.getCategory3(this.category2Id).then(response => {
this.category3Id = null
this.categoryList3 = response.data
this.$emit('listenOnSelect', this.category2Id, 2)
})
},
// 显示属性列表
category3Changed() {
const category = this.categoryList3.find(item => {
return this.category3Id === item.id
})
console.log(category)
// 子组件向父组件传值
this.$emit('listenOnSelect', this.category3Id, 3)
this.$emit('listenOnCateSelect', this.category3Id, category.name)
}
}
}
</script>
js访问接口:CategorySelector.js
import request from '@/utils/request'
export default {
// 查找一级分类
getCategory1() {
return request({
url: '/admin/product/getCategory1',
method: 'get'
})
},
// 查找二级分类
getCategory2(category1Id) {
return request({
url: '/admin/product/getCategory2/' + category1Id,
method: 'get'
})
},
// 查找三级分类
getCategory3(category2Id) {
return request({
url: '/admin/product/getCategory3/' + category2Id,
method: 'get'
})
}
}
<!--三级下拉列表-->
<CategorySelector @listenOnSelect="getAttrInfoList" />
import prop from '@/api/baseinfo/prop'
1.4三级分类(属性)查询实现
创建Mapper:
包名:com.atguigu.gmall.product.mapper
BaseCategory1Mapper :
@Mapper
public interface BaseCategory1Mapper extends BaseMapper<BaseCategory1> {
}
BaseCategory2Mapper :
@Mapper
public interface BaseCategory2Mapper extends BaseMapper<BaseCategory2> {
}
BaseCategory3Mapper
@Mapper
public interface BaseCategory3Mapper extends BaseMapper<BaseCategory3> {
}
BaseAttrInfoMapper :
@Mapper
public interface BaseAttrInfoMapper extends BaseMapper<BaseAttrInfo> {
BaseAttrValueMapper :
@Mapper
public interface BaseAttrValueMapper extends BaseMapper<BaseAttrValue> {
}
创建Service:
public interface ManageService {
/**
* 查询所有的一级分类信息
* @return
*/
List<BaseCategory1> getCategory1();
/**
* 根据一级分类Id 查询二级分类数据
* @param category1Id
* @return
*/
List<BaseCategory2> getCategory2(Long category1Id);
/**
* 根据二级分类Id 查询三级分类数据
* @param category2Id
* @return
*/
List<BaseCategory3> getCategory3(Long category2Id);
/**
* 根据分类Id 获取平台属性数据
* 接口说明:
* 1,平台属性可以挂在一级分类、二级分类和三级分类
* 2,查询一级分类下面的平台属性,传:category1Id,0,0; 取出该分类的平台属性
* 3,查询二级分类下面的平台属性,传:category1Id,category2Id,0;
* 取出对应一级分类下面的平台属性与二级分类对应的平台属性
* 4,查询三级分类下面的平台属性,传:category1Id,category2Id,category3Id;
* 取出对应一级分类、二级分类与三级分类对应的平台属性
*
* @param category1Id
* @param category2Id
* @param category3Id
* @return
*/
List<BaseAttrInfo> getAttrInfoList(Long category1Id, Long category2Id, Long category3Id);
}
实习类:ManageServiceImpl :
@Service
public class ManageServiceImpl implements ManageService {
@Autowired
private BaseCategory1Mapper baseCategory1Mapper;
@Autowired
private BaseCategory2Mapper baseCategory2Mapper;
@Autowired
private BaseCategory3Mapper baseCategory3Mapper;
@Autowired
private BaseAttrInfoMapper baseAttrInfoMapper;
@Autowired
private BaseAttrValueMapper baseAttrValueMapper;
@Override
public List<BaseCategory1> getCategory1() {
return baseCategory1Mapper.selectList(null);
}
@Override
public List<BaseCategory2> getCategory2(Long category1Id) {
// select * from baseCategory2 where Category1Id = ?
QueryWrapper queryWrapper = new QueryWrapper<BaseCategory2>();
queryWrapper.eq("category1_id",category1Id);
List<BaseCategory2> baseCategory2List = baseCategory2Mapper.selectList(queryWrapper);
return baseCategory2List;
}
@Override
public List<BaseCategory3> getCategory3(Long category2Id) {
// select * from baseCategory3 where Category2Id = ?
QueryWrapper queryWrapper = new QueryWrapper<BaseCategory3>();
queryWrapper.eq("category2_id",category2Id);
return baseCategory3Mapper.selectList(queryWrapper);
}
@Override
public List<BaseAttrInfo> getAttrInfoList(Long category1Id, Long category2Id, Long category3Id) {
// 调用mapper:
return baseAttrInfoMapper.selectBaseAttrInfoList(category1Id, category2Id, category3Id);
}
}
Servie中注入mapper的时候会显示报错,这个报错是警告,这是正常的,不管也没事,为了让他不显示可以这样干:
一:加一个注解
二:Alt+回车
勾选去掉,或者更改提示颜色
三:使用注解抑制警告
创建Controller:
@Api(tags = "商品基础属性接口")
@RestController
@RequestMapping("admin/product")
public class BaseManageController {
@Autowired
private ManageService manageService;
/**
* 查询所有的一级分类信息
* @return
*/
@GetMapping("getCategory1")
public Result<List<BaseCategory1>> getCategory1() {
List<BaseCategory1> baseCategory1List = manageService.getCategory1();
return Result.ok(baseCategory1List);
}
/**
* 根据一级分类Id 查询二级分类数据
* @param category1Id
* @return
*/
@GetMapping("getCategory2/{category1Id}")
public Result<List<BaseCategory2>> getCategory2(@PathVariable("category1Id") Long category1Id) {
List<BaseCategory2> baseCategory2List = manageService.getCategory2(category1Id);
return Result.ok(baseCategory2List);
}
/**
* 根据二级分类Id 查询三级分类数据
* @param category2Id
* @return
*/
@GetMapping("getCategory3/{category2Id}")
public Result<List<BaseCategory3>> getCategory3(@PathVariable("category2Id") Long category2Id) {
List<BaseCategory3> baseCategory3List = manageService.getCategory3(category2Id);
return Result.ok(baseCategory3List);
}
/**
* 根据分类Id 获取平台属性数据
* @param category1Id
* @param category2Id
* @param category3Id
* @return
*/
@GetMapping("attrInfoList/{category1Id}/{category2Id}/{category3Id}")
public Result<List<BaseAttrInfo>> attrInfoList(@PathVariable("category1Id") Long category1Id,
@PathVariable("category2Id") Long category2Id,
@PathVariable("category3Id") Long category3Id) {
List<BaseAttrInfo> baseAttrInfoList = manageService.getAttrInfoList(category1Id, category2Id, category3Id);
return Result.ok(baseAttrInfoList);
}
}
getCategory1接口:查询所有的一级分类信息
根据一级分类Id 查询二级分类数据:getCategory2/{category1Id}
根据二级分类Id 查询三级分类数据:getCategory3/{category2Id}
随着分类的增加,下面的属性会逐渐增多,走到哪一级就会显示哪一级的修改
不用查询*
多表查询就需要手动写sql了
在BaseAttrInfoMapper类添加方法:
/**
* 根据分类Id 查询平台属性集合对象 | 编写xml 文件
* @param category1Id
* @param category2Id
* @param category3Id
* @return
*/
List<BaseAttrInfo> selectBaseAttrInfoList(@Param("category1Id")Long category1Id, @Param("category2Id")Long category2Id, @Param("category3Id")Long category3Id);
在BaseAttrInfoMapper.xml添加查询方法:
在resources目录添加mapper文件夹,添加 BaseAttrInfoMapper.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper SYSTEM "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<!--namespace 定义接口的全路径-->
<mapper namespace="com.atguigu.gmall.product.mapper.BaseAttrInfoMapper">
<!--
resultMap:表示返回的映射结果集
id : 表示唯一标识
type:表示返回结果集的数据类型
autoMapping : 自动映射
-->
<resultMap id="baseAttrInfoMap" type="com.atguigu.gmall.model.product.BaseAttrInfo" autoMapping="true">
<!--id:表示主键 property:表示实体类的属性名 column:表示通过sql 执行以后查询出来的字段名-->
<id property="id" column="id"></id>
<!--result : 表示映射普通字段-->
<!--<result property="" column=""></result>-->
<!--mybatis 如何配置一对多-->
<!--ofType : 返回的数据类型-->
<collection property="attrValueList" ofType="com.atguigu.gmall.model.product.BaseAttrValue" autoMapping="true">
<!--如果有字段重复则起别名-->
<id property="id" column="attr_value_id"></id>
</collection>
</resultMap>
<!--id:表示方法名-->
<select id="selectBaseAttrInfoList" resultMap="baseAttrInfoMap">
SELECT
bai.id,
bai.attr_name,
bai.category_id,
bai.category_level,
bav.id attr_value_id,
bav.value_name,
bav.attr_id
FROM
base_attr_info bai
INNER JOIN base_attr_value bav ON bai.id = bav.attr_id
<where>
<if test="category1Id != null and category1Id != 0">
or (bai.category_id = #{category1Id} and bai.category_level = 1)
</if>
<if test="category2Id != null and category2Id != 0">
or (bai.category_id = #{category2Id} and bai.category_level = 2)
</if>
<if test="category3Id != null and category3Id != 0">
or (bai.category_id = #{category3Id} and bai.category_level = 3)
</if>
</where>
order by bai.category_level, bai.id
</select>
</mapper>