<template>
  <div class="app-container">
    <p>管理动态路由</p>
    <el-button type="primary" @click="addFirst">添加第一级路由</el-button>
    <el-tree :data="data" node-key="id" default-expand-all :props="defaultProps" :expand-on-click-node="false">
      <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
          <svg-icon v-if="!convertToBool(data.hidden)" icon-class="eye-open" />
          <svg-icon v-else icon-class="eye" />
          <el-button type="text" size="mini" @click="() => append(data)" v-if="!data.parentId || data.parentId == 0">
            添加子路由
          </el-button>
          <el-button type="text" size="mini" @click="() => edit(data)">
            修改路由
          </el-button>
          <el-button type="text" size="mini" @click="() => remove(data)">
            删除路由
          </el-button>
        </span>
      </span>
    </el-tree>
    <!--新建一级路由，新建子路由，编辑路由-->
    <el-dialog :visible.sync="dialogVisible" :title="dialogTitle">
      <el-form ref="form" :model="permission" label-width="100px" label-position="left" :rules="rules">
        <el-form-item label="路径" prop="path">
          <el-input v-model="permission.path" placeholder="路由path" />
        </el-form-item>
        <el-form-item label="名称" prop="name">
          <el-input v-model="permission.name" placeholder="路由名称" />
        </el-form-item>
        <el-form-item label="路由备注">
          <el-input v-model="permission.menuExplain" placeholder="路由备注" />
        </el-form-item>
        <el-form-item label="组件名称" prop="component">
          <el-input v-model="permission.component" placeholder="组件名称" />
        </el-form-item>
        <el-form-item label="重定向路径">
          <el-input v-model="permission.redirect" placeholder="重定向路径" />
        </el-form-item>
        <el-form-item label="主题" prop="meta.title">
          <el-input v-model="permission.meta.title" placeholder="路由主题" />
        </el-form-item>
        <el-form-item label="图标">
          <el-input v-model="permission.meta.icon" placeholder="路由图标" />
        </el-form-item>
        <el-form-item label="高亮菜单">
          <el-input v-model="permission.meta.activeMenu" placeholder="高亮菜单" />
        </el-form-item>

        <el-checkbox v-model="permission.hidden" label="隐藏"></el-checkbox>
        <el-checkbox v-model="permission.alwaysShow" label="显示"></el-checkbox>
        <el-checkbox v-model="permission.meta.noCache" label="显示缓存"></el-checkbox>
        <el-checkbox v-model="permission.meta.affix" label="affix"></el-checkbox>
        <el-checkbox v-model="permission.meta.breadcrumb" label="面包屑"></el-checkbox>
      </el-form>

      <br />
      <div style="text-align:right;">
        <el-button type="danger" @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="comfirmMenu">提交</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { getMenuTree, addMenu, editMenu, deleteMenu } from '@/api/menu'
import { deepClone } from '@/utils'
import { pathValid } from '@/utils/myValidate'
let id = 1000;

const defaultPermisson = {
  id: '',
  parentId: 0,
  path: '',
  name: '',
  component: 'layout',
  redirect: '',
  hidden: false,
  alwaysShow: true,
  meta: {
    id: '',
    title: '',
    icon: '',
    noCache: false,
    affix: false,
    breadcrumb: false,
    activeMenu: '',
    mnId: ''
  }
}

export default {
  data() {
    return {
      permission: Object.assign({}, defaultPermisson),
      data: [],
      dialogVisible: false,
      dialogType: 'new',
      dialogTitle: '新增一级菜单',
      defaultProps: {
        children: 'children',
        label: 'title'
      },
      rules: {
        path: [{
          required: true, validator: pathValid, trigger: "blur"
        }],
        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
        component: [{ required: true, message: "请输入组件名称", trigger: "blur" }],
        'meta.title': [{ required: true, message: "请输入主题", trigger: "blur" }]
      }

    }
  },

  created() {
    this.getMenuData()
  },

  methods: {
    append(data) {
      console.log(this.dialogTyp)
      this.dialogType = 'new'
      this.dialogTitle = '新增<' + data.title + '>的子菜单'
      this.dialogVisible = true
      this.permission = deepClone(defaultPermisson)
      this.permission.parentId = data.id
    },

    remove(data) {
      this.$confirm('确定要删除该菜单吗(子菜单会一起删除)?', 'Warning', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        deleteMenu(data.id).then(res => {
          if (res.status == 'success') {
            this.getMenuData()
            this.$message({
              type: 'success',
              message: '删除成功!'
            })
          } else {
            this.$message.error(res.data)
          }
        })

      })
        .catch(err => { console.error(err) })

    },

    edit(data) {
      this.dialogType = 'edit'
      this.dialogTitle = '修改<' + data.title + '>菜单'
      this.permission = data;
      this.dialogVisible = true
    },

    addFirst() {
      this.permission = deepClone(defaultPermisson)
      this.dialogType = 'new'
      this.dialogVisible = true
      this.dialogTitle = '新增一级菜单'
    },

    async comfirmMenu() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.dialogType === 'edit') {
            // 修改菜单信息
            // 整理boolean属性
            let submitMenu = deepClone(this.permission)
            // 删除子菜单（子菜单不一起更新）
            delete submitMenu.children
            submitMenu.hidden = this.convertToNumber(submitMenu.hidden)
            submitMenu.alwaysShow = this.convertToNumber(submitMenu.alwaysShow)
            submitMenu.meta.noCache = this.convertToNumber(submitMenu.meta.noCache)
            submitMenu.meta.affix = this.convertToNumber(submitMenu.meta.affix)
            submitMenu.meta.breadcrumb = this.convertToNumber(submitMenu.meta.breadcrumb)

            editMenu(submitMenu).then((res) => {
              if (res.status == "success") {
                this.getMenuData()
                this.$message({
                  type: 'success',
                  message: '修改成功!'
                })
              } else {
                this.$message({
                  type: 'error',
                  message: res.data
                })
              }
            }).catch(err => {
              this.$message({
                type: 'error',
                message: '修改失败!'
              })
            })
            this.dialogVisible = false
            // setTimeout(() => {
            //   this.getMenuData()
            // }, 500);
            this.permission = defaultPermisson
          } else {
            // 添加菜单信息
            // 整理boolean属性
            let submitMenu = deepClone(this.permission)

            submitMenu.hidden = this.convertToNumber(submitMenu.hidden)
            submitMenu.alwaysShow = this.convertToNumber(submitMenu.alwaysShow)
            submitMenu.meta.noCache = this.convertToNumber(submitMenu.meta.noCache)
            submitMenu.meta.affix = this.convertToNumber(submitMenu.meta.affix)
            submitMenu.meta.breadcrumb = this.convertToNumber(submitMenu.meta.breadcrumb)

            addMenu(submitMenu).then((res) => {
              if (res.status == "success") {
                this.$message({
                  type: 'success',
                  message: '添加成功!'
                })
                this.getMenuData()
              } else {
                this.$message({
                  type: 'error',
                  message: res.data
                })
              }

            }).catch(err => {
              this.$message({
                type: 'error',
                message: '添加失败!'
              })
            })
            this.dialogVisible = false

            this.permission = defaultPermisson
          }
        }
      })
    },

    async getMenuData() {
      // 请求后端，获取动态路由tree
      let res = await getMenuTree()
      // 按el-tree组件的要求，整理数据结构
      this.data = this.generateRoutes(res.data)
    },

    generateRoutes(routes) {
      const res = []

      for (let route of routes) {
        const data = route
        // 将路由里面的title元数据，赋给data的title属性
        data.title = route.meta && route.meta.title,//route.meta && route.meta.title

          // 将路由里面的相关属性的值，改成boolean类型
          data.hidden = this.convertToBool(data.hidden)
        data.alwaysShow = this.convertToBool(data.alwaysShow)
        data.meta.noCache = this.convertToBool(data.meta.noCache)
        data.meta.affix = this.convertToBool(data.meta.affix)
        data.meta.breadcrumb = this.convertToBool(data.meta.breadcrumb)

        // 递归子路由
        if (route.children) {
          data.children = this.generateRoutes(route.children)
        }
        res.push(data)
      }
      return res
    },
    convertToBool(v) {
      return v == 0 ? false : true
    },
    convertToNumber(v) {
      return v ? 1 : 0
    }
  }
};
</script>

<style lang="scss" scoped>
.app-container {
  .roles-table {
    margin-top: 30px;
  }

  .permission-tree {
    margin-bottom: 30px;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
</style>
