将菜单的sql在admin 数据库执行
/*
SQLyog Ultimate v11.25 (64 bit)
MySQL - 5.7.27 : Database - gulimall_admin
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`gulimall_admin` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
USE `gulimall_admin`;
/*Table structure for table `sys_menu` */
DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` (
`menu_id` bigint(20) NOT NULL AUTO_INCREMENT,
`parent_id` bigint(20) DEFAULT NULL COMMENT '父菜单ID,一级菜单为0',
`name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
`url` varchar(200) DEFAULT NULL COMMENT '菜单URL',
`perms` varchar(500) DEFAULT NULL COMMENT '授权(多个用逗号分隔,如:user:list,user:create)',
`type` int(11) DEFAULT NULL COMMENT '类型 0:目录 1:菜单 2:按钮',
`icon` varchar(50) DEFAULT NULL COMMENT '菜单图标',
`order_num` int(11) DEFAULT NULL COMMENT '排序',
PRIMARY KEY (`menu_id`)
) ENGINE=InnoDB AUTO_INCREMENT=76 DEFAULT CHARSET=utf8mb4 COMMENT='菜单管理';
/*Data for the table `sys_menu` */
insert into `sys_menu`(`menu_id`,`parent_id`,`name`,`url`,`perms`,`type`,`icon`,`order_num`) values (1,0,'系统管理',NULL,NULL,0,'system',0),(2,1,'管理员列表','sys/user',NULL,1,'admin',1),(3,1,'角色管理','sys/role',NULL,1,'role',2),(4,1,'菜单管理','sys/menu',NULL,1,'menu',3),(5,1,'SQL监控','http://localhost:8080/renren-fast/druid/sql.html',NULL,1,'sql',4),(6,1,'定时任务','job/schedule',NULL,1,'job',5),(7,6,'查看',NULL,'sys:schedule:list,sys:schedule:info',2,NULL,0),(8,6,'新增',NULL,'sys:schedule:save',2,NULL,0),(9,6,'修改',NULL,'sys:schedule:update',2,NULL,0),(10,6,'删除',NULL,'sys:schedule:delete',2,NULL,0),(11,6,'暂停',NULL,'sys:schedule:pause',2,NULL,0),(12,6,'恢复',NULL,'sys:schedule:resume',2,NULL,0),(13,6,'立即执行',NULL,'sys:schedule:run',2,NULL,0),(14,6,'日志列表',NULL,'sys:schedule:log',2,NULL,0),(15,2,'查看',NULL,'sys:user:list,sys:user:info',2,NULL,0),(16,2,'新增',NULL,'sys:user:save,sys:role:select',2,NULL,0),(17,2,'修改',NULL,'sys:user:update,sys:role:select',2,NULL,0),(18,2,'删除',NULL,'sys:user:delete',2,NULL,0),(19,3,'查看',NULL,'sys:role:list,sys:role:info',2,NULL,0),(20,3,'新增',NULL,'sys:role:save,sys:menu:list',2,NULL,0),(21,3,'修改',NULL,'sys:role:update,sys:menu:list',2,NULL,0),(22,3,'删除',NULL,'sys:role:delete',2,NULL,0),(23,4,'查看',NULL,'sys:menu:list,sys:menu:info',2,NULL,0),(24,4,'新增',NULL,'sys:menu:save,sys:menu:select',2,NULL,0),(25,4,'修改',NULL,'sys:menu:update,sys:menu:select',2,NULL,0),(26,4,'删除',NULL,'sys:menu:delete',2,NULL,0),(27,1,'参数管理','sys/config','sys:config:list,sys:config:info,sys:config:save,sys:config:update,sys:config:delete',1,'config',6),(29,1,'系统日志','sys/log','sys:log:list',1,'log',7),(30,1,'文件上传','oss/oss','sys:oss:all',1,'oss',6),(31,0,'商品系统','','',0,'editor',0),(32,31,'分类维护','product/category','',1,'menu',0),(34,31,'品牌管理','product/brand','',1,'editor',0),(37,31,'平台属性','','',0,'system',0),(38,37,'属性分组','product/attrgroup','',1,'tubiao',0),(39,37,'规格参数','product/baseattr','',1,'log',0),(40,37,'销售属性','product/saleattr','',1,'zonghe',0),(41,31,'商品维护','product/spu','',0,'zonghe',0),(42,0,'优惠营销','','',0,'mudedi',0),(43,0,'库存系统','','',0,'shouye',0),(44,0,'订单系统','','',0,'config',0),(45,0,'用户系统','','',0,'admin',0),(46,0,'内容管理','','',0,'sousuo',0),(47,42,'优惠券管理','coupon/coupon','',1,'zhedie',0),(48,42,'发放记录','coupon/history','',1,'sql',0),(49,42,'专题活动','coupon/subject','',1,'tixing',0),(50,42,'秒杀活动','coupon/seckill','',1,'daohang',0),(51,42,'积分维护','coupon/bounds','',1,'geren',0),(52,42,'满减折扣','coupon/full','',1,'shoucang',0),(53,43,'仓库维护','ware/wareinfo','',1,'shouye',0),(54,43,'库存工作单','ware/task','',1,'log',0),(55,43,'商品库存','ware/sku','',1,'jiesuo',0),(56,44,'订单查询','order/order','',1,'zhedie',0),(57,44,'退货单处理','order/return','',1,'shanchu',0),(58,44,'等级规则','order/settings','',1,'system',0),(59,44,'支付流水查询','order/payment','',1,'job',0),(60,44,'退款流水查询','order/refund','',1,'mudedi',0),(61,45,'会员列表','member/member','',1,'geren',0),(62,45,'会员等级','member/level','',1,'tubiao',0),(63,45,'积分变化','member/growth','',1,'bianji',0),(64,45,'统计信息','member/statistics','',1,'sql',0),(65,46,'首页推荐','content/index','',1,'shouye',0),(66,46,'分类热门','content/category','',1,'zhedie',0),(67,46,'评论管理','content/comments','',1,'pinglun',0),(68,41,'spu管理','product/spu','',1,'config',0),(69,41,'发布商品','product/spuadd','',1,'bianji',0),(70,43,'采购单维护','','',0,'tubiao',0),(71,70,'采购需求','ware/purchaseitem','',1,'editor',0),(72,70,'采购单','ware/purchase','',1,'menu',0),(73,41,'商品管理','product/manager','',1,'zonghe',0),(74,42,'会员价格','coupon/memberprice','',1,'admin',0),(75,42,'每日秒杀','coupon/seckillsession','',1,'job',0);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
所有的前端和后端交互的接口文档地址:
https://easydoc.net/s/78237135/ZUqEdvA4/hKJTcbfd
1、modules下新建一个common文件夹(抽取三级分类组件、因为很多菜单用得着)
2、新建category.vue
前端应该有一个attrgroup.vue文件
同样用vue模板生成代码
attrgroup.vue使用elementui的layout布局
菜单
表格
1、将product的category.vue里的el tree搬过来到common的category.vue放到template标签里
{{ node.label }}
append(data)"
>
Append
edit
remove(node, data)"
>
Delete
2、去掉span标签的内容,去掉拖拽功能,默认展示节点等功能
最终template标签剩下这个
3、复制data里的return声明
return {
draggable: false,
pcid:[],
updateNode: [],
category: {
name: "",
parentCid: null,
catLevel: null,
showStatus: 1,
sort: null,
icon: "",
productUnit: "",
catId: null,
expandId: null,
},
dialogVisible: false,
dialogType: "",
title: "",
menus: [],
expandKey: [],
defaultProps: {
children: "children",
label: "name",
},
maxLevel: 0,
};
拖拽功能的数据全部删除
return {
menus: [],
expandKey: [],
defaultProps: {
children: "children",
label: "name",
},
};
4、复制方法getMenus()
getMenu() {
this.dataListLoading = true;
this.$http({
url: this.$http.adornUrl("/product/category/tree"),
method: "get",
}).then((data) => {
let data1 = data.data.data;
this.menus = data1;
});
},
5、在生命周期创建时发起请求
created() {
this.getMenu();
},
6、attrgroup.vue引用它
在script里引入组件
import Category from '../common/category.vue'
将组件注册进components
1、将attrgroup.vue逆向生成的代码部分复制整个div到template
查询
新增
批量删除
修改
删除
2、将data复制替换
data () {
return {
dataForm: {
key: ''
},
dataList: [],
pageIndex: 1,
pageSize: 10,
totalPage: 0,
dataListLoading: false,
dataListSelections: [],
addOrUpdateVisible: false
}
},
3、将接下来的部分也替换
activated () {
this.getDataList()
},
methods: {
// 获取数据列表
getDataList () {
this.dataListLoading = true
this.$http({
url: this.$http.adornUrl('/product/attrgroup/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.addOrUpdateVisible = true
this.$nextTick(() => {
this.$refs.addOrUpdate.init(id)
})
},
// 删除
deleteHandle (id) {
var ids = id ? [id] : this.dataListSelections.map(item => {
return item.attrGroupId
})
this.$confirm(`确定对[id=${ids.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.$http({
url: this.$http.adornUrl('/product/attrgroup/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、导入组件
5、将逆向工程成的attrgroup-add-or-update.vue放置当前文件夹内
nodeClick(data,node,component){
console.log("当前点击的节点信息:",data,node,component);
},
// 向父组件发送事件
this.$emit("tree-node-click",data,node,component);
###父组件接收
回到attrgroup.vue
//感知子组件传递的事件
treenodeClick(data,node,component){
console.log("子组件的category被点击:",data,node,component);
console.log("被点击的子组件id是:",data.catId);
},
//感知子组件传递的事件
treenodeClick(data, node, component) {
console.log("子组件的category被点击:", data, node, component);
console.log("被点击的子组件id是:", data.catId);
// 当是三级分类时给catId赋值
if (node.level == 3) {
this.catId = data.catId;
// 再次调用获取数据列表
this.getDataList();
}
},
1、找到attr-group-add-or-update.vue,将所属分类id换成dataForm.catelogId
2、attr-group-add-or-update.vue 写一个方法
getCategorys(){
this.$http({
url: this.$http.adornUrl("/product/category/tree"),
method: "get",
}).then((data) => {
this.categorys = data.data.data;
console.log("获取到商品数据==》{}",this.categorys);
});
}
在style中指定样式
效果就出来了
但是最后没有数据
是因为我们只有3级菜单,但是最后一个children返回了空集合。需要后台解决
新增点击保存时。catelogId是传的数组。这里时有问题的。只传最终的三级分类id
这时候只用取数组中最后一个值传给后端即可
AttrGroupController
/**
* 列表
*/
@RequestMapping(value = "/list/{catelogId}",method = RequestMethod.POST)
// @RequiresPermissions("product:attrgroup:list")
public R list(@RequestParam Map params,@PathVariable Long catelogId){
PageUtils page = attrGroupService.queryPage(params,catelogId);
return R.ok().put("page", page);
}
AttrGroupService
PageUtils queryPage(Map params,Long catelogId);
AttrGroupServiceImpl
@Override
public PageUtils queryPage(Map params, Long catelogId) {
// 当前端的catelogId为0,没传的时候,
if (catelogId == 0){
return this.queryPage(params);
}
QueryWrapper wrapper = new QueryWrapper().eq("catelog_id",catelogId);
// 当前端传了key
String key = (String)params.get("key");
if (!StringUtils.isEmpty(key)){
// select * from pms_attr_group where catelog_id = ? and (attr_gruop_id = ? or attr_group_name like %%)
wrapper.and((obj)->{
obj.eq("attr_group_id",key).or().like("attr_group_name",key);
});
}
IPage page = this.page(new Query().getPage(params),wrapper);
return new PageUtils(page);
}
商品三级分类获取后,需要将children里面为空的不返回前端
实体类加一注解即可
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List children;