赞
踩
由于字数限制,请阅读原文,原文附源码和sql以及项目演示地址和项目资料。
环境:
win10、idea22023.2、vscode1.7、maven3.5、jdk8、Redis
技术:
springboot2.5.9
springsecurity
Redis
mybatis plus
mysql5.7.38
swagger
jwt
vue2
element ui
vuex
vue-router
axios
mockjs
echarts
less
模块:
登录页面
首页
权限管理
1.用户管理
2.角色管理
3.菜单管理
功能要点:
从0到1实现项目前后端搭建
vuex实现面包屑和Tag功能
vuex+localStorage动态路由和菜单(重点)
封装一个ECharts组件
封装Table表格
树形表格和CheckBox的使用
封装统一返回类
两种方式实现代码生成,解放双手
jwt、swagger、Redis封装
权限管理(重点)
项目截图
1、登录页面
2、首页
3、用户管理
4、角色管理
5、分配权限
6、菜单管理
7、根据权限动态加载菜单和按钮
8、部分主要代码
登录
- <template>
- <el-form
- ref="form"
- label-width="70px"
- :inline="true"
- class="login-container"
- :model="form"
- :rules="rules"
- >
- <h3 class="login_title">系统登录</h3>
- <el-form-item label="用户名" prop="username">
- <el-input v-model="form.username" placeholder="请输入账号"></el-input>
- </el-form-item>
- <el-form-item label="密码" prop="password">
- <el-input
- type="password"
- v-model="form.password"
- placeholder="请输入密码"
- ></el-input>
- </el-form-item>
- <el-form-item label="验证码" prop="code">
- <el-input v-model="form.code" maxlength="6"></el-input>
- </el-form-item>
- <el-form-item>
- <el-image
- :src="captchaImg"
- class="captchaImg"
- style="margin-left: 15px"
- @click="getCaptcha"
- ></el-image>
- </el-form-item>
- <el-form-item>
- <el-button
- @click="submit"
- style="margin-left: 105px; margin-top: 10px"
- type="primary"
- :loading="loading"
- >登录</el-button
- >
- <!-- <el-button
- @click="submit1"
- style="margin-left: 105px; margin-top: 10px"
- type="primary"
- :loading="loading"
- >登录1</el-button
- > -->
- </el-form-item>
- </el-form>
- </template>
- <script>
- // import Mock from 'mockjs'
- // import Cookie from 'js-cookie'
- // import { getMenu } from '../api'
- import qs from "qs";
- import http from "@/utils/request";
- export default {
- data() {
- return {
- captchaImg: "",
- loading: false,
- form: {
- username: "admin",
- password: "111111",
- token: "aaaaa",
- code: "",
- },
- rules: {
- username: [
- { required: true, trigger: "blur", message: "请输入用户名" },
- ],
- password: [{ required: true, trigger: "blur", message: "请输入密码" }],
- },
- };
- },
-
-
- created() {
- this.getCaptcha();
- },
- methods: {
- submit1() {},
- getCaptcha() {
- http.get("/captcha").then((res) => {
- if(res.code === 20000){
- console.log("/captcha");
- console.log(res);
- this.form.token = res.data.data.token;
- this.captchaImg = res.data.data.captchaImg;
- //this.form.code = "";
- }
-
-
- });
- },
- // 登录
- submit() {
- let that = this;
- that.$refs.form.validate((valid) => {
- if (valid) {
- this.loading = true;
- this.$store
- .dispatch("Login", this.form)
- .then((res) => {
-
- if (res.code != 20000) {
- that.$message({
- type: "warning",
- message: res.message,
- });
- this.loading = false;
- return false;
- }
- this.loading = false;
- this.$router.push({ path: "/home" });
- })
- .catch(() => {
- this.loading = false;
- });
- // http
- // .post("/login?" + qs.stringify(this.form))
- // .then((res) => {
- // if (res.code != 20000) {
- // that.$message({
- // type: "warning",
- // message: res.message,
- // });
- // }
- // console.log(res);
-
-
- // const jwt = res.data.authorization;
-
-
- // this.$store.commit("SET_TOKEN", jwt);
- // //
- // this.$router.push("/home");
- // })
- // .catch((e) => {});
-
-
- //this.loading = true;
- // that.$store
- // .dispatch("Login", that.form)
- // .then(() => {
- // //this.loading = false;
- // that.$router.push({ path: "/" });
- // })
- // .catch(() => {
- // //this.loading = false;
- // });
- } else {
- console.log("error submit!!");
- return false;
- }
- });
-
-
- // // token信息
- // const token = Mock.Random.guid()
-
-
- // 校验通过
- // this.$refs.form.validate((valid) => {
- // if (valid) {
- // getMenu(this.form).then(({ data }) => {
- // console.log(data)
- // if (data.code === 20000) {
- // // token信息存入cookie用于不同页面间的通信
- // Cookie.set('token', data.data.token)
-
-
- // // 获取菜单的数据,存入store中
- // this.$store.commit('setMenu', data.data.menu)
- // this.$store.commit('addMenu', this.$router)
- // // 跳转到首页
- // this.$router.push('/home')
- // } else {
- // this.$message.error(data.data.message);
- // }
- // })
- // }
- // })
- },
- },
- };
- </script>
- <style lang="less" scoped>
- .login-container {
- width: 650px;
- border: 1px solid #eaeaea;
- margin: 180px auto;
- padding: 35px 35px 15px 35px;
- background-color: #fff;
- border-radius: 15px;
- box-shadow: 0 0 25px #cac6c6;
- box-sizing: border-box;
- .login_title {
- text-align: center;
- margin-bottom: 40px;
- color: #505458;
- }
- .el-input {
- width: 198px;
- }
- }
- </style>
菜单
- <template>
- <div>
- <el-table
- :data="tableData"
- style="width: 100%; margin-bottom: 20px"
- row-key="id"
- border
- default-expand-all
- :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
- >
- <el-table-column prop="name" label="名称" sortable min-width="20%">
- </el-table-column>
- <el-table-column prop="path" label="访问路径" sortable min-width="15%">
- </el-table-column>
-
-
- <el-table-column
- prop="component"
- label="组件路径"
- sortable
- min-width="15%"
- >
- </el-table-column>
- <el-table-column
- prop="permissionValue"
- label="权限值"
- sortable
- min-width="15%"
- >
- </el-table-column>
- <el-table-column prop="status" label="状态" sortable min-width="10%">
- </el-table-column>
- <el-table-column prop="icon" label="图标" sortable min-width="10%">
- </el-table-column>
-
-
- <el-table-column label="操作" min-width="15%">
- <template slot-scope="scope">
- <!-- 第一层和第二层可以添加菜单,第三层添加功能,第四层修改功能 -->
- <el-button
- v-if="scope.row.level === 1 || scope.row.level === 2"
- type="text"
- size="mini"
- @click="addOrEditMenuDialog(scope.row, 'add')"
- >添加菜单</el-button
- >
- <el-button
- v-if="scope.row.level === 3"
- type="text"
- size="mini"
- @click="
- () => {
- dialogPermissionFormVisible = true;
- permissionForm = { ...PERMISSION_FORM };
- permissionForm.pid = scope.row.id;
- permissionTitle = '添加功能';
- }
- "
- >
- 添加功能</el-button
- >
- <el-button
- v-if="scope.row.level === 4"
- type="text"
- size="mini"
- @click="updatePermissionDialog(scope.row)"
- >修改功能</el-button
- >
- <el-button
- v-if="scope.row.level !== 1 && scope.row.level !== 4"
- type="text"
- size="mini"
- @click="addOrEditMenuDialog(scope.row, 'edit')"
- >修改</el-button
- >
- <el-button
- v-if="scope.row.level !== 1"
- @click="deleteSubmit(scope.row)"
- type="text"
- size="mini"
- >删除</el-button
- >
- </template>
- </el-table-column>
- </el-table>
- <!-- 添加菜单的窗口 -->
- <el-dialog
- :title="title"
- :label-position="labelPosition"
- :visible.sync="dialogFormVisible"
- >
- <el-form
- ref="menuForm"
- :model="menuForm"
- :rules="menuFormRules"
- label-width="120px"
- >
- <el-form-item label="菜单名称" prop="name">
- <el-input v-model="menuForm.name"></el-input>
- </el-form-item>
- <el-form-item label="访问路径" prop="path" v-if="showFlag">
- <el-input v-model="menuForm.path"></el-input>
- </el-form-item>
- <el-form-item label="组件路径" prop="component" v-if="showFlag">
- <el-input v-model="menuForm.component"></el-input>
- </el-form-item>
- <!-- <el-form-item label="权限值" prop="permissionValue">
- <el-input v-model="menuForm.permissionValue"></el-input>
- </el-form-item> -->
- <el-form-item label="图标" prop="icon">
- <el-input v-model="menuForm.icon"></el-input>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="resetMenu()">取 消</el-button>
- <el-button type="primary" @click="addMenuFormSubmit()">确 定</el-button>
- </div>
- </el-dialog>
-
-
- <!-- 添加功能的窗口 -->
- <el-dialog
- :title="permissionTitle"
- :label-position="labelPosition"
- :visible.sync="dialogPermissionFormVisible"
- >
- <el-form
- ref="permissionForm"
- :model="permissionForm"
- :rules="permissionFormRules"
- label-width="120px"
- >
- <el-form-item label="功能名称" prop="name">
- <el-input v-model="permissionForm.name"></el-input>
- </el-form-item>
- <el-form-item label="访问路径" prop="path">
- <el-input v-model="permissionForm.path"></el-input>
- </el-form-item>
- <el-form-item label="组件路径" prop="component">
- <el-input v-model="permissionForm.component"></el-input>
- </el-form-item>
- <el-form-item label="功能权限值" prop="permissionValue">
- <el-input v-model="permissionForm.permissionValue"></el-input>
- </el-form-item>
- <el-form-item label="图标" prop="icon">
- <el-input v-model="permissionForm.icon"></el-input>
- </el-form-item>
- </el-form>
- <div slot="footer" class="dialog-footer">
- <el-button @click="resetPermission()">取 消</el-button>
- <el-button type="primary" @click="addPermissonFormSubmit()"
- >确 定</el-button
- >
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import { getData, updateMenuSubmit, deleteSubmit } from "@/api/permission.js";
- import http from "@/utils/request";
- const MENU_FORM = {
- name: "",
- path: "",
- component: "",
- // status: 0,
- icon: "setting",
- pid: 0,
- type: "1",
- id: "",
- };
- const PERMISSION_FORM = {
- name: "",
- path: "",
- component: "",
- permissionValue: "",
- // status: 0,
- icon: "setting",
- pid: 0,
- type: "2",
- id: "",
- };
- export default {
- data() {
- return {
- showFlag: true,
- labelPosition: "left",
- tableData: [], //获取递归取得的全部菜单
- dialogFormVisible: false, //添加修改菜单窗口开关
- dialogPermissionFormVisible: false, //添加修改功能窗口开关
- title: "添加菜单", //添加修改菜单标题
- permissionTitle: "添加功能", //添加修改菜单标题
- menuForm: MENU_FORM, //添加修改菜单内容
- permissionForm: PERMISSION_FORM, //添加修改功能内容
- //表单验证
- menuFormRules: {
- name: [
- { required: true, message: "请输入菜单名称", trigger: "blur" },
- {
- min: 3,
- max: 30,
- message: "长度在 3 到 30 个字符",
- trigger: "blur",
- },
- ],
- path: [
- { message: "请输入访问路径", trigger: "blur" },
- {
- min: 3,
- max: 18,
- message: "长度在 3 到 18 个字符",
- trigger: "blur",
- },
- ],
- component: [
- { message: "请输入组件路径", trigger: "blur" },
- {
- min: 3,
- max: 18,
- message: "长度在 3 到 18 个字符",
- trigger: "blur",
- },
- ],
- },
- //功能表单验证
- permissionFormRules: {
- name: [
- { required: true, message: "请输入菜单名称", trigger: "blur" },
- { min: 3, max: 8, message: "长度在 3 到 8 个字符", trigger: "blur" },
- ],
-
-
- permissionValue: [
- { required: true, message: "请输入权限值", trigger: "blur" },
- {
- min: 3,
- max: 18,
- message: "长度在 3 到 18 个字符",
- trigger: "blur",
- },
- ],
- },
- };
- },
-
-
- created() {
- //获取递归取得的全部菜单
- this.getAllMenuList();
- },
- methods: {
- //修改功能
- updatePermissionDialog(val) {
- this.dialogPermissionFormVisible = true;
- this.permissionForm = val;
- this.permissionTitle = "修改功能";
- },
- //取消菜单添加或修改
- resetMenu() {
- this.dialogFormVisible = false;
- this.menuForm = {};
- },
-
-
- //取消功能添加或修改
- resetPermission() {
- this.dialogPermissionFormVisible = false;
- this.permissionForm = {};
- },
- //添加修改下级功能
- addPermissonFormSubmit() {
- let that = this;
- this.$refs.permissionForm.validate((valid) => {
- if (valid) {
- if (that.permissionForm.id) {
- //修改
- updateMenuSubmit(that.permissionForm).then((res) => {
- if (res.code === 20000) {
- that.$message({
- type: "success",
- message: "修改功能成功",
- });
- //刷新页面
- that.getAllMenuList();
- that.dialogPermissionFormVisible = false;
- that.permissionForm = { ...PERMISSION_FORM };
- }
- });
- } else {
- //新增
-
-
- //let permission = that.menuForm;
- http({
- url: "/permission/save",
- method: "post",
- data: that.permissionForm,
- }).then((res) => {
- if (res.code === 20000) {
- that.$message({
- type: "success",
- message: "添加功能成功",
- });
- //刷新页面
- that.getAllMenuList();
- that.dialogPermissionFormVisible = false;
- that.permissionForm = { ...PERMISSION_FORM };
- }
- });
- }
- } else {
- return false;
- }
- });
- },
- //删除
- deleteSubmit(val) {
- let that = this;
- this.$confirm("此操作将永久删除该记录,是否继续?", "提升", {
- distinguishCancelAndClose: true,
- confirmButtonText: "确定",
- cancelButtonText: "取消",
- })
- .then(() => {
- deleteSubmit(val.id).then((res) => {
- if (res.code === 20000) {
- that.$message({
- type: "success",
- message: "删除成功",
- });
- //刷新页面
- that.getAllMenuList();
- }
- });
- this.$message({
- type: "info",
- message: "保存修改",
- });
- })
- .catch((action) => {
- this.$message({
- type: "info",
- message:
- action === "cancel" ? "放弃保存并离开页面" : "停留在当前页面",
- });
- });
- // let that = this;
- // this.$confirm("此操作将永久删除该记录,是否继续?", "提升", {
- // cofirmButtonText: "确定",
- // cancelButtonText: "取消",
- // type: "warning",
- // }).then(() => {
- // deleteSubmit(val.id).then((res) => {
- // if (res.code === 20000) {
- // that.$message({
- // type: "success",
- // message: "删除成功",
- // });
- // //刷新页面
- // that.getAllMenuList();
- // }
- // });
- // });
- },
- //修改
- updateMenuSubmit() {
- let that = this;
- updateMenuSubmit(that.menuForm).then((res) => {
- if (res.code === 20000) {
- that.$message({
- type: "success",
- message: "修改菜单成功",
- });
- //刷新页面
- that.getAllMenuList();
- that.dialogFormVisible = false;
- }
- });
- },
- //新增
- addMenuSubmit() {
- let that = this;
- //let permission = that.menuForm;
- http({
- url: "/admin/sys/permission/save",
- method: "post",
- data: that.menuForm,
- }).then((res) => {
- if (res.code === 20000) {
- that.$message({
- type: "success",
- message: "添加菜单成功",
- });
- //刷新页面
- that.getAllMenuList();
- that.dialogFormVisible = false;
- }
- });
- },
- //提交添加菜单的数据
- addMenuFormSubmit() {
- let that = this;
- this.$refs.menuForm.validate((valid) => {
- if (valid) {
- if (that.menuForm.id) {
- that.title = "修改菜单";
- //修改
- that.updateMenuSubmit();
- } else {
- that.title = "添加菜单";
- //新增
- that.addMenuSubmit();
- }
- } else {
- return false;
- }
- });
- },
- //显示添加菜单
- addOrEditMenuDialog(val, flag) {
- if (val.level === 1) {
- this.showFlag = false;
- } else {
- this.showFlag = true;
- }
-
-
- if ("add" === flag) {
- //新增的话,页面的值初始化为定义好的常量
- this.menuForm = { ...MENU_FORM };
- //新增的话,新增的菜单的pid为当前选中的行的id
- this.menuForm.pid = val.id;
- this.title = "添加菜单";
- } else {
- this.title = "修改菜单";
- //修改的话,页面的值初始化为列表的具体的内容
- Object.assign(this.menuForm, val);
- //修改
- if (val.level === 2) {
- this.showFlag = false;
- }
- }
-
-
- this.dialogFormVisible = true;
- },
- //获取递归取得的全部菜单
- getAllMenuList() {
- getData().then((res) => {
- if (res.code === 20000 && res.data) {
- this.tableData = res.data.data;
- //console.log('JSON.stringify(this.tableData) ==='+JSON.stringify(this.tableData))
- }
- });
- },
- },
- };
- </script>
分配权限
- <template>
- <div style="margin: 29px">
- <el-tree
- ref="tree"
- :data="data"
- show-checkbox
- default-expand-all
- node-key="id"
- highlight-current
- :props="defaultProps"
- />
- <el-button :disabled="saveBtnDisabled" type="primary" @click="save"
- >保存</el-button
- >
- </div>
- </template>
-
-
- <script>
- import {
- toAssign,
- doAssign,
- } from "@/api/permission";
- export default {
- data() {
- return {
- saveBtnDisabled: false,
- data: [],
- roleId: "",
- defaultProps: {
- children: "children",
- label: "name",
- },
- };
- },
- watch: {
- $route(to, from) {
- this.init();
- },
- },
- created() {
- this.init();
- },
- methods: {
- init() {
- if (this.$route.params && this.$route.params.id) {
- this.roleId = this.$route.params.id;
- this.getDataList(this.roleId);
- }
- },
- getDataList(roleId) {
- toAssign(roleId).then((res) => {
- if (res.code === 20000 && res.data.data) {
- this.data = res.data.data;
- var list = [];
- var jsonList = JSON.parse(JSON.stringify(this.data));
- var llll = JSON.stringify(this.data);
- console.log("this.data========================= " + this.data);
- console.log("jsonList========================= " + jsonList);
- console.log(
- "JSON.stringify(this.data)========================= " +
- JSON.stringify(this.data)
- );
- this.getJsonList(list, jsonList[0]["children"]);
- this.$refs.tree.setCheckedKeys(list);
- }
- });
- },
- //获取所有的角色的权限
- getJsonList(list, jsonList) {
- for (var i = 0; i < jsonList.length; i++) {
- if (
- jsonList[i]["hasSelect"] == true &&
- jsonList[i]["children"].length === 0
- ) {
- list.push(jsonList[i]["id"]);
- }
- if (jsonList[i]["children"].length > 0) {
- this.getJsonList(list, jsonList[i]["children"]);
- }
- }
- },
- save() {
- this.saveBtnDisabled = true;
- var beforeIds = this.$refs.tree.getHalfCheckedKeys().join(",");
- var afterIds = this.$refs.tree.getCheckedKeys().join(",");
- var ids = beforeIds + "," + afterIds;
- if (ids === ",") {
- ids = [];
- }
- console.log(ids);
- doAssign(this.roleId, ids).then((res) => {
- if (res.code === 20000 && res.success) {
- this.$message({
- type: "info",
- message: "保存成功!",
- });
- this.$router.push({ path: "/role" });
- } else {
- this.$message({
- type: "info",
- message: "保存失败!",
- });
- }
- });
- },
- },
- };
- </script>
-
-
- <style>
- </style>
路由
- import Vue from 'vue'
- import VueRouter from 'vue-router'
- import Home from '@/views/Home.vue'
- import User from '@/views/sys/user/User.vue'
- import Main from '@/views/Main.vue'
- import store from '@/store'
- import { getToken } from '@/utils/auth'
- import { login, logout, getInfo } from '@/api/login'
- Vue.use(VueRouter)
-
-
- // 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
- // 1. 定义 (路由) 组件。
- // 可以从其他文件 import 进来
- // 2. 定义路由
- // 每个路由应该映射一个组件。 其中"component" 可以是
- // 通过 Vue.extend() 创建的组件构造器,
- // 或者,只是一个组件配置对象。
- // 我们晚点再讨论嵌套路由。
- const routes = [
- {
- path: '/login',
- name: 'Login',
- component: () => import('@/views/Login.vue')
- },
- //主路由
- // {
- // path: '/',
- // component: Main,
- // redirect: '/home',
- // children: [
- // //子路由
- // { path: 'home', name: "home", component: Home },//首页
- // // { path: 'user', name: "user", component: User },//用户管理
- // // { path: 'role', name: "role", component: () => import("@/views/sys/Role.vue") },//角色管理
- // // { path: 'menu', name: "menu", component: () => import("@/views/sys/Menu.vue") },//菜单管理管理
- // ]
- // },
- // {
- // path: '/user',
- // name: 'User',
- // component: User
- // },
- ]
-
-
- // 3. 创建 router 实例,然后传 `routes` 配置
- // 你还可以传别的配置参数, 不过先这么简单着吧。
- const router = new VueRouter({
- mode: 'history', // 去掉url中的#
- routes // (缩写) 相当于 routes: routes
- })
-
-
- // 4. 创建和挂载根实例。挂载到main.js的根节点
- // 记得要通过 router 配置参数注入路由,
- // 从而让整个应用都有路由功能
- // const app = new Vue({
- // router
- // }).$mount('#app')
-
-
- // 防止连续点击多次路由报错
- // 获取原型对象push函数
- const originalPush = VueRouter.prototype.push
- // 获取原型对象replace函数
- const originalReplace = VueRouter.prototype.replace
- // 修改原型对象中的push函数
- VueRouter.prototype.push = function push(location) {
- return originalPush.call(this, location).catch(err => err)
- }
- // 修改原型对象中的replace函数
- VueRouter.prototype.replace = function replace(location) {
- return originalReplace.call(this, location).catch(err => err)
- }
-
-
- //模拟菜单数据
- //const authoritys = ['sys:user:list', "sys:user:save", "sys:user:delete"]
-
-
- const menuData1 = [
- // {
- // path: "/",
- // name: "home",
- // label: "首页",
- // icon: "s-home",
- // url: "Home/Home",
- // },
- {
- label: "权限管理",
- name: "system",
- icon: "location",
- children: [
- {
- path: "/user",
- name: "user",
- label: "用户管理",
- icon: "setting",
- component: "sys/user/User",
- },
- {
- path: '/sys/role/distribution/:id',
- name: '角色权限',
- component: 'sys/role/roleForm',
- meta: { title: '角色权限', icon: 'table' },
- hidden: true
- },
- {
- path: '/userForm/:id',
- name: '角色权限',
- component: 'sys/user/userForm',
- meta: { title: '角色权限', icon: 'table' },
- hidden: true
- },
- {
- path: "/role",
- name: "role",
- label: "角色管理",
- icon: "setting",
- component: "sys/role/Role",
- },
- {
- path: "/menu",
- name: "menu",
- label: "菜单管理",
- icon: "setting",
- component: "sys/menu/Menu",
- },
- ],
- },
- ]
- // 拼装动态路由
- const manageRoute = {
- path: '/',
- component: Main,
- redirect: '/login',
- children: [
- //子路由
- { path: 'home', name: "home", component: Home },//首页
-
-
- ]
- }
- //获取数据
- //菜单
- // store.commit('setMenuList', menuData1)
-
-
- //权限用户
- //localStorage.setItem("menus1", JSON.stringify(menuData1))
- // 注意:刷新页面会导致页面路由重置
- const setRoutes = () => {
-
-
- //const storeMenus = localStorage.getItem("menus");
- const storeMenus = localStorage.getItem("menus");
-
-
- if (storeMenus) {
-
-
- // 获取当前的路由对象名称数组
- const currentRouteNames = router.getRoutes().map(v => v.name)
- if (!currentRouteNames.includes('home')) {
-
- const menus = JSON.parse(storeMenus)
- menus.forEach(item => {
-
- if (item.path) { // 当且仅当path不为空的时候才去设置路由
-
- let flag = false;
- if (item.hidden) {
-
-
- flag = true;
- }
- let itemMenu = {
- path: item.path,
- name: item.name,
- hidden: flag,
- component: () => import('../views/' + item.component + '.vue')
- }
-
- manageRoute.children.push(itemMenu)
- } else if (item.children.length) {
- item.children.forEach(item => {
- let flag = false;
- if (item.hidden) {
-
-
- flag = true;
- }
- if (item.path) {
- let itemMenu = {
- path: item.path,
- name: item.name,
- hidden: flag,
- component: () => import('../views/' + item.component + '.vue')
- }
-
-
- manageRoute.children.push(itemMenu)
- }
- })
- }
- })
-
- // 动态添加到现在的路由对象中去
- router.addRoute(manageRoute)
- }
-
-
- }
- }
-
-
- // 重置我就再set一次路由
- setRoutes()
-
-
- //转成路由
- // const menuToRoute = (item) => {
-
-
- // if (!item.component) {
- // return null
- // }
- // // let route = {
- // // name: item.name,
- // // path: item.path.replace("/", ""),
-
-
- // // meta: {
- // // icon: item.icon,
- // // title: item.title,
-
-
- // // }
- // // }
- // // route.component= () => import('../views/' + item.component + '.vue')
- // // route.component=()=>import('@/views/'+item.component+'.vue');
- // // route.component = () => import('@/views/' + item.component + '.vue')
- // let route = { path: item.path.replace("/", ""), name: item.name, component: () => import('../views/' + item.component + '.vue') }
- // return route
- // }
-
-
-
-
-
-
- // router.beforeEach((to, from, next) => {
-
-
- // let that = this
-
-
- // getInfo(store.state.token).then(response => {
-
- // const data = response.data
- // if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
- // store.commit('SET_ROLES', data.roles)
- // }
-
-
- // const buttonAuthList = []
- // menuData = data.permissionList
- //
- // data.permissionValueList.forEach(button => {
- // if (button) {
- // buttonAuthList.push(button)
- // }
-
-
- // })
-
-
- // store.commit('SET_NAME', data.name)
- // //commit('SET_AVATAR', data.avatar)
- // store.commit('SET_BUTTONS', buttonAuthList)
-
-
- // }).catch(error => {
-
-
- // })
- // next()
- // })
-
-
-
-
- export default router
权限
- import router from './router'
- import { login, logout, getInfo } from '@/api/login'
- import { getToken, setToken, removeToken } from '@/utils/auth'
- import http from "@/utils/request";
- import qs from "qs";
- import store from './store'
- router.beforeEach(async (to, from, next) => {
-
-
-
-
- const hasToken = getToken()
-
-
- if (hasToken) {
- if (to.path === '/login') {
- // if is logged in, redirect to the home page
- next()
-
-
- } else {
- // determine whether the user has obtained his permission roles through getInfo
- const hasRoles = store.getters.roles && store.getters.roles.length > 0
- if (hasRoles) {
- next()
- } else {
- // get user info
- // note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
- const response = await store.dispatch('GetInfo')
- if (response.code === 20000) {
- const data = response.data
- if (data.roles && data.roles.length > 0) { // 验证返回的roles是否是一个非空数组
- store.commit('SET_ROLES', data.roles)
- }
-
-
- const buttonAuthList = []
- const menuData = data.permissionList
- store.commit('setMenuList', menuData)
-
-
- //权限用户
- localStorage.setItem("menus", JSON.stringify(menuData))
- data.permissionValueList.forEach(button => {
- if (button) {
- buttonAuthList.push(button)
- }
-
-
- })
-
-
- store.commit('SET_NAME', data.name)
- //commit('SET_AVATAR', data.avatar)
- store.commit('SET_BUTTONS', buttonAuthList)
-
-
-
-
- }
-
-
- }
- }
- }
- next()
- })
mixin
- import Vue from "vue"
-
-
- Vue.mixin({
- methods: {
- hasAuth(perm) {
- var authority = this.$store.state.user.buttons
- return authority.indexOf(perm) > -1
- }
- }
- })
security配置
- package com.stu.myserver.config;
-
-
-
-
- import com.stu.myserver.security.*;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
- import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
- import org.springframework.security.config.annotation.web.builders.HttpSecurity;
- import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
- import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
- import org.springframework.security.config.http.SessionCreationPolicy;
- import org.springframework.security.core.userdetails.UserDetailsService;
- import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
-
-
- /******************************
- * 用途说明: Security配置
- * 作者姓名: 公众号:小明的学习圈子 https://www.stucoding.com/
- * 创建时间: 2022-07-27 23:16
- ******************************/
- @Configuration
- @EnableWebSecurity
- @EnableGlobalMethodSecurity(prePostEnabled = true)
- public class SecurityConfig extends WebSecurityConfigurerAdapter {
- @Autowired
- LoginFailureHandler loginFailureHandler;
-
-
- @Autowired
- LoginSuccessHandler loginSuccessHandler;
-
-
- @Autowired
- CaptchaFilter captchaFilter;
-
- @Autowired
- JwtAuthenticationEntryPoint jwtAuthenticationEntryPoint;
-
-
- @Autowired
- JwtAccessDeniedHandler jwtAccessDeniedHandler;
-
-
- @Autowired
- private UserDetailsService userDetailsService;
-
-
- @Autowired
- JwtLogoutSuccessHandler jwtLogoutSuccessHandler;
-
-
- @Bean
- JwtAuthenticationFilter jwtAuthenticationFilter() throws Exception {
- JwtAuthenticationFilter jwtAuthenticationFilter = new JwtAuthenticationFilter(authenticationManager());
- return jwtAuthenticationFilter;
- }
-
-
- // @Bean
- // BCryptPasswordEncoder bCryptPasswordEncoder() {
- // return new BCryptPasswordEncoder();
- // }
- private static final String[] URL_WHITELIST = {
-
-
- "/user/register",
- "/js/**",
- "/login",
- "/logout",
- "/captcha",
- "/favicon.ico",
- "/login**",
- "/login#/login",
- "/home/getData",
- "captcha/getUserInfo"
-
-
- };
-
-
- protected void configure(HttpSecurity http) throws Exception {
-
-
- http.cors().and().csrf().disable() // 登录配置
- .formLogin()
- .successHandler(loginSuccessHandler)
- .failureHandler(loginFailureHandler)
-
-
- .and()
- .logout()
- .logoutSuccessHandler(jwtLogoutSuccessHandler)
-
-
- // 禁用session
- .and()
- .sessionManagement()
- .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
-
-
- // 配置拦截规则
- .and()
- .authorizeRequests()
- .antMatchers(URL_WHITELIST).permitAll()
- .anyRequest().authenticated()
-
-
- // 异常处理器
- .and()
- .exceptionHandling()
- .authenticationEntryPoint(jwtAuthenticationEntryPoint)
- .accessDeniedHandler(jwtAccessDeniedHandler)
-
-
- // 配置自定义的过滤器
- .and()
- .addFilter(jwtAuthenticationFilter())
- .addFilterBefore(captchaFilter, UsernamePasswordAuthenticationFilter.class);
-
-
-
-
-
-
- }
-
-
- @Override
- protected void configure(AuthenticationManagerBuilder auth) throws Exception {
- auth.userDetailsService(userDetailsService);
- }
- }
Redis配置
- package com.stu.myserver.config;
-
-
-
-
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.data.redis.connection.RedisConnectionFactory;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
- import org.springframework.data.redis.serializer.StringRedisSerializer;
-
-
- /******************************
- * 用途说明: redis配置
- * 作者姓名: 公众号:小明的学习圈子 https://www.stucoding.com/
- * 创建时间: 2022-07-27 23:16
- ******************************/
- @Configuration
- public class RedisConfig {
-
-
- @Bean
- RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
-
-
- RedisTemplate redisTemplate = new RedisTemplate();
- redisTemplate.setConnectionFactory(redisConnectionFactory);
-
-
- Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
- jackson2JsonRedisSerializer.setObjectMapper(new ObjectMapper());
-
-
- redisTemplate.setKeySerializer(new StringRedisSerializer());
- redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
-
-
- redisTemplate.setHashKeySerializer(new StringRedisSerializer());
- redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
-
-
- return redisTemplate;
-
-
- }
-
-
- }
跨域配置
- package com.stu.myserver.config;
-
-
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.cors.CorsConfiguration;
- import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
- import org.springframework.web.filter.CorsFilter;
- import org.springframework.web.servlet.config.annotation.CorsRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-
-
-
- /******************************
- * 用途说明: 跨域
- * 作者姓名: 公众号:小明的学习圈子 https://www.stucoding.com/
- * 创建时间: 2022-07-27 23:16
- ******************************/
- @Configuration
- public class CorsConfig implements WebMvcConfigurer {
- private CorsConfiguration buildConfig() {
- CorsConfiguration corsConfiguration = new CorsConfiguration();
- corsConfiguration.addAllowedOrigin("*");
- corsConfiguration.addAllowedHeader("*");
- corsConfiguration.addAllowedMethod("*");
- corsConfiguration.addExposedHeader("Authorization");
- return corsConfiguration;
- }
-
-
- @Bean
- public CorsFilter corsFilter() {
- UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
- source.registerCorsConfiguration("/**", buildConfig());
- return new CorsFilter(source);
- }
-
-
- @Override
- public void addCorsMappings(CorsRegistry registry) {
- registry.addMapping("/**")
- .allowedOrigins("*")
- // .allowCredentials(true)
- .allowedMethods("GET", "POST", "DELETE", "PUT")
- .maxAge(3600);
- }
- }
PermissionServiceImpl
- package com.stu.myserver.service.impl;
-
-
- import com.alibaba.fastjson.JSONObject;
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.stu.myserver.entity.Permission;
- import com.stu.myserver.entity.RolePermission;
- import com.stu.myserver.mapper.PermissionMapper;
- import com.stu.myserver.service.IPermissionService;
- import com.stu.myserver.service.IRolePermissionService;
- import com.stu.myserver.service.IUserService;
- import org.apache.commons.lang.StringUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import com.stu.myserver.entity.User;
- import org.springframework.util.CollectionUtils;
-
-
- import java.util.ArrayList;
- import java.util.List;
- import java.util.stream.Collectors;
-
-
- /**
- * <p>
- * 权限 服务实现类
- * </p>
- *
- * @author 程序员小明1024
- * @since 2023-08-07
- */
- @Service
- public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements IPermissionService {
-
-
- @Autowired
- private IRolePermissionService rolePermissionService;
-
-
- @Autowired
- private IUserService userService;
-
-
- /***********************************
- * 用途说明:获取全部菜单
- * 返回值说明:
- * @return List<Permission>
- ***********************************/
- @Override
- public List<Permission> listPermissions() {
- QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
- queryWrapper.orderByDesc("id");
-
-
- //把查询的所有菜单用递归的方式生成结构化菜单
- return buildPermissions(baseMapper.selectList(queryWrapper));
- }
-
-
- /***********************************
- * 用途说明:获取全部菜单
- * 返回值说明:
- * @return List<Permission>
- ***********************************/
- private List<Permission> buildPermissions(List<Permission> list) {
- //创建rootList集合,最终数据封装
- List<Permission> rootList = new ArrayList<>();
-
-
- //遍历所有菜单,得到顶层菜单 pid==0,设置leve =1
- for (Permission permission : list) {
- //获取顶层菜单,pid=0
- if ("0".equals(permission.getPid())) {
- //设置level = 1
- permission.setLevel(1);
- //根据顶层菜单,添加子菜单,封装到rootList
- rootList.add(selectChildrenMenu(permission, list));
-
-
- }
- }
-
-
- return rootList;
- }
-
-
- /***********************************
- * 用途说明:递归查询下级菜单
- * @param root
- * @param list
- * 返回值说明:
- * @return com.stu.myserver.entity.Permission
- ***********************************/
- private Permission selectChildrenMenu(Permission root, List<Permission> list) {
- //因为要往下级菜单房新的菜单,需要初始化
- root.setChildren(new ArrayList<Permission>());
- //遍历所有菜单,比较当前对象的id和遍历的子菜单的pid是否相同
- for (Permission permission : list) {
- if (root.getId().equals(permission.getPid())) {
- permission.setLevel(root.getLevel() + 1);
- //递归,查询出来的子菜单放到父菜单里
- root.getChildren().add(selectChildrenMenu(permission, list));
- }
- }
- return root;
- }
-
-
- /***********************************
- * 用途说明:查询所有权限菜单
- * 返回值说明:
- * @return java.util.List<com.stu.service.acl.entity.Permission>
- ***********************************/
- @Override
- public List<Permission> ListAllPermissions() {
- QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
- queryWrapper.orderByDesc("id");
- return bulidPermission(baseMapper.selectList(queryWrapper));
- }
-
-
- /***********************************
- * 用途说明:把返回所有菜单list集合进行封装的方法
- * @param list
- * 返回值说明:
- * @return java.util.List<com.stu.service.acl.entity.Permission>
- ***********************************/
- private List<Permission> bulidPermission(List<Permission> list) {
- //创建list集合,用于数据最终封装
- List<Permission> finalNode = new ArrayList<>();
-
-
- //把所有菜单list集合遍历,得到顶层菜单 pid=0菜单,设置level是1
- for (Permission permission : list) {
- //得到顶层菜单 pid=0菜单
- if ("0".equals(permission.getPid())) {
- permission.setLevel(1);
- //根据顶层菜单,向里面进行查询子菜单,封装到finalNode里面
- finalNode.add(selectChildren(permission, list));
- }
- }
-
-
- return finalNode;
- }
-
-
- /***********************************
- * 用途说明:递归查询下级菜单
- * @param permission
- * @param list
- * 返回值说明:
- * @return com.stu.service.acl.entity.Permission
- ***********************************/
- private Permission selectChildren(Permission permission, List<Permission> list) {
- //1 因为向一层菜单里面放二层菜单,二层里面还要放三层,把对象初始化
- permission.setChildren(new ArrayList<Permission>());
- //2 遍历所有菜单list集合,进行判断比较,比较id和pid值是否相同
- for (Permission child : list) {
- if (permission.getId().equals(child.getPid())) {
- child.setLevel(permission.getLevel() + 1);
- if (child.getChildren() == null) {
- child.setChildren(new ArrayList<>());
- }
- // permission.getChildren().add(child);
- // selectChildren(child,list);
- permission.getChildren().add(selectChildren(child, list));
- }
- }
- return permission;
-
-
- }
-
-
- /***********************************
- * 用途说明:递归删除菜单
- * @param id
- * 返回值说明:
- * @return boolean
- ***********************************/
- @Override
- public boolean removeChildById(String id) {
- List<String> idList = new ArrayList<>();
- selectChildListById(id, idList);
- idList.add(id);
- return baseMapper.deleteBatchIds(idList) > 0;
- }
-
-
- /***********************************
- * 用途说明:根據角色獲取菜單
- * @param id
- * 返回值说明:
- * @return java.util.List<com.stu.service.acl.entity.Permission>
- ***********************************/
- @Override
- public List<Permission> listAllMenu(String id) {
- //获取所有菜单
- List<Permission> allPermissionList = baseMapper.selectList(new QueryWrapper<>());
- //根据角色id呼气角色权限列表
- List<RolePermission> rolePermissionsList = rolePermissionService
- .list(new QueryWrapper<RolePermission>().eq("role_id", id));
- //遍历所有菜单,获取每一项,看是否在权限列表,如果在,就标记
- List<String> permissionIdList = rolePermissionsList.stream().map(e -> e.getPermissionId()).collect(Collectors.toList());
- allPermissionList.forEach(permission -> {
- if (permissionIdList.contains(permission.getId())) {
- permission.setHasSelect(true);
- } else {
- permission.setHasSelect(false);
- }
- });
- /*for (int i = 0; i < allPermissionList.size(); i++) {
- Permission permission = allPermissionList.get(i);
- for (int m = 0; m < rolePermissionList.size(); m++) {
- RolePermission rolePermission = rolePermissionList.get(m);
- if(rolePermission.getPermissionId().equals(permission.getId())) {
- permission.setSelect(true);
- }
- }
- }*/
- return bulidPermission(allPermissionList);
- }
-
-
- /***********************************
- * 用途说明:给角色分配菜单权限
- * @param roleId
- * @param permissionId
- * 返回值说明:
- * @return boolean
- ***********************************/
- @Override
- public boolean saveRolePermissionrelationShip(String roleId, String[] permissionId) {
-
-
- //删除旧的权限
- boolean ttt = rolePermissionService.remove(new QueryWrapper<RolePermission>().eq("role_id", roleId));
- if (null != permissionId && permissionId.length > 0) {
- List<RolePermission> list = new ArrayList<>();
- for (String id : permissionId) {
- RolePermission rolePermission = new RolePermission();
- rolePermission.setRoleId(roleId);
- rolePermission.setPermissionId(id);
- list.add(rolePermission);
- }
-
-
- return rolePermissionService.saveBatch(list);
- }
- return true;
- }
-
-
- /***********************************
- * 用途说明:根据用户id查询有权限的菜单
- * @param id
- * 返回值说明:
- * @return java.util.List<java.lang.String>
- ***********************************/
- @Override
- public List<String> selectPermissionValueListByUserId(String id) {
- List<String> list;
- if (checkAdmin(id)) {
- //如果是超级管理员获取所有权限
- list = baseMapper.selectAllPermissionValue();
- } else {
- //根据用户id查询所有权限
- list = baseMapper.selectPermissionValueByUserId(id);
- }
- return list;
- }
-
-
- /***********************************
- * 用途说明:根据用户id查询所有权限的菜单详细列表
- * @param userId
- * 返回值说明:
- * @return java.util.List<org.json.JSONObject>
- ***********************************/
- @Override
- public List<JSONObject> selectPermissionByUserId(String userId) {
- List<Permission> selectPermissionList = null;
- if (checkAdmin(userId)) {
- //如果是超级管理员获取所有权限
- selectPermissionList = baseMapper.selectList(null);
- } else {
- //根据用户id查询所有权限
- selectPermissionList = baseMapper.selectPermissionByUserId(userId);
- }
- //先转换成树状
- List<Permission> permissionList = bulidPermission(selectPermissionList);
- //然后转化成前端需要的格式
- List<JSONObject> result = bulidJson(permissionList);
-
-
- return result;
- }
-
-
- /***********************************
- * 用途说明:转化成前端需要的格式
- * @param permissionList
- * 返回值说明:
- * @return java.util.List<org.json.JSONObject>
- ***********************************/
- private List<JSONObject> bulidJson(List<Permission> permissionList) {
- List<JSONObject> menus = new ArrayList<>();
- if (permissionList.size() == 1) {
- Permission topNode = permissionList.get(0);
- //组建左侧一级菜单
- List<Permission> oneMenuList = topNode.getChildren();
- for (Permission one : oneMenuList) {
- JSONObject oneMenu = new JSONObject();
- oneMenu.put("path", one.getPath());
- oneMenu.put("component", one.getComponent());
- oneMenu.put("redirect", "noredirect");//第一级不需要重定向
- oneMenu.put("name", "name_" + one.getId());
- oneMenu.put("title", one.getName());
- oneMenu.put("label", one.getName());
- oneMenu.put("icon", one.getIcon());
- oneMenu.put("hidden", false);//一级不需要因此,3级需要
- JSONObject oneMeta = new JSONObject();
- oneMeta.put("title", one.getName());
- oneMeta.put("icon", one.getIcon());
- oneMenu.put("meta", oneMeta);
-
-
- List<JSONObject> children = new ArrayList<>();
- List<Permission> twoMenuList = one.getChildren();//二级菜单
- for (Permission two : twoMenuList) {
- JSONObject twoMenu = new JSONObject();
- twoMenu.put("path", two.getPath());
- twoMenu.put("component", two.getComponent());
- twoMenu.put("title", two.getName());
- twoMenu.put("label", two.getName());
- twoMenu.put("icon", two.getIcon());
- // twoMenu.put("redirect", "noredirect");//第一级不需要重定向
- twoMenu.put("name", "name_" + two.getId());
- twoMenu.put("hidden", false);//一级不需要因此,3级需要
- JSONObject twoMeta = new JSONObject();
- twoMeta.put("title", two.getName());
- twoMeta.put("icon", two.getIcon());
- twoMenu.put("meta", twoMeta);
- children.add(twoMenu);
-
-
- //功能按钮
- List<Permission> threeMenuList = two.getChildren();
- for (Permission three : threeMenuList) {
- if (StringUtils.isEmpty(three.getPath())) {
- continue;
- }
- JSONObject threeMenu = new JSONObject();
- threeMenu.put("path", three.getPath());
- threeMenu.put("component", three.getComponent());
- // threeMenu.put("redirect", "noredirect");//第一级不需要重定向
- threeMenu.put("name", "name_" + three.getId());
- threeMenu.put("title", three.getName());
- threeMenu.put("label", three.getName());
- threeMenu.put("icon", three.getIcon());
- threeMenu.put("hidden", true);//一级不需要因此,3级需要
- JSONObject threeMeta = new JSONObject();
- threeMeta.put("title", three.getName());
- threeMeta.put("icon", three.getIcon());
- threeMenu.put("meta", threeMeta);
-
-
- children.add(threeMenu);
- }
-
-
- }
- oneMenu.put("children", children);
- menus.add(oneMenu);
-
-
- }
- }
- return menus;
- }
-
-
- /***********************************
- * 用途说明:判断是否管理员
- * @param id
- * 返回值说明:
- * @return boolean
- ***********************************/
- private boolean checkAdmin(String id) {
- User user = userService.getById(id);
- if (user != null && "admin".equals(user.getUsername())) {
- return true;
- }
- return false;
- }
-
-
- /***********************************
- * 用途说明:根据当前菜单id查询他的子子孙孙id,封装到list集合
- * @param id
- * @param idList
- * 返回值说明:
- ***********************************/
- private void selectChildListById(String id, List<String> idList) {
- //查询当前菜单的下级
- QueryWrapper<Permission> queryWrapper = new QueryWrapper<>();
- queryWrapper.eq("pid", id);
- queryWrapper.select("id");
- List<Permission> childList = baseMapper.selectList(queryWrapper);
- //把childIdList里面菜单id值获取出来,封装idList里面,做递归查询
- childList.forEach(item -> {
- idList.add(item.getId());
- selectChildListById(item.getId(), idList);
- });
-
-
- }
- }
IndexServiceImpl
- package com.stu.myserver.service.impl;
-
-
- import com.alibaba.fastjson.JSONObject;
-
-
- import com.stu.myserver.entity.Role;
- import com.stu.myserver.entity.User;
- import com.stu.myserver.exception.CustomException;
- import com.stu.myserver.service.IPermissionService;
- import com.stu.myserver.service.IRoleService;
- import com.stu.myserver.service.IUserService;
- import com.stu.myserver.service.IndexService;
- import com.stu.myserver.utils.ResultCodeEnum;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
-
-
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
-
-
- /******************************
- * 用途说明:
- * 作者姓名: Administrator
- * 创建时间: 2022-09-01 22:34
- ******************************/
- @Service
- public class IndexServiceImpl implements IndexService {
-
-
- @Autowired
- private IUserService userService;
-
-
- @Autowired
- private IRoleService roleService;
-
-
- @Autowired
- private IPermissionService permissionService;
-
-
- @Autowired
- private RedisTemplate redisTemplate;
-
-
- /***********************************
- * 用途说明:根据用户明获取用户登录信息
- * @param userName
- * 返回值说明:
- * @return java.util.Map<java.lang.String, java.lang.Object>
- ***********************************/
- @Override
- public Map<String, Object> getUserInfo(String userName) {
- Map<String, Object> result = new HashMap<>();
- User user = userService.selectByUserName(userName);
- if (user == null) {
- throw new CustomException(ResultCodeEnum.FETCH_USERINFO_ERROR);
- }
- //根据用户id获取角色
- List<Role> roleList = roleService.selectRoleByUserId(user.getId());
- //转换成角色名称列表
- List<String> roleNameList = roleList.stream()
- .map(item -> item.getRoleName()).collect(Collectors.toList());
-
-
- //前端框架必须返回一个角色,否则报错,如果没有角色,返回一个空角色
- if (roleNameList.size() == 0) {
- roleNameList.add("");
- }
-
-
- List<String> permissionValueList = permissionService.selectPermissionValueListByUserId(user.getId());
- redisTemplate.opsForValue().set(userName, permissionValueList);
- List<String> permissionValueLisst = (List<String>) redisTemplate.opsForValue().get(userName);
- result.put("name", user.getUsername());
- result.put("roles", roleNameList);
- result.put("permissionValueList", permissionValueList);
- return result;
- }
-
-
- /***********************************
- * 用途说明:根据用户动态获取菜单
- * @param userName
- * 返回值说明:
- * @return java.util.List<org.json.JSONObject>
- ***********************************/
- @Override
- public List<JSONObject> getMenu(String userName) {
- User user = userService.selectByUserName(userName);
- if (user == null) {
- throw new CustomException(ResultCodeEnum.FETCH_USERINFO_ERROR);
- }
- //根据用户动态获取菜单
- return permissionService.selectPermissionByUserId(user.getId());
- }
- }
RoleServiceImpl
- package com.stu.myserver.service.impl;
-
-
- import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
- import com.stu.myserver.entity.Role;
- import com.stu.myserver.entity.UserRole;
- import com.stu.myserver.mapper.RoleMapper;
- import com.stu.myserver.service.IRoleService;
- import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
- import com.stu.myserver.service.IUserRoleService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
-
-
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.stream.Collectors;
-
-
- /**
- * <p>
- * 服务实现类
- * </p>
- *
- * @author 程序员小明1024
- * @since 2023-06-28
- */
- @Service
- public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
- @Autowired
- private IUserRoleService userRoleService;
-
-
- /***********************************
- * 用途说明:根据用户获取角色
- * @param userId
- * 返回值说明:
- * @return java.util.List<com.stu.service.acl.entity.Permission>
- ***********************************/
- @Override
- public Map<String, Object> findRoleByUserId(String userId) {
- //获取所有角色
- List<Role> allRoleList = baseMapper.selectList(new QueryWrapper<>());
- //根据用户id获取角色列表
- List<UserRole> existUserRoleList = userRoleService
- .list(new QueryWrapper<UserRole>().eq("user_id", userId).select("role_id"));
- //遍历所有菜单,获取每一项,看是否在权限列表,如果在,就标记
- List<String> existRoleLists = existUserRoleList.stream().map(e -> e.getRoleId()).collect(Collectors.toList());
-
-
- List<Role> assignRoles = new ArrayList<>();
- allRoleList.forEach(role -> {
- if (existRoleLists.contains(role.getId())) {
- assignRoles.add(role);
- }
- });
-
-
- Map<String, Object> roleMap = new HashMap<>();
- roleMap.put("assignRoles", assignRoles);
- roleMap.put("allRoleList", allRoleList);
- return roleMap;
- }
-
-
- /***********************************
- * 用途说明:给用户分配角色权限
- * @param userId
- * @param roleIds
- * 返回值说明:
- * @return boolean
- ***********************************/
- @Override
- public boolean saveUserRelationShip(String userId, String[] roleIds) {
- //删除旧的所有角色权限
- userRoleService.remove(new QueryWrapper<UserRole>().eq("user_id", userId));
- List<UserRole> list = new ArrayList<>();
- for (String id : roleIds) {
- UserRole rolePermission = new UserRole();
- rolePermission.setRoleId(id);
- rolePermission.setUserId(userId);
- list.add(rolePermission);
- }
-
-
- return userRoleService.saveBatch(list);
- }
-
-
- /***********************************
- * 用途说明:根据userid获取用户信息
- * @param userId
- * 返回值说明:
- * @return java.util.List<com.stu.service.acl.entity.Role>
- ***********************************/
- @Override
- public List<Role> selectRoleByUserId(String userId) {
- //根据用户id获取角色列表
- List<UserRole> userRoleList = userRoleService
- .list(new QueryWrapper<UserRole>().eq("user_id", userId).select("role_id"));
- //遍历所有菜单,获取每一项,看是否在权限列表,如果在,就标记
- List<String> roleIdLists = userRoleList.stream().map(e -> e.getRoleId()).collect(Collectors.toList());
- List<Role> roleList = new ArrayList<>();
- if (roleIdLists.size() > 0) {
- roleList = baseMapper.selectBatchIds(roleIdLists);
- }
-
-
- return roleList;
- }
- }
CodeGenerator
- package com.stu.myserver.utils;
-
-
- import com.baomidou.mybatisplus.annotation.FieldFill;
- import com.baomidou.mybatisplus.generator.FastAutoGenerator;
- import com.baomidou.mybatisplus.generator.config.OutputFile;
- import com.baomidou.mybatisplus.generator.fill.Column;
-
-
- import java.util.Collections;
-
-
- /******************************
- * 用途说明:
- * 作者姓名:公众号:程序员小明1024
- * 创建时间: 2023-06-23 14:52
- ******************************/
- public class CodeGenerator {
-
-
- public static void main(String[] args) {
- generate();
- }
-
-
- private static void generate() {
- String projectPath = System.getProperty("user.dir");
- FastAutoGenerator.create("jdbc:mysql://localhost:3306/2023Java?serverTimezone=Asia/Shanghai", "root", "study")
- .globalConfig(builder -> {
- builder.author("公众号 小明的学习圈子") // 设置作者
- .enableSwagger() // 开启 swagger 模式
- .fileOverride() // 覆盖已生成文件
- .outputDir(projectPath + "/src/main/java"); // 指定输出目录
- })
- .packageConfig(builder -> {
- builder.parent("com.stu.myserver") // 设置父包名
- .moduleName(null) // 设置父包模块名
- .pathInfo(Collections.singletonMap(OutputFile.mapperXml, projectPath + "/src/main/resources/mapper")); // 设置mapperXml生成路径
- })
- .strategyConfig(builder -> {
- builder.entityBuilder().enableLombok()
- .addTableFills(new Column("gmt_create", FieldFill.INSERT))
- .addTableFills(new Column("gmt_modified", FieldFill.INSERT_UPDATE));;
- // builder.mapperBuilder().enableMapperAnnotation().build();
- builder.controllerBuilder().enableHyphenStyle() // 开启驼峰转连字符
- .enableRestStyle(); // 开启生成@RestController 控制器
- builder.addInclude("acl_user_role") // 设置需要生成的表名
- .addTablePrefix("acl_", "sys_"); // 设置过滤表前缀
- })
- // .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
- .execute();
-
-
- }
-
-
-
-
- }
ResponseUtil
- package com.stu.myserver.utils;
-
-
- import com.fasterxml.jackson.databind.ObjectMapper;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.MediaType;
-
-
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
-
-
- /******************************
- * 用途说明:需要寫入response的數據
- * 作者姓名: Administrator
- * 创建时间: 2022-09-01 20:44
- ******************************/
- public class ResponseUtil {
-
-
-
-
- /*这段代码是一个用于在Java Web应用中向客户端发送JSON响应的方法。让我逐行解释其功能:
- 1. `public static void out(HttpServletResponse response, R r)`:
- 这是一个公共静态方法,它接受两个参数,一个是`HttpServletResponse`对象,
- 另一个是泛型`R`的对象`r`。`HttpServletResponse`对象用于设置HTTP响应的状态码、内容类型和写入响应数据。
- 2. `ObjectMapper mapper = new ObjectMapper();`:在方法内部创建了一个Jackson库
- 的`ObjectMapper`对象。Jackson库是用于在Java对象和JSON之间进行序列化和反序列化的流行库。
- 这个`ObjectMapper`对象将用于将`r`对象转换为JSON格式。
- 3. `response.setStatus(HttpStatus.OK.value());`:设置HTTP响应的状态码为200 OK。这表示请求已成功处理。
- 4. `response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);`:
- 设置HTTP响应的内容类型为"application/json;charset=UTF-8",表示响应体将包含JSON数据,并且使用UTF-8字符编码。
- 5. `mapper.writeValue(response.getWriter(), r);`:使用`ObjectMapper`
- 将`r`对象序列化为JSON格式,并将其写入`HttpServletResponse`的输出流(通过`response.getWriter()`
- 获得的输出流)。这样,JSON数据将作为HTTP响应的内容发送给客户端。
- 总之,这段代码的目的是将一个Java对象`r`序列化为JSON格式,并将其作为HTTP响应的内容发送给客户端,
- 同时设置响应的状态码和内容类型。这通常用于Web应用程序中的API端点,以便向客户端提供结构化的数据响应。
- */ public static void out(HttpServletResponse response, R r) {
- ObjectMapper mapper = new ObjectMapper();
- response.setStatus(HttpStatus.OK.value());
- response.setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
- try {
- mapper.writeValue(response.getWriter(), r);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
更多内容阅读原文
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。