<template>
  <a-card title="" :bordered="false">
    <a-form ref="formRef" @keyup.enter.native="searchQuery" :model="queryParam"
            :label-col="labelCol" :wrapper-col="wrapperCol">
      <a-row>
        <a-col :span="4">
          <a-form-item label="学校代码">
            <a-input v-model:value="queryParam.schoolCode" placeholder="请输入学校代码" allowClear/>
          </a-form-item>
        </a-col>
        <a-col :span="4">
          <a-form-item label="学校名称">
            <a-input v-model:value="queryParam.schoolName" placeholder="请输入学校名称" allowClear/>
          </a-form-item>
        </a-col>
      </a-row>
      <a-row>
        <a-col :span="12">
          <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchQuery">查询</a-button>
          <a-button type="primary" preIcon="ant-design:reload-outlined" @click="searchReset" style="margin-left: 8px">重置</a-button>
          <a-button type="primary" preIcon="ant-design:search-outlined" @click="searchNotHasSchool" style="margin-left: 8px">查询缺失院校</a-button>
          <a-button type="primary" preIcon="ant-design:export-outlined" @click="exportXls" style="margin: 8px">导出</a-button>
          <j-upload-button type="primary" preIcon="ant-design:import-outlined" @click="onImportXls" style="margin-left: 8px">导入</j-upload-button>
        </a-col>
      </a-row>
    </a-form>
    <!--
      【即时保存大体思路】：
      1. JVxeTable 上必须加 keep-source 属性
      2. 监听 edit-closed事件，这个事件是在编辑完成后触发
      3. 在这个事件里面判断数据是否更改，如果更改了就调用接口进行保存操作
    -->
    <JVxeTable
      toolbar
      :toolbarConfig="toolbarConfig"
      rowSelection
      keepSource
      asyncRemove
      clickRowShowSubForm
      :height="500"
      :loading="loading"
      :columns="columns"
      :dataSource="dataSource"
      :pagination="pagination"
      @save="handleTableSave"
      @removed="handleTableRemove"
      @edit-closed="handleEditClosed"
      @pageChange="handlePageChange"
      @valueChange="handleValueChange"
      @selectRowChange="handleSelectRowChange"
    >
      <template #myAction="props">
        <a @click="handleEdit(props)">编辑</a>
      </template>

      <template #myAction2="props">
        <a @click="handleShowSub(props)">子级</a>
      </template>

      <!-- 子表单 -->
      <template #subForm="{row}">
          <template v-if="subTable.flag">
              <JVxeTable
                toolbar
                :toolbarConfig="subToolbarConfig"
                rowSelection
                ref="subFormTable"
                height="auto"
                :max-height="350"
                :loading="subTable.loading"
                :columns="subTable.columns"
                :dataSource="subTable.dataSource"
                @removed="handleSubTableRemove"
                @edit-closed="handleSubEditClosed"
              ></JVxeTable>
          </template>
      </template>
    </JVxeTable>
  </a-card>
  <NotSchoolModal @register="registerNotSchool" />

  <a-modal v-model:open="open" title="缺失院校" @ok="handleOk">
    <div class="pt-3px pr-3px">
      <a-table :columns="state.columns" :data-source="state.notSchoolList" :hideOnSinglePage="true" />
    </div>
  </a-modal>

  <!-- 表单区域 -->
  <YxSchoolModal ref="registerModal" @success="handleSuccess"></YxSchoolModal>
</template>

<script lang="ts" setup>
// 即时保存示例
import {reactive, ref} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import {JVxeTypes} from '/@/components/jeecg/JVxeTable/types';
import {useMessage} from '/@/hooks/web/useMessage';
import { useListPage } from '/@/hooks/system/useListPage';
import {getData,saveRow,saveAll,deleteBatch, getExportUrl, getImportUrl, queryNotHasSchool } from "@/views/yx/yxSchool/YxSchool.api";
import {columns as tableColumns } from "@/views/yx/yxSchool/YxSchool.data";
import YxSchoolModal from "@/views/yx/yxSchool/components/YxSchoolModal.vue";
import { useModal } from "@/components/Modal";
import NotSchoolModal from "@/views/yx/yxSchool/components/NotSchoolModal.vue";

const registerModal = ref();
const [registerNotSchool, { openModal: openModal1 }] = useModal();

const labelCol = reactive({
  xs: {span: 24},
  sm: {span: 7},
});
const wrapperCol = reactive({
  xs: {span: 24},
  sm: {span: 16},
});
const {createMessage} = useMessage();
// 工具栏的按钮配置
const toolbarConfig = reactive({
  // add 新增按钮；remove 删除按钮；clearSelection 清空选择按钮
  btn: ['add', 'save', 'remove', 'clearSelection'],
});
const subToolbarConfig = reactive({
  // add 新增按钮；remove 删除按钮；clearSelection 清空选择按钮
  btn: ['add','remove'],
});
// 列表页面公共参数、方法
const { onExportXls, onImportXls } = useListPage({
  tableProps:{
    title: '院校招录专业表',
    canResize:false,
  },
  importConfig:{
    url: getImportUrl,
    success: handleSuccess
  }
});

/**
 * 成功回调
 */
function handleSuccess() {
  loadData();
}

// 是否正在加载
const loading = ref(false);
// 查询参数
const queryParam = reactive({
  schoolCode: '',//院校代码
  schoolName:'',
})
// 分页器参数
const pagination = reactive({
  // 当前页码
  current: 1,
  // 每页的条数
  pageSize: 10,
  // 可切换的条数
  pageSizeOptions: ['10', '20', '30', '100', '200'],
  // 数据总数（目前并不知道真实的总数，所以先填写0，在后台查出来后再赋值）
  total: 0,
});
// 选择的行
const selectedRows = ref<Recordable[]>([]);

// 子表的信息
const subTable = reactive({
  currentRowId: null,
  loading: false,
  pagination: { current: 1, pageSize: 0, pageSizeOptions: ['100', '200'], total: 0 },
  selectedRows: [],
  dataSource: [] as any,
  dataSource2: [] as any,
  columns: [
    {
      title: '院校代码',
      align: "center",
      key: 'schoolCode',
      type: JVxeTypes.input,
    },{
      title: '学校名称',
      align: "center",
      key: 'schoolName',
      type: JVxeTypes.input
    }
  ],
  flag:false
});
// 数据源，控制表格的数据
const dataSource = ref<Recordable[]>([]);
// 列配置，控制表格显示的列
const columns = tableColumns;

loadData();

async function searchQuery() {
  pagination.current = 1
  loadData()
}

async function searchReset() {
  pagination.current = 1
  queryParam.schoolCode = ''
  queryParam.schoolName = ''
  loadData()
}

// 加载数据
async function loadData() {
  loading.value = true;
  // 调用查询数据接口
  await defHttp
    .get({
      // 请求地址
      url: getData,
      // 封装查询条件
      params: {
        schoolCode: queryParam.schoolCode,
        schoolName: queryParam.schoolName,
        pageNo: pagination.current,
        pageSize: pagination.pageSize,
      },
    })
    .then((result) => {
      // 后台查询回来的 total，数据总数量
      pagination.total = result.total;
      // 将查询的数据赋值给 dataSource
      dataSource.value = result.records;
      // 重置选择
      selectedRows.value = [];
    })
    .finally(() => {
      // 这里是无论成功或失败都会执行的方法，在这里关闭loading
      loading.value = false;
    });
}

// 【整体保存】点击保存按钮时触发的事件
function handleTableSave({$table, target}) {
  // 校验整个表格
  $table.validate().then((errMap) => {
    // 校验通过
    if (!errMap) {
      // 获取所有数据
      let tableData = target.getTableData();
      console.log('当前保存的数据是：', tableData);
      // 获取新增的数据
      let newData = target.getNewData();
      console.log('-- 新增的数据：', newData);
      // 获取删除的数据
      let deleteData = target.getDeleteData();
      console.log('-- 删除的数据：', deleteData);
      // 【模拟保存】
      loading.value = true;
      defHttp
        .post({
          url: saveAll,
          params: tableData,
        })
        .then(() => {
          createMessage.success(`保存成功！`);
        })
        .finally(() => {
          loading.value = false;
        });
    }
  });
}

// 触发单元格删除事件
function handleTableRemove(event) {
  // 把 event.deleteRows 传给后台进行删除（注意：这里不会传递前端逻辑新增的数据，因为不需要请求后台删除）
  console.log('待删除的数据: ', event.deleteRows);
  // 也可以只传ID，因为可以根据ID删除
  let deleteIds = event.deleteRows.map((row) => row.id);
  console.log('待删除的数据ids: ', deleteIds);
  // 模拟请求后台删除
  loading.value = true;
  window.setTimeout(() => {
    defHttp
      .delete({
        url: deleteBatch, data: {ids: deleteIds.join(',')}
      }, {joinParamsToUrl: true})
      .then((res) => {
        createMessage.success('删除成功');
        //// 假设后台返回删除成功，必须要调用 confirmRemove() 方法，才会真正在表格里移除（会同时删除选中的逻辑新增的数据）
        event.confirmRemove();
      })
      .finally(() => {
        loading.value = false;
      });
  }, 1000);
}


function handleValueChange(event) {
  console.log('handleValueChange.event: ', event);
  let {$table, row, column} = event;
  let field = column.property;
  console.log(row)
  handleEditClosed(event)
}

// 单元格编辑完成之后触发的事件
function handleEditClosed(event) {
  let {$table, row, column} = event;
  let field = column.property;
  // 判断单元格值是否被修改
  if ($table.isUpdateByRow(row, field)) {
    // 校验当前行
    $table.validate(row).then((errMap) => {
      // 校验通过
      if (!errMap) {
        // 【模拟保存】
        let hideLoading = createMessage.loading(`正在保存"${column.title}"`, 0);
        console.log('即时保存数据：', row);
        defHttp
          .put({
            url: saveRow,
            params: row,
          })
          .then((res) => {
            createMessage.success(`"${column.title}"保存成功！`);
            // 局部更新单元格为已保存状态
            $table.reloadRow(row, null, field);
          })
          .finally(() => {
            hideLoading();
          });
      }
    });
  }
}

  // 当分页参数变化时触发的事件
function handlePageChange(event) {
  // 重新赋值
  pagination.current = event.current;
  pagination.pageSize = event.pageSize;
  // 查询数据
  loadData();
}

// 当选择的行变化时触发的事件
function handleSelectRowChange(event) {
  selectedRows.value = event.selectedRows;
}


function onLookRowHistoryScore(props) {
  // createMessage.success('请在控制台查看输出');
  // console.log('查看: ', { props });
}

// 查询子表数据
function loadSubData(row) {
  if (row) {
    // 这里一定要做限制，限制不能重复查询，否者会出现死循环
    // if (subTable.currentRowId === row.id) {
    //   return true;
    // }
    subTable.currentRowId = row.id;
    subTable.loading = true;
    defHttp
      .get({
        url: '/yx/yxSchoolChild/list',
        params: {
          pageNo: 1,
          pageSize: 30,
          schoolId: row.id
        },
      })
      .then((result) => {
        // 将查询的数据赋值给 dataSource
        subTable.dataSource = result.records;
        subTable.dataSource2 = result.records;
      })
      .finally(() => {
        // 这里是无论成功或失败都会执行的方法，在这里关闭loading
        subTable.flag = true;
        subTable.loading = false;
      });
    return true;
  } else {
    return false;
  }
}

function handleSubTableRemove(event){
  // 把 event.deleteRows 传给后台进行删除（注意：这里不会传递前端逻辑新增的数据，因为不需要请求后台删除）
  console.log('待删除的数据: ', event.deleteRows);
  // 也可以只传ID，因为可以根据ID删除
  let deleteIds = event.deleteRows.map((row) => row.id);
  console.log('待删除的数据ids: ', deleteIds);
  // 模拟请求后台删除
  loading.value = true;
  window.setTimeout(() => {
    defHttp
      .delete({
        url: '/yx/yxSchoolChild/deleteBatch', data: {ids: deleteIds.join(',')}
      }, {joinParamsToUrl: true})
      .then((res) => {
        createMessage.success('删除成功');
        //// 假设后台返回删除成功，必须要调用 confirmRemove() 方法，才会真正在表格里移除（会同时删除选中的逻辑新增的数据）
        event.confirmRemove();
      })
      .finally(() => {
        loading.value = false;
      });
  }, 1000);
}

// 子表单元格编辑完成之后触发的事件
function handleSubEditClosed(event) {
  let {$table, row, column} = event;
  let field = column.property;
  console.log(event)
  // 判断单元格值是否被修改
  if(subTable.dataSource2){
    let index = 0
    for(let i = 0;i<subTable.dataSource2.length;i++){
      let dd = subTable.dataSource2[i]
      if(dd['id'] == row['id'] && dd[field] == row[field]){
        index = i
        return false
      }
    }
    // 校验当前行
    $table.validate(row).then((errMap) => {
      // 校验通过
      if (!errMap) {
        row.schoolId = subTable.currentRowId as any
        if(row.id && row.id.includes('row')){
          row.id = null
        }
        // 【模拟保存】
        let hideLoading = createMessage.loading(`正在保存"${column.title}"`, 0);
        console.log('即时保存数据：', row);
        defHttp
          .put({
            url: '/yx/yxSchoolChild/edit',
            params: row,
          })
          .then((res) => {
            createMessage.success(`"${column.title}"保存成功！`);
            // 局部更新单元格为已保存状态
            $table.reloadRow(row, null, field);
            loadSubData({id:subTable.currentRowId})
            // subTable.dataSource[index] = row
            // subTable.dataSource2 = subTable.dataSource
          })
          .finally(() => {
            hideLoading();
          });
      }
    });
  }
}



/**
 * 导出xls
 * @param name
 * @param url
 */
async function exportXls(isXlsx = false) {
  let name = ''
  let selections = ''
  if (selectedRows.value) {
    selectedRows.value.forEach(i=>{
      selections+=i.id+","
    })
    console.log(selectedRows.value)
  }else{
    createMessage.warning('院校暂不支持大量导出，请选择指定院校导出');
    return;
  }
  loading.value = true;
  const data = await defHttp.get({ url: getExportUrl, params: {selections:selections}, responseType: 'blob', timeout: 60000 }, { isTransformResponse: false });
  if (!data) {
    createMessage.warning('文件下载失败');
    return;
  }
  if (!name || typeof name != 'string') {
    name = '导出文件';
  }
  let blobOptions = { type: 'application/vnd.ms-excel' };
  let fileSuffix = '.xls';
  if (isXlsx === true) {
    blobOptions['type'] = XLSX_MIME_TYPE;
    fileSuffix = XLSX_FILE_SUFFIX;
  }
  loading.value = false;
  if (typeof window.navigator.msSaveBlob !== 'undefined') {
    window.navigator.msSaveBlob(new Blob([data], blobOptions), name + fileSuffix);
  } else {
    let url = window.URL.createObjectURL(new Blob([data], blobOptions));
    let link = document.createElement('a');
    link.style.display = 'none';
    link.href = url;
    link.setAttribute('download', name + fileSuffix);
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link); //下载完成移除元素
    window.URL.revokeObjectURL(url); //释放掉blob对象
  }
}


/**
 * 编辑事件
 */
function handleEdit(props: any) {
  subTable.flag = false
  registerModal.value.disableSubmit = false;
  registerModal.value.edit(props.row);
}

function handleShowSub(props:any){
  loadSubData(props.row)
}


async function searchNotHasSchool(){

  await defHttp
    .get({
      // 请求地址
      url: queryNotHasSchool,
      // 封装查询条件
      params: {
      },
    })
    .then((result) => {
      let list = []
      for (let i = 0; i < result.length; i++) {
        list.push({
          schoolCode: result[i], key : i
        });
      }
      state.notSchoolList = list
      showModal()
    })
    .finally(() => {
      // 这里是无论成功或失败都会执行的方法，在这里关闭loading
    });
}

const open = ref<boolean>(false);
const state = reactive({
  notSchoolList:[],
  columns:[{
    title: '院校代码',
    dataIndex: 'schoolCode',
    key: 'name',
  }]
})
function showModal(){
  open.value = true;
};
function handleOk(e){
  console.log(e);
  open.value = false;
};
// function handleEdit(record: Recordable) {
//   registerModal.value.disableSubmit = false;
//   registerModal.value.edit(record);
// }

</script>

<style scoped></style>

