Newer
Older
dxCard-admin / src / views / demo / jeecg / JVxeTableDemo / func-demo / PopupSubTable.vue
YFJ on 23 Sep 7 KB 项目推送
<template>
  <a-card title="弹出子表示例" :bordered="false">
    <!--
      【弹出子表大体思路】
      1. 必须要有 clickRowShowSubForm 属性,如果该属性设为false,那么就不会弹出子表
      2. 必须要有 subForm 插槽,用于规定弹出子表的内容
      3. highlightCurrentRow 属性可有可无,如果有则点击一行的时候,该行会背景色会常亮
    -->
    <!--
      【弹出详细信息大体思路】
      1. 必须要有 clickRowShowMainForm 属性,如果该属性设为false,那么就不会弹出详细信息
      2. 必须要有 mainForm 插槽,用于规定弹出的内容
    -->
    <JVxeTable
      toolbar
      rowNumber
      rowSelection
      highlightCurrentRow
      clickRowShowSubForm
      clickRowShowMainForm
      :height="750"
      :loading="loading"
      :columns="columns"
      :dataSource="dataSource"
      @detailsConfirm="handleDetailsConfirm"
    >
      <!-- 主表单 -->
      <template #mainForm="{ row }">
        <template v-if="row">
          <a-form ref="form2" :model="row" :rules="rules" :label-col="labelCol" :wrapper-col="wrapperCol">
            <a-row :gutter="8">
              <a-col :span="8">
                <a-form-item label="ID" name="id">
                  <a-input v-model:value="row.id" disabled />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="序号" name="num">
                  <a-input v-model:value="row.num" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="船名" name="ship_name">
                  <a-input v-model:value="row.ship_name" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="呼叫" name="call">
                  <a-input v-model:value="row.call" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="长" name="len">
                  <a-input v-model:value="row.len" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="吨" name="ton">
                  <a-input v-model:value="row.ton" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="付款方" name="payer">
                  <a-input v-model:value="row.payer" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="数" name="count">
                  <a-input v-model:value="row.count" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="公司" name="company">
                  <a-input v-model:value="row.company" />
                </a-form-item>
              </a-col>
              <a-col :span="8">
                <a-form-item label="动向" name="trend">
                  <a-input v-model:value="row.trend" />
                </a-form-item>
              </a-col>
            </a-row>
          </a-form>
        </template>
      </template>

      <!-- 子表单 -->
      <template #subForm="{ row }">
        <template v-if="loadSubData(row)">
          <JVxeTable
            ref="subFormTable"
            height="auto"
            :max-height="350"
            :loading="subTable.loading"
            :columns="subTable.columns"
            :dataSource="subTable.dataSource"
          />
        </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';

  const { createMessage } = useMessage();
  const loading = ref(false);
  const dataSource = ref([]);
  const columns = ref<JVxeColumn[]>([
    { key: 'num', title: '序号', width: '80px' },
    { key: 'ship_name', title: '船名', width: '180px', type: JVxeTypes.input },
    { key: 'call', title: '呼叫', width: '80px' },
    { key: 'len', title: '长', width: '80px' },
    { key: 'ton', title: '吨', width: '120px' },
    { key: 'payer', title: '付款方', width: '120px' },
    { key: 'count', title: '数', width: '40px' },
    {
      key: 'company',
      title: '公司',
      minWidth: '180px',
      // 是否点击显示详细信息
      // 只有当前单元格不能编辑的时候才能生效
      // 如果不设的话,点击就只弹出子表,不会弹出主表的详细信息
      showDetails: true,
    },
    { key: 'trend', title: '动向', width: '120px' },
  ]);
  const selectedRows = ref([]);
  // 子表的信息
  const subTable = reactive({
    currentRowId: null,
    loading: false,
    pagination: { current: 1, pageSize: 200, pageSizeOptions: ['100', '200'], total: 0 },
    selectedRows: [],
    dataSource: [],
    columns: [
      { key: 'dd_num', title: '调度序号', width: '120px' },
      { key: 'tug', title: '拖轮', width: '180px', type: JVxeTypes.input },
      { key: 'work_start_time', title: '作业开始时间', width: '180px', type: JVxeTypes.input },
      { key: 'work_stop_time', title: '作业结束时间', width: '180px', type: JVxeTypes.input },
      { key: 'type', title: '船舶分类', width: '120px', type: JVxeTypes.input },
      { key: 'port_area', title: '所属港区', minWidth: '120px', type: JVxeTypes.input },
    ] as JVxeColumn[],
  });

  // form表单 col
  const labelCol = reactive({ span: 4 });
  const wrapperCol = reactive({ span: 20 });
  const rules = reactive({
    num: [{ required: true, message: '必须输入序号' }],
  });

  // 查询url地址
  enum Api {
    getData = '/mock/vxe/getData',
  }

  loadData();

  // 加载数据
  function loadData() {
    // 封装查询条件
    // 调用查询数据接口
    loading.value = true;
    defHttp
      .get({
        url: Api.getData,
        params: {
          pageNo: 1,
          pageSize: 30,
        },
      })
      .then((result) => {
        // 将查询的数据赋值给 dataSource
        dataSource.value = result.records;
        // 重置选择
        selectedRows.value = [];
      })
      .finally(() => {
        // 这里是无论成功或失败都会执行的方法,在这里关闭loading
        loading.value = false;
      });
  }

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

  // 详细信息里点了确认按钮
  function handleDetailsConfirm({ row, $table, callback }) {
    console.log('保存的数据:', row);
    // 校验当前行
    $table.validate(row).then((errMap) => {
      // 校验通过
      if (!errMap) {
        // 校验子表,如果需要的话,可以操作下面这个对象:
        callback(true);
        loading.value = true;
        setTimeout(() => {
          loading.value = false;
          createMessage.success('保存成功');
        }, 1000);
      } else {
        callback(false);
        createMessage.warn('校验失败');
      }
    });
  }
</script>

<style scoped></style>