<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.majorName" placeholder="请输入专业名称" allowClear/>
          </a-form-item>
        </a-col>
        <a-col :span="3">
          <a-form-item label="专业类别" name="majorType">
            <a-select v-model:value="queryParam.majorType" show-search allow-clear
                      placeholder="请选择专业类别">
              <a-select-option value="">请选择</a-select-option>
              <a-select-option value="音乐类">音乐类</a-select-option>
              <a-select-option value="表演类">表演类</a-select-option>
              <a-select-option value="书法类">书法类</a-select-option>
              <a-select-option value="舞蹈类">舞蹈类</a-select-option>
              <a-select-option value="体育类">体育类</a-select-option>
              <a-select-option value="美术与设计类">美术与设计类</a-select-option>
              <a-select-option value="播音与主持类">播音与主持类</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="3">
          <a-form-item label="文理分科">
            <a-select v-model:value="queryParam.category" show-search allow-clear
                      placeholder="请选择[文科/理科]">
              <a-select-option value="">请选择</a-select-option>
              <a-select-option value="文科">文科</a-select-option>
              <a-select-option value="理科">理科</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="3">
          <a-form-item label="批次">
            <a-select v-model:value="queryParam.batch" show-search allow-clear
                      placeholder="请选择批次">
              <a-select-option value="">请选择</a-select-option>
              <a-select-option value="提前批">提前批</a-select-option>
              <a-select-option value="本科A段">本科A段</a-select-option>
              <a-select-option value="本科B段">本科B段</a-select-option>
              <a-select-option value="本科">体育本科</a-select-option>
              <a-select-option value="高职高专">高职高专</a-select-option>
            </a-select>
          </a-form-item>
        </a-col>
        <a-col :span="3">
          <a-form-item label="数据状态">
            <a-select v-model:value="queryParam.state" show-search allow-clear placeholder="请选择状态">
              <a-select-option value="">请选择</a-select-option>
              <a-select-option value="0">停招</a-select-option>
              <a-select-option value="1">招生</a-select-option>
              <a-select-option value="2">新增</a-select-option>
            </a-select>
          </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: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
      clickRowShowSubForm
      keepSource
      asyncRemove
      :height="500"
      :loading="loading"
      :columns="columns"
      :dataSource="dataSource"
      :pagination="pagination"
      @save="handleTableSave"
      @removed="handleTableRemove"
      @edit-closed="handleEditClosed"
      @pageChange="handlePageChange"
      @selectRowChange="handleSelectRowChange"
    >
      <template #myAction="props">
        <a @click="onLookRowHistoryScore(props)">历年分数</a>
<!--        <a-divider type="vertical" />-->
<!--        <Popconfirm title="确定删除吗？" @confirm="onDeleteRow(props)">-->
<!--          <a>删除</a>-->
<!--        </Popconfirm>-->
      </template>

      <!-- 子表单 -->
      <template #subForm="{ row }">
        <template v-if="loadSubData(row)">
          <JVxeTable
            toolbar
            :title="'标题'"
            :toolbarConfig="subToolbarConfig"
            rowSelection
            ref="subFormTable"
            height="auto"
            :max-height="350"
            :loading="subTable.loading"
            :columns="subTable.columns"
            :dataSource="subTable.dataSource"
            @edit-closed="handleHistoryScoreEditClosed"
          />
        </template>
      </template>

    </JVxeTable>
  </a-card>
</template>

<script lang="ts" setup>
// 即时保存示例
import {reactive, ref} from 'vue';
import {defHttp} from '/@/utils/http/axios';
import {JVxeColumn, JVxeTypes} from '/@/components/jeecg/JVxeTable/types';
import {useMessage} from '/@/hooks/web/useMessage';
import { useListPage } from '/@/hooks/system/useListPage';
import {XLSX_FILE_SUFFIX, XLSX_MIME_TYPE} from "@/hooks/system/useMethods";
import {columnsN } from "@/views/yx/yxHistoryMajorEnroll/YxHistoryMajorEnroll.data";
import { getImportUrl } from "@/views/yx/yxSchoolMajor/YxSchoolMajor.api";
import {getData as getHistoryData,saveRow as saveHistoryRow} from "@/views/yx/yxHistoryMajorEnroll/YxHistoryMajorEnroll.api";

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'],
});
// 列表页面公共参数、方法
const { onExportXls, onImportXls } = useListPage({
  tableProps:{
    title: '院校招录专业表',
    canResize:false,
  },
  importConfig:{
    url: getImportUrl,
    success: handleSuccess
  }
});

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

// 是否正在加载
const loading = ref(false);
// 查询参数
const queryParam = reactive({
  schoolCode: '',//院校代码
  majorName: '',//专业代码
  majorType: '',//专业类别
  category: '',//文理分科
  batch:'',//批次
  state:'',//数据状态
})
// 分页器参数
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: columnsN,
});
// 数据源，控制表格的数据
const dataSource = ref<Recordable[]>([]);
// 列配置，控制表格显示的列
const columns = ref<JVxeColumn[]>([
  /*{ key: 'num', title: '序号', width: 80, type: JVxeTypes.normal },*/
  {
    title: '操作',
    key: 'action',
    type: JVxeTypes.slot,
    fixed: 'right',
    minWidth: 120,
    align: 'center',
    slotName: 'myAction',
  },
  {
    // 列的标题
    title: '数据状态',
    // 字段key，跟后台数据的字段名匹配
    key: 'state',
    // 列的宽度
    width: 100,
    // 如果加上了该属性，就代表当前单元格是可编辑的，type就是表单的类型，input就是简单的输入框
    type: JVxeTypes.select,
    // 下拉选项
    options: [
      { title: '停招', value: '0' },
      { title: '招生', value: '1' },
      { title: '新增', value: '2' }
    ],
    // allowInput: true,
    allowSearch: true,
    placeholder: '请选择',
  },
  {
    // 列的标题
    title: '学校代码',
    // 字段key，跟后台数据的字段名匹配
    key: 'schoolCode',
    // 列的宽度
    width: 100,
    // 如果加上了该属性，就代表当前单元格是可编辑的，type就是表单的类型，input就是简单的输入框
    type: JVxeTypes.input
  },
  {
    title: '专业代码',
    key: 'majorCode',
    width: 100,
    type: JVxeTypes.input
  },
  {
    title: '专业名称',
    key: 'majorName',
    width: 200,
    type: JVxeTypes.textarea
  },
  {
    title: '招生代码',
    key: 'enrollmentCode',
    width: 100,
    type: JVxeTypes.input
  },
  {
    title: '学费',
    key: 'tuition',
    width: 80,
    type: JVxeTypes.inputNumber,
  },
  {
    title: '备注',
    key: 'detail',
    width: 300,
    type: JVxeTypes.textarea,
  },
  {
    title: '科类(文科/理科)',
    key: 'category',
    width: 100,
    type: JVxeTypes.input,
  },
  {
    title: '录取方式缩写(用于筛选条件)',
    key: 'rulesEnrollProbabilitySx',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '对外录取方式',
    key: 'rulesEnrollProbability',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '对外录取方式运算符',
    key: 'probabilityOperator',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '内部录取方式',
    key: 'privateRulesEnrollProbability',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '内部录取方式运算符',
    key: 'privateProbabilityOperator',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '批次',
    key: 'batch',
    width: 100,
    type: JVxeTypes.input,
  },
  /* {
     title: '文化分省控线',
     key: 'culturalControlLine',
     width:100,
     type: JVxeTypes.inputNumber,
   },
   {
     title: '专项分数线',
     key: 'specialControlLine',
     width:100,
     type: JVxeTypes.inputNumber,
   },*/
  {
    title: '专业类型',
    key: 'majorType',
    width: 110,
    type: JVxeTypes.input,
  },
  {
    title: '二级专业类型',
    key: 'majorTypeChild',
    width: 130,
    type: JVxeTypes.input,
  },
  {
    title: '计划招生(人)',
    key: 'planNum',
    width: 100,
    type: JVxeTypes.inputNumber,
  },
  /*{
    title: '是否使用主项成绩',
    key: 'checkMaster',
    width:100,
    type: JVxeTypes.input,
  },*/
  {
    title: '主考科目',
    key: 'mainSubjects',
    width: 150,
    type: JVxeTypes.input,
  },
  {
    title: '学制',
    key: 'semester',
    width: 100,
    type: JVxeTypes.input,
  },
  {
    title: '院校限制',
    key: 'limitation',
    width: 150,
    type: JVxeTypes.textarea,
  },
  {
    title: '文化分数限制',
    key: 'culturalScoreLimitation',
    width: 130,
    type: JVxeTypes.inputNumber,
  },
  {
    title: '专业分数限制',
    key: 'professionalScoreLimitation',
    width: 130,
    type: JVxeTypes.inputNumber,
  },
  {
    title: '语文成绩限制',
    key: 'chineseScoreLimitation',
    width: 130,
    type: JVxeTypes.inputNumber,
  },
  {
    title: '英语成绩限制',
    key: 'englishScoreLimitation',
    width: 130,
    type: JVxeTypes.inputNumber,
  },

]);

// 查询url地址
enum Api {
  getData = '/yx/yxSchoolMajor/list',
  // 模拟保存单行数据（即时保存）
  saveRow = '/yx/yxSchoolMajor/edit',
  // 模拟保存整个表格的数据
  saveAll = '/yx/yxSchoolMajor/saveBatch',
  deleteBatch = '/yx/yxSchoolMajor/deleteBatch',
  exportXls = '/yx/yxSchoolMajor/exportXls',
  importExcel = '/yx/yxSchoolMajor/importExcel',
}

loadData();

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

async function searchReset() {
  pagination.current = 1
  queryParam.schoolCode = ''
  queryParam.majorName = ''
  queryParam.majorType = ''
  queryParam.category = ''
  queryParam.batch = ''
  queryParam.state = ''
  loadData()
}

// 加载数据
async function loadData() {
  loading.value = true;
  // 调用查询数据接口
  await defHttp
    .get({
      // 请求地址
      url: Api.getData,
      // 封装查询条件
      params: {
        schoolCode: queryParam.schoolCode ? '*' + queryParam.schoolCode + '*' : '',
        majorName: queryParam.majorName ? '*' + queryParam.majorName + '*' : '',
        majorType:queryParam.majorType,
        category:queryParam.category,
        batch:queryParam.batch,
        state:queryParam.state,
        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: Api.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: Api.deleteBatch, data: {ids: deleteIds.join(',')}
      }, {joinParamsToUrl: true})
      .then((res) => {
        createMessage.success('删除成功');
        //// 假设后台返回删除成功，必须要调用 confirmRemove() 方法，才会真正在表格里移除（会同时删除选中的逻辑新增的数据）
        event.confirmRemove();
      })
      .finally(() => {
        loading.value = false;
      });
  }, 1000);
}

// 单元格编辑完成之后触发的事件
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: Api.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: getHistoryData,
        params: {
          pageNo: 1,
          pageSize: 30,
          schoolCode: row.schoolCode,
          majorName:row.majorName,
          category:row.category,
          batch:row.batch
        },
      })
      .then((result) => {
        // 将查询的数据赋值给 dataSource
        subTable.dataSource = result.records;
        subTable.dataSource2 = result.records;
      })
      .finally(() => {
        // 这里是无论成功或失败都会执行的方法，在这里关闭loading
        subTable.loading = false;
      });
    return true;
  } else {
    return false;
  }
}

// 子表单元格编辑完成之后触发的事件
function handleHistoryScoreEditClosed(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) {
        // 【模拟保存】
        let hideLoading = createMessage.loading(`正在保存"${column.title}"`, 0);
        console.log('即时保存数据：', row);
        defHttp
          .put({
            url: saveHistoryRow,
            params: row,
          })
          .then((res) => {
            createMessage.success(`"${column.title}"保存成功！`);
            // 局部更新单元格为已保存状态
            $table.reloadRow(row, null, field);
            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)
  }
  const data = await defHttp.get({ url: Api.exportXls, 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;
  }
  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对象
  }
}
</script>

<style scoped></style>

