gaoluyang
2026-08-06 377c0a70c094d024aeb0bb94f4b791c6d5530c1e
src/views/safeProduction/safetyTrainingAssessment/detail.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,323 @@
<template>
  <div class="app-container">
    <PageHeader content="培训记录">
    </PageHeader>
    <div class="search_form">
      <div class="search_item">
        <span class="search_title">人员名称:</span>
        <el-input v-model="searchForm.searchText"
                  style="width: 240px"
                  placeholder="输入客户名称搜索"
                  @change="searchName"
                  clearable
                  prefix-icon="Search" />
        <el-button type="primary"
                   @click="searchName"
                   style="margin-left: 10px">搜索</el-button>
      </div>
      <div class="search_item">
        <span class="search_title">年份:</span>
        <el-date-picker v-model="searchForm.invoiceDate"
                        type="year"
                        @change="searchDate"
                        placeholder="选择年">
        </el-date-picker>
        <el-button type="primary"
                   @click="searchDate"
                   style="margin-left: 10px">搜索</el-button>
        <el-button type="primary"
                   @click="exportData"
                   style="margin-left: 20px;margin-right: 20px">导出</el-button>
      </div>
    </div>
    <div style="display: flex">
      <div class="table_list">
        <el-table :data="tableData"
                  border
                  v-loading="tableLoading"
                  :row-key="(row) => row.id"
                  @row-click="rowClickMethod"
                  height="calc(100vh - 18.5em)">
          <el-table-column align="center"
                           label="序号"
                           type="index"
                           width="60" />
          <el-table-column label="名称"
                           prop="nickName"
                           show-overflow-tooltip
                           width="200" />
          <el-table-column label="所属部门"
                           prop="deptNames"
                           show-overflow-tooltip
                           width="200" />
          <el-table-column label="联系方式"
                           prop="phonenumber"
                           show-overflow-tooltip
                           width="200" />
          <!-- <el-table-column label="email"
                           prop="email"
                           show-overflow-tooltip
                           width="200" /> -->
          <!-- <el-table-column label="应收金额(元)"
                           prop="unReceiptPaymentAmount"
                           show-overflow-tooltip
                           width="200">
            <template #default="{ row, column }">
              <el-text type="danger">
                {{ formattedNumber(row, column, row.unReceiptPaymentAmount) }}
              </el-text>
            </template>
          </el-table-column> -->
        </el-table>
        <pagination v-show="total > 0"
                    :total="total"
                    layout="total, sizes, prev, pager, next, jumper"
                    :page="page.current"
                    :limit="page.size"
                    @pagination="paginationChange" />
      </div>
      <div class="table_list">
        <el-table :data="receiptRecord"
                  border
                  :row-key="(row) => row.id"
                  height="calc(100vh - 18.5em)">
          <el-table-column align="center"
                           label="序号"
                           type="index"
                           width="60" />
          <el-table-column label="培训日期"
                           prop="trainingDate"
                           show-overflow-tooltip />
          <el-table-column label="培训内容"
                           prop="trainingContent"
                           show-overflow-tooltip />
          <el-table-column label="培训课时"
                           prop="classHour"
                           show-overflow-tooltip />
          <el-table-column label="考核结果"
                           prop="examinationResults"
                           show-overflow-tooltip>
            <template #default="{ row }">
              <el-tag :type="row.examinationResults === '合格' ? 'success' : 'danger'">
                {{ row.examinationResults }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>
      </div>
    </div>
  </div>
</template>
<script setup>
  import { onMounted, ref } from "vue";
  import Pagination from "@/components/PIMTable/Pagination.vue";
  import {
    safeTrainingDetailListPage,
    safeTrainingDetailExport,
  } from "@/api/safeProduction/safetyTrainingAssessment.js";
  import { userListNoPage } from "@/api/system/user.js";
  const { proxy } = getCurrentInstance();
  const tableData = ref([]);
  const receiptRecord = ref([]);
  const tableLoading = ref(false);
  const page = reactive({
    current: 1,
    size: 100,
  });
  const recordPage = reactive({
    current: 1,
    size: 100,
  });
  const total = ref(0);
  const recordTotal = ref(0);
  const data = reactive({
    searchForm: {
      searchText: "",
      invoiceDate: "",
    },
  });
  const customerId = ref("");
  const { searchForm } = toRefs(data);
  const originReceiptRecord = ref([]);
  // æŸ¥è¯¢åˆ—表
  /** æœç´¢æŒ‰é’®æ“ä½œ */
  const handleQuery = () => {
    page.current = 1;
    getList();
  };
  const paginationChange = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  const tableDataCopy = ref([]);
  const getList = () => {
    tableLoading.value = true;
    userListNoPage({}).then(res => {
      console.log("res", res.data);
      tableData.value = res.data;
      tableDataCopy.value = res.data;
      if (tableData.value.length > 0) {
        customerId.value = tableData.value[0].userId;
        receiptPaymentList(customerId.value);
        tableLoading.value = false;
      }
    });
  };
  const exportData = () => {
    safeTrainingDetailExport({
      userId: customerId.value,
    })
      .then(res => {
        // åˆ›å»ºBlob对象
        const blob = new Blob([res], {
          type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        });
        // åˆ›å»ºä¸‹è½½é“¾æŽ¥
        const url = window.URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = url;
        link.download = `记录详情_${tableData.value[0].nickName}.docx`;
        // æ¨¡æ‹Ÿç‚¹å‡»ä¸‹è½½
        document.body.appendChild(link);
        link.click();
        // æ¸…理临时对象
        setTimeout(() => {
          document.body.removeChild(link);
          window.URL.revokeObjectURL(url);
        }, 100);
        ElMessage.success("导出成功");
      })
      .catch(err => {
        console.error("导出失败:", err);
        ElMessage.error("导出失败,请重试");
      });
  };
  const formattedNumber = (row, column, cellValue) => {
    return parseFloat(cellValue).toFixed(2);
  };
  // ä¸»è¡¨åˆè®¡æ–¹æ³•
  const summarizeMainTable = param => {
    return proxy.summarizeTable(
      param,
      ["invoiceTotal", "receiptPaymentAmount", "unReceiptPaymentAmount"],
      {
        ticketsNum: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
        futureTickets: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
      }
    );
  };
  // å­è¡¨åˆè®¡æ–¹æ³•
  const summarizeMainTable1 = param => {
    var summarizeTable = proxy.summarizeTable(
      param,
      ["invoiceAmount", "receiptAmount", "unReceiptAmount"],
      {
        ticketsNum: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
        futureTickets: { noDecimal: true }, // ä¸ä¿ç•™å°æ•°
      }
    );
    // å–最后一行数据;
    if (receiptRecord.value?.length > 0) {
      const index = tableData.value.findIndex(
        item => item.id == customerId.value
      );
      summarizeTable[summarizeTable.length - 1] =
        tableData.value[index].unReceiptPaymentAmount.toFixed(2);
    } else {
      summarizeTable[summarizeTable.length - 1] = 0.0;
    }
    return summarizeTable;
  };
  const goBack = () => {
    proxy.$router.push({
      path: "/safeProduction/safetyTrainingAssessment",
    });
  };
  const searchName = () => {
    tableData.value = tableDataCopy.value;
    if (searchForm.value.searchText) {
      tableData.value = tableData.value.filter(item =>
        item.nickName.includes(searchForm.value.searchText)
      );
      customerId.value = tableData.value[0].userId;
    }
    receiptPaymentList(customerId.value);
  };
  const dateFormat = (date, format = "yyyy-MM-dd") => {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, "0");
    const day = String(date.getDate()).padStart(2, "0");
    return format.replace("yyyy", year).replace("MM", month).replace("dd", day);
  };
  const searchDate = () => {
    receiptRecord.value = originReceiptRecordCopy.value;
    console.log("searchForm.value.invoiceDate", searchForm.value.invoiceDate);
    if (searchForm.value.invoiceDate) {
      const year = dateFormat(searchForm.value.invoiceDate, "yyyy");
      receiptRecord.value = receiptRecord.value.filter(item => {
        console.log("item.trainingDate", item.trainingDate);
        return item.trainingDate.includes(year);
      });
    }
  };
  const originReceiptRecordCopy = ref([]);
  const receiptPaymentList = id => {
    const param = {
      userId: id,
    };
    console.log("param", param);
    safeTrainingDetailListPage(param).then(res => {
      originReceiptRecord.value = res.data.records;
      handlePagination({ page: 1, limit: recordPage.size });
      recordTotal.value = res.data.length;
    });
  };
  // æ±‡æ¬¾è®°å½•列表分页
  const recordPaginationChange = pagination => {
    handlePagination(pagination);
  };
  const rowClickMethod = row => {
    customerId.value = row.userId;
    receiptPaymentList(customerId.value);
  };
  const handlePagination = ({ page, limit }) => {
    recordPage.current = page;
    recordPage.size = limit;
    const start = (page - 1) * limit;
    const end = start + limit;
    receiptRecord.value = originReceiptRecord.value.slice(start, end);
    originReceiptRecordCopy.value = originReceiptRecord.value.slice(start, end);
  };
  onMounted(() => {
    getList();
  });
</script>
<style scoped lang="scss">
  .table_list {
    width: 50%;
  }
  .search_back {
    cursor: pointer;
    color: #0f497e;
  }
  .search_item {
    width: 50%;
    display: flex;
    align-items: center;
    justify-content: flex-start;
    margin-right: 20px;
  }
</style>