jiangping
2023-08-17 8d7cb8876ac222eca1c82d5bab250f5551531edb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
<template>
  <GlobalWindow
    class="menu-config-dialog"
    :visible.sync="visible"
    :confirm-working="isWorking"
    :with-footer="!isReadonly"
    width="576px"
    :title="title"
    @confirm="confirm"
  >
    <p class="tip" v-if="role != null">为角色 <em>{{role.name}}</em> 配置可访问的菜单</p>
    <el-tree
      ref="tree"
      :data="menus"
      show-checkbox
      node-key="id"
      default-expand-all
      :default-checked-keys="selectedIds"
      :expand-on-click-node="false"
      :check-on-click-node="true"
      :props="{children: 'children',label: 'name'}">
    </el-tree>
  </GlobalWindow>
</template>
 
<script>
import GlobalWindow from '@/components/common/GlobalWindow'
import { createRoleMenu } from '@/api/system/role'
import { fetchTree as fetchMenuList } from '@/api/system/menu'
export default {
  name: 'MenuConfigWindow',
  components: { GlobalWindow },
  data () {
    return {
      visible: false,
      isWorking: false,
      isReadonly: false,
      title: '授权菜单',
      // 角色
      role: null,
      type: 1,
      // 所有菜单
      menus: [],
      // 已选中的菜单
      selectedIds: []
    }
  },
  methods: {
    /**
     * 打开窗口
     *
     * @param role 目标角色
     * @param type 0平台 1企业PC 2企业H5
     */
    open (title, role, type, readonly = false) {
      this.title = title
      this.role = role
      this.isReadonly = readonly
      this.type = type
      // console.log(role)
      // const formData = new FormData()
      // formData.append('type', role.type)
      // formData.append('moduleId', 1)
      fetchMenuList({ type: type, moduleId: 1 })
        .then(records => {
          this.menus = records
          // 如果为固定角色,则固定菜单不可更改
          this.__handleFixedMenus(this.menus, this.role)
          // 找出叶节点
          role.menus = role.menus.filter(menu => role.menus.findIndex(m => m.parentId === menu.id) === -1)
          // 初始化选中
          this.selectedIds = role.menus.map(r => r.id)
          // console.log('selectedIds', this.selectedIds)
          // 只讀
          if (readonly) {
            this.__toReadonlyMenus(this.menus)
            // console.log('menus', this.menus)
          }
          this.visible = true
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
    },
    /**
     * 确认选择菜单
     */
    confirm () {
      const selectedMenus = this.$refs.tree.getCheckedNodes(false, true)
      this.isWorking = true
      createRoleMenu({
        roleId: this.role.id,
        menuIds: selectedMenus.map(menu => menu.id),
        type: this.type
      })
        .then(() => {
          this.$tip.apiSuccess('菜单授权成功')
          this.visible = false
          this.$emit('success')
        })
        .catch(e => {
          this.$tip.apiFailed(e)
        })
        .finally(() => {
          this.isWorking = false
        })
    },
    /**
     * 处理固定菜单
     *
     * @param menus 菜单列表
     * @param role 角色
     * @private
     */
    __handleFixedMenus (menus, role) {
      if (menus == null || menus.length === 0) {
        return
      }
      for (const menu of menus) {
        menu.disabled = false
        if (role.fixed && menu.fixed) {
          menu.disabled = true
        }
        this.__handleFixedMenus(menu.children, role)
      }
    },
    /**
     * 調整為只讀菜單
     */
    __toReadonlyMenus (menus) {
      if (menus == null || menus.length === 0) {
        return
      }
      for (const menu of menus) {
        menu.disabled = true
        this.__toReadonlyMenus(menu.children)
      }
    }
  }
}
</script>
 
<style scoped lang="scss">
@import "@/assets/style/variables.scss";
.global-window {
  .tip {
    margin-bottom: 12px;
    em {
      font-style: normal;
      color: $primary-color;
      font-weight: bold;
    }
  }
  ::v-deep .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
    background-color: #81a4d8;
    border-color: #1c9226;
  }
}
</style>