<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">
        <Auth auth="sysUser:page">
          <div class="yo-query-bar">
            <a-form-model :model="query" @submit.native.prevent layout="inline">
              <a-form-model-item label="关键词">
                <a-input allow-clear placeholder="请输入姓名、账号、手机号" v-model="query.searchValue" />
              </a-form-model-item>
              <a-form-model-item label="状态">
                <a-select
                  :style="{ width: '170px' }"
                  allow-clear
                  placeholder="请选择状态"
                  v-model="query.searchStatus"
                >
                  <a-select-option
                    :key="i"
                    :value="item.code"
                    v-for="(item, i) in codes.common_status"
                  >{{ item.value }}</a-select-option>
                </a-select>
              </a-form-model-item>
              <a-form-model-item>
                <a-button-group>
                  <a-button @click="onQuery" html-type="submit" type="primary">查询</a-button>
                  <a-button @click="onReset">重置</a-button>
                </a-button-group>
              </a-form-model-item>
            </a-form-model>
          </div>
        </Auth>

        <yo-list :load-data="loadData" item-layout="horizontal" ref="list" size="large">
          <Auth auth="sysUser:add" slot="operator">
            <a-button @click="onOpen('add-form')" icon="plus">新增用户</a-button>
          </Auth>
          <a-list-item key="record.id" slot="renderItem" slot-scope="record">
            <Auth auth="sysUser:edit" slot="actions">
              <a @click="onOpen('edit-form', record)">编辑</a>
            </Auth>
            <Auth auth="sysUser:delete" slot="actions">
              <a-popconfirm @confirm="onDelete(record)" placement="topRight" title="是否确认删除">
                <a>删除</a>
              </a-popconfirm>
            </Auth>
            <Auth :auth="{ sysUser: [['grantRole'], ['grantData']] }" slot="actions">
              <a-dropdown placement="bottomRight">
                <a class="ant-dropdown-link">
                  授权
                  <a-icon type="down" />
                </a>
                <a-menu slot="overlay">
                  <Auth auth="sysUser:grantRole">
                    <a-menu-item>
                      <a @click="onOpen('role-form', record)">授权角色</a>
                    </a-menu-item>
                  </Auth>
                  <Auth auth="sysUser:grantData">
                    <a-menu-item>
                      <a @click="onOpen('data-form', record)">授权额外数据</a>
                    </a-menu-item>
                  </Auth>
                </a-menu>
              </a-dropdown>
            </Auth>
            <a-list-item-meta>
              <div slot="title">{{ record.nickName || record.name }}</div>
              <div slot="description">{{ record.account }}</div>
              <yo-image
                :id="record.avatar"
                :size="48"
                icon="user"
                shape="square"
                slot="avatar"
                type="avatar"
              />
            </a-list-item-meta>
            <a-descriptions :column="2" class="flex-1">
              <a-descriptions-item label="性别">{{ bindCodeValue(record.sex, 'sex') }}</a-descriptions-item>
              <a-descriptions-item label="手机">{{ record.phone || '未设置' }}</a-descriptions-item>
              <a-descriptions-item :span="2" label="邮箱">{{ record.email || '未设置' }}</a-descriptions-item>
            </a-descriptions>
            <div class="yo-list-content--h">
              <Auth auth="sysUser:changeStatus">
                <div class="yo-list-content--h--item text-center">
                  <a-switch
                    :checked="!record.status"
                    :checked-children="bindCodeValue(0, 'common_status')"
                    :loading="record.statusChanging"
                    :un-checked-children="bindCodeValue(1, 'common_status')"
                    @change="(checked) => onSetUserStatus(record, checked)"
                  />
                </div>
              </Auth>
            </div>
          </a-list-item>
        </yo-list>
      </a-card>
    </container>

    <!-- 新增表单 -->
    <yo-modal-form
      :action="$api[api.add]"
      :title="'新增' + name"
      :width="1024"
      @ok="onReloadData"
      ref="add-form"
    >
      <form-body mode="add" />
    </yo-modal-form>

    <!-- 编辑表单 -->
    <yo-modal-form
      :action="$api[api.edit]"
      :title="'编辑' + name"
      :width="1024"
      @ok="onReloadData"
      ref="edit-form"
    >
      <form-body mode="edit" />
    </yo-modal-form>

    <role-form @ok="onReloadData" ref="role-form" />
    <data-form @ok="onReloadData" ref="data-form" />
  </yo-tree-layout>
</template>
<script>
/* 需要引用YoTreeLayout组件 */
import YoTreeLayout from '@/components/yoTreeLayout';
import YoList from '@/components/yoList';
import FormBody from './form';

import RoleForm from './roleForm';
import DataForm from './dataForm';

/* 在此管理整个页面需要的接口名称 */
const api = {
  tree: 'getOrgTree',
  page: 'getUserPage',
  add: 'sysUserAdd',
  edit: 'sysUserEdit',
  delete: 'sysUserDelete',
  /* ... */
};

export default {
  components: {
    YoTreeLayout,
    YoList,
    FormBody,
    RoleForm,
    DataForm,
  },

  data() {
    return {
      api,

      name: '用户',

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

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

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

  created() {
    this.onLoadCodes();

    /** 根据权限添加操作列 */
    const flag = this.$auth({
      sysUser: [['edit'], ['delete'], ['grantRole'], ['grantData']],
    });
    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 = {
        sysEmpParam: {
          orgId: id,
        },
      };
      this.onQuery();
    },

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

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

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

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

    /**
     * 必要方法
     * 加载字典数据
     * 如果不需要获取相应的字典数据,此方法内容可空
     */
    onLoadCodes() {
      this.$api
        .$queue([
          this.$api.sysDictTypeDropDownAwait({ code: 'sex' }),
          this.$api.sysDictTypeDropDownAwait({ code: 'common_status' }),
          /* ... */
        ])
        .then(([code1, code2]) => {
          this.codes.sex = code1.data;
          this.codes.common_status = 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,
        orgId: this.query.sysEmpParam.orgId,
        /* 按需添加其他参数 */
        /* ... */
      });
    },

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

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

    onSetUserStatus(record, checked) {
      this.$set(record, 'statusChanging', true);
      this.$api
        .sysUserChangeStatus({
          id: record.id,
          status: +!checked,
        })
        .then(({ success, message }) => {
          if (success) {
            this.$message.success('操作成功');
            this.onReloadData();
          } else {
            this.$message.error(message);
          }
        })
        .finally(() => {
          record.statusChanging = false;
        });
    },

    onResetPassword(record) {
      this.$api
        .sysUserResetPwd({
          id: record.id,
        })
        .then(({ success, message }) => {
          if (success) {
            this.$message.success('重置成功');
          } else {
            this.$message.error(message);
          }
        });
    },
  },
};
</script>