<template>
  <!-- 
    普通树查询表格
    v 1.2
    2021-04-30
    Lufthafen
  -->
  <yo-tree-layout
    :load-data="loadTreeData"
    @select="onSelect"
    default-expanded-keys
    ref="tree-layout"
  >
    <container>
      <a-card :bordered="false">
        <yo-table
          :columns="columns"
          :load-data="loadData"
          @query="onQuery"
          @resetQuery="onResetQuery"
          ref="table"
        >
          <Auth auth="authCode:page" slot="query">
            <!-- 此处添加查询表单控件 -->
            <!-- ... -->
          </Auth>
          <Auth auth="authCode:add" slot="operator">
            <a-button @click="onOpen('add-form')" icon="plus">新增机构</a-button>
          </Auth>
          <!-- 格式化字段内容 -->
          <!-- ... -->
          <!-- 添加操作控件 -->
          <span slot="action" slot-scope="text, record">
            <yo-table-actions>
              <Auth auth="authCode:edit">
                <a @click="onOpen('edit-form', record)">编辑</a>
              </Auth>
              <Auth auth="authCode:delete">
                <a-popconfirm @confirm="onDelete(record)" placement="topRight" title="是否确认删除">
                  <a>删除</a>
                </a-popconfirm>
              </Auth>
              <!-- 可在此处添加其他操作控件 -->
              <!-- ... -->
            </yo-table-actions>
          </span>
        </yo-table>
      </a-card>
    </container>

    <!-- 新增表单 -->
    <yo-modal-form :action="$api[api.add]" :title="`新增${name}`" @ok="onReloadData" ref="add-form">
      <form-body />
    </yo-modal-form>

    <!-- 编辑表单 -->
    <yo-modal-form :action="$api[api.edit]" :title="`编辑${name}`" @ok="onReloadData" ref="edit-form">
      <form-body />
    </yo-modal-form>
  </yo-tree-layout>
</template>
<script>
/* 需要引用YoTreeLayout组件 */
import YoTreeLayout from '@/components/yoTreeLayout';
import FormBody from './form';

/* 在此管理整个页面需要的接口名称 */
const api = {
  tree: 'testTreeApi...',
  page: 'testPageApi...',
  add: 'testAddApi',
  edit: 'testEditApi',
  delete: 'testDeleteApi...',
  /* ... */
};

export default {
  components: {
    YoTreeLayout,
    FormBody,
  },

  data() {
    return {
      ...api,

      name: '...',

      /* 查询条件 */
      query: {},

      /* 表格字段 */
      columns: [],

      /* 字典编码储存格式 */
      codes: {
        code1: [],
        code2: [],
      },
    };
  },

  created() {
    this.onLoadCodes();

    /** 根据权限添加操作列 */
    const flag = this.$auth(/* ... */);
    if (flag) {
      this.columns.push({
        title: '操作',
        width: '150px',
        dataIndex: 'action',
        scopedSlots: { customRender: 'action' },
      });
    }
  },

  methods: {
    /**
     * 树形选择界面必要的方法
     * 传给yo-table-layout以示意数据接口
     */
    loadTreeData() {
      return this.$api[api.tree]().then((res) => {
        return res.data;
      });
    },

    /**
     * 树形选择界面必要的方法
     * 选择树节点事件
     */
    onSelect([id]) {
      /** 在选择事件中可以对右侧表格添加父节点id的查询条件 */
      this.query = {
        pid: id,
      };
      this.onQuery();
    },

    /**
     * 必要的方法
     * 传给yo-table以示意数据接口及其参数和返回的数据结构
     */
    loadData(params) {
      return this.$api[api.page]({
        ...params,
        ...this.query,
      }).then((res) => {
        return res.data;
      });
    },

    /**
     * 有查询功能时的必要方法
     * 加载数据时初始化分页信息
     */
    onQuery() {
      this.$refs.table.onReloadData(true);
    },

    /**
     * 必要方法
     * 重新列表数据
     */
    onReset() {
      /* 与普通查询页不同的是,这里的父节点参数不应该在重置后被清空 */
      Object.keys(this.query).forEach((p) => {
        if (p !== 'pid') {
          this.query[p] = undefined;
        }
      });
      this.onQuery();
    },

    /**
     * 必要方法
     * 重新列表数据
     */
    onReloadData() {
      this.$refs.table.onReloadData();
      this.$refs['tree-layout'].onReloadData();
    },

    /**
     * 必要方法
     * 加载字典数据
     * 如果不需要获取相应的字典数据,此方法内容可空
     */
    onLoadCodes() {
      this.$api
        .$queue([
          this.$api.sysDictTypeDropDownAwait({ code: 'code1' }),
          this.$api.sysDictTypeDropDownAwait({ code: 'code2' }),
          /* ... */
        ])
        .then(([code1, code2]) => {
          this.codes.code1 = code1.data;
          this.codes.code2 = code2.data;
          /* ... */
        });
    },

    /**
     * 必要方法
     * 绑定数据字典值
     */
    bindCodeValue(code, name) {
      const c = this.codes[name].find((p) => p.code == code);
      if (c) {
        return c.value;
      }
      return null;
    },

    /**
     * 有编辑新增功能的必要方法
     * 从列表页调用窗口的打开方法
     */
    onOpen(formName, record) {
      this.$refs[formName].onOpen({
        record,
        pid: this.query.pid,
        /* 按需添加其他参数 */
        /* ... */
      });
    },

    /**
     * 必要方法
     * 可以用做一系列操作的公共回调,此方法中会重新加载当前列表
     */
    onResult(success, successMessage) {
      if (success) {
        this.$message.success(successMessage);
        this.onReloadData();
      }
    },

    /**
     * 必要方法
     * 删除时调用
     */
    onDelete(record) {
      this.$refs.table.onLoading();
      this.$api[api.delete](record)
        .then(({ success }) => {
          this.onResult(success, '删除成功');
        })
        .finally(() => {
          this.$refs.table.onLoaded();
        });
    },
  },
};
</script>