一、商品列表的展示
1.1 创建商品修改页面goods-update.vue
<template>
<div class="mod-config">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-form-item>
<el-input v-model="dataForm.key" placeholder="参数名" clearable></el-input>
</el-form-item>
<el-form-item>
<el-button @click="getDataList()">查询</el-button>
<el-button v-if="isAuth('manager:goods:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button>
<el-button v-if="isAuth('manager:goods:delete')" type="danger" @click="deleteHandle()" :disabled="dataListSelections.length <= 0">批量删除</el-button>
</el-form-item>
</el-form>
<el-table
:data="dataList"
border
v-loading="dataListLoading"
@selection-change="selectionChangeHandle"
style="width: 100%;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="id"
header-align="center"
align="center"
label="商品ID">
</el-table-column>
<el-table-column
prop="goodsName"
header-align="center"
align="center"
label="商品名称">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="一级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category1Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="二级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category2Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="三级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category3Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="状态">
<template slot-scope="scope">
<span>{{status[scope.row.auditStatus]}}</span>
</template>
</el-table-column>
<el-table-column
fixed="right"
header-align="center"
align="center"
width="150"
label="操作">
<template slot-scope="scope">
<el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
<el-button type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</template>
1.2 goods-update.vue JS代码部分:
<script>
export default {
data () {
return {
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
status:["未审核","己审核","审核未通过","己关闭"], //代表商品状态值,数据库为数值,为了显示成中文状态这里定义成数组
itemCats:[],
}
},
activated () {
//1. 查询所有商品数据
this.getDataList()
//2. 查询所有分类
this.findItemCats();
},
methods: {
// 查询所有分类
findItemCats(){
this.$http({
url: this.$http.adornUrl('/shop/itemcat/findAll'),
method: 'get',
}).then(({data}) => {
if (data && data.code === 0) {
for (let i = 0; i < data.list.length; i++) {
let itemCat = data.list[i];
console.log("itemCat:",itemCat);
//以分类id为key,以分类名称为值放到分类数组中(为了显示中文字符)
this.itemCats[itemCat.id] = itemCat.name;
}
}
})
},
// 获取数据列表
getDataList () {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/shop/goods/list'),
method: 'get',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'key': this.dataForm.key
})
}).then(({data}) => {
if (data && data.code === 0) {
this.dataList = data.page.list
this.totalPage = data.page.totalCount
} else {
this.dataList = []
this.totalPage = 0
}
this.dataListLoading = false
})
},
// 每页数
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
// 当前页
currentChangeHandle (val) {
this.pageIndex = val
this.getDataList()
},
// 多选
selectionChangeHandle (val) {
this.dataListSelections = val
},
// 新增 / 修改
addOrUpdateHandle (id) {
this.$router.push(`/shop-goods?id=${id}`)
},
// 删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.id
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/shop/goods/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}
}
}
</script>
1.3 运行效果如下:
二、商品的修改
第一部分:修改商品的展示:
2.1 点击“修改”按钮事件处理:
// 修改
addOrUpdateHandle (id) {
this.$router.push(`/shop-goods?id=${id}`)
},
说明: 代表跳转到/shop-goods页面,即:shop目录下的goods.vue页面。
2.2 在modules/shop/goods.vue文件中,得到传入id并发请求获取复合商品对象
export default {
data () {
return {
goodsForm:{
goods:{typeTemplateId:'',brandId:''},
goodsDesc:{itemImages:[],customAttributeItems:[],specificationItems:[]},
items:[],
},
categorys1:[], //一级分类
categorys2:[], //二级分类
categorys3:[], //三级分类
brandList:[], //代表某个模板下的品牌列表
dialogFormVisible:false, //代表对话框的显示与隐藏
imageEntity:{}, //代表每次上传的文件对象
fileList:[], //代表上传后的文件列表
specGroup:[], //代表规格及规格列表
optionList:[], //代表是否选择
}
},
created() {
//1. 查询一级分类
this.findCategorys1();
//2. 接受修改页面的商品id,并根据id查询商品
this.findById();
},
watch:{ //用于监控某个变量值的变化
category1newId(itemCatId,oldV){ //itemCatId:代表当前用户选择的一级分类的id
//1. 根据一级分类的父id向后台发出查询请求,查询出此一级分类id对应的二级分类列表
this.$http({
url: this.$http.adornUrl(`/shop/itemcat/findByParentId/${itemCatId}`),
method: 'get',
}).then(({data}) => {
if(data.code == 0){
// delete this.goodsForm.goods.category2Id
this.categorys2 = data.list;
}
})
},
category2newId(itemCatId,oldV){ //itemCatId:代表当前用户选择的二级分类的id
//1. 根据二级分类的父id向后台发出查询请求,查询出此一级分类id对应的三级分类列表
this.$http({
url: this.$http.adornUrl(`/shop/itemcat/findByParentId/${itemCatId}`),
method: 'get',
}).then(({data}) => {
if(data.code == 0){
// delete this.goodsForm.goods.category3Id
this.categorys3 = data.list;
}
})
},
category3newId(itemCatId,oldV){ //itemCatId:代表当前用户选择的三级分类的id
//1. 根据三级分类的父id向后台发出查询请求,查询出此三级分类对应的模板id
this.$http({
url: this.$http.adornUrl(`/shop/itemcat/info/${itemCatId}`),
method: 'get',
}).then(({data}) => {
if(data.code == 0){
this.goodsForm.goods.typeTemplateId = data.itemCat.typeId;
}
})
},
typetemplatenewId(typeId,oldV){ //typeId:代表当前模板id
//0.1 得到修改页面传入的参数id
let id = this.$route.query.id;
//1. 模板id发生变化就到后台查询出这个模板对应的品牌列表
//2. 模板id发生变化,到模板对象中的扩展属性
this.$http({
url: this.$http.adornUrl(`/shop/typetemplate/info/${typeId}`),
method: 'get',
}).then(({data}) => {
if(data.code == 0){
// console.log("data:",data)
//① 得到模板的品牌列表
this.brandList = JSON.parse(data.typeTemplate.brandIds);
//② 得到模板的扩展属性列表
if(!id){ //如果是添加商品操作,才执行下面的语句
this.goodsForm.goodsDesc.customAttributeItems = JSON.parse(data.typeTemplate.customAttributeItems)
}
//③ 得到模板的规格及规格选项列表
this.$http({
url: this.$http.adornUrl(`shop/specification/findSpecByTypeId/${typeId}`),
method: 'get',
}).then(({data}) => {
this.specGroup = data.specifications;
console.log("data:",this.specGroup);
if(!this.$route.query.id){ //此处一定要添加这个条件,否则,此值就会在显示修改页面时,将得到的optionList的值覆盖掉
this.optionList = [];
data.specifications.forEach(sp=>{
this.optionList.push([]);
})
}
})
}
})
}
},
computed:{ //自动计算属性值的变化
category1newId(){ //1. 计算一级分类id的值是否变化
return this.goodsForm.goods.category1Id;
},
category2newId(){ //2. 计算二级分类id的值是否变化
return this.goodsForm.goods.category2Id;
},
category3newId(){ //3. 计算三级分类id的值是否变化
return this.goodsForm.goods.category3Id;
},
typetemplatenewId(){ //4. 监控模板id值的变化
return this.goodsForm.goods.typeTemplateId;
}
},
methods: {
//0.根据商品id,查询商品
findById(){
//0.1 得到修改页面传入的参数id
let id = this.$route.query.id;
let _this = this;
//0.2 根据商品id在后台查询商品
this.$http({
url: this.$http.adornUrl(`/shop/goods/findById/${id}`),
method: 'get',
}).then(({data}) => {
if(data.code == 0){
_this.goodsForm = data.goods;
this.goodsForm.goods.brandId = parseInt(data.goods.goods.brandId);
//0.3 将后端查询到的字符串转换为json对象
this.goodsForm.goodsDesc.specificationItems = JSON.parse(this.goodsForm.goodsDesc.specificationItems)
this.goodsForm.goodsDesc.itemImages = JSON.parse(this.goodsForm.goodsDesc.itemImages)
this.goodsForm.goodsDesc.customAttributeItems = JSON.parse(this.goodsForm.goodsDesc.customAttributeItems)
this.goodsForm.items.forEach(item=>{
item.spec = JSON.parse(item.spec);
})
//0.4 让规格选项自动勾选
this.optionList = [];
this.goodsForm.goodsDesc.specificationItems.forEach(spec=>{
this.optionList.push(spec.attributeValue);
})
console.log("optionList:",this.optionList);
}
})
},
//1. 查询一级分类
findCategorys1(){
this.$http({
url: this.$http.adornUrl('/shop/itemcat/findAll'),
method: 'get',
}).then(({data}) => {
this.categorys1 = data.categorys1;
})
},
//保存商品
save(){
//1. 处理前端的json对象为字符串,因为后台都是字符串
this.goodsForm.goodsDesc.specificationItems = JSON.stringify(this.goodsForm.goodsDesc.specificationItems)
this.goodsForm.goodsDesc.itemImages = JSON.stringify(this.goodsForm.goodsDesc.itemImages)
this.goodsForm.goodsDesc.customAttributeItems = JSON.stringify(this.goodsForm.goodsDesc.customAttributeItems)
this.goodsForm.items.forEach(item=>{
item.spec = JSON.stringify(item.spec);
})
//2. 向后台发送请求
this.$http({
url: this.$http.adornUrl(`/shop/goods/${this.$route.query.id ? 'update':'save'} `),
method: `${this.$route.query.id ? 'put' : 'post'}`,
data:this.goodsForm
}).then(({data}) => {
if(data.code == 0){
this.goodsForm={
goods:{typeTemplateId:''},
goodsDesc:{itemImages:[],customAttributeItems:[],specificationItems:[]},
items:[],
}
this.fileList = []
this.optionList=[]; //选择的规格选项列表
this.specGroup=[]
this.imageEntity = {}
}
})
},
//进行文件上传
uploadFile(val){
//1. 构造上传的表单对象
let data = new FormData();
//2. 添加要上传的文件数据
data.append("file",val.file); //上传的文件对象
//3. 清空上传的列表
this.fileList = [];
//4. 开始上传
this.$http({
url: this.$http.adornUrl('/shop/upload'),
method: 'post',
data:data,
headers:{"Context-Type":"multipart/form-data"}
}).then(({data}) => {
if(data.code == 0){
//如果上传成功,就向文件列表添加文件
this.fileList.push({name:val.raw,url:data.url});
this.imageEntity.url = data.url;
}
})
},
//保存图片
saveImage(){
this.goodsForm.goodsDesc.itemImages.push(this.imageEntity);
this.dialogFormVisible=false
},
//点击规格选项时的事件处理
getSpecItems(){
console.log("optionList:",this.optionList); //this.optionList:放的是选中的规格选项的值
if(!this.$route.query.id){
}
//0. 每次要设置为默认值
this.goodsForm.goodsDesc.specificationItems = [];
//1. 遍历optionList,在其中遍历this.specGroup,为this.goodsForm.goodsDesc.specificationItems赋值
for (let i = 0; i < this.optionList.length; i++) {
//1.1 得到对应规格的名称
let specName = this.specGroup[i].text;
//1.2 为this.goodsForm.goodsDesc.specificationItems赋值
this.goodsForm.goodsDesc.specificationItems.push({"attributeName":specName,"attributeValue":this.optionList[i]})
}
//2. 【方法一】进行兼容性处理,如果attributeValue这个数组没有值,就将这个对象从this.goodsForm.goodsDesc.specificationItems数组中删除
// for (let i = 0; i < this.optionList.length; i++) {
// let len = this.goodsForm.goodsDesc.specificationItems[i].attributeValue.length;
// if(len == 0){
// this.goodsForm.goodsDesc.specificationItems.splice(i,1);
// break;
// }
// }
//3. 【方法二】采用过滤器处理,只显示attributeValue.length > 0
this.goodsForm.goodsDesc.specificationItems = this.goodsForm.goodsDesc.specificationItems.filter(f=>f.attributeValue.length > 0);
//4. 为goodsForm.items(sku商品列表)赋值
this.createItems();
},
createItems(){
//1. 定义sku商品列表的初始值
this.goodsForm.items = [{spec:{},price:0,num:9999,status:'0',isDefault:'0'}];
//2. 得到用户点击的规格及选项的值
let items = this.goodsForm.goodsDesc.specificationItems;
//3. 遍历上面的items将用户勾选的规格及选项的值赋值给sku列表
items.forEach(item=>{
this.goodsForm.items = this.createColumn(this.goodsForm.items,item.attributeName,item.attributeValue);
})
},
createColumn(items,specName,specValue){
//1. 定义存放返回结果的数组
let skuList = [];
//2. 遍历items数组
items.forEach(item=>{
specValue.forEach(val=>{
//2.1 根据原来的数据深克隆出新行数据
let row = JSON.parse(JSON.stringify(item));
//2.2 为新行的spec对象赋值
row.spec[specName] = val
//2.3 添加此新行到返回的新数组中
skuList.push(row);
})
})
return skuList;
},
}
}
</script>
注意: 1、在修改页面到达时,对于自定义扩展属性一定要判断是否有id,如果没有id才会其设置默认值:
//② 得到模板的扩展属性列表
if(!id){ //如果是添加商品操作,才执行下面的语句
this.goodsForm.goodsDesc.customAttributeItems = JSON.parse(data.typeTemplate.customAttributeItems)
}
注意: 2、在修改页面到达时,对于添加规格默认选中项列表值数组opitonList的处理:
if(!this.$route.query.id){ //此处一定要添加这个条件,否则,此值就会在显示修改页面时,将得到的optionList的值覆盖掉
this.optionList = [];
data.specifications.forEach(sp=>{
this.optionList.push([]);
})
}
2.3 goods.vue中的页面部分不变:
2.4 在后台goodsController中添加findById方法
/**
* 功能: 根据id查询得到复合商品对象
* 参数:
* 返回值: com.zelin.utils.R
* 时间: 2021/7/30 12:38
*/
@RequestMapping("/findById/{id}")
public R findById(@PathVariable("id") Long id){
Goods goods = goodsService.findById(id);
return R.ok().put("goods", goods);
}
2.5 在sellerGoods-serice服务层添加findById方法
/**
* 功能: 根据商品id查询复合类型商品
* 参数:
* 返回值: com.zelin.entity.group.Goods
* 时间: 2021/7/29 21:47
*/
@Override
public Goods findById(Long id) {
//1. 得到商品对象
GoodsEntity goodsEntity = this.getById(id);
System.out.println("goodsEntity = " + goodsEntity);
//2. 得到商品描述对象
GoodsDescEntity goodsDesc = goodsDescService.getById(id);
System.out.println("goodsDesc = " + goodsDesc);
//3. 查询sku商品列表
List<ItemEntity> items = itemService.list(new QueryWrapper<ItemEntity>().eq("goods_id", id));
System.out.println("items = " + items);
//4. 定义复合对象
Goods goods = new Goods();
goods.setGoods(goodsEntity);
goods.setGoodsDesc(goodsDesc);
goods.setItems(items);
//5. 返回
return goods;
}
2.6 最终页面效果:
第二部分:完成修改商品:
2.7 后台控制器添加修改商品:
/**
* 修改
*/
@RequestMapping("/update")
//@RequiresPermissions("manager:goods:update")
public R update(@RequestBody Goods goods){
goodsService.update(goods);
return R.ok();
}
2.8 后台服务层sellergoods-service/goodsServiceImpl.java
/**
* 功能: 修改商品
* 参数:
* 返回值: void
* 时间: 2021/7/30 15:35
*/
@Override
@Transactional
public void update(Goods goods) {
//1. 修改goods商品
this.updateById(goods.getGoods());
//2. 修改goodsDesc商品描述
goodsDescService.updateById(goods.getGoodsDesc());
//3. 对sku商品表,先根据goodsId这个外键删除
itemService.remove(new QueryWrapper<ItemEntity>().eq("goods_id",goods.getGoods().getId()));
//4. 添加sku商品列表
this.insertItem(goods);
}
三、商品审核
3.1 打开renren-fast-vue-manager这个运营商管理的前台页面:
3.2 定义modules/manager/goods.vue文件
3.2.1 进行商品的展示:
<template>
<div class="mod-config">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-button-group>
<el-button type="primary" icon="el-icon-delete" plain>删除</el-button>
<el-button type="primary" icon="el-icon-share" plain @click="updateStatus('1')">审核通过</el-button>
<el-button type="primary" icon="el-icon-edit" plain @click="updateStatus('2')">驳回</el-button>
<el-button type="primary" icon="el-icon-refresh" plain>刷新</el-button>
</el-button-group>
</el-form>
<el-table
:data="dataList"
border
v-loading="dataListLoading"
@selection-change="selectionChangeHandle"
style="width: 100%;margin-top: 10px;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="id"
header-align="center"
align="center"
label="商品ID">
</el-table-column>
<el-table-column
prop="goodsName"
header-align="center"
align="center"
label="商品名称">
</el-table-column>
<el-table-column
prop="price"
header-align="center"
align="center"
label="商品价格">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="一级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category1Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="二级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category2Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="三级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category3Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="状态">
<template slot-scope="scope">
<span>{{status[scope.row.auditStatus]}}</span>
</template>
</el-table-column>
<el-table-column
fixed="right"
header-align="center"
align="center"
width="150"
label="操作">
<template slot-scope="scope">
<el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
<el-button type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</template>
3.2.2 配套的js部分:
<script>
export default {
data () {
return {
dataForm:{
key:''
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false,
status:["未审核","己审核","审核未通过","己关闭"],
itemCats:[], //代表所有分类
selectIds:[], //被选中的商品id数组
}
},
activated () {
this.getDataList()
this.findItemCats()
},
methods: {
// 查询所有分类
findItemCats(){
this.$http({
url: this.$http.adornUrl('/manager/itemcat/findAll'),
method: 'get',
}).then(({data}) => {
if (data && data.code === 0) {
data.list.forEach(itemCat=>{
this.itemCats[itemCat.id] = itemCat.name;
})
}
})
},
// 获取数据列表
getDataList () {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/manager/goods/list'),
method: 'get',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'key': this.dataForm.key
})
}).then(({data}) => {
if (data && data.code === 0) {
this.dataList = data.page.list
this.totalPage = data.page.totalCount
} else {
this.dataList = []
this.totalPage = 0
}
this.dataListLoading = false
})
},
// 每页数
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
// 当前页
currentChangeHandle (val) {
this.pageIndex = val
this.getDataList()
},
// 多选
selectionChangeHandle (val) {
this.dataListSelections = val
//得到选中的商品id
this.selectIds = val.map(m=>{
return m.id;
})
console.log("dataListSelections--->",val)
},
// 删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.id
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/manager/goods/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}
}
}
</script>
3.3 商品审核:
3.3.1 前端:
//审核商品(参数,代表审核的状态值 1:通过 2:驳回)
updateStatus(status){
this.$http({
url: this.$http.adornUrl(`/manager/goods/updateStatus?ids=${this.selectIds}&status=${status}`),
method: 'get',
}).then(({data}) => {
if (data && data.code === 0) {
this.getDataList()
}
})
},
3.3.2 后端:
GoodsController:
/**
* 功能: 批量审核数据
* 参数:
* 返回值: com.zelin.utils.R
* 时间: 2021/7/30 16:11
*/
@RequestMapping("/updateStatus")
public R updateStatus(Long[] ids,String status){
goodsService.updateStatus(ids,status);
return R.ok();
}
GoodsServiceImpl:
/**
* 功能: 只显示未审核的
* 参数:
* 返回值: com.zelin.utils.PageUtils
* 时间: 2021/7/30 16:28
*/
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<GoodsEntity> page = this.page(
new Query<GoodsEntity>().getPage(params),
new QueryWrapper<GoodsEntity>().eq("audit_status","0")
);
return new PageUtils(page);
}
四、逻辑删除商品
4.1 配置GoodsEntity实体类
/**
* 是否删除
*/
@TableLogic
private int isDelete;
4.2 后端控制器:
/**
* 逻辑删除
*/
@RequestMapping("/delete")
//@RequiresPermissions("manager:goods:delete")
public R delete(@RequestBody Long[] ids){
goodsService.removeByIds(Arrays.asList(ids));
return R.ok();
}
4.3 前端:
// 调用后台逻辑删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.id
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/manager/goods/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}
4.4 页面效果:
/**
* 功能: 根据id查询得到复合商品对象
* 参数:
* 返回值: com.zelin.utils.R
* 时间: 2021/7/30 12:38
*/
@RequestMapping("/findById/{id}")
public R findById(@PathVariable("id") Long id){
Goods goods = goodsService.findById(id);
return R.ok().put("goods", goods);
}
/**
* 功能: 根据商品id查询复合类型商品
* 参数:
* 返回值: com.zelin.entity.group.Goods
* 时间: 2021/7/29 21:47
*/
@Override
public Goods findById(Long id) {
//1. 得到商品对象
GoodsEntity goodsEntity = this.getById(id);
System.out.println("goodsEntity = " + goodsEntity);
//2. 得到商品描述对象
GoodsDescEntity goodsDesc = goodsDescService.getById(id);
System.out.println("goodsDesc = " + goodsDesc);
//3. 查询sku商品列表
List<ItemEntity> items = itemService.list(new QueryWrapper<ItemEntity>().eq("goods_id", id));
System.out.println("items = " + items);
//4. 定义复合对象
Goods goods = new Goods();
goods.setGoods(goodsEntity);
goods.setGoodsDesc(goodsDesc);
goods.setItems(items);
//5. 返回
return goods;
}
/**
* 修改
*/
@RequestMapping("/update")
//@RequiresPermissions("manager:goods:update")
public R update(@RequestBody Goods goods){
goodsService.update(goods);
return R.ok();
}
/**
* 功能: 修改商品
* 参数:
* 返回值: void
* 时间: 2021/7/30 15:35
*/
@Override
@Transactional
public void update(Goods goods) {
//1. 修改goods商品
this.updateById(goods.getGoods());
//2. 修改goodsDesc商品描述
goodsDescService.updateById(goods.getGoodsDesc());
//3. 对sku商品表,先根据goodsId这个外键删除
itemService.remove(new QueryWrapper<ItemEntity>().eq("goods_id",goods.getGoods().getId()));
//4. 添加sku商品列表
this.insertItem(goods);
}
<template>
<div class="mod-config">
<el-form :inline="true" :model="dataForm" @keyup.enter.native="getDataList()">
<el-button-group>
<el-button type="primary" icon="el-icon-delete" plain>删除</el-button>
<el-button type="primary" icon="el-icon-share" plain @click="updateStatus('1')">审核通过</el-button>
<el-button type="primary" icon="el-icon-edit" plain @click="updateStatus('2')">驳回</el-button>
<el-button type="primary" icon="el-icon-refresh" plain>刷新</el-button>
</el-button-group>
</el-form>
<el-table
:data="dataList"
border
v-loading="dataListLoading"
@selection-change="selectionChangeHandle"
style="width: 100%;margin-top: 10px;">
<el-table-column
type="selection"
header-align="center"
align="center"
width="50">
</el-table-column>
<el-table-column
prop="id"
header-align="center"
align="center"
label="商品ID">
</el-table-column>
<el-table-column
prop="goodsName"
header-align="center"
align="center"
label="商品名称">
</el-table-column>
<el-table-column
prop="price"
header-align="center"
align="center"
label="商品价格">
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="一级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category1Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="二级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category2Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="三级类目">
<template slot-scope="scope">
<span>{{itemCats[scope.row.category3Id]}}</span>
</template>
</el-table-column>
<el-table-column
header-align="center"
align="center"
label="状态">
<template slot-scope="scope">
<span>{{status[scope.row.auditStatus]}}</span>
</template>
</el-table-column>
<el-table-column
fixed="right"
header-align="center"
align="center"
width="150"
label="操作">
<template slot-scope="scope">
<el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.id)">修改</el-button>
<el-button type="text" size="small" @click="deleteHandle(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
@size-change="sizeChangeHandle"
@current-change="currentChangeHandle"
:current-page="pageIndex"
:page-sizes="[10, 20, 50, 100]"
:page-size="pageSize"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper">
</el-pagination>
</div>
</template>
<script>
export default {
data () {
return {
dataForm:{
key:''
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false,
status:["未审核","己审核","审核未通过","己关闭"],
itemCats:[], //代表所有分类
selectIds:[], //被选中的商品id数组
}
},
activated () {
this.getDataList()
this.findItemCats()
},
methods: {
// 查询所有分类
findItemCats(){
this.$http({
url: this.$http.adornUrl('/manager/itemcat/findAll'),
method: 'get',
}).then(({data}) => {
if (data && data.code === 0) {
data.list.forEach(itemCat=>{
this.itemCats[itemCat.id] = itemCat.name;
})
}
})
},
// 获取数据列表
getDataList () {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/manager/goods/list'),
method: 'get',
params: this.$http.adornParams({
'page': this.pageIndex,
'limit': this.pageSize,
'key': this.dataForm.key
})
}).then(({data}) => {
if (data && data.code === 0) {
this.dataList = data.page.list
this.totalPage = data.page.totalCount
} else {
this.dataList = []
this.totalPage = 0
}
this.dataListLoading = false
})
},
// 每页数
sizeChangeHandle (val) {
this.pageSize = val
this.pageIndex = 1
this.getDataList()
},
// 当前页
currentChangeHandle (val) {
this.pageIndex = val
this.getDataList()
},
// 多选
selectionChangeHandle (val) {
this.dataListSelections = val
//得到选中的商品id
this.selectIds = val.map(m=>{
return m.id;
})
console.log("dataListSelections--->",val)
},
// 删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.id
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/manager/goods/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}
}
}
</script>
//审核商品(参数,代表审核的状态值 1:通过 2:驳回)
updateStatus(status){
this.$http({
url: this.$http.adornUrl(`/manager/goods/updateStatus?ids=${this.selectIds}&status=${status}`),
method: 'get',
}).then(({data}) => {
if (data && data.code === 0) {
this.getDataList()
}
})
},
/**
* 功能: 批量审核数据
* 参数:
* 返回值: com.zelin.utils.R
* 时间: 2021/7/30 16:11
*/
@RequestMapping("/updateStatus")
public R updateStatus(Long[] ids,String status){
goodsService.updateStatus(ids,status);
return R.ok();
}
/**
* 功能: 只显示未审核的
* 参数:
* 返回值: com.zelin.utils.PageUtils
* 时间: 2021/7/30 16:28
*/
@Override
public PageUtils queryPage(Map<String, Object> params) {
IPage<GoodsEntity> page = this.page(
new Query<GoodsEntity>().getPage(params),
new QueryWrapper<GoodsEntity>().eq("audit_status","0")
);
return new PageUtils(page);
}
/**
* 是否删除
*/
@TableLogic
private int isDelete;
/**
* 逻辑删除
*/
@RequestMapping("/delete")
//@RequiresPermissions("manager:goods:delete")
public R delete(@RequestBody Long[] ids){
goodsService.removeByIds(Arrays.asList(ids));
return R.ok();
}
// 调用后台逻辑删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.id
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/manager/goods/delete'),
method: 'post',
data: this.$http.adornData(ids, false)
}).then(({data}) => {
if (data && data.code === 0) {
this.$message({
message: '操作成功',
type: 'success',
duration: 1500,
onClose: () => {
this.getDataList()
}
})
} else {
this.$message.error(data.msg)
}
})
})
}