2 changed files with 434 additions and 0 deletions
			
			
		@ -0,0 +1,329 @@ | 
				
			|||
<template> | 
				
			|||
  <el-dialog :visible.sync="visible" | 
				
			|||
             :title="!dataForm.id ? $t('add') : $t('update')" | 
				
			|||
             :close-on-click-modal="false" | 
				
			|||
             :close-on-press-escape="false"> | 
				
			|||
    <el-form :model="dataForm" | 
				
			|||
             :rules="dataRule" | 
				
			|||
             ref="dataForm" | 
				
			|||
             @keyup.enter.native="dataFormSubmitHandle()" | 
				
			|||
             label-width="120px"> | 
				
			|||
      <el-form-item prop="type" | 
				
			|||
                    :label="$t('menu.type')" | 
				
			|||
                    size="mini"> | 
				
			|||
        <el-radio-group v-model="dataForm.type" | 
				
			|||
                        :disabled="!!dataForm.id"> | 
				
			|||
          <el-radio :label="0">{{ $t('menu.type0') }}</el-radio> | 
				
			|||
          <el-radio :label="1">{{ $t('menu.type1') }}</el-radio> | 
				
			|||
        </el-radio-group> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item prop="name" | 
				
			|||
                    :label="$t('menu.name')"> | 
				
			|||
        <el-input v-model="dataForm.name" | 
				
			|||
                  :placeholder="$t('menu.name')"></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item v-if="dataForm.type === 0" | 
				
			|||
                    prop="menuCode" | 
				
			|||
                    :label="$t('menu.menuCode')"> | 
				
			|||
        <el-input v-model="dataForm.menuCode" | 
				
			|||
                  :placeholder="$t('menu.menuCode')"></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item prop="parentName" | 
				
			|||
                    :label="$t('menu.parentName')" | 
				
			|||
                    class="menu-list"> | 
				
			|||
        <el-popover v-model="menuListVisible" | 
				
			|||
                    ref="menuListPopover" | 
				
			|||
                    placement="bottom-start" | 
				
			|||
                    trigger="click"> | 
				
			|||
          <el-tree :data="menuList" | 
				
			|||
                   :props="{ label: 'name', children: 'children' }" | 
				
			|||
                   node-key="id" | 
				
			|||
                   ref="menuListTree" | 
				
			|||
                   :highlight-current="true" | 
				
			|||
                   :expand-on-click-node="false" | 
				
			|||
                   accordion | 
				
			|||
                   @current-change="menuListTreeCurrentChangeHandle"> | 
				
			|||
          </el-tree> | 
				
			|||
        </el-popover> | 
				
			|||
        <el-input v-model="dataForm.parentName" | 
				
			|||
                  v-popover:menuListPopover | 
				
			|||
                  :readonly="true" | 
				
			|||
                  :placeholder="$t('menu.parentName')"> | 
				
			|||
          <i v-if="dataForm.pid !== '0'" | 
				
			|||
             slot="suffix" | 
				
			|||
             @click.stop="deptListTreeSetDefaultHandle()" | 
				
			|||
             class="el-icon-circle-close el-input__icon"></i> | 
				
			|||
        </el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item v-if="dataForm.type === 0" | 
				
			|||
                    prop="url" | 
				
			|||
                    :label="$t('menu.url')"> | 
				
			|||
        <el-input v-model="dataForm.url" | 
				
			|||
                  :placeholder="$t('menu.url')"></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item prop="sort" | 
				
			|||
                    :label="$t('menu.sort')"> | 
				
			|||
        <el-input-number v-model="dataForm.sort" | 
				
			|||
                         controls-position="right" | 
				
			|||
                         :min="0" | 
				
			|||
                         :label="$t('menu.sort')"></el-input-number> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item v-if="dataForm.type === 0" | 
				
			|||
                    prop="icon" | 
				
			|||
                    :label="$t('menu.icon')" | 
				
			|||
                    class="icon-list"> | 
				
			|||
        <el-popover v-model="iconListVisible" | 
				
			|||
                    ref="iconListPopover" | 
				
			|||
                    placement="bottom-start" | 
				
			|||
                    trigger="click" | 
				
			|||
                    popper-class="mod-sys__menu-icon-popover"> | 
				
			|||
          <div class="mod-sys__menu-icon-inner"> | 
				
			|||
            <div class="mod-sys__menu-icon-list"> | 
				
			|||
              <el-button v-for="(item, index) in iconList" | 
				
			|||
                         :key="index" | 
				
			|||
                         @click="iconListCurrentChangeHandle(item)" | 
				
			|||
                         :class="{ 'is-active': dataForm.icon === item }"> | 
				
			|||
                <svg class="icon-svg" | 
				
			|||
                     aria-hidden="true"> | 
				
			|||
                  <use :xlink:href="`#${item}`"></use> | 
				
			|||
                </svg> | 
				
			|||
              </el-button> | 
				
			|||
            </div> | 
				
			|||
          </div> | 
				
			|||
        </el-popover> | 
				
			|||
        <el-input v-model="dataForm.icon" | 
				
			|||
                  v-popover:iconListPopover | 
				
			|||
                  :readonly="true" | 
				
			|||
                  :placeholder="$t('menu.icon')"></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item v-if="dataForm.type === 1" | 
				
			|||
                    prop="permissions" | 
				
			|||
                    :label="$t('menu.permissions')"> | 
				
			|||
        <el-input v-model="dataForm.permissions" | 
				
			|||
                  :placeholder="$t('menu.permissionsTips')"></el-input> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item v-for="(item, index) in dataForm.resourceList" | 
				
			|||
                    :key="item.key" | 
				
			|||
                    :prop="`resourceList.${index}.resourceUrl`" | 
				
			|||
                    :rules="{ required: true, message: $t('validate.required'), trigger: 'blur' }" | 
				
			|||
                    :label="index === 0 ? $t('menu.resource') : ''" | 
				
			|||
                    class="resource-list"> | 
				
			|||
        <el-row> | 
				
			|||
          <el-col :span="22"> | 
				
			|||
            <el-input v-model="item.resourceUrl" | 
				
			|||
                      :placeholder="$t('menu.resourceUrl')"> | 
				
			|||
              <el-select v-model="item.resourceMethod" | 
				
			|||
                         slot="prepend" | 
				
			|||
                         :placeholder="$t('menu.resourceMethod')"> | 
				
			|||
                <el-option label="GET" | 
				
			|||
                           value="GET"></el-option> | 
				
			|||
                <el-option label="POST" | 
				
			|||
                           value="POST"></el-option> | 
				
			|||
                <el-option label="PUT" | 
				
			|||
                           value="PUT"></el-option> | 
				
			|||
                <el-option label="DELETE" | 
				
			|||
                           value="DELETE"></el-option> | 
				
			|||
              </el-select> | 
				
			|||
            </el-input> | 
				
			|||
          </el-col> | 
				
			|||
          <el-col :span="2" | 
				
			|||
                  class="text-center"> | 
				
			|||
            <el-button @click="resourceDeleteHandle(item)" | 
				
			|||
                       size="small" | 
				
			|||
                       type="text">{{ $t('delete') }}</el-button> | 
				
			|||
          </el-col> | 
				
			|||
        </el-row> | 
				
			|||
      </el-form-item> | 
				
			|||
      <el-form-item :label="dataForm.resourceList.length <= 0 ? $t('menu.resource') : ''"> | 
				
			|||
        <el-button @click="resourceAddHandle()" | 
				
			|||
                   class="aui-button--dashed w-percent-100">{{ $t('menu.resourceAddItem') }}</el-button> | 
				
			|||
      </el-form-item> | 
				
			|||
    </el-form> | 
				
			|||
    <template slot="footer"> | 
				
			|||
      <el-button @click="visible = false">{{ $t('cancel') }}</el-button> | 
				
			|||
      <el-button type="primary" | 
				
			|||
                 @click="dataFormSubmitHandle()">{{ $t('confirm') }}</el-button> | 
				
			|||
    </template> | 
				
			|||
  </el-dialog> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<script> | 
				
			|||
import debounce from 'lodash/debounce' | 
				
			|||
import { getIconList } from '@/utils' | 
				
			|||
export default { | 
				
			|||
  data () { | 
				
			|||
    return { | 
				
			|||
      visible: false, | 
				
			|||
      menuList: [], | 
				
			|||
      menuListVisible: false, | 
				
			|||
      iconList: [], | 
				
			|||
      iconListVisible: false, | 
				
			|||
      dataForm: { | 
				
			|||
        id: '', | 
				
			|||
        type: 0, | 
				
			|||
        name: '', | 
				
			|||
        pid: '0', | 
				
			|||
        parentName: '', | 
				
			|||
        url: '', | 
				
			|||
        resourceList: [], | 
				
			|||
        permissions: '', | 
				
			|||
        sort: 0, | 
				
			|||
        icon: '', | 
				
			|||
        menuCode: '' | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
  computed: { | 
				
			|||
    dataRule () { | 
				
			|||
      return { | 
				
			|||
        name: [ | 
				
			|||
          { required: true, message: this.$t('validate.required'), trigger: 'blur' } | 
				
			|||
        ], | 
				
			|||
        parentName: [ | 
				
			|||
          { required: true, message: this.$t('validate.required'), trigger: 'change' } | 
				
			|||
        ] | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
  watch: { | 
				
			|||
    'dataForm.type' (val) { | 
				
			|||
      this.$refs['dataForm'].clearValidate() | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
  methods: { | 
				
			|||
    init () { | 
				
			|||
      this.visible = true | 
				
			|||
      this.$nextTick(() => { | 
				
			|||
        this.$refs['dataForm'].resetFields() | 
				
			|||
        this.iconList = getIconList() | 
				
			|||
        this.dataForm.parentName = this.$t('menu.parentNameDefault') | 
				
			|||
        this.dataForm.resourceList = [] | 
				
			|||
        this.getMenuList().then(() => { | 
				
			|||
          if (this.dataForm.id) { | 
				
			|||
            this.getInfo() | 
				
			|||
          } | 
				
			|||
        }) | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 获取菜单列表 | 
				
			|||
    getMenuList () { | 
				
			|||
      return this.$http.get('/sys/appmenu/list?type=0').then(({ data: res }) => { | 
				
			|||
        if (res.code !== 0) { | 
				
			|||
          return this.$message.error(res.msg) | 
				
			|||
        } | 
				
			|||
        this.menuList = res.data | 
				
			|||
      }).catch(() => { }) | 
				
			|||
    }, | 
				
			|||
    // 获取信息 | 
				
			|||
    getInfo () { | 
				
			|||
      this.$http.get(`/sys/appmenu/${this.dataForm.id}`).then(({ data: res }) => { | 
				
			|||
        if (res.code !== 0) { | 
				
			|||
          return this.$message.error(res.msg) | 
				
			|||
        } | 
				
			|||
        this.dataForm = { | 
				
			|||
          ...this.dataForm, | 
				
			|||
          ...res.data | 
				
			|||
        } | 
				
			|||
        if (this.dataForm.pid === '0') { | 
				
			|||
          return this.deptListTreeSetDefaultHandle() | 
				
			|||
        } | 
				
			|||
        this.$refs.menuListTree.setCurrentKey(this.dataForm.pid) | 
				
			|||
      }).catch(() => { }) | 
				
			|||
    }, | 
				
			|||
    // 上级菜单树, 设置默认值 | 
				
			|||
    deptListTreeSetDefaultHandle () { | 
				
			|||
      this.dataForm.pid = '0' | 
				
			|||
      this.dataForm.parentName = this.$t('menu.parentNameDefault') | 
				
			|||
    }, | 
				
			|||
    // 上级菜单树, 选中 | 
				
			|||
    menuListTreeCurrentChangeHandle (data) { | 
				
			|||
      this.dataForm.pid = data.id | 
				
			|||
      this.dataForm.parentName = data.name | 
				
			|||
      this.menuListVisible = false | 
				
			|||
    }, | 
				
			|||
    // 图标, 选中 | 
				
			|||
    iconListCurrentChangeHandle (icon) { | 
				
			|||
      this.dataForm.icon = icon | 
				
			|||
      this.iconListVisible = false | 
				
			|||
    }, | 
				
			|||
    // 菜单资源, 添加 | 
				
			|||
    resourceAddHandle () { | 
				
			|||
      this.dataForm.resourceList.push({ | 
				
			|||
        key: new Date().getTime(), | 
				
			|||
        resourceMethod: 'GET', | 
				
			|||
        resourceUrl: '' | 
				
			|||
      }) | 
				
			|||
    }, | 
				
			|||
    // 菜单资源, 删除 | 
				
			|||
    resourceDeleteHandle (resource) { | 
				
			|||
      this.dataForm.resourceList = this.dataForm.resourceList.filter(item => item.key !== resource.key) | 
				
			|||
    }, | 
				
			|||
    // 表单提交 | 
				
			|||
    dataFormSubmitHandle: debounce(function () { | 
				
			|||
      this.$refs['dataForm'].validate((valid) => { | 
				
			|||
        if (!valid) { | 
				
			|||
          return false | 
				
			|||
        } | 
				
			|||
        this.$http[!this.dataForm.id ? 'post' : 'put']('/sys/appmenu', this.dataForm).then(({ data: res }) => { | 
				
			|||
          if (res.code !== 0) { | 
				
			|||
            return this.$message.error(res.msg) | 
				
			|||
          } | 
				
			|||
          this.$message({ | 
				
			|||
            message: this.$t('prompt.success'), | 
				
			|||
            type: 'success', | 
				
			|||
            duration: 500, | 
				
			|||
            onClose: () => { | 
				
			|||
              this.visible = false | 
				
			|||
              this.$emit('refreshDataList') | 
				
			|||
            } | 
				
			|||
          }) | 
				
			|||
        }).catch(() => { }) | 
				
			|||
      }) | 
				
			|||
    }, 1000, { 'leading': true, 'trailing': false }) | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
 | 
				
			|||
<style lang="scss"> | 
				
			|||
.mod-sys__menu { | 
				
			|||
  .resource-list { | 
				
			|||
    .el-select .el-input__inner { | 
				
			|||
      min-width: 110px; | 
				
			|||
      text-align: center; | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
  .menu-list, | 
				
			|||
  .icon-list { | 
				
			|||
    .el-input__inner, | 
				
			|||
    .el-input__suffix { | 
				
			|||
      cursor: pointer; | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
  &-icon-popover { | 
				
			|||
    width: 458px; | 
				
			|||
    overflow: hidden; | 
				
			|||
  } | 
				
			|||
  &-icon-inner { | 
				
			|||
    width: 478px; | 
				
			|||
    max-height: 258px; | 
				
			|||
    overflow-x: hidden; | 
				
			|||
    overflow-y: auto; | 
				
			|||
  } | 
				
			|||
  &-icon-list { | 
				
			|||
    width: 458px; | 
				
			|||
    padding: 0; | 
				
			|||
    margin: -8px 0 0 -8px; | 
				
			|||
    > .el-button { | 
				
			|||
      padding: 8px; | 
				
			|||
      margin: 8px 0 0 8px; | 
				
			|||
      > span { | 
				
			|||
        display: inline-block; | 
				
			|||
        vertical-align: middle; | 
				
			|||
        width: 18px; | 
				
			|||
        height: 18px; | 
				
			|||
        font-size: 18px; | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</style> | 
				
			|||
@ -0,0 +1,105 @@ | 
				
			|||
<template> | 
				
			|||
  <el-card shadow="never" | 
				
			|||
           class="aui-card--fill"> | 
				
			|||
    <div class="mod-sys__menu"> | 
				
			|||
      <el-form :inline="true" | 
				
			|||
               :model="dataForm" | 
				
			|||
               @keyup.enter.native="getDataList()"> | 
				
			|||
        <el-form-item> | 
				
			|||
          <el-button v-if="$hasPermission('sys:menu:save')" | 
				
			|||
                     type="primary" | 
				
			|||
                     @click="addOrUpdateHandle()">{{ $t('add') }}</el-button> | 
				
			|||
        </el-form-item> | 
				
			|||
      </el-form> | 
				
			|||
      <el-table v-loading="dataListLoading" | 
				
			|||
                :data="dataList" | 
				
			|||
                border | 
				
			|||
                style="width: 100%;"> | 
				
			|||
        <table-tree-column prop="name" | 
				
			|||
                           :label="$t('menu.name')" | 
				
			|||
                           header-align="center" | 
				
			|||
                           width="150"></table-tree-column> | 
				
			|||
        <el-table-column prop="icon" | 
				
			|||
                         :label="$t('menu.icon')" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center"> | 
				
			|||
          <template slot-scope="scope"> | 
				
			|||
            <svg class="icon-svg" | 
				
			|||
                 aria-hidden="true"> | 
				
			|||
              <use :xlink:href="`#${scope.row.icon}`"></use> | 
				
			|||
            </svg> | 
				
			|||
          </template> | 
				
			|||
        </el-table-column> | 
				
			|||
        <el-table-column prop="type" | 
				
			|||
                         :label="$t('menu.type')" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center"> | 
				
			|||
          <template slot-scope="scope"> | 
				
			|||
            <el-tag v-if="scope.row.type === 0" | 
				
			|||
                    size="small">{{ $t('menu.type0') }}</el-tag> | 
				
			|||
            <el-tag v-else | 
				
			|||
                    size="small" | 
				
			|||
                    type="info">{{ $t('menu.type1') }}</el-tag> | 
				
			|||
          </template> | 
				
			|||
        </el-table-column> | 
				
			|||
        <el-table-column prop="sort" | 
				
			|||
                         :label="$t('menu.sort')" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center"></el-table-column> | 
				
			|||
        <el-table-column prop="url" | 
				
			|||
                         :label="$t('menu.url')" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center" | 
				
			|||
                         width="150" | 
				
			|||
                         :show-overflow-tooltip="true"></el-table-column> | 
				
			|||
        <el-table-column prop="permissions" | 
				
			|||
                         :label="$t('menu.permissions')" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center" | 
				
			|||
                         width="150" | 
				
			|||
                         :show-overflow-tooltip="true"></el-table-column> | 
				
			|||
        <el-table-column :label="$t('handle')" | 
				
			|||
                         fixed="right" | 
				
			|||
                         header-align="center" | 
				
			|||
                         align="center" | 
				
			|||
                         width="150"> | 
				
			|||
          <template slot-scope="scope"> | 
				
			|||
            <el-button v-if="$hasPermission('sys:menu:update')" | 
				
			|||
                       type="text" | 
				
			|||
                       size="small" | 
				
			|||
                       @click="addOrUpdateHandle(scope.row.id)">{{ $t('update') }}</el-button> | 
				
			|||
            <el-button v-if="$hasPermission('sys:menu:delete')" | 
				
			|||
                       type="text" | 
				
			|||
                       size="small" | 
				
			|||
                       @click="deleteHandle(scope.row.id)">{{ $t('delete') }}</el-button> | 
				
			|||
          </template> | 
				
			|||
        </el-table-column> | 
				
			|||
      </el-table> | 
				
			|||
      <!-- 弹窗, 新增 / 修改 --> | 
				
			|||
      <add-or-update v-if="addOrUpdateVisible" | 
				
			|||
                     ref="addOrUpdate" | 
				
			|||
                     @refreshDataList="getDataList"></add-or-update> | 
				
			|||
    </div> | 
				
			|||
  </el-card> | 
				
			|||
</template> | 
				
			|||
 | 
				
			|||
<script> | 
				
			|||
import mixinViewModule from '@/mixins/view-module' | 
				
			|||
import TableTreeColumn from '@/components/table-tree-column' | 
				
			|||
import AddOrUpdate from './app-menu-add-or-update' | 
				
			|||
export default { | 
				
			|||
  mixins: [mixinViewModule], | 
				
			|||
  data () { | 
				
			|||
    return { | 
				
			|||
      mixinViewModuleOptions: { | 
				
			|||
        getDataListURL: '/sys/appmenu/list', | 
				
			|||
        deleteURL: '/sys/appmenu' | 
				
			|||
      } | 
				
			|||
    } | 
				
			|||
  }, | 
				
			|||
  components: { | 
				
			|||
    TableTreeColumn, | 
				
			|||
    AddOrUpdate | 
				
			|||
  } | 
				
			|||
} | 
				
			|||
</script> | 
				
			|||
					Loading…
					
					
				
		Reference in new issue