MenuDialog.vue 6.14 KB
<template>
  <ht-sidebar-dialog
    :title="titleType + '菜单'"
    width="30%"
    :visible.sync="dialogVisible"
  >
    <el-form data-vv-scope="editMenuForm" :model="menu" size="mini">
      <ht-form-item label="上级菜单">
        <ht-input
          name="parent-menu-name"
          v-model="currentNodeData.name"
          autocomplete="off"
          :disabled="hasParent"
          v-if="hasParent"
          style="width: 400px"
        ></ht-input>
        <tree-select
          v-if="!hasParent"
          v-model="currentEditParentNodeId"
          :normalizer="normalizer"
          :multiple="false"
          :options="showTreeData"
          noOptionsText=" "
          noChildrenText=" "
          class="tree-select"
          style="width: 400px"
          placeholder="请选择父节点"
        />
      </ht-form-item>
      <ht-form-item label="上级菜单别名" v-if="hasParent">
        <ht-input
          name="parent-menu-alias"
          v-model="currentNodeData.alias"
          autocomplete="off"
          style="width: 400px"
          disabled
        ></ht-input>
      </ht-form-item>
      <ht-form-item label="菜单名称">
        <ht-input
          name="menu-name"
          v-model="menu.name"
          autocomplete="off"
          :validate="{required: true}"
          :maxlength="10"
          style="width: 400px"
          :showWordLimit="true"
        ></ht-input>
      </ht-form-item>
      <ht-form-item label="别名">
        <ht-input
          name="menu-alias"
          v-model="menu.alias"
          :disabled="!!menu.id"
          v-pinyin="menu.name"
          autocomplete="off"
          style="width: 400px"
          :validate="'required|alpha_dash'"
          :maxlength="50"
          :showWordLimit="true"
        ></ht-input>
      </ht-form-item>
      <ht-form-item label="排序">
        <ht-input
          name="menu-sn"
          v-model="menu.sn"
          autocomplete="off"
          style="width: 400px"
          validate="required|numeric"
          :maxlength="9"
          :showWordLimit="true"
        ></ht-input>
      </ht-form-item>
      <ht-form-item label="activeTab" title="三级菜单默认显示的tab">
        <ht-input
          name="menu-icon"
          v-model="menu.activeTab"
          autocomplete="off"
          style="width: 400px"
          :maxlength="50"
          :showWordLimit="true"
        ></ht-input>
      </ht-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="close()">{{ $t('eip.common.cancel') }}</el-button>
      <el-button @click="save()" type="primary">{{
        $t('eip.common.save')
      }}</el-button>
    </div>
  </ht-sidebar-dialog>
</template>

<script>
import utils from '@/hotent-ui-util'
import _ from "lodash"
const treeSelect = () => import('@riophae/vue-treeselect')
export default {
  name: 'menu-dialog',
  components: {
    treeSelect,
  },
  props: {
    treeData: {
      type: Array,
      default: () => {
        return []
      },
    },
  },
  computed: {
    showTreeData() {
      let treeData = _.cloneDeep(this.treeData)
      utils.nestForEach(treeData, 'children', (item) => {
        if (!item.children || item.children.length === 0) {
          delete item.children
        }
        if (item.alias === this.menu.alias) {
            item.name = null
        }
      })
      return utils.nestFilter(treeData, 'children', item => item.alias !== this.menu.alias)
    },
  },
  data() {
    return {
      dialogVisible: false,
      menu: {alias: ''},
      icons: [],
      currentNodeData: {},
      hasParent: true,
      currentEditParentNodeId: '',
      tabsStyle: {},
      paramParentId: '',
      titleType: '新增',
    }
  },
  methods: {
    open(data, actionType) {
      this.menu = {alias: ''}
      if (actionType === 'edit') {
        this.titleType = '编辑'
        this.getEditData(data)
      } else {
        //上层节点
        this.titleType = '新增'
        this.menu.path = data.path
        this.menu.parentId = data.id
        this.hasParent = true
      }
      this.dialogVisible = true
      this.currentNodeData = data
      this.currentEditParentNodeId = data.parentId
    },
    getEditData(data) {
      this.hasParent = false
      this.$http
        .get('${portal}/sys/sysMenu/v1/getJson?id=' + data.id)
        .then((response) => {
          this.menu = response.data
          this.$validator.validate()
          if (this.menu.tabsStyle) {
            this.tabsStyle = JSON.parse(this.menu.tabsStyle)
          } else {
            this.tabsStyle = {tabType: null}
          }
        })
    },
    normalizer(node) {
      return {
        id: node.id,
        label: node.name,
        children: node.children,
        isDefaultExpanded: false,
      }
    },
    save() {
      utils
        .validateForm(this, 'editMenuForm')
        .then(() => {
          if (
            this.menu.id &&
            this.currentNodeData &&
            this.currentNodeData.parentId !== this.currentEditParentNodeId
          ) {
            this.paramParentId = this.currentEditParentNodeId
          }
          this.menu.tabsStyle = JSON.stringify(this.tabsStyle)
          if(this.menu.hasOwnProperty('pkVal')){
            this.$delete(this.menu,'pkVal')
          }
          this.$http
            .post(
              `${window.context.portal}/sys/sysMenu/v1/save?parentId=${
                this.paramParentId || ''
              }`,
              this.menu
            )
            .then((resp) => {
              if (resp.data.state) {
                this.$emit('confirm')
                this.$message.success(resp.data.message)
                this.dialogVisible = false
              }
            })
        })
        .catch((r) => {
          this.$message.error(
            `有${r.length}个字段未通过校验,请正确填写表单内容。`
          )
        })
    },
    close() {
      this.dialogVisible = false
    },
  },
}
</script>

<style lang="scss" scoped>
.tree-select {
  ::v-deep {
    .vue-treeselect__control {
      border-radius: 2px;
      height: 32px;
      .vue-treeselect__placeholder,
      .vue-treeselect__single-value {
        line-height: 32px;
      }
    }
  }
}
</style>