前端代码
EchartsDemo.vue
<template>
<div >
<div style="with:800px;height:500px" ref="bar">
</div>
</div>
</template>
<script>
export default {
data(){
return {
}
},
methods:{
echartsInit(){
//初始化容器
debugger;
var myChart = this.$echarts.init(this.$refs.bar);
var option = {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data:['销量']
},
xAxis: {
data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
},
yAxis: {},
series: [{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
myChart.setOption(option);
}
},
mounted(){
this.echartsInit();
}
}
</script>
<style>
</style>
UserList.vue 树形图菜单
<template>
<div>
<el-row>
<el-col :span="24">
<!-- 搜索框部分 -->
<el-form :inline="true" class="demo-form-inline">
<el-form-item label="用户名">
<el-input placeholder="用户名" v-model="name"></el-input>
</el-form-item>
<el-form-item label="商品状态">
<el-input placeholder="上架/下架" v-model="state"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="queryBtn">查询</el-button>
</el-form-item>
</el-form>
<el-button type="danger" @click="batchDel">批量删除</el-button>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<!-- 数据部分 -->
<el-table
:data="tableData"
stripe
border
style="width: 100%"
@selection-change="handleSelectionChange">
<el-table-column
type="selection"
width="55">
</el-table-column>
<el-table-column
prop="id"
label="编号"
width="180">
</el-table-column>
<el-table-column
prop="shopname"
label="商品名称"
align="center"
width="180">
</el-table-column>
<el-table-column
prop="shoptype"
label="小店分类">
</el-table-column>
<el-table-column
prop="price"
label="线上销售价格">
</el-table-column>
<el-table-column
prop="shopnumber"
label="库存数量">
</el-table-column>
<el-table-column
prop="shopstate"
label="商品状态">
</el-table-column>
<el-table-column
prop="outnumber"
label="销量">
</el-table-column>
<el-table-column
prop="updatee"
label="上架时间">
</el-table-column>
<el-table-column
label="操作">
<template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" circle @click="addshpooer"></el-button>
<el-button type="warning" icon="el-icon-share" circle @click="authMenu(scope.row.account)"></el-button>
<el-button type="danger" icon="el-icon-delete" circle @click="removeshopper(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<!-- 分页部分 -->
<el-pagination
background
:page-sizes="[2, 10, 20]"
:page-size="pageSize"
:current-page="pageNum"
@prev-click="prevPage"
@next-click="nextPage"
@size-change="changePage"
layout="total, sizes,prev, pager, next"
:total="total">
</el-pagination>
</el-col>
</el-row>
<el-dialog title="收货地址" :visible.sync="dialogFormVisible">
<el-row>
<el-col :span="18">
<el-form >
<el-form-item label="日期" label-width="80px">
<el-input v-model="dialogform.date"></el-input>
</el-form-item>
<el-form-item label="姓名" label-width="80px">
<el-input v-model="dialogform.name"></el-input>
</el-form-item>
<el-form-item label="地址" label-width="80px">
<el-input v-model="dialogform.address"></el-input>
</el-form-item>
</el-form>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogFormVisible = false">确 定</el-button>
</div>
</el-dialog>
<el-dialog title="菜单授权" :visible.sync="dialogMenuVisible">
<el-row>
<el-col :span="18">
<!-- 树形菜单 -->
<!-- <el-tree :data="data" :props="defaultProps" ></el-tree> -->
<el-tree
:data="data"
show-checkbox
node-key="id"
:default-expanded-keys="[2, 3]"
:default-checked-keys="[2]"
:props="defaultProps">
</el-tree>
</el-col>
</el-row>
<div slot="footer" class="dialog-footer">
<el-button @click="dialogMenuVisible = false">取 消</el-button>
<el-button type="primary" @click="dialogMenuVisible = false">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
export default {
data(){
return {
pageNum:1,
pageSize:2,
total:0,
name:'',
state:'',
dialogFormVisible:false,
dialogMenuVisible:false,
dialogform:{
id:'',
shopname:'',
shoptype:'',
price:'',
shopnumber:'',
shopstate:'',
outnumber:''
},
menuList:[
{index:'1',icon:'el-icon-location',name:'就业管理',
childrenMenu:[
{index:'2',name:'模拟面试'},
{index:'3',name:'就业考核'}
]
},
{index:'5',icon:'el-icon-video-camera-solid',name:'尊严管理',
childrenMenu:[
{index:'6',name:'尊严目标'},
{index:'7',name:'尊严冲刺'}
]}
],
tableData: [],
//全局变量
selectionData:[],
data: [{
label: '一级 1',
id:1,
childrenMenu: [{
label: '二级 1-1',
id:2,
childrenMenu: [{
label: '三级 1-1-1',
id:3,
},
{
label: '四级 1-1-1',
id:4,
}
]
}]
}],
//label:树图显示内容
defaultProps: {
children: 'childrenMenu',
label: 'id'
}
}
},
methods:{
authMenu(account){
this.dialogMenuVisible=true;
//1.查系统所有的菜单,并以树形图展示
//2:查用户拥有的菜单,并在树形图回显
let jwt=localStorage.getItem("jwt");
this.$axios.get('api/user/queryUserMenuTree?account='+account,{headers:{'jwt':jwt}})
.then(res=>{
console.log(res.data)
})
},
batchDel(){
//怎么拿到选中id?
let ids=[];
this.selectionData.forEach(e=>{
ids.push(e.id);
});
console.log(ids);
if(ids.length==0){
this.$message("请选择数据")
return;
}
let jwt=localStorage.getItem('jwt');
this.$axios.post("api/shopper/batchDel",ids,{headers:{'jwt':jwt}})
.then(res=>{
if(res.data.code==200){
this.$message({
message:'删除成功',
type:'success'
});
this.queryBtn();
}
})
},
//批量选择
handleSelectionChange(val){
//每行数据
console.log(val)
this.selectionData=val;
},
updateData(row){
this.dialogFormVisible = true;
this.dialogform = JSON.parse(JSON.stringify(row));
},
prevPage(val){
this.pageNum=val;
this.queryBtn();
},
nextPage(val){
this.pageNum=val;
this.queryBtn();
},
changePage(val){
this.pageNum=1;
this.pageSize=val;
this.queryBtn();
},
queryBtn(){
let jwt=localStorage.getItem('jwt');
let param={};
param.pageNum=this.pageNum;
param.pageSize=this.pageSize;
let data={};
data.shopname=this.name;
data.shopstate=this.state;
param.data=data;
this.$axios.post('api/shopper/queryShopper',param,{headers:{'jwt':jwt}})
.then(res=>{
console.log(res.data);
if(res.data.code==200){
let pageData=res.data.data;
this.tableData=pageData.list;
this.pageNum=pageData.pageNum;
this.pageSize=pageData.pageSize;
this.total=pageData.total
}
})
},
addshpooer(){
this.$router.push({name:'shopperAdd'})
},
removeshopper(row){
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//发请求代码
this.dialogform = JSON.parse(JSON.stringify(row));
const jwt=localStorage.getItem("jwt");
this.$axios.get('api/shopper/removeShopper?id='+this.dialogform.id,{headers:{'jwt':jwt}})
.then(res=>{
console.log(res.data)
if(res.data.code==5000){
alert("没有操作权限!!!")
}
if(res.data.code==200){
this.queryBtn();
}
})
this.$message({
type: 'success',
message: '删除成功!'
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
created(){
this.queryBtn();
}
}
}
</script>
<style scoped>
</style>
后端代码
MenuDao.java
package com.x.springsecurityday01.dao;
import com.x.springsecurityday01.domain.Menus;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface MenuDao {
/**
* 根据登录人账号,去查该人拥有的菜单
*/
List<Menus> queryMenusByAccount(String account);
List<Menus> queryAllMenus();
}
UserDao.java
package com.x.springsecurityday01.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.x.springsecurityday01.domain.Users;
import com.x.springsecurityday01.domain.vo.MenusTreeVo;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserDao {
/**
* 根据账号查用户信息及其权限
*/
Users getUserInfoByAccount(String account);
/**
* 根据用户名和性别查询用户信息
* @param name
* @param gender
* @return
*/
List<Users> getUserInfoByNameAndGender(String name,Integer gender);
/**
* 新增用户
* @param users
*/
void insertUser(Users users);
void removeUser(Integer id);
void updateUser(Users users);
Users selectById(Integer id);
/**
* 根据用户id删除用户菜单中间表
* @param userId
*/
void deleteUserMenusByUserId(Integer userId);
/**
* 添加用户菜单权限
* @param menusTreeVo
*/
void insertUserMenus(@Param("menusTreeVo") MenusTreeVo menusTreeVo);
}
MenusTreeVo.java
package com.x.springsecurityday01.domain.vo;
import lombok.Data;
import java.util.List;
@Data
public class MenusTreeVo {
private Integer userId;
private List<Integer> menus;
}
UserService.java
package com.x.springsecurityday01.service;
import com.x.springsecurityday01.domain.Menus;
import com.x.springsecurityday01.domain.Users;
import com.x.springsecurityday01.domain.vo.MenusTreeVo;
import com.x.springsecurityday01.util.RequestParams;
import com.x.springsecurityday01.util.ResponseResult;
import java.util.List;
public interface UserService {
ResponseResult<?> queryUserInfo(String name,Integer gender);
ResponseResult<?> insertUser(Users users);
ResponseResult<?> removeUser(Integer id);
ResponseResult<?> updateUser(Users users);
ResponseResult<?> selectById(Integer id);
ResponseResult<?> queryMenusByUser(String account);
ResponseResult<?> queryUserInfoByPage(RequestParams<Users> param);
ResponseResult<?> queryUserMenuTree(String account);
ResponseResult<?> saveUserMenus(MenusTreeVo menusTreeVo);
}
UserSErviceImpl.java
package com.x.springsecurityday01.service.impl;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.x.springsecurityday01.dao.MenuDao;
import com.x.springsecurityday01.dao.UserDao;
import com.x.springsecurityday01.domain.Menus;
import com.x.springsecurityday01.domain.Users;
import com.x.springsecurityday01.domain.vo.MenusTreeVo;
import com.x.springsecurityday01.service.UserService;
import com.x.springsecurityday01.util.RequestParams;
import com.x.springsecurityday01.util.ResponseResult;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service
public class UserSErviceImpl implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private MenuDao menuDao;
@Autowired
private StringRedisTemplate redisTemplate;
@Override
public ResponseResult<?> queryUserInfo(String name, Integer gender) {
List<Users> users = userDao.getUserInfoByNameAndGender(name, gender);
return new ResponseResult<>().ok(users);
}
@Override
public ResponseResult<?> insertUser(Users users) {
try {
userDao.insertUser(users);
return new ResponseResult().ok();
} catch (Exception e) {
e.printStackTrace();
return new ResponseResult().fail();
}
}
@Override
public ResponseResult<?> removeUser(Integer id) {
try {
userDao.removeUser(id);
return new ResponseResult().ok();
} catch (Exception e) {
e.printStackTrace();
return new ResponseResult().fail();
}
}
@Override
public ResponseResult<?> updateUser(Users users) {
try {
userDao.updateUser(users);
return new ResponseResult().ok();
} catch (Exception e) {
e.printStackTrace();
return new ResponseResult().fail();
}
}
@Override
public ResponseResult<?> selectById(Integer id) {
Users users=userDao.selectById(id);
return new ResponseResult<>().ok(users);
}
/**
* 查询用户菜单
* 缓存一致性问题?出现缓存不一致的原因:因为对原始数据做变更了(增删改)
* 解决方案;
* 1:数据库改了,缓存也改(不采用修改缓存的方案)
* 2:对原始数据(增删改)操作,删除缓存
*
* @param account
* @return
*/
@Override
public ResponseResult<?> queryMenusByUser(String account) {
String userStr = redisTemplate.opsForValue().get("menu:" + account);
//redis是否有缓存数据
if(userStr!=null||"".equals(userStr)){
List<Menus> menus = JSON.parseArray(userStr, Menus.class);
List<Menus> menuNode = getMenuNode(menus);
return new ResponseResult<>().ok(menuNode);
}else {
//缓存没有,查数据,并且把数据库数据缓存到redis
List<Menus> menus = menuDao.queryMenusByAccount(account);
//解决缓存穿透
if(menus==null){
redisTemplate.opsForValue().set("menu"+account,"");
}else {
redisTemplate.opsForValue().set("menu"+account,JSON.toJSONString(menus));
}
List<Menus> menuNode = getMenuNode(menus);
return new ResponseResult<>().ok(menuNode);
}
}
/**
* 把菜单封装成树形结构
* @param menus
* @return
*/
public List<Menus> getMenuNode(List<Menus> menus ){
//找到所有的一级菜单
List<Menus> parentMenus = menus.stream().filter(e -> e.getParentId() == null)
.collect(Collectors.toList());
for(Menus parentMenu :parentMenus){
List<Menus> childrenMenus=new ArrayList<>();
for(Menus menu:menus){
//找出一级菜单对应二级菜单
if(parentMenu.getId().equals(menu.getParentId())){
//
childrenMenus.add(menu);
}
}
parentMenu.setChildrenMenu(childrenMenus);
}
return parentMenus;
}
@Override
public ResponseResult<?> queryUserInfoByPage(RequestParams<Users> param) {
//带分页查询用户信息
//分页开始
PageHelper.startPage(param.getPageNum(),param.getPageSize());
//调dao层接口
List<Users> userInfo = userDao.getUserInfoByNameAndGender(param.getData().getUsername(), 0);
//把dao层接口返回参数放入pageInfo
PageInfo pageInfo=new PageInfo(userInfo);
return new ResponseResult<>().ok(pageInfo);
}
/**
* 1.查询系统所有菜单
* 2.根据用户账号查询拥有菜单id
* @param account
* @return
*/
@Override
public ResponseResult<?> queryUserMenuTree(String account) {
List<Menus> menus = menuDao.queryAllMenus();
//1.查询系统所有菜单
List<Menus> menuNode = getMenuNode(menus);
//2.根据用户账号查询拥有菜单id
List<Menus> userMenus = menuDao.queryMenusByAccount(account);
//可以把集合的泛型类,转成一个map,可以通过map的key获取对应的数据,然后组装成一个新的集合
List<Integer> userMenuId = userMenus.stream().map(e -> e.getId()).collect(Collectors.toList());
Map map=new HashMap<>();
map.put("menus",menuNode);
map.put("userMenuId",userMenuId);
return new ResponseResult<>().ok(map);
}
@Override
@Transactional
public ResponseResult<?> saveUserMenus(MenusTreeVo menusTreeVo) {
try {
userDao.deleteUserMenusByUserId(menusTreeVo.getUserId());
if(!CollectionUtils.isEmpty(menusTreeVo.getMenus())){
userDao.insertUserMenus(menusTreeVo);
}
//redisTemplate.delete("");
return new ResponseResult<>().ok();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
}
MenuDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.x.springsecurityday01.dao.MenuDao">
<select id="queryMenusByAccount" resultType="com.x.springsecurityday01.domain.Menus">
SELECT
tm.id,
tm.name,
tm.icon,
tm.parent_id as parentId,
tm.link
FROM t_menu tm
LEFT JOIN t_user_menu tum on tm.id=tum.menu_id
LEFT JOIN users u on tum.user_id=u.id
<where>
<if test="account!=null and account!='' ">
u.account=#{account}
</if>
</where>
</select>
<select id="queryAllMenus" resultType="com.x.springsecurityday01.domain.Menus">
SELECT
tm.id,
tm.name,
tm.icon,
tm.parent_id as parentId,
tm.link
FROM
t_menu tm
</select>
</mapper>
UserDao.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.x.springsecurityday01.dao.UserDao">
<resultMap id="userMap" type="com.x.springsecurityday01.domain.Users">
<result property="id" column="id"></result>
<result property="username" column="username"></result>
<result property="account" column="account"></result>
<result property="password" column="password"></result>
<collection property="anth" ofType="java.lang.String">
<result column="anth_code"></result>
</collection>
</resultMap>
<select id="getUserInfoByAccount" resultMap="userMap">
SELECT
us.id,
us.username,
us.account,
us.password,
ta.anth_code
FROM
users us
left join t_user_anth tua on us.id=tua.user_id
left join t_anth ta on tua.anth_id=ta.id
WHERE account=#{account}
</select>
<select id="getUserInfoByNameAndGender" resultType="com.x.springsecurityday01.domain.Users">
select
id,
username,
account,
phone,
sex gender
from
users
<where>
<if test="name!=null and name!=''">
and username like concat('%',#{name},'%')
</if>
<if test="gender!=null and gender!=0">
and sex=#{gender}
</if>
</where>
</select>
<insert id="insertUser" parameterType="com.x.springsecurityday01.domain.Users">
insert into users(username,account,password,phone)
values (#{username},#{account},#{password},#{phone})
</insert>
<delete id="removeUser" parameterType="com.x.springsecurityday01.domain.Users">
delete from users where id=#{id}
</delete>
<update id="updateUser" parameterType="com.x.springsecurityday01.domain.Users">
update users set username=#{username},account=#{account},password=#{password} where id=#{id}
</update>
<select id="selectById" resultType="com.x.springsecurityday01.domain.Users">
select * from users where id=#{id}
</select>
<delete id="deleteUserMenusByUserId">
delete from t_user_menu where user_id=#{userId}
</delete>
<insert id="insertUserMenus" parameterType="com.x.springsecurityday01.domain.vo.MenusTreeVo">
insert into t_user_menu (user_id,menu_id) values
<foreach collection="menusTreeVo.menus" item="id" separator="," >
(#{menusTreeVo.userId},#{id})
</foreach>
</insert>
</mapper>
UserController.java
package com.woniu.springsecurityday01.controller;
import com.alibaba.fastjson.JSON;
import com.x.springsecurityday01.domain.Users;
import com.x.springsecurityday01.domain.vo.MenusTreeVo;
import com.x.springsecurityday01.service.UserService;
import com.x.springsecurityday01.util.RequestParams;
import com.x.springsecurityday01.util.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/queryUser")
public ResponseResult<?> queryUser(String name,Integer gender){
return userService.queryUserInfo(name,gender);
}
@PostMapping("/addUser")
@PreAuthorize("hasAuthority('stu:query')")
public ResponseResult<?> addUser(@RequestBody Users users){
//log.info(JSON.toJSONString(users));
return userService.insertUser(users);
}
@GetMapping("/removeUser")
@PreAuthorize("hasAuthority('stu:query')")
public ResponseResult<?> removeUser(Integer id){
return userService.removeUser(id);
}
@PostMapping("/updateUser")
@PreAuthorize("hasAuthority('stu:query')")
public ResponseResult<?> updateUser(@RequestBody Users users){
return userService.updateUser(users);
}
@GetMapping("/findId")
@PreAuthorize("hasAuthority('stu:query')")
public ResponseResult<?> selectById(Integer id){
return userService.selectById(id);
}
@RequestMapping("getUserMenu")
public ResponseResult<?> queryUserMenus(String account){
return userService.queryMenusByUser(account);
}
@PostMapping("queryUser")
public ResponseResult<?> queryUser(@RequestBody RequestParams<Users> requestParams){
//log.info(JSON.toJSONString(requestParams));
return userService.queryUserInfoByPage(requestParams);
}
@RequestMapping("queryUserMenuTree")
public ResponseResult<?> queryUserMenu(String account){
return userService.queryUserMenuTree(account);
}
@PostMapping("saveUserMenu")
public ResponseResult<?> saveUserMenu(@RequestBody MenusTreeVo menusTreeVo){
//log.info("树型菜单的值{}",JSON.toJSONString(menusTreeVo));
return userService.saveUserMenus(menusTreeVo);
}
}
SELECT
tg.name,
IFNULL(sum(tuo.buy_num) ,0)as orders
FROM
t_good tg
LEFT JOIN
t_user_order tuo on tg.id=tuo.good_id
GROUP BY tg.name