<template>
  <el-container
    class="fullheight menu-manager"
    style="border: 1px solid #eee"
    name="menuManager"
  >
    <ht-menu-manager
      ref="htMenuManager"
      @node-click="handleNodeClick"
      :showEdit="false"
      node-key="id"
      :isExpandTree="false"
      @menu-action="menuAction"
      style="border-right: 1px solid #eee"
      :filter="menuFilter"
      @meunTreeDataList="
        val => {
          this.meunTreeDataList = val
        }
      "
    />
    <el-container v-if="editMenuFormVisible">
      <el-main class="menu-content">
        <el-form
          data-vv-scope="editMenuForm_new"
          :model="menu"
          size="mini"
          :inline="true"
          label-width="120px"
          v-form="{formItemAlign: 'left'}"
        >
          <div
            v-if="menu.id !== '3' && menu.path.startsWith('-1.3.') && !isHref"
          >
            <ht-form-item label="菜单类型">
              <el-radio-group v-model="menu.type" @change="handleTypeChange">
                <el-radio label="catalog">目录</el-radio>
                <el-radio label="page" :disabled="isDisabledMenuClass"
                  >页面</el-radio
                >
              </el-radio-group>
            </ht-form-item>
          </div>
          <ht-form-item
            label="上级菜单"
            v-if="menu.id !== '-1' && menu.id !== menu.parentId"
            class="form-item-style form-item-left"
          >
            <!-- <ht-input
              name="parent-menu-name"
              v-model="currentNodeData.name"
              autocomplete="off"
              :disabled="hasParent"
              v-if="hasParent"
            ></ht-input> -->
            <ht-input
              v-if="
                meunTreeDataList[0] &&
                  currentEditParentNodeId == meunTreeDataList[0].id
              "
              name="parent-menu-alias"
              :value="meunTreeDataList[0] && meunTreeDataList[0].name"
              autocomplete="off"
              style="width: 348px"
              disabled
            ></ht-input>
            <tree-Select
              v-else
              v-model="currentEditParentNodeId"
              :normalizer="normalizer"
              :multiple="false"
              :options="treeData"
              noOptionsText=" "
              noChildrenText=" "
              noResultsText="无对应节点"
              class="pre-menu"
              :disabled="
                (menu.parentId == '-1' && !!menu.id) ||
                  disableChangeParentAlias.indexOf(menu.alias) > -1
              "
              placeholder="请选择父节点"
            />
          </ht-form-item>
          <!-- <ht-form-item
            label="上级菜单别名"
            class="form-item-style"
            v-if="menu.id !== '-1'"
          >
            <ht-input
              v-if="hasParent"
              name="parent-menu-alias"
              v-model="currentNodeData.alias"
              autocomplete="off"
              style="width: 348px"
              disabled
            ></ht-input>
            <el-input
              v-else-if="currentNodeData.parentAlias"
              v-model="currentNodeData.parentAlias"
              :disabled="true"
              size="small"
            ></el-input>
          </ht-form-item> -->
          <br />
          <ht-form-item
            label="菜单名称"
            class="form-item-style is-required form-item-left"
          >
            <ht-input
              name="menu-name"
              v-model="menu.name"
              autocomplete="off"
              :validate="'required'"
              :maxlength="10"
              :showWordLimit="true"
            >
              <template slot="append">
                <el-button
                  icon="icon-guojihua"
                  class="international-btn"
                  size="small"
                  @click="editI18nMessage()"
                  >国际化</el-button
                ></template
              >
            </ht-input>
          </ht-form-item>
          <ht-form-item
            v-if="!isHref"
            label="菜单别名"
            class="form-item-style is-required"
          >
            <ht-input
              name="menu-alias"
              v-model="menu.alias"
              :disabled="menu.id ? true : false"
              autocomplete="off"
              style="width: 348px"
              :validate="
                'required|alpha_dash|isExist:${portal}/sys/sysMenu/v1/isMenuExistByAlias?alias=,' +
                  menu.alias
              "
              :maxlength="50"
              :showWordLimit="true"
            ></ht-input>
          </ht-form-item>
          <ht-form-item label="Url地址" v-show="isHref" class="form-item-style">
            <ht-input
              name="menu-href"
              v-model="menu.href"
              autocomplete="off"
              style="width: 348px"
              :maxlength="500"
              :showWordLimit="true"
            ></ht-input>
          </ht-form-item>
          <br />
          <ht-form-item
            label="排序"
            class="form-item-style is-required form-item-left"
          >
            <ht-input
              name="menu-sn"
              v-model="menu.sn"
              autocomplete="off"
              validate="required|numeric"
              :maxlength="10"
              :showWordLimit="true"
            ></ht-input>
          </ht-form-item>

          <ht-form-item
            label="追加token"
            v-show="isHref"
            class="form-item-style"
          >
            <el-switch
              v-model="menu.tokenEnabled"
              active-color="#13ce66"
              inactive-color="#ff4949"
            >
            </el-switch>
          </ht-form-item>
          <ht-form-item
            label="获取模式"
            v-if="isHref && menu.tokenEnabled"
            class="form-item-style form-item-left"
          >
            <ht-radio
              v-model="menu.tokenType"
              validate="required"
              :options="tokenTypeOptions"
            ></ht-radio>
          </ht-form-item>
          <ht-form-item
            label="票据KEY"
            v-if="isHref && menu.tokenType === 1 && menu.tokenEnabled"
            class="form-item-style"
          >
            <ht-input
              v-model="menu.tokenKey"
              validate="regex:^[a-zA-Z][a-zA-Z0-9_]*$,只能输入字母、数字、下划线，且以字母开头"
              :maxlength="30"
              show-word-limit
              placeholder="如  token"
            >
              <template slot="append">
                <el-button type="primary" plain @click="showBizAuthDialog"
                  >配置认证接口
                </el-button>
              </template>
            </ht-input>
          </ht-form-item>

          <ht-form-item
            v-if="!isHref && !isFrontMenu"
            label="activeTab"
            title="三级菜单默认显示的tab"
            class="form-item-style"
          >
            <ht-input
              name="menu-icon"
              v-model="menu.activeTab"
              autocomplete="off"
              style="width: 348px"
              :maxlength="50"
              :showWordLimit="true"
            ></ht-input>
          </ht-form-item>
          <ht-form-item
            label="菜单图标"
            class="form-item-style"
            v-if="isShowIcon"
          >
            <div class="menu-icon__wrap">
              <div
                class="menu-icon"
                :class="menu.menuIcon"
                v-show="menu.menuIcon"
              ></div>
              <div class="btn-group">
                <IconDialog @selected="icons" style="display: inherit" />
                <el-button
                  v-if="menu.menuIcon"
                  plain
                  size="small"
                  style="margin-left: 16px"
                  @click="deleteIcon"
                  >删除图标</el-button
                >
              </div>
            </div>
          </ht-form-item>
          <ht-form-item
            v-if="menu.type === 'page' && !isHref"
            label="页面路径"
            class="form-item-style form-item-left"
          >
            <ht-input
              v-model="routeExtend.component"
              :validate="{
                required: true,
                regex: {
                  exp: '/^@/views/',
                  message: '校验失败，请输入以@/views开头的路径。'
                }
              }"
              :disabled="isDisabledPagePath"
            ></ht-input>
          </ht-form-item>
          <ht-form-item
            v-if="
              menu.type === 'page' &&
                !isHref &&
                excludeComponent(routeExtend.component)
            "
            label="菜单页签切换"
            class="form-item-style"
          >
            <template #label>
              <el-tooltip
                class="item"
                effect="dark"
                content="选择切换不刷新时,菜单别名必须和页面路径对应vue组件name名一致，否则此配置将无效"
                placement="top"
              >
                <i class="icon-query"></i>
              </el-tooltip>
              <span>菜单页签切换</span>
            </template>
            <el-radio-group
              v-model="menu.isRefresh"
              size="small"
              class="refresh-radio-group"
            >
              <el-radio-button :label="1" class="refresh-radio-btn"
                >切换刷新</el-radio-button
              >
              <el-radio-button :label="0" class="not-refresh-radio-btn"
                >切换不刷新</el-radio-button
              >
            </el-radio-group>
          </ht-form-item>
          <br />
          <ht-form-item
            v-if="!isFrontMenu && !isHref"
            label="标签页风格"
            class="form-item-style tab-style"
            title="默认使用菜单配置 菜单没有配置， 则使用全局配置， 全局配置也没有则使用默认样式"
          >
            <el-radio-group v-model="tabsStyle.tabType" size="small">
              <el-radio-button label="card">选项卡样式</el-radio-button>
              <el-radio-button label>默认样式</el-radio-button>
              <el-radio-button label="border-card">卡片化</el-radio-button>
            </el-radio-group>
          </ht-form-item>
          <el-table :data="menu.sysMethods" style="width: 100%" border>
            <el-table-column prop="name" label="请求方法描述" width="260">
              <template slot="header">
                <span class="is-required">请求方法描述</span>
              </template>
              <template slot-scope="scope">
                <ht-input
                  v-model="scope.row.name"
                  autocomplete="off"
                  validate="required"
                  placeholder="方法描述"
                  :maxlength="50"
                  :showWordLimit="true"
                ></ht-input>
              </template>
            </el-table-column>
            <el-table-column prop="alias" label width="260">
              <template slot="header">
                <span class="is-required">别名</span>
                <el-tooltip
                  content="别名为字母数字组合，且以字母开头，不能包括特殊字符"
                  placement="right"
                >
                  <i class="icon-question" style="margin-right: 8px" />
                </el-tooltip>
              </template>
              <template slot-scope="scope">
                <ht-input
                  v-model="menu.sysMethods[scope.$index].alias"
                  :model-expression="
                    'menu.sysMethods[' + scope.$index + '].alias'
                  "
                  v-pinyin="menu.sysMethods[scope.$index].name"
                  autocomplete="off"
                  :validate="{
                    required: true,
                    regex: {
                      exp: '^[a-zA-z][a-zA-z0-9]+$',
                      message: '别名有误'
                    }
                  }"
                  :disabled="scope.row.id ? true : false"
                  placeholder="唯一别名"
                  :maxlength="50"
                  :showWordLimit="true"
                ></ht-input>
              </template>
            </el-table-column>
            <el-table-column prop="requestUrl" label width="auto">
              <template slot="header">
                <span class="is-required">后台请求地址</span>
                <el-tooltip
                  content="请求地址必须以/开头,并且只能包括英文、数字和/"
                  placement="right"
                >
                  <i class="icon-question" style="margin-right: 8px" />
                </el-tooltip>
              </template>
              <template slot-scope="scope">
                <ht-input
                  v-model="scope.row.requestUrl"
                  style="width: 90%"
                  autocomplete="off"
                  :validate="{
                    required: true,
                    regex: {
                      exp: '^/[a-zA-Z0-9\\\\\\/\\+]+$',
                      message: '请求地址输入有误'
                    }
                  }"
                  placeholder="请输入后台请求地址"
                  :maxlength="50"
                  :showWordLimit="true"
                ></ht-input>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="140">
              <template slot-scope="scope">
                <el-button type="text" @click="removeSysMethod(scope.row)"
                  >删除</el-button
                >
              </template>
            </el-table-column>
          </el-table>
          <div class="table-add">
            <i class="el-icon-circle-plus-outline add-icon"></i>
            <el-button type="text" @click="addSysMethods" title="添加接口"
              >添加</el-button
            >
          </div>
        </el-form>
      </el-main>
      <el-footer>
        <ht-submit-button
          :url="`/sys/sysMenu/v1/save?parentId=` + paramParentId"
          context="portal"
          :model="menu"
          scope-name="editMenuForm_new"
          :is-submit="isSubmit"
          @before-save-data="beforeSaveData"
          @after-save-data="afterSaveData"
          v-if="
            !menu.id ||
              (!menu.tenantId && userAttrs.tenantId == -1) ||
              !userAttrs.tenantId ||
              userAttrs.tenantId == menu.tenantId
          "
          >{{ menu.id ? '更新' : '保存' }}</ht-submit-button
        >
      </el-footer>
    </el-container>
    <!-- 子级批量排序 -->
    <ht-sidebar-dialog
      width="28%"
      title="子菜单批量排序"
      :visible="batchSortDialog"
      :before-close="handleBatchSortClose"
      :append-to-body="true"
    >
      <table class="form-table" cellspacing="0" cellpadding="0" border="0">
        <tbody>
          <tr v-for="data in subMenuList" :key="data.id">
            <th width="90px">菜单名称:</th>
            <td>{{ data.name }}</td>
            <th width="70px" class="is-required">排序:</th>
            <td width="90px">
              <ht-input
                v-model="data.sn"
                type="number"
                autocomplete="off"
                validate="required"
              />
            </td>
          </tr>
        </tbody>
      </table>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleBatchSortClose()">{{
          $t('eip.common.cancel')
        }}</el-button>
        <el-button @click="save()" type="primary">{{
          $t('eip.common.save')
        }}</el-button>
      </div>
    </ht-sidebar-dialog>
    <el-dialog
      width="400px"
      top="8vh"
      title="菜单移动"
      :visible="handleDialog"
      :before-close="handleClose"
      :close-on-click-modal="false"
      append-to-body
    >
      <el-scrollbar>
        <ht-tree
          style="height: 500px"
          :data="treeMenuData"
          :props="defaultMenuProps"
          @node-click="handleMenuNodeClick"
          :expand-on-click-node="false"
          ref="htTypeTree"
        ></ht-tree>
      </el-scrollbar>
      <div slot="footer" class="dialog-footer">
        <el-button @click="handleClose">取 消</el-button>
        <el-button type="primary" @click="handleSave">确 定</el-button>
      </div>
    </el-dialog>
    <el-container v-show="!editMenuFormVisible">
      <div class="el-tree__empty-block">
        <el-image :src="noDataImg"></el-image>
        <p class="no-data-text">请选择一个菜单进行操作~</p>
      </div>
    </el-container>
    <!-- 导入 -->
    <el-dialog
      title="上传文件"
      :visible="uploadDialogVisible"
      :before-close="beforeClose"
    >
      <el-upload
        :http-request="handleImport"
        accept=".zip"
        :file-list="fileList"
        :limit="1"
        :on-exceed="onExceed"
        action=""
      >
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传zip文件</div>
      </el-upload>
    </el-dialog>
    <el-dialog
      title="路由配置"
      :visible.sync="routeEditDialogVisible"
      width="30%"
    >
      <span>
        <codemirror v-model="routeJson" :options="cmOptions"></codemirror>
      </span>
      <span slot="footer">
        <el-button @click="routeEditDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="routeEditConfirm">确认</el-button>
      </span>
    </el-dialog>
    <i18n-message-edit ref="i18nMessageEdit" :messageKey="i18nMessageKey" />
    <!-- 配置认证接口对话框 -->
    <biz-auth-dialog @onConfirm="authDialogConfirm" ref="bizAuthDialog" />
  </el-container>
</template>
<script>
import portalApi from '@/api/portal.js'
const HtMenuManager = () => import('@/components/system/HtMenuManager.vue')
const EipSysTypeSelector = () =>
  import('@/components/selector/EipSysTypeSelector.vue')
import IconDialog from '@/components/dialog/IconDialog.vue'
const treeSelect = () => import('@riophae/vue-treeselect')
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
import req from '@/request.js'
import utils from '@/hotent-ui-util.js'
import componentConfig from './componentConfig.js'
import i18nMessageEdit from '@/components/system/I18nMessageEdit.vue'
import {mapState} from 'vuex'
const bizAuthDialog = () => import('@/components/dialog/BizAuthDialog.vue')
const getRouteExtend = function() {
  return {
    path: '',
    component: '',
    redirect: '',
    alwaysShow: false,
    caseSensitive: false,
    meta: {
      title: ''
    }
  }
}
export default {
  name: 'MenuManager',
  components: {
    HtMenuManager,
    EipSysTypeSelector,
    IconDialog,
    treeSelect,
    i18nMessageEdit,
    bizAuthDialog
  },
  data() {
    return {
      tokenTypeOptions: [
        {
          key: 0,
          value: '当前用户'
        },
        {
          key: 1,
          value: '接口获取'
        }
      ],
      isFrontMenu: false,
      isHref: false, //是否是添加URL菜单
      editMenuFormVisible: false,
      treeMenuData: [],
      defaultMenuProps: {
        children: 'children',
        label: 'name'
      },
      treeData: [],
      treeDataCopy: [],
      currentTreeData: [],
      menuNames: [],
      defaultProps: {
        children: 'children',
        label: 'name'
      },
      data: [],
      pageResult: {
        page: 1,
        pageSize: 20,
        total: 0
      },
      handleDialog: false,
      dialogVisible: false,
      menu: {
        alias: '',
        tabsStyle: '',
        sysMethods: [],
        open: true,
        href: '',
        type: 'catalog',
        isRefresh: 1
      },
      tabsStyle: {tabType: null},
      currentNodeData: {},
      hasParent: false,
      batchSortDialog: false, //子菜单批量排序侧边弹框
      subMenuList: [], //子菜单集合
      uploadDialogVisible: false,
      fileList: [],
      parentMenuId: '',
      currentEditParentNodeId: '',
      isSubmit: true,
      paramParentId: '',
      routeExtend: getRouteExtend(),
      routeEditDialogVisible: false,
      routeJson: '',
      cmOptions: {
        value: '',
        mode: 'javascript',
        readOnly: false,
        smartIndent: true,
        tabSize: 2,
        theme: 'base16-light',
        lineNumbers: true,
        line: true
      },
      parentMenu: null,
      noDataImg: require('@/assets/nodata_images/no-tag.png'),
      componentOptions: componentConfig,
      i18nMessageKey: '',
      disableChangeParentAlias: [
        'matter',
        'NewMatter',
        'startProcess',
        'MyTask',
        'Request',
        'approvalForm',
        'CirculateMatter',
        'personal',
        'Setting',
        'Message',
        'EmailCenter',
        'security'
      ] //不允许切换上级菜单的菜单别名
    }
  },
  computed: {
    ...mapState('login', ['currentUser']),
    userAttrs() {
      return this.currentUser.userAttrs || {}
    },
    frontMenu() {
      return this.data
    },
    isDisabledPagePath() {
      let isDisabled = false
      if (this.routeExtend.component && this.menu.id) {
        isDisabled = this.routeExtend.component.startsWith('@') ? false : true
      }
      return isDisabled
    },
    excludeComponent() {
      const components = [
        '@/views/matter/StartProcess',
        '@/views/matter/ApprovalForm',
        'DatavLayout',
        'TemplateLayout',
        'QuerySqlLayout',
        '@/views/personal/setting',
        '@/views/home/index',
        'indexLayout'
      ]
      return component => {
        return !components.includes(component)
      }
    },
    isShowIcon() {
      return this.menu.parentId === '1' || this.menu.parentId === '3'
    },
    isDisabledMenuClass() {
      //一级菜单禁止修改菜单类型为页面
      const count = this.currentNodeData.path.match(/\./g).length
      return count == 3
    }
  },
  mounted() {
    this.loadTreeData()
  },
  methods: {
    //显示 配置认证接口对话框
    showBizAuthDialog() {
      var tokenApiObj = {}
      if (this.menu.tokenApi) {
        tokenApiObj = JSON.parse(Base64.decode(this.menu.tokenApi) || '{}')
      }
      this.$refs.bizAuthDialog.showDialog(tokenApiObj)
    },
    //配置认证接口对话框 确认保存
    authDialogConfirm(tokenApi) {
      this.menu.tokenApi = Base64.encode(JSON.stringify(tokenApi))
    },
    editI18nMessage() {
      this.i18nMessageKey = this.menu.alias
      this.$refs.i18nMessageEdit.handleOpen()
    },
    handleBatchSortClose() {
      this.batchSortDialog = false
    },
    //保存子菜单批量排序
    save() {
      var subMenuList =  this.subMenuList
      subMenuList.forEach(subMenu =>{
        if(subMenu.hasOwnProperty('isOpen')){
          delete subMenu.isOpen
        }
      })
      portalApi.saveBatch(subMenuList).then(data => {
        this.batchSortDialog = false
        this.$refs.htMenuManager.$refs.htMenuTree.loadData()
        this.$message({
          showClose: true,
          message: data.message,
          type: 'success'
        })
      })
    },
    //移动菜单确认事件
    handleSave() {},
    handleMenuNodeClick(node) {},
    handleClose() {
      this.handleDialog = false
    },
    icons(icon) {
      this.$set(this.routeExtend.meta, 'icon', icon)
      this.$set(this.menu, 'menuIcon', icon)
    },
    deleteIcon() {
      this.$set(this.routeExtend.meta, 'icon', '')
      this.$set(this.menu, 'menuIcon', '')
    },
    async handleNodeClick(data, node) {
      if (data.href) {
        this.isHref = true
      } else {
        this.isHref = false
      }
      this.getEditData(data)
      this.currentNodeData = {
        ...data,
        parentAlias: node.parent && node.parent.data.alias
      }
      this.currentEditParentNodeId = data.parentId
      this.paramParentId = ''
      this.handleTreeData(data, node)
    },
    handleTreeData(data, node, loadLeaf = false) {
      const menuIdList = ['1', '3'] //1-管理端菜单 3-应用端菜单
      if (menuIdList.includes(data.id)) {
        this.filterTreeDataById(data.id, data)
      } else if (menuIdList.includes(data.parentId)) {
        this.filterTreeDataByParentId(data.parentId)
      } else if (data.parentId == '-1') {
        this.filterTreeDataById(data.id, data)
      }
      if (data.path.startsWith('-1.1.')) {
        this.filterTreeDataById('1', data)
        if (node.level - 2 > 0 || loadLeaf) {
          this.filterTreeDataByParentId('1')
        }
        this.isFrontMenu = false
      } else if (data.path.startsWith('-1.3.')) {
        this.filterTreeDataById('3', data)
        if (node.level - 2 > 0 || loadLeaf) {
          this.filterTreeDataByParentId('3')
        }
        this.isFrontMenu = true
        // 不是应用端也不是管理端
      } else if (data.path.startsWith('-1.')) {
        const modelTopMenuId = data.path.split('.')[1]
        this.filterTreeDataById(modelTopMenuId, data)
        if (node.level - 2 > 0 || loadLeaf) {
          this.filterTreeDataByParentId(modelTopMenuId)
        }
        this.isFrontMenu = false
      }
    },
    filterTreeDataById(id, data = '') {
      this.treeData = this.treeDataCopy.map(item => {
        return {
          ...item,
          children: item.children.filter(it => it.id === id)
        }
      })
      if (data && this.action !== 'add' && this.action !== 'addHref') {
        const cloneTreeData = _.cloneDeep(this.treeData)
        if (cloneTreeData && cloneTreeData.length) {
          const newTreeData = utils.nest2tile(cloneTreeData).filter(item => {
            const itemPathLength = item.path && item.path.split('.').length
            if (data.alias && data.path.startsWith('-1.1.') && ['datavShow','templateShow','querySqlShow'].includes(data.alias.split('/')[0])){
              return (
                itemPathLength < 5 &&
               data.path !== item.path &&
               item.type === 'catalog' &&
               !item.href
              )
            }
            return (
              itemPathLength < 6 &&
              data.path !== item.path &&
              item.type === 'catalog' &&
              !item.href
            )
          })
          this.treeData = utils.tile2nest(newTreeData)
        }
      }
    },
    filterTreeDataByParentId(parentId) {
      const cloneTreeData = _.cloneDeep(this.treeData)
      if (cloneTreeData[0] && cloneTreeData[0].children) {
        this.treeData = cloneTreeData[0].children.filter(
          it => it.id === parentId
        )
        this.currentTreeData = _.cloneDeep(this.treeData)
      }
    },
    menuAction(command) {
      //判断是否是添加前端下级菜单
      if (
        command.data.path.startsWith('-1.3.') &&
        command.action != 'addHref'
      ) {
        this.isFrontMenu = true
      } else {
        this.isFrontMenu = false
      }
      //判断是否是添加URL菜单
      if (command.action == 'addHref') {
        this.isHref = true
      } else if (command.action == 'edit' && command.href) {
        this.isHref = true
      } else {
        this.isHref = false
      }
      this.action = command.action
      this.editMenuFormVisible = false
      let node = command.node
      let data = command.data
      let action = command.action
      this.currentNodeData = data
      this.menu = {
        ...this.menu,
        ...{
          href: '',
          name: '',
          alias: '',
          menuIcon: '',
          sn: '',
          activeTab: '',
          tabsStyle: '',
          sysMethods: []
        }
      }
      this.routeExtend = getRouteExtend()
      delete this.menu.tenantId
      switch (action) {
        case 'batchSort':
          this.subMenuList = [...data.children]
          this.batchSortDialog = true
          break
        case 'add':
          this.menu.id = ''
          this.menu.parentId = data.id
          this.hasParent = true
          this.menu.path = data.path
          this.editMenuFormVisible = true
          this.tabsStyle = {tabType: null}
          this.parentMenu = data
          this.menu.type = command.type
          this.currentNodeData.parentAlias =
            node.parent && node.parent.data.alias
          this.currentEditParentNodeId = data.id
          this.handleTreeData(command.data, command.node, true)
          break
        case 'addHref':
          const key =
            Date.parse(new Date()) + '_' + Math.ceil(Math.random() * 99999)
          this.menu.alias = 'href/template/' + key
          this.menu.id = ''
          this.menu.parentId = data.id
          this.hasParent = true
          this.menu.path = data.path
          this.editMenuFormVisible = true
          this.tabsStyle = {tabType: null}
          this.menu.routeExtend = ''
          this.currentEditParentNodeId = data.id
          this.handleTreeData(command.data, command.node, true)
          break
        case 'edit':
          this.getEditData(data)
          break
        case 'delete':
          this.$confirm(`是否删除菜单[${data.name}]?`, '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'success'
          })
            .then(() => {
              this.removeMenuById(data.id)
            })
            .catch(() => {})

          break
        case 'moveto':
          const this_ = this
          portalApi.getMenuTree().then(data => {
            this_.handleDialog = true
            this_.treeMenuData = data
          })
          // this.$message("暂未提供该功能");

          break
        case 'export':
          this.exportFile(data)
          break
        case 'import':
          this.importFile(data)
        default:
          break
      }
    },
    exportFile(data) {
      let id = data.id
      let url =
        window.context.portal + '/sys/sysMenu/v1/export?parentMenuId=' + id
      req.download(url)
    },
    handleImport(param) {
      let formData = new FormData()
      formData.append('file', param.file)
      portalApi.importSysMenus(formData, this.parentMenuId).then(resp => {
        if (resp.state) {
          if (resp.value && resp.value.startsWith('菜单已存在:')) {
            this.confirmCoverImport(resp.value.replace('菜单已存在:', ''))
          } else {
            this.handleSuccess()
          }
        } else {
          this.beforeClose()
        }
      })
    },
    confirmCoverImport(fileId) {
      this.$confirm('部分菜单已存在，是否覆盖已有菜单继续导入？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          this.$http
            .post(
              '${portal}/sys/sysMenu/v1/coverImport?parentMenuId=' +
                this.parentMenuId +
                '&cacheId=' +
                fileId
            )
            .then(resp => {
              if (resp.data.state) {
                this.handleSuccess()
              }
            })
        })
        .catch(() => {
          this.fileList = []
          this.uploadDialogVisible = false
        })
    },
    handleSuccess() {
      this.$message({type: 'success', message: '导入成功'})
      this.uploadDialogVisible = false
      this.fileList = []
      this.$refs.htMenuManager.$refs.htMenuTree.loadData()
    },
    beforeClose() {
      this.uploadDialogVisible = false
      this.fileList = []
    },
    importFile(data) {
      this.parentMenuId = data.id
      this.uploadDialogVisible = true
    },
    getEditData(data) {
      this.editMenuFormVisible = false
      this.hasParent = false
      this.$http
        .get('${portal}/sys/sysMenu/v1/getJson?id=' + data.id)
        .then(response => {
          this.menu = response.data
          if (response.data.routeExtend) {
            this.routeExtend = JSON.parse(response.data.routeExtend)
          } else {
            this.routeExtend = getRouteExtend()
          }
          this.editMenuFormVisible = true
          if (this.menu.type) {
            this.handleTypeChange(this.menu.type, true)
          }
          this.$validator.validate()
          if (this.menu.tabsStyle) {
            this.tabsStyle = JSON.parse(this.menu.tabsStyle)
          } else {
            this.tabsStyle = {tabType: null}
          }
        })
    },
    removeMenuById(id, force) {
      portalApi.removeMenuById(id, force).then(
        data => {
          if (!data.errorCode) {
            this.$refs.htMenuManager.$refs.htMenuTree.loadData()
            this.$message({
              showClose: true,
              message: '删除成功',
              type: 'success'
            })
          } else {
            this.$confirm(data.message, '提示', {
              confirmButtonText: '确定',
              cancelButtonText: '取消',
              type: 'warning'
            })
              .then(() => {
                this.removeMenuById(id, true)
              })
              .catch(() => {})
          }
        },
        error => {}
      )
    },
    beforeSaveData() {
      this.isSubmit = true
      if (
        this.menu.id &&
        this.currentNodeData &&
        this.currentNodeData.parentId != this.currentEditParentNodeId
      ) {
        this.paramParentId = this.currentEditParentNodeId
      }
      // 新增时 可自由选择父id
      if (!this.menu.id && this.currentEditParentNodeId) {
        this.menu.parentId = this.currentEditParentNodeId
      }
      if (this.tabsStyle.tabType) {
        this.menu.tabsStyle = JSON.stringify(this.tabsStyle)
      }
      let isChildren = false
      if (this.menu.path.startsWith('-1.3.')) {
        if (this.menu.path.split('.').length > 4 && this.menu.id) {
          isChildren = true
        } else if (!this.menu.id && this.parentMenu) {
          let parentPath = this.parentMenu.path
          if (parentPath.split('.').length > 3) {
            isChildren = true
          }
        }
      }
      if (isChildren) {
        this.routeExtend.meta.isChildren = true
      } else {
        delete this.routeExtend.meta.isChildren
      }
      if (this.isHref) {
        this.menu.routeExtend = ''
      } else {
        const {path, type, name, parentId, alias} = this.menu
        let currentComponent = 'Layout'
        const menuPathLength = path.split('.').length
        const menuLevel = this.menu.id ? menuPathLength - 3 : menuPathLength - 2
        if (type === 'catalog') {
          this.routeExtend.alwaysShow = true
          if (this.currentEditParentNodeId !== '3') {
            currentComponent = 'MultilevelMenuLayout'
          }
        } else {
          currentComponent = this.routeExtend.component
          this.routeExtend.alwaysShow = false
        }
        if (this.currentEditParentNodeId === '3') {
          this.routeExtend.meta.isChildren = false
        } else {
          this.routeExtend.meta.isChildren = true
        }
        let columnPath = this.routeExtend.path
        if (this.menu.id) {
          if (
            this.currentEditParentNodeId === '3' &&
            !this.routeExtend.path.startsWith('/')
          ) {
            columnPath = `/${this.routeExtend.path}`
          } else {
            columnPath = `${this.routeExtend.path}`
          }
        } else {
          columnPath = this.isShowIcon ? `/${alias}` : alias
        }
        this.routeExtend = {
          ...this.routeExtend,
          component: currentComponent,
          path: name === '首页' && parentId === '3' ? '/' : columnPath,
          meta: {
            ...this.routeExtend.meta,
            title: name,
            icon: this.menu.menuIcon
          }
        }
        this.menu.routeExtend = JSON.stringify(this.routeExtend)
      }
      if (this.menu.hasOwnProperty('pkVal')) {
        this.$delete(this.menu, 'pkVal')
      }
    },
    afterSaveData() {
      let msg = '是否继续添加下级菜单?'
      if (this.menu.id) {
        msg = '是否继续编辑菜单?'
      }
      if (this.menu.type === 'catalog' && !this.isHref) {
        this.$confirm(msg, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'success'
        })
          .then(() => {
            this.resetMenuConfig()
          })
          .catch(() => {
            this.resetMenuConfig()
            this.editMenuFormVisible = false
          })
      } else {
        this.resetMenuConfig()
        this.editMenuFormVisible = false
      }
      this.$refs.htMenuManager.$refs.htMenuTree.loadData()
      this.loadTreeData()
    },
    resetMenuConfig() {
      if (!this.menu.id) {
        this.menu = {
          ...this.menu,
          ...{
            href: '',
            name: '',
            alias: '',
            menuIcon: '',
            sn: '',
            activeTab: '',
            tabsStyle: '',
            sysMethods: []
          }
        }
        this.routeExtend = getRouteExtend()
      }
    },
    addSysMethods() {
      this.menu.sysMethods.push({name: '', alias: '', requestUrl: ''})
    },
    removeSysMethod(row) {
      this.menu.sysMethods.remove(row)
    },
    loadTreeData() {
      portalApi.getMenuTree().then(data => {
        data[0].children = data[0].children.filter(item => item.id != '2')
        this.treeData = data
        this.treeDataCopy = _.cloneDeep(data)
        this.initTreeNames(data)
      })
    },
    normalizer(node) {
      return {
        id: node.id,
        label: node.name,
        children: node.children,
        isDefaultExpanded: false
      }
    },
    initTreeNames(data) {
      if (data && data.length > 0) {
        let _this = this
        data.forEach(item => {
          _this.menuNames.push(item.name)
          _this.initTreeNames(item.children)
        })
      }
    },
    handleTreeNodeClick(node) {},
    handleEditRoute() {
      this.routeJson = JSON.stringify(this.routeExtend, null, '\t')
      this.routeEditDialogVisible = true
    },
    routeEditConfirm() {
      let route
      let errorCb = this.$message.error.bind(
        null,
        'JSON格式校验未通过，请检查输入'
      )
      try {
        route = JSON.parse(this.routeJson.replace('\t', ''))
      } catch (e) {
        errorCb()
        return
      }
      if (!route) {
        errorCb()
        return
      }
      this.routeExtend = route
      this.routeEditDialogVisible = false
    },
    onExceed() {
      this.$message.warning('只能选择一个zip文件!')
    },
    handleTypeChange(type, noClearComponet) {
      if (!noClearComponet) {
        this.routeExtend.component = ''
      }
      let cloneTreeData = _.cloneDeep(this.currentTreeData)
      // if (type == 'page') {
      //   if(!noClearComponet){
      //     this.currentEditParentNodeId = null
      //   }
      //   if (
      //     cloneTreeData[0] &&
      //     cloneTreeData[0].children &&
      //     cloneTreeData[0].children.length > 0
      //   ) {
      //     this.treeData = cloneTreeData[0].children.map((item) => item)
      //   }
      // } else {
      this.treeData = cloneTreeData
      // }
    },
    menuFilter(item) {
      if (item.id === '2' || item.id === '4') {
        return false
      }
      return item.alias !== 'personal' && item.alias !== 'appCenter1'
    }
  }
}
</script>

<style lang="scss" scoped>
.menu-manager {
  ::v-deep {
    .form-item-style .el-form-item__content {
      .inputs.ht-form-inputs__inline .el-input-group--append {
        .el-input__inner {
          border-radius: 2px 0 0 2px;
        }
      }
      .el-input-group__append {
        border-radius: 0 2px 2px 0;
        background-color: #ececec;
        .international-btn {
          background: #ececec;
          color: #333;
          padding: 7px 12px;
          border-radius: 0 2px 2px 0;
        }
      }
      .refresh-radio-group {
        .el-radio-button {
          .el-radio-button__inner {
            color: #666666;
          }
        }
        .el-radio-button__orig-radio:checked + .el-radio-button__inner {
          background: #e8f3ff;
          border-color: #409eff;
          color: #409eff;
        }
      }
      .el-radio-button:first-child .el-radio-button__inner {
        border-radius: 2px 0 0 2px;
      }
      .el-radio-button:last-child .el-radio-button__inner {
        border-radius: 0 2px 2px 0;
      }
    }
    .pre-menu {
      .vue-treeselect__control {
        border-color: #ececec;
        height: 30px;
      }
    }
    .pre-menu.vue-treeselect--disabled {
      cursor: not-allowed;
      .vue-treeselect__control {
        background: #ececec;
        border: none;
      }
    }
    .tab-style {
      .el-radio-button__inner {
        border-color: #dcdee0;
        font-size: 14px;
      }
    }
  }
}
>>> .error-small {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  padding-top: 0;
  margin-top: 0;
  position: absolute;
  top: 80%;
  left: 0;
}
>>> .el-table td,
th {
  padding: 13px 0;
}

>>> .el-form-item__content {
  width: 250px;
}

.form-empty {
  position: absolute;
  text-align: center;
  width: 300px;
  font-size: 20px;
  top: 200px;
  left: 50%;
  margin-left: -150px;
  color: #ccc;
}
.menu-content {
  padding: 48px;
  .table-add {
    width: calc(100% - 2px);
    height: 48px;
    line-height: 48px;
    text-align: center;
    border: 1px solid #ebebeb;
    border-top: none;
    .add-icon {
      font-size: 16px;
      color: #409eff;
      padding-right: 8px;
    }
    ::v-deep {
      .el-button {
        font-size: 14px;
        color: #409eff;
        padding: 0;
      }
    }
  }
  ::v-deep {
    .el-table__empty-block {
      display: none;
    }
  }
}
.form-item-style {
  margin-bottom: 32px;
  .menu-icon__wrap {
    display: flex;
    align-items: center;
  }
  .menu-icon {
    height: 48px;
    text-align: center;
    line-height: 48px;
    background: #eeeeee;
    border-radius: 2px;
    color: #409eff;
    font-size: 32px;
    margin-right: 16px;
    padding: 0 8px;
  }
  .btn-group {
    display: flex;
    height: 32px;
  }
  ::v-deep {
    .el-form-item__label {
      color: #888;
    }
    .el-form-item__content {
      width: 348px;
      .vue-treeselect__control {
        height: 32px;
        border-radius: 2px;
        border-color: #dcdee0;
      }
      .inputs.ht-form-inputs__inline {
        width: 348px;
        .el-input--small {
          font-size: 14px;
          .el-input__inner {
            border-radius: 2px;
            color: #333;
          }
        }
      }
      .el-input__inner {
        color: #333;
        border-color: #dcdee0;
      }
      .el-input.is-disabled .el-input__inner {
        background-color: #ececec;
        border-color: #ececec;
      }
      .el-button--small {
        padding: 8px 16px;
        font-size: 14px;
        color: #666;
        border-radius: 2px;
      }
    }
  }
}
.form-item-left {
  margin-right: 180px;
}
::v-deep {
  .el-footer {
    text-align: center;
    .el-button {
      padding: 10px 40px;
      border-radius: 2px;
      font-size: 14px;
    }
  }
}
</style>
