index.vue 12.6 KB
<template>
  <div class="app-container">
    <div class="query-from">
      <el-form :inline="true" :rules="rules" :model="fromParams" class="demo-form-inline">
        <el-form-item label="报表日期" props="date">
          <!-- 日期 -->
          <el-date-picker style="width: 130px;" v-model="fromParams.date" type="date" align="right" unlink-panels
            format="YYYY/MM/DD" value-format="YYYY-MM-DD"></el-date-picker>
        </el-form-item>
        <el-form-item label="工号" props="jobCode">
          <el-input style="width: 120px;" v-model="fromParams.jobCode" placeholder="请输入工号" clearable
            @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="姓名" props="name">
          <el-input style="width: 120px;" v-model="fromParams.name" placeholder="请输入姓名" clearable
            @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="执行线路" props="lineName">
          <el-input style="width: 120px;" v-model="fromParams.lineName" placeholder="请输入执行线路" clearable
            @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="超时15分钟过滤" props="stage">
          <el-select style="width: 120px;" v-model="fromParams.stage" placeholder="请选择过滤条件">
            <el-option v-for="dict in filter_status" :key="dict.value" :label="dict.label" :value="dict.value" />
          </el-select>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onQuery">查询</el-button>
        </el-form-item>
        <el-form-item>
          <el-button type="primary" @click="onExportDateType('date')">按天导出</el-button>
          <el-button type="primary" @click="onExportDateType('month')">按月导出</el-button>
          <el-button type="primary" @click="onExportDateBySplit">按照时间段导出</el-button>
        </el-form-item>

        <el-form-item>
          <el-tooltip effect="dark" content="今天的报表请在隔天2:30后导出,签到数据最为完善。可以通过查看详情直接看到员工的签到情况。" placement="right"><el-icon>
              <QuestionFilled />
            </el-icon></el-tooltip>
        </el-form-item>
      </el-form>
    </div>


    <el-table v-loading="loading" :data="tableData" @selection-change="handleSelectionChange" border max-height="600"
      :default-expand-all="false" :row-class-name="tableRowClassName">
      <el-table-column label="序号" type="index" width="60" align="center">
        <template #default="scope">
          {{ (currentPage - 1) * size + scope.$index + 1 }}
        </template>
      </el-table-column>
      <el-table-column label="工号" align="center" prop="jobCode" width="100" />
      <el-table-column label="姓名" align="center" prop="name" />
      <el-table-column label="工种" align="center" prop="posts" sortable />
      <el-table-column label="部门" align="center" prop="fleetName" sortable />
      <el-table-column label="线路" align="center" prop="lineName" width="130" sortable />
      <el-table-column label="路牌" align="center" prop="lpName" sortable />
      <el-table-column label="车辆自编号" align="center" prop="nbbm" width="120" sortable />
      <el-table-column label="应签到次数" align="center" prop="planSignInCount" width="120" />
      <el-table-column label="实际签到次数" align="center" prop="actualSignInCount" width="120" />
      <el-table-column label="应签退次数" align="center" prop="planSignOutCount" width="120" />
      <el-table-column label="实际签退次数" align="center" prop="actualSignOutCount" width="120" />
      <el-table-column label="有无异常" align="center" prop="exString" sortable>
        <template #default="scope">
          <el-tag class="ml-2" type="success" v-if="scope.row.exString == '无异常'">{{ scope.row.exString }}</el-tag>
          <el-tag class="ml-2" type="danger" v-else>{{ scope.row.exString }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="排班日期" align="center" prop="scheduleDate" width="180" sortable />
      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" fixed="right" width="160">
        <template #default="scope">
          <el-button link type="primary" icon="Edit" @click="handleQueryDetail(scope.row)">查看详情</el-button>
        </template>
      </el-table-column>
    </el-table>


    <div style=" padding: 32px 16px; ">
      <div style="position: absolute;right: 0;">
        <el-pagination class="page" v-model:current-page="currentPage" v-model:page-size="size" :page-sizes="pageSizes"
          layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="handleSizeChange"
          @current-change="handleCurrentChange" />
      </div>
    </div>



    <el-dialog :title="title" v-model="open" width="1080px" append-to-body>
      <el-table v-loading="detailLoading" :data="detailList" border :default-expand-all="false">
        <el-table-column label="工号" align="center" prop="jobCode" fixed="left" />
        <el-table-column label="姓名" align="center" prop="name" fixed="left" />
        <el-table-column label="工种" align="center" prop="posts" />
        <el-table-column label="部门" align="center" prop="fleetName" />
        <el-table-column label="线路" align="center" prop="lineName" />
        <el-table-column label="路牌" align="center" prop="lpName" />
        <el-table-column label="车辆自编号" align="center" prop="nbbm" width="130" />
        <el-table-column label="打卡场地" align="center" prop="siteName" width="182" />
        <el-table-column label="计划操作" align="center" prop="planAction" />
        <el-table-column label="实际操作" align="center" prop="actualAction">
          <template #default="scope">
            <el-tag class="ml-2" type="success" v-if="scope.row.actualAction != null">{{ scope.row.actualAction
              }}</el-tag>
            <el-tag class="ml-2" type="danger" v-else>{{ scope.row.planAction == "签到" ? "未签到" : "未签退" }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="计划打卡" align="center" prop="planTime" width="180" />
        <el-table-column label="实际打卡" align="center" prop="actualTime" width="180" />
        <el-table-column label="酒精测试" align="center" prop="alcoholString" />
        <el-table-column label="有无异常" align="center" prop="exString">
          <template #default="scope">
            <el-tag class="ml-2" type="success" v-if="scope.row.exString == '无异常'">{{ scope.row.exString
              }}</el-tag>
            <el-tag class="ml-2" type="danger" v-else>{{ scope.row.exString }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="原因" align="center" fixed="right" prop="remark" width="300" />
      </el-table>
    </el-dialog>


    <el-dialog title="请选择导出日期" v-model="openDateFlag" width="1080px" append-to-body>
      <el-form>
        <el-form-item label="日期">
          <el-date-picker v-model="exportDate" :format="exportFormat == 'month' ? 'YYYY-MM' : 'YYYY-MM-DD'"
            :value-format="exportFormat == 'month' ? 'YYYY-MM' : 'YYYY-MM-DD'" :type="exportFormat"
            placeholder="选择导出日期" />
        </el-form-item>
      </el-form>
      <el-button type="primary" @click="onExport()">导出</el-button>
    </el-dialog>

    <el-dialog title="选择导出时间段" v-model="openDateSplitFlag" width="1080px" append-to-body>
      <el-form :model="exportDatePrams">
        <el-form-item label="日期">
          <el-date-picker v-model="exportDatePrams.startDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" type="date"
            placeholder="选择开始日期" />
        </el-form-item>
        <el-form-item label="日期">
          <el-date-picker v-model="exportDatePrams.endDate" format="YYYY-MM-DD" value-format="YYYY-MM-DD" type="date"
            placeholder="选择结束日期" />
        </el-form-item>
      </el-form>
      <el-button type="primary"
        @click="exportByTimePeriod(exportDatePrams.startDate, exportDatePrams.endDate)">导出</el-button>
    </el-dialog>
  </div>
</template>

<script setup>
import { getReportDetail, getReportList } from "@/api/report/report.js";
import moment from "moment";
import { nextTick, onMounted, ref } from "vue";
const { proxy } = getCurrentInstance();
const { filter_status, sign_type, sign_in, alcohol } = proxy.useDict('filter_status', 'sign_type', 'sign_in', 'alcohol');
const fromParams = ref({});
const open = ref(false);
const inList = ref([]);
const detailList = ref([]);
const loading = ref(false);
const detailLoading = ref(false);
const ids = ref([]);
const title = ref('打卡详情')
const page = ref(1) //第几页
const size = ref(10) //一页多少条
const total = ref(0); //总条目数
const pageSizes = [5, 10, 20, 50]; //每页显示多少条
const tableData = ref([]) // 表格数据
const currentPage = ref(1) // 当前页
const exportDate = ref()
const exportFormat = ref("date")
const exportDatePrams = ref({
  startDate: "",
  endDate: ""
})
const openDateFlag = ref(false)
const openDateSplitFlag = ref(false)

const rules = ref({
  date: [
    { required: true, message: "报表日期不能为空", trigger: "blur" }
  ]
})
// 默认当天
nextTick(() => {
  // date默认当天
  fromParams.value.date = moment().format("YYYY-MM-DD");
})
const handleQuery = () => {
  getList();
};
const tableRowClassName = ({
  row
}) => {
  if (row.exString == '有异常') {
    return 'warning-row'
  } else {
    return ''
  }
}


onMounted(() => {
  fromParams.value.stage = "0";
  const currentTime = moment().format('HH:mm');
  if (currentTime < '02:30') {
    fromParams.value.date = moment().subtract(1, 'day').format('YYYY-MM-DD');
  } else {
    fromParams.value.date = moment().format("YYYY-MM-DD");
  }
  getList(); // 初始化列表数据

});

const getList = () => {
  loading.value = true;
  getReportList({
    jobCode: fromParams.value.jobCode ? fromParams.value.jobCode : "",
    date: fromParams.value.date ? fromParams.value.date : "",
    name: fromParams.value.name ? fromParams.value.name : "",
    lineName: fromParams.value.lineName ? fromParams.value.lineName : "",
    exportFlag: 0,
    stage: fromParams.value.stage
  }).then((res) => {
    inList.value = res.data
    loading.value = false;
    getTableData();
  });
};

const getTableData = () => {
  //inList为全部数据
  tableData.value = inList.value.slice(
    (page.value - 1) * size.value,
    page.value * size.value
  );
  total.value = inList.value.length;
}

const handleSizeChange = (val) => {
  size.value = val;
  getTableData();
}
const handleCurrentChange = (val) => {
  page.value = val;
  getTableData();
}

const onQuery = () => {
  getList();
};


const handleSelectionChange = (val) => {
  ids.value = val.map(item => item.id)
}
const handleQueryDetail = (val) => {
  reset();
  open.value = true;
  detailLoading.value = true;
  getReportDetail({
    jobCode: val.jobCode,
    date: val.scheduleDate
  }).then((res) => {
    detailList.value = res.data
    detailLoading.value = false;
  });
}
const reset = () => {
  detailList.value = [];
}
// 导出
const onExport = () => {
  // exportReportList({}).then((res) => {
  //   console.log(res)
  // } ,`in_${new Date().getTime()}.xlsx`);
  // console.log("导出");
  if (!exportDate.value) {
    proxy.$message({
      message: '请选择日期',
      type: 'warning'
    })
    return
  }
  let namePre = exportFormat.value === 'date' ? exportDate.value : exportDate.value + '-01';
  console.log(namePre);
  proxy.download('report/export', {
    date: namePre,
    exportFlag: exportFormat.value === 'date' ? 1 : 2
  }, `${exportDate.value}签到报表.xlsx`)

}

/**
 * 按照时间段导出
 * @param {string} startDate
 * @param {string} endDate
 */
const exportByTimePeriod = (startDate, endDate) => {
  // 校验日期
  if (!startDate || !endDate) {
    proxy.$message({
      message: '请选择日期',
      type: 'warning'
    })
    return
  }
  proxy.download('report/export', {
    startDate,
    endDate,
    exportFlag: 3
  }, `${startDate}到${endDate}的签到报表.xlsx`, {
    timeout: 300000
  })

}

const onExportDateBySplit = () => {
  openDateSplitFlag.value = true
  exportDatePrams.value.startDate = ''
  exportDatePrams.value.endDate = ''
}

const onExportDateType = (val) => {
  openDateFlag.value = true
  exportFormat.value = val
  exportDate.value = ''
}
</script>

<style>
.el-table .warning-row {
  --el-table-tr-bg-color: var(--el-color-danger-light-9);
}

.el-table .success-row {
  --el-table-tr-bg-color: var(--el-color-success-light-9);
}
</style>