el-table行合并,根据后端数据计算哪些行要合并,且有两列需要处理

发布于:2025-08-01 ⋅ 阅读:(17) ⋅ 点赞:(0)

<template>
  <el-dialog
    v-model="drawerVisible"
    :destroy-on-close="true"
    fullscreen
    :title="`${drawerProps.title}`"
    class="m-fullscreen-dialog"
  >
    <div class="table-box">
      <ProTable
        ref="proTable"
        :columns="columns"
        :request-api="getTableList"
        :init-param="initParam"
        :data-callback="dataCallback"
        :pagination="true"
        :span-method="objectSpanMethod"
      >
        <template #tableHeader> </template>
        <template #operation="scope">
          <el-button type="primary" link @click="handleDialogTable1(scope.row)">日志</el-button>
          <el-button type="primary" link @click="handleDetail(scope.row)">详情</el-button>
        </template>
      </ProTable>
    </div>
    <DetailDialog ref="detailDialogRef"></DetailDialog>
    <DialogTable1 ref="dialogTable1Ref"></DialogTable1>
  </el-dialog>
</template>

<script setup lang="tsx" name="UserDrawer">
import { ref, reactive, nextTick } from "vue";
import { ElMessage, FormInstance } from "element-plus";
import { User } from "@/api/interface";
import { ColumnProps } from "@/components/ProTable/interface";
import moment from "moment";
import { useHandleData } from "@/hooks/useHandleData";
import { roleExport } from "@/api/modules/authCenter/permission";
import { useDownload } from "@/utils/useDownload";
import ProTable from "@/components/ProTable/index.vue";
import { deleteUser, getUserGender } from "@/api/modules/user";
import DetailDialog from "./DetailDialog.vue";
//@ts-ignore
import DialogTable1 from "./DialogTable1.vue";
import { getDailyMeetingListByPage } from "@/api/modules/productionAndOperation/scheduleManagement";
import { getDictByCodeList } from "@/utils/tools";

interface DrawerProps {
  title: string;
  isView: boolean;
  row: Partial<User.ResUserList>;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
}

//#region 配置
const proTable = ref<any>();
const initParam = reactive({ type: 1 });
const detailDialogRef: any = ref(null);
const dialogTable1Ref: any = ref(null);

const handleGetProfessionalCompany = async () => {
  let dictList = await getDictByCodeList(["sys_professional_company_list", "table2"]);
  let result = dictList["sys_professional_company_list"];
  // professionalCompanyList.value = result;

  return {
    code: 200,
    data: result,
    msg: "成功"
  };
};

const handleGetWorkType = async () => {
  return {
    code: 200,
    data: [
      {
        label: "新增事项",
        value: "0"
      },
      {
        label: "滚动更新",
        value: "1"
      }
    ],
    msg: "成功"
  };
};

const handleGetCompletionStatus = async () => {
  return {
    code: 200,
    data: [
      {
        label: "持续跟踪",
        value: "0"
      },
      {
        label: "已完成",
        value: "1"
      }
    ],
    msg: "成功"
  };
};

const columns = reactive<ColumnProps<User.ResUserList>[]>([
  {
    prop: "meetingDate",
    label: "例会日期",
    width: 200,
    search: {
      span: 2,
      render: ({ searchParam }) => {
        return (
          <el-date-picker
            vModel_trim={searchParam.daterangeValue}
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style={{ maxWidth: "300px" }}
          />
        );
      },
      defaultValue: ["2025-04-18", "2025-04-20"]
    }
  },

  {
    prop: "professionalCompany",
    label: "专业公司",
    enum: handleGetProfessionalCompany,
    search: { el: "select", props: { filterable: true } },
    fieldNames: { label: "label", value: "value" },
    width: 200
  },
  {
    prop: "workType",
    label: "工作类型",
    enum: handleGetWorkType,
    fieldNames: { label: "label", value: "value" }
  },
  {
    prop: "itemContent",
    label: "议定事项内容",
    minWidth: 200
  },
  {
    prop: "implementationStatus",
    label: "落实情况",
    minWidth: 200
  },
  {
    prop: "startTime",
    label: "开始时间",
    minWidth: 200
  },
  {
    prop: "endTime",
    label: "结束时间",
    minWidth: 200
  },
  {
    prop: "completionStatus",
    label: "完成情况",
    enum: handleGetCompletionStatus,
    fieldNames: { label: "label", value: "value" }
  },
  {
    prop: "createTime",
    label: "开始/结束时间",
    isShow: false,
    width: 200,
    search: {
      span: 2,
      render: ({ searchParam }) => {
        return (
          <el-date-picker
            vModel_trim={searchParam.daterangeValue}
            type="daterange"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            style={{ maxWidth: "300px" }}
          />
        );
      },
      defaultValue: ["2025-04-18", "2025-04-20"]
    }
  },
  {
    prop: "content",
    label: "搜索",
    isShow: false,
    search: { el: "input", label: "搜索", props: { placeholder: "请输入内容" } }
  },

  { prop: "operation", label: "操作", fixed: "right", width: 200 }
]);
const drawerVisible = ref(false);
const drawerProps = ref<any>({
  isView: false,
  title: "",
  row: {}
});
// 接收父组件传过来的参数
const acceptParams = (params: DrawerProps) => {
  drawerProps.value = params;
  drawerVisible.value = true;
  nextTick(() => {});
};

//#endregion

//#region 列表

const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
  if (columnIndex === 0) {
    console.log("0", row);
    if (row.branchNameIndex === 1) {
      return {
        rowspan: row.count,
        colspan: 1
      };
    } else {
      return {
        rowspan: 0,
        colspan: 0
      };
    }
  }

  if (columnIndex === 1) {
    console.log("1", row);

    if (row.branchNameIndex2 === 1) {
      return {
        rowspan: row.count2,
        colspan: 1
      };
    } else {
      return {
        rowspan: 1,
        colspan: 0
      };
    }
  }
};
const dataCallback = (data: any) => {
  return {
    list: data.list,
    total: data.total
  };
};

let obj = {};
const formatData = (list: any) => {
  list.forEach((item: any) => {
    let count = list.filter((listItem: any) => listItem.meetingDate === item.meetingDate).length;
    if (obj[item.meetingDate]) {
      obj[item.meetingDate]++;
    } else {
      obj[item.meetingDate] = 1;
    }
    let count2 = list
      .filter((listItem: any) => listItem.meetingDate === item.meetingDate)
      .filter((listItem: any) => listItem.professionalCompany === item.professionalCompany).length;
    if (obj[item.meetingDate + item.professionalCompany]) {
      obj[item.meetingDate + item.professionalCompany]++;
    } else {
      obj[item.meetingDate + item.professionalCompany] = 1;
    }
    item.branchNameIndex = obj[item.meetingDate];
    item.branchNameIndex2 = obj[item.meetingDate + item.professionalCompany];

    item.count = count;
    item.count2 = count2;
  });

  return list;
};

const formatData2 = (list: any) => {
  list.forEach((item: any) => {
    let count = list.filter((listItem: any) => listItem.professionalCompany === item.professionalCompany).length;
    if (obj[item.professionalCompany]) {
      obj[item.professionalCompany]++;
    } else {
      obj[item.professionalCompany] = 1;
    }
    item.branchNameIndex2 = obj[item.professionalCompany];

    item.count2 = count;
  });

  return list;
};

const getTableList = async (params: any) => {
  if (typeof params.datePicker === "object") {
    console.log("日期", moment(params.datePicker).format("YYYY-MM-DD"));
  }
  if (typeof params.daterangeValue === "object") {
    console.log(
      "日期范围",
      moment(params.daterangeValue[0]).format("YYYY-MM-DD"),
      moment(params.daterangeValue[1]).format("YYYY-MM-DD")
    );
  }
  console.log("params", params);

  let newParams = {
    content: params.content,
    professionalCompany: params.professionalCompany,
    pageNum: params.pageNum,
    pageSize: params.pageSize
  };
  let res: any = await getDailyMeetingListByPage(newParams);

  obj = {};
  let data = formatData([...res.data.records]);
  // data = formatData2(data);

  let list = data.map((item: any, index: any) => {
    return {
      ...item,
      number: index + 1 + (params.pageNum - 1) * params.pageSize
    };
  });
  res = {
    code: 200,
    msg: "成功",
    data: {
      list,
      pageNum: 1,
      pageSize: 10,
      total: res.data.total - 0
    }
  };

  return res;
};

const deleteAccount = async (params: User.ResUserList) => {
  proTable.value?.getTableList();
};

//#endregion

//#region 工具条
const editUser = (values: any) => {
  console.log("edit", values);
  proTable.value?.clearSelection();
};
const handleExport = async () => {
  let res = await roleExport(proTable.value.searchParam);
  if (res) {
    useDownload(res, "国际油价走势表");
  } else {
    ElMessage.warning("没有要导出的内容");
  }
};

const handleDetail = (row: any) => {
  row = {
    isView: false,
    row: { ...row },
    api: editUser,
    getTableList: proTable.value?.getTableList
  };
  detailDialogRef.value?.acceptParams(params);
};

const handleDialogTable1 = (row: any) => {
  const params = {
    title: "日志",
    isView: false,
    row: {},
    api: undefined,
    getTableList: undefined
  };
  dialogTable1Ref.value?.acceptParams(params);
};

//#endregion

defineExpose({
  acceptParams
});
</script>

<style scoped lang="scss">
.m-chart {
  height: 650px;
  width: 100%;
  margin: 10px 0 0 0;
}
</style>


网站公告

今日签到

点亮在社区的每一天
去签到