1、gateway网关跨域属性修改,options预请求缓存

2、商城商品三级分类功能实现
pull/254/head
xjs 4 years ago
parent 50c240e6d4
commit f298959388

@ -31,6 +31,8 @@ public class GatewayConfig
config.addAllowedMethod("*"); config.addAllowedMethod("*");
config.addAllowedOrigin("*"); config.addAllowedOrigin("*");
config.addAllowedHeader("*"); config.addAllowedHeader("*");
//缓存options预请求
config.setMaxAge(60000L);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser()); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);

@ -0,0 +1,58 @@
import request from '@/utils/request'
// 获取菜单
export function getMenus() {
return request({
url: '/mall-product/product/category/list/tree',
method: 'get',
})
}
//删除分类
export function removeMenus(ids) {
return request({
url: '/mall-product/product/category/delete',
method: 'delete',
data:ids
})
}
//添加三级分类
export function addCategory(data) {
return request({
url: '/mall-product/product/category/save',
method: 'post',
data:data
})
}
//修改三级分类
export function editCategory(data) {
return request({
url: '/mall-product/product/category/update',
method: 'put',
data:data
})
}
//获取具体一个三级分类
export function getCategory(data) {
return request({
url: `/mall-product/product/category/info/${data.catId}`,
method: 'get',
})
}
//批量修改
export function batchSave(data) {
return request({
url: '/mall-product/product/category/update/sort',
method: 'put',
data:data
})
}

@ -0,0 +1,357 @@
<template>
<div class="app-container">
<el-form :inline="true">
<el-form-item label="">
<el-switch v-model="draggable" active-text="开启拖拽" inactive-text="关闭拖拽"></el-switch>
</el-form-item>
<el-form-item label="">
<el-button type="danger" size="mini" @click="batchDelete" icon="el-icon-delete">批量删除</el-button>
<el-button v-if="draggable" size="mini" @click="batchSave" icon="el-icon-check"></el-button>
</el-form-item>
</el-form>
<el-tree
:data="menus"
:props="defaultProps"
:expand-on-click-node="false"
show-checkbox
node-key="catId"
:default-expanded-keys="expandedKey"
:draggable="draggable"
:allow-drop="allowDrop"
@node-drop="handleDrop"
ref="menuTree">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span>{{ node.label }}</span>
<span style="margin-left: 40px">
<el-button
v-if="node.level <=2"
type="text"
size="mini"
icon="el-icon-plus"
@click="() => append(data)"
>添加</el-button>
<el-divider direction="vertical"></el-divider>
<el-button type="text" icon="el-icon-edit" size="mini" @click="edit(data)"></el-button>
<el-divider direction="vertical"></el-divider>
<el-button
v-if="node.childNodes.length==0"
type="text"
size="mini"
icon="el-icon-delete"
@click="() => remove(node, data)"
>删除</el-button>
</span>
</span>
</el-tree>
<el-dialog
:title="title"
:visible.sync="dialogVisible"
width="30%"
:close-on-click-modal="false">
<el-form :model="category">
<el-form-item label="分类名称">
<el-input v-model="category.name" autocomplete="off"></el-input>
</el-form-item>
<el-form-item label="菜单图标" prop="icon">
<el-popover
placement="bottom-start"
width="460"
trigger="click"
@show="$refs['iconSelect'].reset()"
>
<IconSelect ref="iconSelect" @selected="selected"/>
<el-input slot="reference" v-model="category.icon" placeholder="点击选择图标" readonly>
<svg-icon
v-if="category.icon"
slot="prefix"
:icon-class="category.icon"
class="el-input__icon"
style="height: 32px;width: 16px;"
/>
<i v-else slot="prefix" class="el-icon-search el-input__icon"/>
</el-input>
</el-popover>
</el-form-item>
<el-form-item label="计量单位">
<el-input v-model="category.productUnit" autocomplete="off"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="submitData"> </el-button>
</span>
</el-dialog>
</div>
</template>
<script>
//jsjsjson
import {addCategory, batchSave, editCategory, getCategory, getMenus, removeMenus} from "@/api/mall/product/category";
import IconSelect from "@/components/IconSelect";
export default {
//import使
components: {IconSelect},
name: "Category",
props: {},
data() {
return {
pCid: [],
draggable: false,
updateNodes: [],
maxLevel: 0,
title: "",
dialogType: "", //edit,add
category: {
name: "",
parentCid: 0,
catLevel: 0,
showStatus: 1,
sort: 0,
productUnit: "",
icon: "",
catId: null
},
dialogVisible: false,
menus: [],
expandedKey: [],
defaultProps: {
children: "children",
label: "name"
}
};
},
// data
computed: {},
//data
watch: {},
//
methods: {
//
selected(name) {
this.category.icon = name;
},
getMenus() {
this.$modal.loading("请稍候...");
getMenus().then(res => {
this.$modal.closeLoading()
this.menus = res.page;
})
},
batchDelete() {
let catIds = [];
let checkedNodes = this.$refs.menuTree.getCheckedNodes();
for (let i = 0; i < checkedNodes.length; i++) {
catIds.push(checkedNodes[i].catId);
}
this.$confirm(`是否批量删除菜单?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
removeMenus(catIds).then(res => {
this.$modal.notifySuccess("删除成功")
this.getMenus();
})
}).catch(() => {
});
},
batchSave() {
batchSave(this.updateNodes).then(res => {
this.$modal.notifySuccess("菜单顺序等修改成功")
this.getMenus();
this.expandedKey = this.pCid;
this.updateNodes = [];
this.maxLevel = 0;
})
},
handleDrop(draggingNode, dropNode, dropType, ev) {
//1id
let pCid = 0;
let siblings = null;
if (dropType === "before" || dropType === "after") {
pCid =
dropNode.parent.data.catId === undefined
? 0
: dropNode.parent.data.catId;
siblings = dropNode.parent.childNodes;
} else {
pCid = dropNode.data.catId;
siblings = dropNode.childNodes;
}
this.pCid.push(pCid);
//2
for (let i = 0; i < siblings.length; i++) {
if (siblings[i].data.catId === draggingNode.data.catId) {
//
let catLevel = draggingNode.level;
if (siblings[i].level !== draggingNode.level) {
//
catLevel = siblings[i].level;
//
this.updateChildNodeLevel(siblings[i]);
}
this.updateNodes.push({
catId: siblings[i].data.catId,
sort: i,
parentCid: pCid,
catLevel: catLevel
});
} else {
this.updateNodes.push({catId: siblings[i].data.catId, sort: i});
}
}
},
updateChildNodeLevel(node) {
if (node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
var cNode = node.childNodes[i].data;
this.updateNodes.push({
catId: cNode.catId,
catLevel: node.childNodes[i].level
});
this.updateChildNodeLevel(node.childNodes[i]);
}
}
},
allowDrop(draggingNode, dropNode, type) {
//13
//1
this.countNodeLevel(draggingNode);
//+3
let deep = Math.abs(this.maxLevel - draggingNode.level) + 1;
// this.maxLevel
if (type === "inner") {
return deep + dropNode.level <= 3;
} else {
return deep + dropNode.parent.level <= 3;
}
},
countNodeLevel(node) {
//
if (node.childNodes != null && node.childNodes.length > 0) {
for (let i = 0; i < node.childNodes.length; i++) {
if (node.childNodes[i].level > this.maxLevel) {
this.maxLevel = node.childNodes[i].level;
}
this.countNodeLevel(node.childNodes[i]);
}
}
},
//
edit(data) {
this.dialogType = "edit";
this.title = "修改分类";
this.dialogVisible = true;
//
getCategory(data).then(res => {
this.category = res.data
})
},
append(data) {
this.dialogType = "add";
this.title = "添加分类";
this.dialogVisible = true;
this.category.parentCid = data.catId;
this.category.catLevel = data.catLevel * 1 + 1;
this.category.catId = null;
this.category.name = "";
this.category.icon = "";
this.category.productUnit = "";
this.category.sort = 0;
this.category.showStatus = 1;
},
submitData() {
if (this.dialogType === "add") {
this.addCategory();
}
if (this.dialogType === "edit") {
this.editCategory();
}
},
//
editCategory() {
editCategory(this.category).then(res => {
this.$modal.notifySuccess("菜单修改成功")
this.dialogVisible = false;
this.getMenus();
this.expandedKey = [this.category.parentCid];
})
},
//
addCategory() {
addCategory(this.category).then(res => {
this.$modal.notifySuccess("菜单保存成功")
//
this.dialogVisible = false;
//
this.getMenus();
//
this.expandedKey = [this.category.parentCid];
})
},
//
remove(node, data) {
var ids = [data.catId];
this.$confirm(`是否删除【${data.name}】菜单?`, "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
removeMenus(ids).then(res => {
this.$modal.notifySuccess("删除成功")
this.getMenus();
//
this.expandedKey = [node.parent.data.catId];
})
}).catch(() => {
});
},
},
// - 访this
created() {
this.getMenus();
},
// - 访DOM
mounted() {
},
beforeCreate() {
}, // -
beforeMount() {
}, // -
beforeUpdate() {
}, // -
updated() {
}, // -
beforeDestroy() {
}, // -
destroyed() {
}, // -
activated() {
} //keep-alive
};
</script>
<style scoped>
</style>

@ -1,20 +1,17 @@
package com.xjs.mall.product.controller; package com.xjs.mall.product.controller;
import java.util.Arrays; import com.ruoyi.common.log.annotation.Log;
import java.util.Map; import com.ruoyi.common.log.enums.BusinessType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.entity.CategoryEntity;
import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.service.CategoryService;
import com.xjs.utils.PageUtils;
import com.xjs.utils.R; import com.xjs.utils.R;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.List;
/** /**
@ -22,39 +19,45 @@ import com.xjs.utils.R;
* *
* @author xiejs * @author xiejs
* @email 1294405880@qq.com * @email 1294405880@qq.com
* @date 2022-03-15 10:16:53 * @since 2022-03-15 10:16:53
*/ */
@RestController @RestController
@RequestMapping("product/category") @RequestMapping("product/category")
@Api(tags = "商城-商品-分类")
public class CategoryController { public class CategoryController {
@Autowired @Autowired
private CategoryService categoryService; private CategoryService categoryService;
/** /**
* * --
*/ */
@RequestMapping("/list") @GetMapping("/list/tree")
public R list(@RequestParam Map<String, Object> params){ @ApiOperation("树形结构")
PageUtils page = categoryService.queryPage(params); public R list() {
return R.ok().put("page", page); List<CategoryEntity> list = categoryService.listWithTree();
return R.ok().put("page", list);
} }
/** /**
* *
*/ */
@RequestMapping("/info/{catId}") @GetMapping("/info/{catId}")
@ApiOperation("信息")
public R info(@PathVariable("catId") Long catId) { public R info(@PathVariable("catId") Long catId) {
CategoryEntity category = categoryService.getById(catId); CategoryEntity category = categoryService.getById(catId);
return R.ok().put("category", category); return R.ok().put("data", category);
} }
/** /**
* *
*/ */
@RequestMapping("/save") @PostMapping("/save")
@ApiOperation("保存")
@Log(title = "商品分类", businessType = BusinessType.INSERT)
public R save(@RequestBody CategoryEntity category) { public R save(@RequestBody CategoryEntity category) {
categoryService.save(category); categoryService.save(category);
@ -64,19 +67,31 @@ public class CategoryController {
/** /**
* *
*/ */
@RequestMapping("/update") @PutMapping("/update")
@ApiOperation("修改")
@Log(title = "商品分类", businessType = BusinessType.UPDATE)
public R update(@RequestBody CategoryEntity category) { public R update(@RequestBody CategoryEntity category) {
categoryService.updateById(category); categoryService.updateById(category);
return R.ok(); return R.ok();
} }
@PutMapping("/update/sort")
@Log(title = "商品分类", businessType = BusinessType.UPDATE)
public R updateSort(@RequestBody CategoryEntity[] categoryEntities) {
categoryService.updateBatchById(Arrays.asList(categoryEntities));
return R.ok();
}
/** /**
* *
*/ */
@RequestMapping("/delete") @DeleteMapping("/delete")
@ApiOperation("删除")
@Log(title = "商品分类", businessType = BusinessType.DELETE)
public R delete(@RequestBody Long[] catIds) { public R delete(@RequestBody Long[] catIds) {
categoryService.removeByIds(Arrays.asList(catIds));
categoryService.removeMenuByIds(Arrays.asList(catIds));
return R.ok(); return R.ok();
} }

@ -1,18 +1,20 @@
package com.xjs.mall.product.entity; package com.xjs.mall.product.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.List;
import lombok.Data;
/** /**
* *
* *
* @author xiejs * @author xiejs
* @email 1294405880@qq.com * @email 1294405880@qq.com
* @date 2022-03-15 10:16:53 * @since 2022-03-15 10:16:53
*/ */
@Data @Data
@TableName("pms_category") @TableName("pms_category")
@ -39,6 +41,7 @@ public class CategoryEntity implements Serializable {
/** /**
* [0-1] * [0-1]
*/ */
@TableLogic(value = "1",delval = "0")
private Integer showStatus; private Integer showStatus;
/** /**
* *
@ -57,4 +60,10 @@ public class CategoryEntity implements Serializable {
*/ */
private Integer productCount; private Integer productCount;
/**
*
*/
@TableField(exist = false)
private List<CategoryEntity> children;
} }

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
import com.xjs.utils.PageUtils; import com.xjs.utils.PageUtils;
import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.entity.CategoryEntity;
import java.util.List;
import java.util.Map; import java.util.Map;
/** /**
@ -16,5 +17,17 @@ import java.util.Map;
public interface CategoryService extends IService<CategoryEntity> { public interface CategoryService extends IService<CategoryEntity> {
PageUtils queryPage(Map<String, Object> params); PageUtils queryPage(Map<String, Object> params);
/**
*
* @return list
*/
List<CategoryEntity> listWithTree();
/**
*
* @param asList ids
*/
void removeMenuByIds(List<Long> asList);
} }

@ -1,29 +1,78 @@
package com.xjs.mall.product.service.impl; package com.xjs.mall.product.service.impl;
import org.springframework.stereotype.Service;
import java.util.Map;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjs.utils.PageUtils;
import com.xjs.utils.Query;
import com.xjs.mall.product.dao.CategoryDao; import com.xjs.mall.product.dao.CategoryDao;
import com.xjs.mall.product.entity.CategoryEntity; import com.xjs.mall.product.entity.CategoryEntity;
import com.xjs.mall.product.service.CategoryService; import com.xjs.mall.product.service.CategoryService;
import com.xjs.utils.PageUtils;
import com.xjs.utils.Query;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service("categoryService") @Service("categoryService")
public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService { public class CategoryServiceImpl extends ServiceImpl<CategoryDao, CategoryEntity> implements CategoryService {
@Resource
private CategoryDao categoryDao;
@Override @Override
public PageUtils queryPage(Map<String, Object> params) { public PageUtils queryPage(Map<String, Object> params) {
IPage<CategoryEntity> page = this.page( IPage<CategoryEntity> page = this.page(
new Query<CategoryEntity>().getPage(params), new Query<CategoryEntity>().getPage(params),
new QueryWrapper<CategoryEntity>() new QueryWrapper<>()
); );
return new PageUtils(page); return new PageUtils(page);
} }
@Override
public List<CategoryEntity> listWithTree() {
//1、查询所有分类
List<CategoryEntity> entities = categoryDao.selectList(null);
//2、找到所有一级分类
return entities.stream().filter(categoryEntity ->
categoryEntity.getParentCid() == 0)
.peek(menu -> menu.setChildren(this.getChildrens(menu, entities)))
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
.collect(Collectors.toList());
}
@Override
public void removeMenuByIds(List<Long> asList) {
// todo 检查当前要删除的菜单是否被其他的地方引用
categoryDao.deleteBatchIds(asList);
}
/**
*
*
* @param root
* @param all
* @return list
*/
private List<CategoryEntity> getChildrens(CategoryEntity root, List<CategoryEntity> all) {
//-----------peek和map区别---------------//
//map有返回值peek没有返回值
return all.stream().filter(categoryEntity -> Objects.equals(categoryEntity.getParentCid(), root.getCatId()))
.peek(categoryEntity -> categoryEntity.setChildren(getChildrens(categoryEntity, all)))
.sorted(Comparator.comparingInt(menu -> (menu.getSort() == null ? 0 : menu.getSort())))
.collect(Collectors.toList());
}
} }
Loading…
Cancel
Save