<template>
  <div class="app-container">
    <el-container>
      <el-aside width="20%">
        <div class="slot-tree">
          <!-- 异步加载树   -->
          <div>
            <el-button type="text" @click="refreshTree">资源目录树</el-button>
          </div>
          <el-tree
            :key="treeKeyId"
            node-key="resId"
            :props="resPorp"
            :load="syncLoadResLabel"
            :auto-expand-parent="true"
            :current-node-key="currNode"
            accordion
            lazy
            :highlight-current="true"
            @node-click="handleNodeClick"
          >
            <span class="custom-tree-node" slot-scope="{ node, data }">
              <span>{{ node.label }}</span>
              <span v-if="data.type !== 3" class="append">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-circle-plus"
                  @click="() => handleCreate(data)"
                />
              </span>
              <span class="append">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-edit-outline"
                  @click="() => handleUpdate(data)"
                />
              </span>
              <span class="append">
                <el-button
                  type="text"
                  size="mini"
                  icon="el-icon-delete"
                  @click="() => handleDelete(data)"
                />
              </span>
            </span>
          </el-tree>
        </div>
      </el-aside>

      <el-main>
        <el-card class="box-card">
          <div slot="header" class="clearfix">
            <div class="filter-container">
              <el-input
                placeholder="资源名"
                style="width: 200px;"
                class="filter-item"
                v-model="listQuery.keywords"
                @keyup.enter.native="handleFilter"
              />
              <el-button
                v-waves
                class="filter-item"
                type="primary"
                icon="el-icon-search"
                @click="handleFilter"
                >搜索</el-button
              >
              <el-button
                class="filter-item"
                style="margin-left: 10px;"
                type="primary"
                icon="el-icon-circle-plus-outline"
                @click="handleCreate(null)"
                >新建</el-button
              >
            </div>
            <!-- 分页 -->
            <swPage
              v-if="total > 0"
              key="1"
              :listQuery="listQuery"
              :total="total"
              pos="topLeft"
              @retPage="retPage"
            />
          </div>
          <div>
            <el-table
              v-loading="listLoading"
              :key="tableKey"
              :data="list"
              size="mini"
              stripe
              border
              fit
              highlight-current-row
              style="width: 100%;"
            >
              <el-table-column
                label="名称"
                align="left"
                width="120"
                prop="name"
              />

              <el-table-column label="权限" align="center" prop="code" />

              <el-table-column label="权限" align="center" prop="perms" />

              <el-table-column
                label="路由权限"
                align="center"
                prop="routerPath"
              />

              <el-table-column label="资源级别" align="center" width="100">
                <template slot-scope="scope">
                  <span>{{ scope.row.system | ststemFilter }}</span>
                </template>
              </el-table-column>

              <el-table-column label="操作" align="center" width="300">
                <template slot-scope="scope">
                  <el-button
                    v-if="scope.row.type !== 3"
                    type="primary"
                    size="mini"
                    title="新建"
                    icon="el-icon-circle-plus-outline"
                    @click="handleCreate(scope.row)"
                    >新建</el-button
                  >
                  <el-button
                    type="primary"
                    size="mini"
                    title="编辑"
                    icon="el-icon-edit"
                    @click="handleUpdate(scope.row)"
                  >
                    编辑
                  </el-button>
                  <el-button
                    size="mini"
                    type="danger"
                    icon="el-icon-delete"
                    title="删除"
                    @click="handleDelete(scope.row)"
                    >删除
                  </el-button>
                </template>
              </el-table-column>
            </el-table>

            <!-- 分页 -->
            <swPage
              v-if="total > 0"
              key="2"
              :listQuery="listQuery"
              :total="total"
              pos="btmRight"
              @retPage="retPage"
            />
          </div>
        </el-card>
      </el-main>
    </el-container>

    <!-- 新增或编辑对话框-->
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormVisible"
      top="10px"
    >
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="midData"
        label-position="right"
        label-width="90px"
        style="width: 80%; margin-left:50px;"
      >
        <el-form-item label="ID" v-show="false">
          <el-input v-model="midData.resId" disabled />
        </el-form-item>

        <el-form-item label="名称" prop="name">
          <el-input v-model="midData.name" />
        </el-form-item>

        <el-form-item label="code" prop="code">
          <el-input v-model="midData.code" />
        </el-form-item>

        <el-form-item label="权限" prop="perms">
          <el-input v-model="midData.perms" />
        </el-form-item>

        <el-row>
          <el-col :span="12">
            <el-form-item label="资源级别" prop="system">
              <el-select
                v-model="midData.system"
                class="filter-item"
                placeholder="Please select"
              >
                <el-option
                  v-for="item in systemOptions"
                  :key="item.key"
                  :label="item.display_name"
                  :value="item.key"
                />
              </el-select>
            </el-form-item>
          </el-col>

          <el-col :span="12">
            <el-form-item label="资源类型" prop="type">
              <el-select
                class="filter-item"
                placeholder="Please select"
                v-model="midData.type"
              >
                <el-option
                  v-for="item in typesOptions"
                  :key="item.key"
                  :label="item.display_name"
                  :value="item.key"
                />
              </el-select>
            </el-form-item>
          </el-col>
        </el-row>

        <el-form-item label="图标">
          <el-input v-model="midData.icon" />
        </el-form-item>

        <el-form-item label="英文名">
          <el-input v-model="midData.ename" />
        </el-form-item>

        <el-form-item label="路由路径" prop="routerPath">
          <el-input v-model="midData.routerPath" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="dialogStatus === 'create' ? createData() : updateData()"
          >确认</el-button
        >
      </div>
    </el-dialog>
  </div>
</template>

<script>
import waves from "@/directive/waves";
import swPage from "@/views/common/swPage";

import {
  fetchListNew,
  fetchList,
  createRes,
  getResInfo,
  updateRes,
  deleteRes,
  dynamicTree,
  checkCodeExist
} from "@/api/auth/res";

const typesOptions = [
  { key: 1, display_name: "菜单" },
  { key: 2, display_name: "子菜单" },
  { key: 3, display_name: "按钮" },
  { key: 15, display_name: "外部接口" }
];

const systemOptions = [
  { key: -1, display_name: "平台" },
  { key: 1, display_name: "用户" }
];

const typesKeyValue = typesOptions.reduce((acc, cur) => {
  acc[cur.key] = cur.display_name;
  return acc;
}, {});

const systemKeyValue = systemOptions.reduce((acc, cur) => {
  acc[cur.key] = cur.display_name;
  return acc;
}, {});

export default {
  inject: ["reload"], //刷新
  name: "resIndex",
  directives: {
    waves
  },
  components: {
    swPage
  },
  filters: {
    typeFilter(key) {
      return typesKeyValue[key];
    },
    ststemFilter(key) {
      return systemKeyValue[key];
    }
  },
  data() {
    var checkCode = (rule, value, callback) => {
      // 为菜单或者子菜单时，router必须填写

      checkCodeExist(value, this.midData.resId).then(response => {
        let exist = response.data.exist;
        if (exist) {
          callback(new Error("此code已存在!"));
        } else {
          callback();
        }
      });
    };
    var checkRouter = (rule, value, callback) => {
      // 为菜单或者子菜单时，router必须填写
      if (this.midData.type === 1 || this.midData.type === 2) {
        if (value === "") {
          callback(new Error("请输入路由路径!"));
        } else {
          callback();
        }
      } else {
        callback();
      }
    };
    return {
      tableKey: 0,
      treeKeyId: 0, //树key 用户出刷新
      topResTree: null, //资源树 - 顶级
      childResTree: null, //子节点
      lastRecode: null, //最后操作的节点
      currNode: null, //当前节点资源ID
      currNodeData: null, //当前属性的数据
      isGetList: false, //异步加载树 - 会同时触发 树的“load node-click”事件，这时存在右侧table不刷新 此字段解决此问题
      resPorp: {
        //树结构
        label: "name",
        isLeaf: "leaf"
      },
      list: [],
      total: null,
      listLoading: false,
      listQuery: {
        page: 1,
        limit: 10,
        keywords: null,
        parentId: null
      },
      listTwoQuery: {
        page: 1,
        limit: 10,
        keywords: null
      },
      listThreeQuery: {
        page: 1,
        limit: 10,
        keywords: null
      },
      resTreeQuery: {
        //资源树
        parentId: null
      },
      dialogFormVisible: false,
      dialogStatus: "",
      textMap: {
        update: "编辑",
        create: "新建"
      },
      isUpdate: false,
      typesOptions,
      systemOptions,
      midData: {
        type: "1",
        system: "-1",
        resId: "",
        name: "",
        code: "",
        perms: "",
        icon: "",
        ename: "",
        parentId: "",
        routerPath: ""
      },
      rules: {
        name: [{ required: true, message: "请填写名称", trigger: "change" }],
        type: [{ required: true, message: "请选择类型", trigger: "blur" }],
        system: [
          { required: true, message: "请选择资源级别", trigger: "blur" }
        ],
        code: [
          { required: true, message: "请输入资源code", trigger: "blur" },
          { validator: checkCode, trigger: "blur" }
        ],
        routerPath: [{ validator: checkRouter, trigger: "blur" }]
      },
      title: "",
      dialogTableVisible: false,
      threeList: [],
      threeTotal: null
    };
  },
  created() {},
  methods: {
    refreshTree() {
      this.currNode = null;
      this.resTreeQuery.parentId = null;
      this.treeKeyId = this.treeKeyId + 1;
    },
    syncLoadResLabel(node, resolve) {
      //同步目录
      if (node.level === 0) {
        //动态加载  -- 如果 节点下的数据没有触发过会触发，已有的数据就不在触发
        // -> /sysOrgRes/tree
        dynamicTree(this.resTreeQuery).then(response => {
          //顶级目录
          this.topResTree = response.data.resTree;
          //设置当前节点的父亲节点
          if (response.data.currRes != null) {
            //父节点
            this.listQuery.parentId = response.data.currRes;
            this.getList(); //根据父节点获取子目录table
          }
          //父组件产值
          return resolve(this.topResTree);
        });
      } else if (node.level > 0) {
        this.isGetList = true;
        this.resTreeQuery.parentId = node.data.resId;
        dynamicTree(this.resTreeQuery).then(response => {
          this.childResTree = response.data.resTree;
          return resolve(this.childResTree);
        });
        this.currNodeData = node.data;
        this.currNode = this.currNodeData.resId;
      }
    },
    handleNodeClick(data, node) {
      //点击node触发
      if (node.isLeaf) {
        //叶子节点
        this.currNode = data.resId;
      } else {
        //非叶子节点
        if (this.isGetList || this.currNode != data.resId) {
          this.currNode = data.resId;
          //页码
          this.listQuery.page = 1;
          //父节点
          this.listQuery.parentId = this.currNode;
          this.getList(); //根据父节点获取子目录table
          this.isGetList = false;
        }
      }
      this.currNodeData = node.data;
    },
    getList() {
      this.listLoading = true;
      fetchList(this.listQuery).then(response => {
        this.list = response.data.list;
        this.total = response.data.total;
        setTimeout(() => {
          this.listLoading = false;
        }, 0.5 * 1000);
      });
    },
    retPage() {
      //分页
      this.getList();
    },
    handleFilter() {
      this.listQuery.page = 1;
      this.getList();
    },
    handleThreeFilter() {
      this.listThreeQuery.page = 1;
      this.handleLoadByPage();
    },
    handleThreeSizeChange(val) {
      this.listThreeQuery.limit = val;
      this.handleLoadByPage();
    },
    handleThreeCurrentChange(val) {
      this.listThreeQuery.page = val;
      this.handleLoadByPage();
    },
    handleThreeDialogClose() {
      this.listThreeQuery = {
        page: 1,
        limit: 10,
        keywords: null
      };
    },
    resetMidData() {
      this.midData.type = 1;
      this.midData.system = -1;
      this.midData.resId = "";
      this.midData.name = "";
      this.midData.code = "";
      this.midData.perms = "";
      this.midData.icon = "";
      this.midData.ename = "";
      this.midData.parentId = "";
      this.midData.routerPath = "";
    },
    handleLoadByPage() {
      const item = this.threeList[0];
      const query = {};
      query.type = item.type;
      query.parentId = item.parentId;
      query.limit = this.listThreeQuery.limit;
      query.page = this.listThreeQuery.page;
      query.keywords = this.listThreeQuery.keywords;
      this.listLoading = true;
      fetchListNew(query).then(response => {
        this.threeList = response.data.list;
        this.threeTotal = response.data.total;
        setTimeout(() => {
          this.listLoading = false;
        }, 0.5 * 1000);
      });
    },
    handleCreate(param) {
      this.resetMidData();
      this.dialogFormVisible = true;
      this.isUpdate = false;
      this.dialogStatus = "create";
      const item = this.threeList[0];
      if (param !== null) {
        this.midData.parentId = param.resId;
      }
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });

      if (param !== null) {
        if (param.type == 1) {
          this.midData.type = 2;
        } else if (param.type == 2) {
          this.midData.type = 3;
        }
        this.midData.system = param.system;
      }
    },
    createData() {
      this.$refs["dataForm"].validate(valid => {
        if (valid) {
          console.log(this.midData);
          createRes(this.midData).then(() => {
            this.dialogFormVisible = false;
            this.$notify({
              title: "成功",
              message: "创建成功",
              type: "success",
              duration: 3000
            });
            //重新加载数据
            this.reload();
          });
        }
      });
    },
    handleUpdate(row) {
      this.resetMidData();
      this.dialogFormVisible = true;
      this.dialogStatus = "update";
      this.isUpdate = true;
      getResInfo(row.resId).then(response => {
        this.midData = Object.assign({}, response.data); // copy obj
      });
      this.$nextTick(() => {
        this.$refs["dataForm"].clearValidate();
      });
    },
    updateData() {
      this.$refs["dataForm"].validate(valid => {
        if (valid) {
          const tempData = Object.assign({}, this.midData);
          updateRes(tempData).then(() => {
            this.dialogFormVisible = false;
            this.isUpdate = false;
            this.$notify({
              title: "成功",
              message: "更新成功",
              type: "success",
              duration: 3000
            });
            this.resetMidData(); //设置数据
            this.reload();
          });
        }
      });
    },
    handleDelete(row) {
      this.$confirm("是否删除该记录?", "提示", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning"
      })
        .then(() => {
          let data = { resId: row.resId };
          deleteRes(data).then(() => {
            this.$message({
              type: "success",
              message: "删除成功!"
            });
            this.refreshTree();
          });
        })
        .catch(() => {
          this.$message({
            type: "info",
            message: "已取消"
          });
        });
    }
  }
};
</script>

<style scoped>
.box-card {
  margin-left: 10px;
}
.el-tree-node__content:hover .append {
  display: inline !important;
}
.append {
  display: none;
}
</style>
