<template>
  <yo-tree-layout :load-data="loadTreeData" @select="onSelect" default-expanded-keys>
    <container>
      <a-alert closable type="error">
        <template slot="message">
          后端bug:生日不填写,在保存时会默认写入0001-01-01
          <br />权限问题,在这里需要用到组织架构以及职位的数据接口,所以必须配置该两项的菜单
        </template>
      </a-alert>
      <br />
      <a-card :bordered="false">
        <Auth auth="sysUser:page">
          <div class="yo-query-bar">
            <a-form-model :model="query" 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.find(p => p.code === 'common_status').values"
                  >{{ item.value }}</a-select-option>
                </a-select>
              </a-form-model-item>
              <a-form-model-item>
                <a-button-group>
                  <a-button @click="onQuery" 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('org-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>
            <div class="yo-list-content--h">
              <div class="yo-list-content--h--item">
                <span>性别</span>
                <p>{{ bindCodeValue(record.sex, 'sex') }}</p>
              </div>
              <div class="yo-list-content--h--item">
                <span>手机</span>
                <p>{{ record.phone }}</p>
              </div>
              <Auth auth="sysUser:changeStatus">
                <div class="yo-list-content--h--item">
                  <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>
    <add-form @ok="onReloadData" ref="add-form" />
    <edit-form @ok="onReloadData" ref="edit-form" />
    <role-form @ok="onReloadData" ref="role-form" />
    <org-form @ok="onReloadData" ref="org-form" />
  </yo-tree-layout>
</template>
<script>
import YoTreeLayout from '@/components/yoTreeLayout';
import YoList from '@/components/yoList';

import AddForm from './addForm';
import EditForm from './editForm';
import RoleForm from './roleForm';
import OrgForm from './orgForm';

export default {
  components: {
    YoTreeLayout,
    YoList,
    AddForm,
    EditForm,
    RoleForm,
    OrgForm,
  },

  data() {
    return {
      query: {},
      codes: [
        {
          code: 'sex',
          values: [],
        },
        {
          code: 'common_status',
          values: [],
        },
      ],
    };
  },

  created() {
    this.onLoadCodes();
  },

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

    onSelect([id]) {
      this.query = {
        'sysEmpParam.orgId': id,
      };
      this.onQuery();
    },

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

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

    onReset() {
      Object.keys(this.query).forEach((p) => {
        if (p !== 'sysEmpParam.orgId') {
          this.query[p] = undefined;
        }
      });
      this.onQuery();
    },

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

    /**
     * 加载字典数据时的必要方法
     */
    onLoadCodes() {
      this.$api
        .$queue([
          this.$api.sysDictTypeDropDownWait({ code: 'sex' }),
          this.$api.sysDictTypeDropDownWait({ code: 'common_status' }),
        ])
        .then(([sex, commonStatus]) => {
          this.codes.find((p) => p.code === 'sex').values = sex.data;
          this.codes.find((p) => p.code === 'common_status').values = commonStatus.data;
        });
    },
    bindCodeValue(code, name) {
      const c = this.codes.find((p) => p.code == name).values.find((p) => p.code == code);
      if (c) {
        return c.value;
      }
      return null;
    },

    /**
     * 有编辑新增功能的必要方法
     * 从列表页调用窗口的打开方法
     */
    onOpen(formName, record) {
      try {
        this.$refs[formName].onOpen(record, this.query['sysEmpParam.orgId']);
      } catch {
        console.warn('component open method not found');
      }
    },

    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);
          }
        });
    },

    onDelete(record) {
      this.$api.sysUserDelete(record).then(({ success, message }) => {
        if (success) {
          this.$message.success('删除成功');
          this.onReloadData();
        } else {
          this.$message.error(message);
        }
      });
    },
  },
};
</script>