Spring Security(六):前端菜單,角色權限頁面的搭建

目前項目中作了幾個有關權限控制的頁面,主要作了三個,角色管理,資源管理,角色權限的頁面。 css

角色管理

該頁面主要是對角色的crud,這個比較簡單就很少講了。 前端

資源管理

這個頁面實際上是對菜單的配置,也就是路由的設置,我採用了組件複用的思路,就是增長和更新頁面用的是同一個組件,啓用前判斷是增長仍是更新就行了。 vue

若是是新增的話有一個會初始化
更新的話就會獲得信息,顯示出來

Vue代碼

  1. 新建src\views\pre\perm\edit.vue文件,這個其實編輯按鈕引用的組件,經過這裏能夠設置咱們要進行的操做的是編輯,而後經過scope獲取到數據
<template>
		  <div>
		    <el-button size="mini" type="success" @click="to">編輯</el-button>
		    <eForm ref="form" :menus="menus" :sup_this="sup_this" :is-add="false"/>
		  </div>
		</template>
		<script>
		import eForm from './form'
		export default {
		  components: { eForm },
		  props: {
		    data: {
		      type: Object,
		      required: true
		    },
		    sup_this: {
		      type: Object,
		      required: true
		    },
		    menus: {
		      type: Array,
		      required: true
		    }
		  },
		  methods: {
		    to() {
		      const _this = this.$refs.form
		      _this.roleIds = []
		      _this.form = { per_id: this.data.per_id, per_component: this.data.per_component, per_name: this.data.per_name, per_sort: this.data.per_sort,
		        per_parent_id: this.data.per_parent_id, per_resource: this.data.per_resource, per_icon: this.data.per_icon, per_describe: this.data.per_describe }
		      _this.dialog = true
		    }
		  }
		}
		</script>
		
		<style scoped>
		  div{
		    display: inline-block;
		    margin-right: 3px;
		  }
		</style>

複製代碼

2.新建一個src\views\pre\perm\form.vue文件 這個就是咱們要複用的組件了數據庫

<template>
	  <el-dialog :append-to-body="true" :visible.sync="dialog" :title="isAdd ? '新增菜單' : '編輯菜單'" width="600px">
	    <el-form ref="form" :model="form" :rules="rules" size="small" label-width="80px">
	      <el-form-item label="菜單圖標">
	        <el-popover
	          placement="bottom-start"
	          width="460"
	          trigger="click"
	          @show="$refs['iconSelect'].reset()">
	          <el-input slot="reference" v-model="form.icon" style="width: 460px;" placeholder="點擊選擇圖標" readonly>
	            <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.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="菜單名稱" prop="per_name">
	        <el-input v-model="form.per_name" placeholder="名稱" style="width: 460px;"/>
	      </el-form-item>
	      <el-form-item label="菜單排序" prop="per_sort">
	        <el-input v-model.number="form.per_sort" placeholder="序號越小越靠前" style="width: 460px;"/>
	      </el-form-item>
	      <el-form-item label="URL地址">
	        <el-input v-model="form.per_resource" placeholder="組件路徑" style="width: 460px;"/>
	      </el-form-item>
	      <el-form-item label="組件路徑">
	        <el-input v-model="form.per_component" placeholder="組件路徑" style="width: 460px;"/>
	      </el-form-item>
	      <el-form-item label="上級菜單">
	        <treeselect v-model="form.per_parent_id" :options="menus" style="width: 460px;" placeholder="選擇上級類目" />
	      </el-form-item>
	      <el-form-item label="菜單描述" prop="per_describe">
	        <el-input v-model.number="form.per_describe" placeholder="請填寫菜單描述" style="width: 460px;"/>
	      </el-form-item>
	    </el-form>
	    <div slot="footer" class="dialog-footer">
	      <el-button type="text" @click="cancel">取消</el-button>
	      <el-button :loading="loading" type="primary" @click="doSubmit">確認</el-button>
	    </div>
	  </el-dialog>
	</template>
	
	<script>
	// import the component
	import Treeselect from '@riophae/vue-treeselect'
	// import the styles
	import '@riophae/vue-treeselect/dist/vue-treeselect.css'
	import { add, edit } from '@/api/menu'
	export default {
	  components: { Treeselect },
	  props: {
	    menus: {
	      type: Array,
	      required: true
	    },
	    isAdd: {
	      type: Boolean,
	      required: true
	    },
	    sup_this: {
	      type: Object,
	      default: null
	    }
	  },
	  data() {
	    return {
	      loading: false, dialog: false,
	      form: { per_id: null, per_name: '', per_sort: 999, per_resource: '', per_component: '', per_parent_id: 0, per_icon: '', per_describe: '' },
	      roleIds: [],
	      rules: {
	        per_name: [
	          { required: true, message: '請輸入名稱', trigger: 'blur' }
	        ],
	        per_sort: [
	          { required: true, message: '請輸入序號', trigger: 'blur', type: 'number' }
	        ]
	      }
	    }
	  },
	  methods: {
	    cancel() {
	      this.resetForm()
	    },
	    doSubmit() {
	      this.$refs['form'].validate((valid) => {
	        if (valid) {
	          this.loading = true
	          this.form.roles = []
	          const _this = this
	          this.roleIds.forEach(function(data, index) {
	            const role = { id: data }
	            _this.form.roles.push(role)
	          })
	          if (this.isAdd) {
	            this.doAdd()
	          } else this.doEdit()
	        } else {
	          return false
	        }
	      })
	    },
	    doAdd() {
	      add(this.form).then(res => {
	        this.resetForm()
	        this.$notify({
	          title: '添加成功',
	          type: 'success',
	          duration: 2500
	        })
	        this.loading = false
	        this.$parent.$parent.init()
	        this.$parent.$parent.getMenus()
	      }).catch(error => {
	        this.loading = false
	        this.$message({
	          showClose: true,
	          message: error,
	          type: 'error'
	        })
	      })
	    },
	    doEdit() {
	      edit(this.form).then(res => {
	        this.resetForm()
	        this.$notify({
	          title: '修改爲功',
	          type: 'success',
	          duration: 2500
	        })
	        this.loading = false
	        this.sup_this.init()
	        this.sup_this.getMenus()
	      }).catch(err => {
	        this.loading = false
	        console.log(err.msg)
	      })
	    },
	    resetForm() {
	      this.dialog = false
	      this.$refs['form'].resetFields()
	      this.form = { name: '', sort: 999, path: '', component: '', iframe: 'false', pid: 0, icon: '' }
	      this.roleIds = []
	    },
	    selected(name) {
	      this.form.icon = name
	    }
	  }
	}
	</script>
	
	<style scoped>
	
	</style>

複製代碼

作了這個通用的組件就不用在代碼中同時引用兩個組件了。api

角色權限

個人這個項目前端對權限的控制對象主要是頁面的路由,能夠動態的去設置角色能夠顯示哪些菜單。使用了el-tree這個組件...不會css...頁面很醜莫見怪... 系統管理員的頁面 bash

測試用戶,固然正常狀況下用戶是不該該能夠看到這些關於全縣的頁面的,我這裏只是拿來測試。
能夠看到測試用戶那邊的路由頁面根據咱們的配置就顯示出來了

動態配置的思路

角色權限這個頁面中的樹形組件實際上是對咱們數據庫中的RolePermission組件進行增刪改查,大體過程是:app

  • 經過角色id得到用戶的路由集合,而後經過el-tree組件去渲染是否被選中
  • 更新的思路是首先刪除RolePermission表中這個角色id全部的數據,而後根據咱們前端拿到的id集合去批量增長。

小問題

因爲el-tree組件拿到咱們後臺給的父節點的id,會直接把子節點所有選中,可是這個明顯不符合咱們的要求,目前的解決辦法是把父子節點的關聯移除,這樣有個問題是咱們本身去配置的時候選中父節點,子節點要一個一個去選擇...我還在想解決辦法...svg

相關文章
相關標籤/搜索