Browse Source

菜单管理系统,新增开发

daxiong.yang 7 years ago
parent
commit
4553463b60
5 changed files with 85 additions and 159 deletions
  1. 1 0
      index.html
  2. 1 1
      src/utils/index.js
  3. 70 20
      src/views/menu/add-or-update.vue
  4. 12 137
      src/views/menu/index.vue
  5. 1 1
      src/views/role/index.vue

+ 1 - 0
index.html

5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
6
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
7
  <title>Vue-cli-basic</title>
7
  <title>Vue-cli-basic</title>
8
  <link href="https://cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">
8
  <script src="./static/config/index.js?v=<%=new Date().getTime()%>"></script>
9
  <script src="./static/config/index.js?v=<%=new Date().getTime()%>"></script>
9
</head>
10
</head>
10
<body>
11
<body>

+ 1 - 1
src/utils/index.js

12
 * @param {*} id
12
 * @param {*} id
13
 * @param {*} pid
13
 * @param {*} pid
14
 */
14
 */
15
export function treeDataTranslate (data, id, pid) {
15
export function treeDataTranslate (data, id = 'id', pid = 'parentId') {
16
  var res = []
16
  var res = []
17
  var temp = {}
17
  var temp = {}
18
  for (var i = 0; i < data.length; i++) {
18
  for (var i = 0; i < data.length; i++) {

+ 70 - 20
src/views/menu/add-or-update.vue

1
<template>
1
<template>
2
  <el-dialog
2
  <el-dialog
3
    :title="!dataForm.userId ? '新增' : '修改'"
3
    :title="!dataForm.id ? '新增' : '修改'"
4
    :close-on-click-modal="false"
4
    :close-on-click-modal="false"
5
    :visible.sync="visible">
5
    :visible.sync="visible">
6
    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="80px">
6
    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="80px">
15
        <el-input v-model="dataForm.name" placeholder="菜单名称或按钮名称"></el-input>
15
        <el-input v-model="dataForm.name" placeholder="菜单名称或按钮名称"></el-input>
16
      </el-form-item>
16
      </el-form-item>
17
      <el-form-item label="上级菜单" prop="parentName">
17
      <el-form-item label="上级菜单" prop="parentName">
18
        <el-input v-model="dataForm.parentName" placeholder="一级菜单"></el-input>
19
        <el-tree
20
          :data="menuList"
21
          :props="menuListTreeProps"
22
          node-key="menuId"
23
          ref="menuListTree"
24
          :default-expand-all="true"
25
          show-checkbox>
26
        </el-tree>
18
        <el-popover
19
          ref="menuListPopover"
20
          placement="bottom-end"
21
          trigger="click">
22
          <el-tree
23
            :data="menuList"
24
            :props="menuListTreeProps"
25
            node-key="menuId"
26
            ref="menuListTree"
27
            @current-change="menuListTreeCurrentChangeHandle"
28
            :default-expand-all="true"
29
            :expand-on-click-node="false">
30
          </el-tree>
31
        </el-popover>
32
        <el-input v-model="dataForm.parentName" v-popover:menuListPopover :readonly="true" placeholder="点击选择上级菜单" class="menu-list__input"></el-input>
27
      </el-form-item>
33
      </el-form-item>
28
      <el-form-item label="菜单URL" prop="url">
34
      <el-form-item label="菜单URL" prop="url">
29
        <el-input v-model="dataForm.url" placeholder="菜单URL"></el-input>
35
        <el-input v-model="dataForm.url" placeholder="菜单URL"></el-input>
35
        <el-input-number v-model="dataForm.orderNum" :min="1" :max="10" label="排序号"></el-input-number>
41
        <el-input-number v-model="dataForm.orderNum" :min="1" :max="10" label="排序号"></el-input-number>
36
      </el-form-item>
42
      </el-form-item>
37
      <el-form-item label="菜单图标" prop="icon">
43
      <el-form-item label="菜单图标" prop="icon">
38
        <el-input v-model="dataForm.icon" placeholder="菜单图标"></el-input>
39
      </el-form-item>
40
      <el-form-item label="" size="mini">
41
        <span>获取图标方法: <a href="http://element-cn.eleme.io/#/zh-CN/component/icon" target="_blank">http://element-cn.eleme.io/#/zh-CN/component/icon</a></span>
44
        <el-row>
45
          <el-col :span="22">
46
            <el-input v-model="dataForm.icon" placeholder="菜单图标"></el-input>
47
          </el-col>
48
          <el-col :span="2" class="icon-tips">
49
            <el-tooltip placement="top" effect="light">
50
              <div slot="content">
51
                <span>获取图标: </span><br/>
52
                1. 暂时兼容旧版引入使用 <a href="//fontawesome.io/icons/" target="_blank">fontawesome</a><br/>
53
                2. 之后统一全站修改使用 <a href="//github.com/daxiongYang/vue-cli-basic/blob/master/src/iconfont/index.js" target="_blank">iconfont</a>
54
              </div>
55
              <i class="el-icon-warning"></i>
56
            </el-tooltip>
57
          </el-col>
58
        </el-row>
42
      </el-form-item>
59
      </el-form-item>
43
    </el-form>
60
    </el-form>
44
    <span slot="footer" class="dialog-footer">
61
    <span slot="footer" class="dialog-footer">
51
<script>
68
<script>
52
  import API from '@/api'
69
  import API from '@/api'
53
  import { treeDataTranslate } from '@/utils'
70
  import { treeDataTranslate } from '@/utils'
71
  import isFinite from 'lodash/isFinite'
54
  export default {
72
  export default {
55
    data () {
73
    data () {
56
      var validateUrl = (rule, value, callback) => {
74
      var validateUrl = (rule, value, callback) => {
63
      return {
81
      return {
64
        visible: false,
82
        visible: false,
65
        dataForm: {
83
        dataForm: {
66
          id: 0,
67
          type: '',
84
          id: null,
85
          type: 1,
68
          name: '',
86
          name: '',
87
          parentId: null,
69
          parentName: '',
88
          parentName: '',
70
          url: '',
89
          url: '',
71
          perms: '',
90
          perms: '',
76
          name: [
95
          name: [
77
            { required: true, message: '菜单名称不能为空', trigger: 'blur' }
96
            { required: true, message: '菜单名称不能为空', trigger: 'blur' }
78
          ],
97
          ],
98
          parentName: [
99
            { required: true, message: '上级菜单不能为空', trigger: 'change' }
100
          ],
79
          url: [
101
          url: [
80
            { validator: validateUrl, trigger: 'blur' }
102
            { validator: validateUrl, trigger: 'blur' }
81
          ]
103
          ]
89
    },
111
    },
90
    methods: {
112
    methods: {
91
      init (id) {
113
      init (id) {
92
        this.dataForm.id = id || 0
114
        this.dataForm.id = isFinite(id) ? id : null
93
        API.menu.select().then(({data}) => {
115
        API.menu.select().then(({data}) => {
94
          this.menuList = treeDataTranslate(data.menuList, 'menuId', 'parentId') || []
95
          console.log(this.menuList)
116
          this.menuList = treeDataTranslate(data.menuList, 'menuId')
117
        }).then(() => {
118
          this.visible = true
119
          this.$nextTick(() => {
120
            this.$refs['dataForm'].resetFields()
121
          })
122
        }).then(() => {
123
          if (isFinite(this.dataForm.id)) {
124
          }
96
        })
125
        })
97
        this.visible = true
126
      },
127
      // 菜单树选中
128
      menuListTreeCurrentChangeHandle (data, node) {
129
        this.dataForm.parentId = data.menuId
130
        this.dataForm.parentName = data.name
98
      },
131
      },
99
      dataFormSubmit () {
132
      dataFormSubmit () {
100
        this.$refs['dataForm'].validate((valid) => {
133
        this.$refs['dataForm'].validate((valid) => {
130
    }
163
    }
131
  }
164
  }
132
</script>
165
</script>
166
167
<style lang="scss">
168
  .mod-menu {
169
    .menu-list__input {
170
       > .el-input__inner {
171
        cursor: pointer;
172
      }
173
    }
174
    .icon-tips {
175
      font-size: 18px;
176
      text-align: center;
177
      color: #e6a23c;
178
      cursor: pointer;
179
    }
180
  }
181
</style>
182

+ 12 - 137
src/views/menu/index.vue

2
  <div class="mod-menu">
2
  <div class="mod-menu">
3
    <el-form :inline="true" :model="dataForm">
3
    <el-form :inline="true" :model="dataForm">
4
      <el-form-item>
4
      <el-form-item>
5
        <el-button type="primary" @click="addOrUpdateHandle()">新增</el-button>
5
        <el-button v-if="isAuth('sys:user:save')" type="primary" @click="addOrUpdateHandle()">新增</el-button>
6
      </el-form-item>
6
      </el-form-item>
7
    </el-form>
7
    </el-form>
8
    <tree-table
8
    <tree-table
9
      :columns="treeTableColumns"
9
      :columns="treeTableColumns"
10
      :data="dataList"
10
      :data="dataList"
11
      highlight-current-row
12
      border
11
      border
13
      style="width: 100%;">
12
      style="width: 100%;">
14
      <el-table-column
13
      <el-table-column
28
        header-align="center"
27
        header-align="center"
29
        align="center"
28
        align="center"
30
        label="图标">
29
        label="图标">
30
        <template slot-scope="scope">
31
          <i :class="['fa-lg', scope.row.icon]"></i>
32
        </template>
31
      </el-table-column>
33
      </el-table-column>
32
      <el-table-column
34
      <el-table-column
33
        prop="type"
35
        prop="type"
69
        width="200"
71
        width="200"
70
        label="操作">
72
        label="操作">
71
        <template slot-scope="scope">
73
        <template slot-scope="scope">
72
          <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.userId)">修改</el-button>
73
          <el-button type="text" size="small" @click="deleteHandle(scope.row.userId)">删除</el-button>
74
          <el-button v-if="isAuth('sys:user:update')" type="text" size="small" @click="addOrUpdateHandle(scope.row.menuId)">修改</el-button>
75
          <el-button v-if="isAuth('sys:user:delete')" type="text" size="small" @click="deleteHandle(scope.row.menuId)">删除</el-button>
74
        </template>
76
        </template>
75
      </el-table-column>
77
      </el-table-column>
76
    </tree-table>
78
    </tree-table>
81
83
82
<script>
84
<script>
83
  import TreeTable from '@/components/tree-table'
85
  import TreeTable from '@/components/tree-table'
86
  import AddOrUpdate from './add-or-update'
84
  import API from '@/api'
87
  import API from '@/api'
85
  import { treeDataTranslate } from '@/utils'
88
  import { treeDataTranslate } from '@/utils'
86
  import AddOrUpdate from './add-or-update'
87
  import { isEmail, isMobile } from '@/utils/validate'
88
  export default {
89
  export default {
89
    data () {
90
    data () {
90
      var validatePassword = (rule, value, callback) => {
91
        if (!this.addOrUpdateForm.userId && !/\S/.test(value)) {
92
          callback(new Error('密码不能为空'))
93
        } else {
94
          callback()
95
        }
96
      }
97
      var validateComfirmPassword = (rule, value, callback) => {
98
        if (!this.addOrUpdateForm.userId && !/\S/.test(value)) {
99
          callback(new Error('确认密码不能为空'))
100
        } else if (this.addOrUpdateForm.password !== value) {
101
          callback(new Error('确认密码与密码输入不一致'))
102
        } else {
103
          callback()
104
        }
105
      }
106
      var validateEmail = (rule, value, callback) => {
107
        if (!isEmail(value)) {
108
          callback(new Error('邮箱格式错误'))
109
        } else {
110
          callback()
111
        }
112
      }
113
      var validateMobile = (rule, value, callback) => {
114
        if (!isMobile(value)) {
115
          callback(new Error('手机号格式错误'))
116
        } else {
117
          callback()
118
        }
119
      }
120
      return {
91
      return {
121
        dataForm: {
122
          userName: ''
123
        },
92
        dataForm: {},
124
        treeTableColumns: [
93
        treeTableColumns: [
125
          {
94
          {
126
            text: 'ID',
95
            text: 'ID',
129
          }
98
          }
130
        ],
99
        ],
131
        dataList: [],
100
        dataList: [],
132
        pageIndex: 1,
133
        pageSize: 10,
134
        totalPage: 0,
135
        dataListLoading: false,
101
        dataListLoading: false,
136
        dataListSelections: [],
137
        roleList: [],
138
        addOrUpdateVisible: false,
139
        addOrUpdateForm: {
140
          userId: 0,
141
          userName: '',
142
          password: '',
143
          comfirmPassword: '',
144
          email: '',
145
          mobile: '',
146
          roleIdList: [],
147
          status: 1
148
        },
149
        addOrUpdateRule: {
150
          userName: [
151
            { required: true, message: '用户名不能为空', trigger: 'blur' }
152
          ],
153
          password: [
154
            { validator: validatePassword, trigger: 'blur' }
155
          ],
156
          comfirmPassword: [
157
            { validator: validateComfirmPassword, trigger: 'blur' }
158
          ],
159
          email: [
160
            { required: true, message: '邮箱不能为空', trigger: 'blur' },
161
            { validator: validateEmail, trigger: 'blur' }
162
          ],
163
          mobile: [
164
            { required: true, message: '手机号不能为空', trigger: 'blur' },
165
            { validator: validateMobile, trigger: 'blur' }
166
          ]
167
        }
102
        addOrUpdateVisible: false
168
      }
103
      }
169
    },
104
    },
170
    components: {
105
    components: {
179
      getDataList () {
114
      getDataList () {
180
        this.dataListLoading = true
115
        this.dataListLoading = true
181
        API.menu.list().then(({data}) => {
116
        API.menu.list().then(({data}) => {
182
          this.dataList = treeDataTranslate(data, 'menuId', 'parentId') || []
117
          this.dataList = treeDataTranslate(data, 'menuId')
183
          this.dataListLoading = false
118
          this.dataListLoading = false
184
        })
119
        })
185
      },
120
      },
186
      // 多选
187
      selectionChangeHandle (val) {
188
        this.dataListSelections = val
189
      },
190
      // 新增 / 修改
121
      // 新增 / 修改
191
      addOrUpdateHandle (id) {
122
      addOrUpdateHandle (id) {
192
        this.addOrUpdateVisible = true
123
        this.addOrUpdateVisible = true
193
        this.$nextTick(() => {
124
        this.$nextTick(() => {
194
          this.$refs.addOrUpdate.init(id)
125
          this.$refs.addOrUpdate.init(id)
195
        })
126
        })
196
        // this.addOrUpdateForm.userId = id || 0
197
        // API.role.listByUser().then(({data}) => {
198
        //   this.roleList = data && data.code === 0 ? data.list : []
199
        // }).then(() => {
200
        //   this.addOrUpdateVisible = true
201
        //   this.$nextTick(() => {
202
        //     this.$refs['addOrUpdateForm'].resetFields()
203
        //   })
204
        // }).then(() => {
205
        //   if (this.addOrUpdateForm.userId) {
206
        //     API.user.info(this.addOrUpdateForm.userId).then(({data}) => {
207
        //       if (data && data.code === 0) {
208
        //         this.addOrUpdateForm.userName = data.user.username
209
        //         this.addOrUpdateForm.email = data.user.email
210
        //         this.addOrUpdateForm.mobile = data.user.mobile
211
        //         this.addOrUpdateForm.roleIdList = data.user.roleIdList
212
        //         this.addOrUpdateForm.status = data.user.status
213
        //       }
214
        //     })
215
        //   }
216
        // })
217
      },
218
      // 新增 / 修改, 提交
219
      addOrUpdateFormSubmit () {
220
        this.$refs['addOrUpdateForm'].validate((valid) => {
221
          if (valid) {
222
            var params = {
223
              'userId': this.addOrUpdateForm.userId || undefined,
224
              'username': this.addOrUpdateForm.userName,
225
              'password': this.addOrUpdateForm.password,
226
              'email': this.addOrUpdateForm.email,
227
              'mobile': this.addOrUpdateForm.mobile,
228
              'status': this.addOrUpdateForm.status,
229
              'roleIdList': this.addOrUpdateForm.roleIdList
230
            }
231
            var tick = this.addOrUpdateForm.userId ? API.user.update(params) : API.user.add(params)
232
            tick.then(({data}) => {
233
              if (data && data.code === 0) {
234
                this.$message({
235
                  message: '操作成功',
236
                  type: 'success',
237
                  duration: 1500,
238
                  onClose: () => {
239
                    this.addOrUpdateVisible = false
240
                    this.getDataList()
241
                  }
242
                })
243
              } else {
244
                this.$message.error(data.msg)
245
              }
246
            })
247
          }
248
        })
249
      },
127
      },
250
      // 删除
128
      // 删除
251
      deleteHandle (id) {
129
      deleteHandle (id) {
252
        var userIds = id ? [id] : this.dataListSelections.map(item => {
253
          return item.userId
254
        })
255
        this.$confirm(`确定对[id=${userIds.join(',')}]进行[${id ? '删除' : '批量删除'}]操作?`, '提示', {
130
        this.$confirm(`确定对[id=${id}]进行[删除]操作?`, '提示', {
256
          confirmButtonText: '确定',
131
          confirmButtonText: '确定',
257
          cancelButtonText: '取消',
132
          cancelButtonText: '取消',
258
          type: 'warning'
133
          type: 'warning'
259
        }).then(() => {
134
        }).then(() => {
260
          API.user.del(userIds).then(({data}) => {
135
          API.menu.del([id]).then(({data}) => {
261
            if (data && data.code === 0) {
136
            if (data && data.code === 0) {
262
              this.$message({
137
              this.$message({
263
                message: '操作成功',
138
                message: '操作成功',

+ 1 - 1
src/views/role/index.vue

175
      addOrUpdateHandle (id) {
175
      addOrUpdateHandle (id) {
176
        this.addOrUpdateForm.roleId = id || 0
176
        this.addOrUpdateForm.roleId = id || 0
177
        API.menu.list().then(({data}) => {
177
        API.menu.list().then(({data}) => {
178
          this.menuList = treeDataTranslate(data, 'menuId', 'parentId') || []
178
          this.menuList = treeDataTranslate(data, 'menuId')
179
        }).then(() => {
179
        }).then(() => {
180
          this.addOrUpdateDialogVisible = true
180
          this.addOrUpdateDialogVisible = true
181
          this.$nextTick(() => {
181
          this.$nextTick(() => {