<template>
  <div class="content-view">
    <div class="table-head-tool">
      <Button type="primary" @click="addWarp()">新增</Button>
    </div>
    <div class="table-body">
        <TreeGrid :columns="gridOption.columns" :data="gridOption.data"></TreeGrid>
    </div>
    <editModal ref="editModal" :columns="gridOption.editColumns" :rules="gridOption.rules">
      <div slot="bottom">

        <fieldItem name='类别'>
          <RadioGroup v-model="editRow.type">
            <Radio :label="item.key" :key="item.key" v-for="item in typeSource">
              {{item.value}}
            </Radio>
          </RadioGroup>
        </fieldItem>

        <div v-if="editRow.type==='页面'||editRow.type==='功能'">
          <fieldItem name='数据模型'>
            <Select v-model="editRow.model_id">
              <Option v-for="item in modelRows" :value="item.id" :key="item.id">{{ item.value }}</Option>
            </Select>
          </fieldItem>

          <fieldItem name='组件地址'>
            <Input v-model="editRow.component" placeholder="(模块+路由).vue" />
          </fieldItem>

          <fieldItem name='api地址'>
            <Input v-model="editRow.api_path" placeholder="(模型).js" />
          </fieldItem>
        </div>

        <fieldItem name='地址' v-if="editRow.type==='外链'">
          <Input v-model="editRow.component" placeholder="请输入网址" />
        </fieldItem>

      </div>
    </editModal>
  </div>
</template>

<script>
import uiTool from '@/utils/uiTool'
import menuServer from '@/api/system/menuServer'

export default {
  name: 'tree_table_page',
  data() {
    let rules = {}
    rules['name'] = [{ required: true, message: '请填写昵称' }]
    rules['path'] = [{ required: true, message: '请填写路由' }]
    rules['icon'] = [{ required: true, message: '请选择图标' }]
    rules['is_show_menu'] = [{ required: true, message: '请选择是否在菜单' }]
    rules['is_show'] = [{ required: true, message: '请选择是否启用' }]
    rules['sort'] = [{ required: true, message: '请填写排序' }]

    const source = [
      { key: 0, value: '否' },
      { key: 1, value: '是' }
    ]
    let that = this

    const editColumns = [
      { key: 'name', title: '名称' },
      {
        key: 'parent_node_ids',
        title: '父菜单',
        editRender(h, value) {
          let val = value || []
          return h('Cascader', {
            props: {
              filterable: true,
              'change-on-select': true,
              value: val,
              data: that.gridOption.menuData
            },
            on: {
              'on-change'(value, selectedData) {
                that.parent_node_ids = value
                that.editRow.parent_id = value[value.length - 1]
              }
            }
          })
        }
      },
      { key: 'path', title: '路由', placeholder: '例:system,user' },
      {
        key: 'icon',
        title: '图标',
        com: 'SelectIcon',
        render(h, params) {
          return h('Icon', { props: { type: params.row.icon, size: '24' } })
        }
      },

      {
        key: 'is_show_menu',
        title: '是否显示在菜单',
        com: 'Radio',
        source: source,
        render(h, param) {
          if (param.row.is_show_menu) {
            return <span>是</span>
          } else {
            return <span>否</span>
          }
        }
      },
      {
        key: 'is_show',
        title: '是否启用',
        com: 'Radio',
        source: source,
        render(h, param) {
          if (param.row.is_show) {
            return <span>是</span>
          } else {
            return <span>否</span>
          }
        }
      },
      { key: 'sort', title: '排序' }
    ]

    return {
      parent_node_ids: [],
      editRow: {
        type: '',
        model_id: '',
        parent_id: '',
        path: '',
        component: ''
      },
      typeSource: [
        { key: '菜单', value: '菜单' },
        { key: '页面', value: '页面' },
        { key: '功能', value: '功能' },
        { key: '外链', value: '外链' }
      ],
      menuRows: [],
      modelRows: [{ id: 0, value: '自定义模板', key: 'custom_template' }],
      gridOption: {
        rules,
        editColumns,
        columns: [
          { title: 'id', key: 'id', width: '120', is_show_edit: 0 },
          ...editColumns,
          {
            key: 'type',
            title: '类别',
            com: 'Radio',
            source: [
              { key: '菜单', value: '菜单' },
              { key: '页面', value: '页面' },
              { key: '外链', value: '外链' }
            ]
          },

          { key: 'component', title: '组件地址' },
          { key: 'api_path', title: 'api地址' },
          { key: 'model_id', title: '模型id' },
          {
            key: 'operat',
            title: '操作',
            width: 500,
            render: (h, params) => {
              let btns = [
                {
                  title: '修改',
                  type: 'primary',
                  click: () => {
                    this.editModal(params.row)
                  }
                },
                {
                  title: '删除',
                  type: 'primary',
                  click: () => {
                    this.delConfirm(params.row)
                  }
                }
              ]

              if (params.row.type === '菜单') {
                btns.push({
                  title: '新增页面',
                  type: 'primary',
                  click: () => {
                    this.addSonWarp(params.row)
                  }
                })
              }

              if (params.row.model_id) {
                btns.push({
                  title: '自动生成（前端）',
                  type: 'primary',
                  click: () => {
                    this.generate(params.row)
                  }
                })

                btns.push({
                  title: '自动生成（api）',
                  type: 'primary',
                  click: () => {
                    this.generateModel(params.row)
                  }
                })
              }

              return uiTool.getBtn(h, btns)
            }
          }
        ],
        data: [],
        menuData: []
      }
    }
  },
  created() {
    this.init()
    this.initCol()
  },
  watch: {
    'editRow.parent_id'() {
      this.calculate()
    },
    'editRow.path'(val) {
      this.calculate()
    },
    'editRow.model_id'(val) {
      this.calculate()
    },
    'editRow.type'(val) {
      this.calculate()
    }
  },

  methods: {
    async init() {
      let res = await menuServer.list()
      let tree = uiTool.transformTree(res.data)
      this.gridOption.data = this.mapTree(tree)

      let menuRows = res.data.filter((p) => p.type === '菜单')
      this.menuRows = menuRows
      let menuTree = uiTool.transformTree(menuRows)
      this.gridOption.menuData = this.mapTree(menuTree)

      this.$store.dispatch('setAuthorityMenus')

    },
    async initCol() {
      let res = await menuServer.modelAll()

      let data = res.data.map((row) => {
        let { id, key, name } = row
        let value = key
        if (name) {
          value = value + '-' + name
        }

        return { id, value, key }
      })
      this.modelRows = [{ id: 0, value: '自定义模板', key: 'custom_template' }, ...data] || []
    },

    calculate() {
      let modulePath = ''
      let parent_node_ids = this.parent_node_ids
      parent_node_ids.forEach((id) => {
        let menuRow = this.menuRows.find((p) => p.id === id)
        if (menuRow) {
          modulePath += menuRow.path + '/'
        }
      })

      if (this.editRow.type === '菜单' || this.editRow.type === '外链') {
        this.editRow.component = ''
        this.editRow.api_path = ''
        return
      }

      if (this.editRow.path) {
        let path = this.editRow.path.replace(/\//g, '_').replace(/:/g, '')

        this.editRow.component = modulePath + path + '.vue'
        this.editRow.api_path = modulePath + path + '_server.js'
      }
    },
    mapTree(tree) {
      let curTree = tree.map((p) => {
        if (p.children && p.children.length > 0) {
          p.children = this.mapTree(p.children)
        }

        return {
          ...p,
          value: p.id,
          label: p.name,
          expand: false,
          children: p.children
        }
      })

      return curTree
    },
    editModal(row) {
      this.parent_node_ids = row.parent_node_ids
      this.editRow = row
      this.$refs.editModal.editShow(this.editRow, async (newRow) => {
        let param = Object.assign({}, this.editRow, newRow)
        await menuServer.edit(param)
        this.$Message.success('修改成功！')
        this.init()
      })
    },
    addWarp() {
      this.editRow = {
        type: '菜单',
        model_id: 0,
        component: '',
        parent_id: 0,
        parent_node_ids: [],
        path: '',
        is_show: 1,
        is_show_menu: 1
      }
      this.$refs.editModal.addShow(this.editRow, async (newRow) => {
        let param = Object.assign({}, newRow)
        await menuServer.add(param)
        this.$Message.success('新增成功！')
        this.init()
      })
    },
    addSonWarp(row) {
      let { parent_node_ids, id, model_id } = row
      this.parent_node_ids = parent_node_ids
      this.editRow = {
        type: '页面',
        parent_id: id,
        model_id,
        component: '',
        parent_node_ids,
        is_show: 1,
        is_show_menu: 1
      }
      this.$refs.editModal.addShow(this.editRow, async (newRow) => {
        let param = Object.assign({}, newRow)
        await menuServer.add(param)
        this.$Message.success('新增成功！')
        this.init()
      })
    },
    async delConfirm(row) {
      uiTool.delConfirm(async () => {
        await menuServer.del(row)
        this.$Message.success('删除成功！')
        this.init()
      })
    },
    async generate(row) {
      uiTool.showConfirm(
        {
          content: '你确定生成吗，生成将覆盖原来已存在apiServer和vuePage,请谨慎操作'
        },
        async () => {
          let res = await menuServer.generate(row)
          this.$Message.success('生成成功！')
          this.init()
        }
      )
    },
    async generateModel(row) {
      uiTool.showConfirm(
        {
          content: '你确定生成吗，生成将覆盖原来已存在model和controller,请谨慎操作'
        },
        async () => {
          let res = await menuServer.generateModel(row)
          this.$Message.success('生成成功！')
          this.init()
        }
      )
    }
  }
}
</script>

<style>

</style>
