<!-- 目录管理 -->
<template>
  <div class="dir-manager" style="height: 100%; width: 100%; padding: 0; margin: 0">
    <!-- 头部 -->
    <div class="head">
      <a-card class="box-card" body-style="{height:'100%'}">
        <div class="head-rows">
          <div class="head-col">目录：</div>
          <div class="head-col"><a-select ref="select" style="width: 220px" :value="inputSearchValue">
              <a-select-option v-for="item in searchCategory" :key="item.id" :value="item.id">{{
                item.name
              }}</a-select-option>
            </a-select>
          </div>
        </div>
      </a-card>
    </div>
    <!-- 左边 -->
    <div class="mains">
      <div class="left">
        <a-card class="box-card" body-style="{height:'100%'}">
          <a-input-search v-model:value="treeSearchValue" style="margin-bottom: 8px" placeholder="搜索关键字" />
          <a-tree :tree-data="treeData" @select="select" :expandedKeys="expandedKeys"
            :auto-expand-parent="autoExpandParent" @expand="onExpand">
            <template #title="{ title }">
              <span v-if="title.indexOf(treeSearchValue) > -1">
                {{ title.substr(0, title.indexOf(treeSearchValue)) }}
                <span style="color: #f50">{{ treeSearchValue }}</span>
                {{ title.substr(title.indexOf(treeSearchValue) + treeSearchValue.length) }}
              </span>
              <span v-else>{{ title }}</span>
            </template>
          </a-tree>
        </a-card>
      </div>
      <!-- 右边 -->
      <div class="right">
        <div class="right-top">
          <a-card class="box-card" body-style="{height:'100%'}">
            <div style="
                border-bottom-style: solid;
                border-bottom-width: 1px;
                border-bottom-color: #ddd;
                height: 40px;
                padding: 10px;
                padding-top: 0px;
                margin-top: 0px;
              ">
              <a-row>
                <a-col :span="9"><span style="font-weight: 700; font-size: 16px">节点编辑</span>
                </a-col>
                <a-col :span="15">
                  <a-row type="flex" justify="end">
                    <div class="btn" style="margin-right: 10px;">
                      <a-button type="primary" @click="getTreeData">刷新</a-button>
                    </div>
                    <div class="btn" style="margin-right: 10px;">
                      <a-button type="primary" @click="addTreeNode">添加根节点</a-button>
                    </div>
                    <div class="btn" style="margin-right: 10px;">
                      <a-button type="primary" @click="addTreeChildNode">添加子节点</a-button>
                    </div>
                    <div class="btn">
                      <a-popconfirm title="确定删除该节点及其子节点？" @confirm="delTreeNode">
                        <a-button danger :disabled="!editBtuState">删除节点</a-button>
                      </a-popconfirm>
                    </div>
                  </a-row>
                </a-col>
              </a-row>
            </div>
            <a-form :model="formState" :labelCol="{ span: 5 }" :wrapperCol="{ span: 15 }" style="margin-top: 20px"
              layout="horizontal">
              <a-row :gutter="24">
                <a-col :span="8">
                  <a-form-item label="名称">
                    <a-input v-model:value="formState.name" />
                  </a-form-item>
                </a-col>
                <a-col :span="8">
                  <a-form-item label="别名">
                    <a-input v-model:value="formState.alaisename" />
                  </a-form-item>
                </a-col>
                <a-col :span="8">
                  <a-form-item label="排序">
                    <a-input v-model:value="formState.sortindex" disabled />
                  </a-form-item>
                </a-col>
              </a-row>
              <a-row :gutter="24">
                <a-col :span="8">
                  <a-form-item label="描述">
                    <a-textarea v-model:value="formState.remark" />
                  </a-form-item>
                </a-col>
              </a-row>
            </a-form>
            <div style="margin-top: 60px">
              <div class="col-item" style="width: 100%;display: flex;justify-content: flex-end;">
                <a-button type="primary" style="margin-right: 10px;" @click="moveNode(-1)"
                  :disabled="!editBtuState">上移节点</a-button>
                <a-button type="primary" style="margin-right: 10px;" @click="moveNode(1)"
                  :disabled="!editBtuState">下移节点</a-button>
                <a-button type="primary" @click="editNode" :disabled="!editBtuState">保存节点</a-button>
              </div>
            </div>
          </a-card>
        </div>

        <div class="right-bottom">
          <a-card class="box-card" body-style="{height:'100%'}">
            <div style="
                border-bottom-style: solid;
                border-bottom-width: 1px;
                border-bottom-color: #ddd;
                height: 40px;
              ">
              <a-row>
                <a-col :span="10">
                  <span style="font-weight: 700; font-size: 16px">操作记录</span>
                </a-col>
              </a-row>
            </div>
            <div class="list-box">
              <a-list size="small" :data-source="recordsData" v-if="recordsData.length">
                <template #renderItem="{ item }">
                  <a-list-item>{{ item }}</a-list-item>
                </template>
              </a-list>
              <a-empty :image="simpleImage" v-else />
            </div>
          </a-card>
        </div>
      </div>
    </div>
    <DirManagerDrawer v-if="ifShowDialog" @closeDialog="ifShowDialog = false" :formData="formState2"
      :drawerTitle="drawerTitle" @onSubmit="onSubmit"></DirManagerDrawer>
  </div>
</template>
<script>
import { defineComponent, ref } from 'vue';
import { getTreeRootId, getTreeList, delNode, updateNode, updateNodeList } from '/@/api/sys/dirManager';
// import Guid from 'guid';
import { v4 as uuidv4 } from 'uuid';
import { session } from '/@/utils/Memory';
import { message, Empty } from 'ant-design-vue';
import DirManagerDrawer from './DirManagerDrawer.vue';

export default defineComponent({

  components: { DirManagerDrawer },

  data() {
    return {
      // 搜索框数据
      searchCategory: [],
      // 树的搜索值
      treeSearchValue: '',
      // 树形数据
      treeData: [],
      // 表单数据
      formState: {
        id: '',
        pid: '',
        name: '',
        alaisename: '',
        remark: '',
        sortindex: '',
      },
      // 头部搜索框的值
      inputSearchValue: '',
      // 新增弹窗表单
      formState2: {
        pid: '',
        pName: '',
        type: "0",
        sortindex: 0,
      },
      // 编辑按钮使用状态
      editBtuState: true,
      //用于树状结构搜索的dataList
      dataList: [],
      expandedKeys: [],
      autoExpandParent: true,
      ifShowDialog: false,
      drawerTitle: '',
      delIds: '',
      simpleImage: Empty.PRESENTED_IMAGE_SIMPLE,
      recordsData: []
    };
  },

  mounted() {
    this.getTreeData();
  },

  watch: {
    treeSearchValue(value) {
      if (value) {
        let expanded = this.dataList
          .map(item => {
            if (item.title.indexOf(value) > -1) {
              return this.getParentKey(item.key, this.treeData);
            }
            return null;
          })
          .filter((item, i, self) => item && self.indexOf(item) === i);
        this.expandedKeys = expanded;
      } else {
        this.expandedKeys = [];
      }
      this.treeSearchValue = value;
      this.autoExpandParent = true;
    },
    formState: {
      handler(val) {
        this.editBtuState = Boolean(val.id)
      },
      immediate: true,
      deep: true
    },
  },

  methods: {
    //获取树节点列表
    getTreeData() {
      this.treeData = []
      this.dataList = []
      this.formState = {
        id: '',
        pid: '',
        name: '',
        alaisename: '',
        remark: '',
        sortindex: ''
      }
      let param = {
        1: session.getItem('tokenV2')
      }
      getTreeRootId(param).then(res => {
        this.searchCategory = JSON.parse(res.result)
        this.inputSearchValue = this.searchCategory[0].id
        let param2 = {
          1: session.getItem('tokenV2'),
          2: this.searchCategory[0].id
        }
        getTreeList(param2).then(res2 => {
          const data = JSON.parse(res2.result);
          // 让每层带上自己的孩子节点、title、key
          data.forEach((item) => {
            item['title'] = item.name;
            item['key'] = item.id;
            data.forEach((item2) => {
              if (item.id == item2.pid) {
                if (item.children) {
                  item.children.push(item2);
                } else {
                  item['children'] = [];
                  item.children.push(item2);
                }
              }
            });
          });
          data.forEach((item) => {
            if (this.searchCategory[0].id === item.pid) {
              this.treeData.push(item);
            }
          });
          this.generateList(this.treeData)
        })
      })
    },
    //生成用于树搜索的dataList
    generateList(data) {
      for (let i = 0; i < data.length; i++) {
        const node = data[i];
        const key = node.key;
        this.dataList.push({
          key,
          title: node.title,
        });
        if (node.children) {
          this.generateList(node.children);
        }
      }
    },
    //获取所有父节点key
    getParentKey(key, tree) {
      let parentKey;
      for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node.children) {
          if (node.children.some(item => item.key === key)) {
            parentKey = node.key;
          } else if (this.getParentKey(key, node.children)) {
            parentKey = this.getParentKey(key, node.children);
          }
        }
      }
      return parentKey;
    },
    //树结构展开时触发
    onExpand(keys) {
      this.expandedKeys = keys;
      this.autoExpandParent = false;
    },

    // 点击树节点
    select(selectkey, { selectedNodes, node }) {
      console.log(node.dataRef);
      if (selectkey.length) {
        this.formState = {
          ...node.dataRef
        }
      } else {
        this.formState = {
          id: '',
          pid: '',
          name: '',
          alaisename: '',
          remark: '',
          sortindex: ''
        }
      }
    },

    // 添加树节点
    addTreeNode() {
      if (this.inputSearchValue) {
        this.searchCategory.forEach((item) => {
          if (this.inputSearchValue === item.id) {
            this.formState2.pName = item.name;
            this.formState2.pid = item.id;
            this.formState2.sortindex = this.treeData.length;
            this.drawerTitle = '添加根节点'
            this.ifShowDialog = true;
          }
        });
      } else {
        //没有选择头部分类
        message.error('没有目录')
      }
    },

    // 添加子节点
    addTreeChildNode() {
      // message.warning('请选择需要添加子节点的父节点！', 5);
      if (this.formState.id) {
        this.formState2.pName = this.formState.name;
        this.formState2.pid = this.formState.id;
        this.formState2.sortindex = this.formState.children ? this.formState.children.length : 0;
        this.drawerTitle = '添加子节点'
        this.ifShowDialog = true;
      } else {
        message.error('请先选择父节点')
      }
    },

    //删除节点
    delTreeNode() {
      if (this.formState.id) {
        this.delIds = ''
        this.getChildrenIds(this.formState)
        let param = {
          1: session.getItem('tokenV2'),
          2: this.delIds
        }
        delNode(param).then(res => {
          if (res.result === "true") {
            message.success('删除成功');
            this.recordsData.push(`删除节点：${this.formState.name}`)
            this.getTreeData();
          } else {
            message.error('删除失败');
          }
        })
      } else {
        message.error('请先选择节点');
      }
    },

    //获取节点下所有子节点ids
    getChildrenIds(node) {
      this.delIds += node.id + ','
      if (node.children && node.children.length) {
        node.children.forEach(item => {
          this.getChildrenIds(item)
        })
      }
    },

    // 修改节点
    editNode() {
      if (this.editBtuState) {
        let editData = {
          id: this.formState.id,
          pid: this.formState.pid,
          name: this.formState.name,
          alaisename: this.formState.alaisename,
          type: this.formState.type,
          sortindex: this.formState.sortindex,
          remark: this.formState.remark,
        };
        let param = {
          1: session.getItem('tokenV2'),
          2: JSON.stringify(editData)
        }
        updateNode(param).then(res => {
          if (res.status === '0') {
            message.success('修改成功')
            this.recordsData.push(`修改节点：${this.formState.name}`)
            this.searchCategory = [];
            this.getTreeData();
          }
        })
      }
    },

    //移动节点
    async moveNode(flag) {
      //判断是否为根节点, 并获取同层级的数组
      let data = []
      let mvNode = null
      if (this.formState.pid !== this.inputSearchValue) {
        let param = {
          1: session.getItem('tokenV2'),
          2: this.formState.pid
        }
        let resData = await getTreeList(param)
        data = JSON.parse(resData.result);
        data = data.filter(item => item.id !== this.formState.pid)
      } else {
        data = this.treeData
      }
      data.sort((a, b) => a['sortindex'] - b['sortindex'])
      // 判断移动方向
      if (flag === 1) {
        // 判断是否是最后一个
        data.forEach((item, index) => {
          if (this.formState.id === item.id) {
            if ((index + 1) >= data.length) {
              message.info('已经是最后一个节点')
            } else {
              mvNode = data[index + 1]
            }
          }
        })
      } else {
        // 判断是否是第一个
        data.forEach((item, index) => {
          if (this.formState.id === item.id) {
            if ((index - 1) < 0) {
              message.info('已经是第一个节点')
            } else {
              mvNode = data[index - 1]
            }
          }
        })
      }
      //此处使用批量更新
      if (mvNode) {
        let editData = {
          id: this.formState.id,
          pid: this.formState.pid,
          name: this.formState.name,
          alaisename: this.formState.alaisename,
          type: this.formState.type,
          sortindex: mvNode.sortindex,
          remark: this.formState.remark,
        };
        let mvData = {
          id: mvNode.id,
          pid: mvNode.pid,
          name: mvNode.name,
          alaisename: mvNode.alaisename,
          type: mvNode.type,
          sortindex: this.formState.sortindex,
          remark: mvNode.remark,
        }
        let param = {
          1: session.getItem('tokenV2'),
          2: JSON.stringify([editData, mvData])
        }
        updateNodeList(param).then(res => {
          if (res.status==="0"){
            message.success('修改成功')
            this.recordsData.push(`移动节点：${this.formState.name}`)
            this.searchCategory = [];
            this.getTreeData();
          }
        })
      }
    },

    //弹窗确认
    onSubmit(e, item) {
      this.ifShowDialog = false
      if (e) {
        this.recordsData.push(`添加节点：${item}`)
        this.getTreeData();
      }
    }
  },
});
</script>

<style lang="less" scoped>
.dir-manager {
  .head {
    padding: 20px 20px 0;

    .box-card {
      height: calc(100% - 0px);

      .head-rows {
        width: 500px;
        display: flex;
        align-items: center;
      }
    }
  }

  .mains {
    .box-card {
      height: calc(100% - 0px);
    }

    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    height: calc(100% - 102px);

    .left {
      height: calc(100% - 0px);
      width: 20%;
    }

    .right {
      display: flex;
      flex-direction: column; //设置主轴为y轴
      justify-content: flex-start; //子元素排列方式，
      align-items: center; //设置侧轴上子元素对齐方式
      padding: 0 0 0 20px;
      height: calc(100% - 0px);
      width: 100%;
      // height: 50%;
      // width: 78%;
      // margin-left: 1%;
      // margin-right: 1%;
      // border: 1px red solid;

      .right-top {
        height: 50%;
        width: 100%;
        margin-left: 1%;
        margin-right: 1%;
        margin-bottom: 2%;

        .right-top-item {
          border-style: solid;
          border-width: 1px;
          border-color: #ddd;
          box-shadow: 0 0 10px #ddd;
          height: 250px;
          margin-top: 10px;
          padding: 10px;
        }
      }

      .right-bottom {
        height: 50%;
        width: 100%;
        margin-left: 1%;
        margin-right: 1%;

        .list-box {
          height: 282px;
          overflow: auto;
          // display: flex;
          // align-items: center;
          // justify-content: center;
        }

        .right-bottom-item {
          border-style: solid;
          border-width: 1px;
          border-color: #ddd;
          box-shadow: 0 0 10px #ddd;
          height: 250px;
          margin-top: 10px;
          padding: 10px;
        }
      }
    }
  }
}
</style>
