1498 lines
51 KiB
Vue
1498 lines
51 KiB
Vue
<template>
|
||
<div class="app-container" id="monthReport">
|
||
<el-radio-group
|
||
v-model="tabIndex"
|
||
size="medium"
|
||
style="margin-bottom: 10px"
|
||
>
|
||
<el-radio-button label="考勤报表"></el-radio-button>
|
||
<el-radio-button label="异常考勤统计"></el-radio-button>
|
||
</el-radio-group>
|
||
<!-- 考勤率页面 -->
|
||
<div v-show="tabIndex === '考勤报表'">
|
||
<el-form
|
||
:model="queryParams"
|
||
ref="queryForm"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="auto"
|
||
>
|
||
<el-form-item label="选择月份">
|
||
<el-date-picker
|
||
v-model="queryParams.month"
|
||
type="monthrange"
|
||
range-separator="至"
|
||
start-placeholder="开始月份"
|
||
end-placeholder="结束月份"
|
||
value-format="yyyy-MM"
|
||
:clearable="false"
|
||
:editable="false"
|
||
style="width: 240px"
|
||
>
|
||
</el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item label="部门" prop="orgIdList">
|
||
<treeselect
|
||
v-model="queryParams.orgIdList"
|
||
:options="deptOptions"
|
||
:normalizer="normalizer"
|
||
multiple
|
||
placeholder="选择部门"
|
||
style="width: 240px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="姓名" prop="userName">
|
||
<el-input
|
||
v-model="queryParams.userName"
|
||
placeholder="请输入姓名"
|
||
clearable
|
||
style="width: 240px"
|
||
@keyup.enter.native="handleQuery"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="外勤预警" prop="outside">
|
||
<el-select
|
||
v-model="queryParams.outside"
|
||
placeholder="选择外勤预警"
|
||
style="width: 240px"
|
||
>
|
||
<el-option label="是" value="预警" />
|
||
<el-option label="否" value="未预警" />
|
||
</el-select>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="handleQuery"
|
||
>搜索</el-button
|
||
>
|
||
<el-button
|
||
icon="el-icon-refresh"
|
||
size="mini"
|
||
@click="resetQuery"
|
||
>重置</el-button
|
||
>
|
||
</el-form-item>
|
||
</el-form>
|
||
<el-row :gutter="10" class="mb8">
|
||
<el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExport"
|
||
v-hasPermi="['att:attMonthReport:export']"
|
||
>导出
|
||
</el-button>
|
||
</el-col>
|
||
|
||
<!-- <el-col :span="1.5">
|
||
<el-button
|
||
type="warning"
|
||
plain
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="handleDays"
|
||
v-hasPermi="['system:user:admin']"
|
||
>更新应出勤天数
|
||
</el-button>
|
||
|
||
<el-button
|
||
type="primary"
|
||
plain
|
||
icon="el-icon-date"
|
||
size="mini"
|
||
@click="onHandleYearData"
|
||
>年数据
|
||
</el-button>
|
||
</el-col> -->
|
||
|
||
<right-toolbar
|
||
:showSearch.sync="showSearch"
|
||
@queryTable="getList"
|
||
></right-toolbar>
|
||
</el-row>
|
||
|
||
<el-table v-loading="loading" :data="typeList">
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryParams.pageNum - 1) * queryParams.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
align="center"
|
||
:key="item.prop"
|
||
:prop="item.prop"
|
||
:label="item.label"
|
||
v-for="item in mainListFields"
|
||
>
|
||
<template #header>
|
||
<span v-if="item.label === '外勤次数'">
|
||
外勤次数
|
||
<el-tooltip
|
||
effect="dark"
|
||
placement="top"
|
||
content="大于5天为外勤预警"
|
||
>
|
||
<i class="el-icon-info" />
|
||
</el-tooltip>
|
||
</span>
|
||
|
||
<span v-else>
|
||
{{ item.label }}
|
||
</span>
|
||
</template>
|
||
<template slot-scope="scope">
|
||
<span
|
||
v-if="item.needShow"
|
||
style="color: #02a7f0; cursor: pointer"
|
||
@click="openRecord(scope.row, item.type)"
|
||
>
|
||
{{ scope.row[item.prop] }}
|
||
</span>
|
||
<span v-else>{{ scope.row[item.prop] }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="total > 0"
|
||
:total="total"
|
||
:page.sync="queryParams.pageNum"
|
||
:limit.sync="queryParams.pageSize"
|
||
@pagination="getList"
|
||
/>
|
||
</div>
|
||
|
||
<div v-show="tabIndex === '异常考勤统计'">
|
||
<el-form
|
||
:model="queryParamsAbnormal"
|
||
ref="queryFormAbnormal"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="auto"
|
||
>
|
||
<el-form-item label="年份">
|
||
<el-date-picker
|
||
clearable
|
||
type="year"
|
||
value-format="yyyy"
|
||
placeholder="请选择年份"
|
||
v-model="queryParamsAbnormal.year"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="月份">
|
||
<el-date-picker
|
||
clearable
|
||
type="month"
|
||
value-format="yyyy-MM"
|
||
placeholder="请选择月份"
|
||
v-model="queryParamsAbnormal.attCurrentMonth"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="部门" prop="orgIdList">
|
||
<treeselect
|
||
v-model="queryParamsAbnormal.orgIdList"
|
||
:options="deptOptions"
|
||
:normalizer="normalizer"
|
||
multiple
|
||
placeholder="选择部门"
|
||
style="width: 240px"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item label="姓名" prop="userName">
|
||
<el-input
|
||
v-model="queryParamsAbnormal.userName"
|
||
placeholder="请输入姓名"
|
||
clearable
|
||
style="width: 240px"
|
||
@keyup.enter.native="handleQueryAbnormal"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="handleQueryAbnormal"
|
||
>
|
||
查询
|
||
</el-button>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="resetQueryAbnormal"
|
||
>
|
||
重置
|
||
</el-button>
|
||
|
||
<el-button
|
||
type="warning"
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExportAbnormal"
|
||
>
|
||
导出
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<el-table v-loading="loading" :data="abnormalList">
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryParamsAbnormal.pageNum - 1) *
|
||
queryParamsAbnormal.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
:label="item.label"
|
||
align="center"
|
||
:prop="item.prop"
|
||
v-for="item in abnormalListFields"
|
||
:key="item.prop"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span
|
||
v-if="item.needShow"
|
||
style="color: #02a7f0; cursor: pointer"
|
||
@click="openRecord(scope.row, item.type)"
|
||
>
|
||
{{ scope.row[item.prop] }}
|
||
</span>
|
||
<span v-else>{{ scope.row[item.prop] }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
</div>
|
||
|
||
<!-- 相关记录 -->
|
||
<el-dialog
|
||
:title="title"
|
||
width="1300px"
|
||
height="1000px"
|
||
append-to-body
|
||
@close="cancelRecord"
|
||
:visible.sync="showRecord"
|
||
>
|
||
<el-form
|
||
:model="queryRecord"
|
||
ref="queryFormRecord"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="110px"
|
||
>
|
||
<el-form-item label="选择考勤时间段">
|
||
<el-date-picker
|
||
v-model="dateRange"
|
||
style="width: 240px"
|
||
value-format="yyyy-MM-dd"
|
||
type="daterange"
|
||
range-separator="-"
|
||
start-placeholder="开始日期"
|
||
end-placeholder="结束日期"
|
||
:picker-options="pickerOptions"
|
||
></el-date-picker>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="handleQueryRecord"
|
||
>查询</el-button
|
||
>
|
||
<!-- <el-button icon="el-icon-refresh" size="mini" @click="resetRecord">重置</el-button>-->
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<el-table
|
||
:data="tableDataRecord"
|
||
width="900px"
|
||
height="600px"
|
||
row-key="id"
|
||
>
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryRecord.pageNum - 1) * queryRecord.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="id"
|
||
align="center"
|
||
prop="id"
|
||
v-if="false"
|
||
/>
|
||
<el-table-column
|
||
label="姓名"
|
||
align="center"
|
||
prop="name"
|
||
width="80"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="所属部门"
|
||
align="center"
|
||
prop="orgName"
|
||
width="150"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="考勤日期"
|
||
align="center"
|
||
prop="attCurrent"
|
||
width="150"
|
||
sortable
|
||
>\
|
||
<template slot-scope="scope">
|
||
<span>{{ formatDate(scope.row.attCurrent) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="上班打卡时间"
|
||
align="center"
|
||
prop="goWorkTime"
|
||
width="180"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="上班状态"
|
||
align="center"
|
||
prop="goWorkStatus"
|
||
width="100"
|
||
sortable
|
||
>
|
||
<template slot-scope="scope">
|
||
<dict-tag
|
||
:options="dict.type.att_status"
|
||
:value="scope.row.goWorkStatus"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="上班打卡地址"
|
||
align="center"
|
||
prop="goWorkAddress"
|
||
sortable
|
||
width="180"
|
||
/>
|
||
<el-table-column
|
||
label="下班打卡时间"
|
||
align="center"
|
||
prop="offWorkTime"
|
||
width="180"
|
||
ortable
|
||
/>
|
||
<el-table-column
|
||
label="下班状态"
|
||
align="center"
|
||
prop="offWorkStatus"
|
||
width="100"
|
||
sortable
|
||
>
|
||
<template slot-scope="scope">
|
||
<dict-tag
|
||
:options="dict.type.att_status"
|
||
:value="scope.row.offWorkStatus"
|
||
/>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="下班打卡地址"
|
||
align="center"
|
||
prop="offWorkAddress"
|
||
width="180"
|
||
sortable
|
||
/>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="totalTwo > 0"
|
||
:total="totalTwo"
|
||
:page.sync="queryRecord.pageNum"
|
||
:limit.sync="queryRecord.pageSize"
|
||
@pagination="getListRecord"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<!-- 外出次数查询 -->
|
||
<el-dialog
|
||
:title="title"
|
||
:visible.sync="showOutCount"
|
||
width="1200px"
|
||
height="1000px"
|
||
append-to-body
|
||
>
|
||
<el-form
|
||
:model="queryRecordOutCount"
|
||
ref="queryFormRecord"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="110px"
|
||
>
|
||
<el-form-item>
|
||
<el-button
|
||
type="warning"
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExportOutCountList"
|
||
>导出</el-button
|
||
>
|
||
</el-form-item>
|
||
</el-form>
|
||
|
||
<el-table
|
||
v-loading="loadingTwo"
|
||
:data="tableDataOutCount"
|
||
width="900px"
|
||
height="600px"
|
||
row-key="id"
|
||
>
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryRecordOutCount.pageNum - 1) *
|
||
queryRecordOutCount.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="考勤日期"
|
||
align="center"
|
||
prop="attCurrentDay"
|
||
width="180"
|
||
:show-overflow-tooltip="true"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{ formatDate(scope.row.attCurrentDay) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="打卡时间"
|
||
align="center"
|
||
prop="attCurrentTime"
|
||
width="140"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="打卡地址"
|
||
align="center"
|
||
prop="attAddress"
|
||
sortable
|
||
/>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="totalTwoOutCount > 0"
|
||
:total="totalTwoOutCount"
|
||
:page.sync="queryRecord.pageNum"
|
||
:limit.sync="queryRecord.pageSize"
|
||
@pagination="getOutCountList"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<!-- 打卡次数记录 -->
|
||
<el-dialog
|
||
:title="title"
|
||
:visible.sync="showAttCount"
|
||
width="1200px"
|
||
height="1000px"
|
||
append-to-body
|
||
>
|
||
<el-form
|
||
:model="queryAttCount"
|
||
ref="queryFormRecordAtt"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="110px"
|
||
>
|
||
<el-form-item> </el-form-item>
|
||
</el-form>
|
||
|
||
<el-table
|
||
v-loading="loadingAttCount"
|
||
:data="tableDataAttCount"
|
||
width="900px"
|
||
height="600px"
|
||
row-key="id"
|
||
>
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryAttCount.pageNum - 1) *
|
||
queryAttCount.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="考勤日期"
|
||
align="center"
|
||
prop="attCurrentDay"
|
||
:show-overflow-tooltip="true"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{ formatDate(scope.row.attCurrentDay) }}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="考勤时间"
|
||
align="center"
|
||
prop="attCurrentTime"
|
||
sortable
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
<el-table-column
|
||
label="打卡地址"
|
||
align="center"
|
||
prop="attAddress"
|
||
sortable
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
<el-table-column
|
||
label="备注"
|
||
align="center"
|
||
prop="remark"
|
||
sortable
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="totalAttCount > 0"
|
||
:total="totalAttCount"
|
||
:page.sync="queryAttCount.pageNum"
|
||
:limit.sync="queryAttCount.pageSize"
|
||
@pagination="getClockingRecordListByUserId"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<!-- 应出勤天数组成 -->
|
||
<el-dialog
|
||
:title="title"
|
||
:visible.sync="showRequiredDays"
|
||
width="1200px"
|
||
height="1000px"
|
||
append-to-body
|
||
>
|
||
<el-form
|
||
:model="queryRequiredDays"
|
||
ref="queryFormRecord"
|
||
size="small"
|
||
:inline="true"
|
||
v-show="showSearch"
|
||
label-width="110px"
|
||
>
|
||
</el-form>
|
||
|
||
<el-table
|
||
v-loading="loadingTwoRequiredDays"
|
||
:data="tableDataRequiredDays"
|
||
width="900px"
|
||
height="600px"
|
||
row-key="id"
|
||
>
|
||
<el-table-column
|
||
label="序号"
|
||
align="center"
|
||
width="80"
|
||
type="index"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
(queryRequiredDays.pageNum - 1) *
|
||
queryRequiredDays.pageSize +
|
||
scope.$index +
|
||
1
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="月份"
|
||
align="center"
|
||
prop="attCurrentMonth"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="应出勤天数"
|
||
align="center"
|
||
prop="attDays"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="所属考勤组"
|
||
align="center"
|
||
prop="groupName"
|
||
sortable
|
||
/>
|
||
<el-table-column
|
||
label="考勤规则"
|
||
align="center"
|
||
prop="attCurrentDay"
|
||
width="180"
|
||
:show-overflow-tooltip="true"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span>{{
|
||
parseAttendanceRule(scope.row.attRules)
|
||
}}</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column
|
||
label="节假日"
|
||
align="center"
|
||
prop="isHaveHoliday"
|
||
width="180"
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
<el-table-column
|
||
label="应出勤开始时间"
|
||
align="center"
|
||
prop="attStartDate"
|
||
sortable
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
<el-table-column
|
||
label="应出勤结束时间"
|
||
align="center"
|
||
prop="attEndDate"
|
||
sortable
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="totalTwoRequiredDays > 0"
|
||
:total="totalTwoRequiredDays"
|
||
:page.sync="queryRequiredDays.pageNum"
|
||
:limit.sync="queryRequiredDays.pageSize"
|
||
@pagination="getRequiredDaysList"
|
||
/>
|
||
</el-dialog>
|
||
|
||
<!-- 年数据 -->
|
||
<el-dialog
|
||
title="年数据列表"
|
||
:visible.sync="showYearDataVisible"
|
||
width="85%"
|
||
height="80%"
|
||
append-to-body
|
||
>
|
||
<el-form :inline="true">
|
||
<el-form-item label="年份">
|
||
<el-date-picker
|
||
type="year"
|
||
style="width: 240px"
|
||
value-format="yyyy"
|
||
placeholder="选择年份"
|
||
v-model="queryYearDataParams.year"
|
||
/>
|
||
</el-form-item>
|
||
<el-form-item>
|
||
<el-button
|
||
type="primary"
|
||
icon="el-icon-search"
|
||
size="mini"
|
||
@click="getYearDataList"
|
||
>
|
||
查询
|
||
</el-button>
|
||
<el-button
|
||
icon="el-icon-refresh"
|
||
size="mini"
|
||
@click="resetQueryYearData"
|
||
>
|
||
重置
|
||
</el-button>
|
||
|
||
<el-button
|
||
type="warning"
|
||
icon="el-icon-download"
|
||
size="mini"
|
||
@click="handleExportYearDataList"
|
||
>
|
||
导出
|
||
</el-button>
|
||
</el-form-item>
|
||
</el-form>
|
||
<el-table :data="tableDataYearData" border>
|
||
<el-table-column
|
||
align="center"
|
||
label="用户名"
|
||
prop="userName"
|
||
/>
|
||
<el-table-column
|
||
align="center"
|
||
width="170"
|
||
label="部门"
|
||
prop="orgName"
|
||
:show-overflow-tooltip="true"
|
||
/>
|
||
|
||
<el-table-column
|
||
:label="item.label + '月'"
|
||
v-for="item in monthColList"
|
||
:key="item.dataValue"
|
||
align="center"
|
||
>
|
||
<template slot-scope="scope">
|
||
<span
|
||
style="cursor: pointer"
|
||
:style="{
|
||
color:
|
||
scope.row[item.dataValue] == 1
|
||
? '#409eff'
|
||
: '#f56c6c',
|
||
}"
|
||
@click="openYearDataDetail(scope.row, item.label)"
|
||
>
|
||
{{
|
||
scope.row[item.dataValue] == 1 ? '正常' : '异常'
|
||
}}
|
||
</span>
|
||
</template>
|
||
</el-table-column>
|
||
</el-table>
|
||
|
||
<pagination
|
||
v-show="totalYearData > 0"
|
||
:total="totalYearData"
|
||
:page.sync="queryYearDataParams.pageNum"
|
||
:limit.sync="queryYearDataParams.pageSize"
|
||
@pagination="getYearDataList"
|
||
/>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
import { getDetail, getDays } from '@/api/report/monthlyError'
|
||
import {
|
||
getMonthAttReport,
|
||
exportMonthReport,
|
||
getClockingRecordListByUserId,
|
||
getRequiredDaysList,
|
||
getYearDataListAPI,
|
||
} from '@/api/report/monthReport'
|
||
import {
|
||
getAttendanceRateList,
|
||
getLateEarlyAbsentList,
|
||
getAttendanceRateDetail,
|
||
getAttAbnormalDetailsList,
|
||
exportAttRateTypeList,
|
||
exportAbnormalList,
|
||
} from '@/api/report/attendanceRate'
|
||
|
||
import { listDeptTree } from '@/api/system/userInfo'
|
||
import Treeselect from '@riophae/vue-treeselect'
|
||
import '@riophae/vue-treeselect/dist/vue-treeselect.css'
|
||
import {
|
||
getOutCountList,
|
||
exportOutCountList,
|
||
exportYearDataListAPI,
|
||
} from '@/api/report/attReport'
|
||
|
||
var monstr = ''
|
||
export default {
|
||
name: 'MonthReport',
|
||
dicts: ['att_status'],
|
||
components: { Treeselect },
|
||
data() {
|
||
return {
|
||
// 遮罩层
|
||
loading: false,
|
||
// 选中数组
|
||
ids: [],
|
||
// 非单个禁用
|
||
single: true,
|
||
// 非多个禁用
|
||
multiple: true,
|
||
// 显示搜索条件
|
||
showSearch: true,
|
||
// 总条数
|
||
total: 0,
|
||
// 字典表格数据
|
||
typeList: [],
|
||
// 弹出层标题
|
||
title: '',
|
||
title1: '正常打卡天数',
|
||
title2: '迟到记录',
|
||
title3: '早退记录',
|
||
title4: '旷工记录',
|
||
title5: '打卡地异常记录',
|
||
title6: '出入异常记录',
|
||
title7: '请假记录',
|
||
title8: '轮休记录',
|
||
title9: '临时外出记录',
|
||
title10: '出差天数',
|
||
title11: '打卡记录',
|
||
title12: '外勤记录',
|
||
title13: '培训记录',
|
||
// 是否显示弹出层
|
||
open: false,
|
||
showRecord: false,
|
||
dateRange: [],
|
||
attCurrentMonth: '',
|
||
pickerOptions: {
|
||
disabledDate: this.disabledDate,
|
||
},
|
||
queryRecord: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
userId: undefined,
|
||
attStatus: undefined,
|
||
attCurrentMonth: undefined,
|
||
leavePaidRate: '',
|
||
leaveUnpaidRate: '',
|
||
},
|
||
tableDataRecord: [],
|
||
totalTwo: 0,
|
||
dialogQueryForm: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
},
|
||
dialogList: [],
|
||
dialogTotal: 0,
|
||
|
||
// 查询参数
|
||
queryParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
month: undefined,
|
||
userName: undefined,
|
||
orgIdList: undefined,
|
||
orgName: undefined,
|
||
outside: undefined,
|
||
},
|
||
deptOptions: [],
|
||
|
||
queryRecordOutCount: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
userId: undefined,
|
||
attCurrentDay: undefined,
|
||
userName: undefined,
|
||
},
|
||
showOutCount: false,
|
||
totalTwoOutCount: 0,
|
||
// 遮罩层
|
||
loadingTwo: false,
|
||
tableDataOutCount: [],
|
||
|
||
queryAttCount: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
month: undefined,
|
||
userName: undefined,
|
||
},
|
||
showAttCount: false,
|
||
totalAttCount: 0,
|
||
// 遮罩层
|
||
loadingAttCount: false,
|
||
tableDataAttCount: [],
|
||
|
||
queryRequiredDays: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
userId: undefined,
|
||
attCurrentDay: undefined,
|
||
userName: undefined,
|
||
attCurrentMonth: undefined,
|
||
},
|
||
showRequiredDays: false,
|
||
totalTwoRequiredDays: 0,
|
||
// 遮罩层
|
||
loadingTwoRequiredDays: false,
|
||
tableDataRequiredDays: [],
|
||
|
||
showYearDataVisible: false,
|
||
queryYearDataParams: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
year: String(new Date().getFullYear()), // 当前年份
|
||
},
|
||
tableDataYearData: [],
|
||
totalYearData: 0,
|
||
|
||
// 主列表字段
|
||
mainListFields: [
|
||
{ label: '姓名', prop: 'userName' },
|
||
{ label: '部门', prop: 'orgName' },
|
||
{ label: '考勤月份', prop: 'attCurrentMonth' },
|
||
{ label: '应出勤天数', prop: 'requiredDays' },
|
||
|
||
{
|
||
label: '考勤率',
|
||
prop: 'normalRate',
|
||
needShow: true,
|
||
type: '正常打卡天数',
|
||
},
|
||
{
|
||
label: '迟到率',
|
||
prop: 'lateRate',
|
||
needShow: true,
|
||
type: '迟到记录',
|
||
},
|
||
{
|
||
label: '旷工率',
|
||
prop: 'skippingRate',
|
||
needShow: true,
|
||
type: '旷工记录',
|
||
},
|
||
{
|
||
label: '早退率',
|
||
prop: 'earlyRate',
|
||
needShow: true,
|
||
type: '早退记录',
|
||
},
|
||
{
|
||
label: '休假率(带薪)',
|
||
prop: 'leavePaidRate',
|
||
needShow: true,
|
||
type: '带薪1',
|
||
},
|
||
{
|
||
label: '休假率(不带薪)',
|
||
prop: 'leaveUnpaidRate',
|
||
needShow: true,
|
||
type: '带薪0',
|
||
},
|
||
// { label: "异常打卡率", prop: "abnormalRate" },
|
||
{ label: '外勤次数', prop: 'outsideAttNum' },
|
||
],
|
||
|
||
// 月份初始化列表
|
||
monthColList: [
|
||
{ label: '1', dataValue: 'oneMonth' },
|
||
{ label: '2', dataValue: 'twoMonth' },
|
||
{ label: '3', dataValue: 'threeMonth' },
|
||
{ label: '4', dataValue: 'fourMonth' },
|
||
{ label: '5', dataValue: 'fiveMonth' },
|
||
{ label: '6', dataValue: 'sixMonth' },
|
||
{ label: '7', dataValue: 'sevenMonth' },
|
||
{ label: '8', dataValue: 'eightMonth' },
|
||
{ label: '9', dataValue: 'nineMonth' },
|
||
{ label: '10', dataValue: 'tenMonth' },
|
||
{ label: '11', dataValue: 'elevenMonth' },
|
||
{ label: '12', dataValue: 'twelveMonth' },
|
||
],
|
||
|
||
tabIndex: '考勤报表',
|
||
abnormalList: [],
|
||
abnormalListFields: [
|
||
{ label: '姓名', prop: 'userName' },
|
||
{ label: '单位', prop: 'orgName' },
|
||
{
|
||
label: '迟到天数',
|
||
prop: 'lateNum',
|
||
needShow: true,
|
||
type: '早退记录',
|
||
},
|
||
{
|
||
label: '旷工天数',
|
||
prop: 'skippingNum',
|
||
needShow: true,
|
||
type: '旷工记录',
|
||
},
|
||
{
|
||
label: '早退天数',
|
||
prop: 'earlyNum',
|
||
needShow: true,
|
||
type: '早退记录',
|
||
},
|
||
],
|
||
queryParamsAbnormal: {
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
year: '',
|
||
attCurrentMonth: new Date()
|
||
.toISOString()
|
||
.split('T')[0]
|
||
.slice(0, 7), // 默认当月
|
||
userName: undefined,
|
||
orgIdList: [],
|
||
orgName: undefined,
|
||
},
|
||
}
|
||
},
|
||
created() {
|
||
this.getDeptList()
|
||
this.getAbnormalList()
|
||
this.getMonth()
|
||
this.getList()
|
||
},
|
||
methods: {
|
||
parseAttendanceRule(ruleString) {
|
||
const days = [
|
||
'周一',
|
||
'周二',
|
||
'周三',
|
||
'周四',
|
||
'周五',
|
||
'周六',
|
||
'周日',
|
||
]
|
||
const needAttend = ruleString.split(',').map((item) => item === '1')
|
||
let result = ''
|
||
|
||
needAttend.forEach((attend, index) => {
|
||
if (attend) {
|
||
if (result !== '') result += '、'
|
||
result += days[index].replace('周', '')
|
||
}
|
||
})
|
||
return result || '无'
|
||
},
|
||
|
||
formatDate(dateString) {
|
||
const date = new Date(dateString) // 创建日期对象
|
||
const year = date.getFullYear() // 获取年份
|
||
const month = String(date.getMonth() + 1).padStart(2, '0') // 获取月份(注意:月份从0开始)
|
||
const day = String(date.getDate()).padStart(2, '0') // 获取日期
|
||
const weekdays = [
|
||
'星期天',
|
||
'星期一',
|
||
'星期二',
|
||
'星期三',
|
||
'星期四',
|
||
'星期五',
|
||
'星期六',
|
||
] // 星期几数组
|
||
const weekday = weekdays[date.getDay()] // 获取星期几
|
||
|
||
return `${year}-${month}-${day} ${weekday}` // 组合成所需格式
|
||
},
|
||
getMonth() {
|
||
// 默认当月
|
||
var nowDate = new Date()
|
||
var date = {
|
||
year: nowDate.getFullYear(),
|
||
month: nowDate.getMonth() + 1,
|
||
day: nowDate.getDate(),
|
||
}
|
||
const dayDate =
|
||
date.year +
|
||
'-' +
|
||
(date.month >= 10 ? date.month : '0' + date.month)
|
||
this.$set(this.queryParams, 'month', [dayDate, dayDate])
|
||
},
|
||
getDeptList() {
|
||
listDeptTree().then((response) => {
|
||
this.deptOptions = this.handleTree(response.data, 'id')
|
||
})
|
||
},
|
||
/** 转换部门数据结构 */
|
||
normalizer(node) {
|
||
if (node.children && !node.children.length) {
|
||
delete node.children
|
||
}
|
||
return {
|
||
id: node.id,
|
||
label: node.orgName,
|
||
children: node.children,
|
||
}
|
||
},
|
||
handleSelect(value, instanceId) {
|
||
console.log('Selected:', value)
|
||
// 在这里处理选择事件
|
||
this.queryParams.orgName = value.orgName
|
||
},
|
||
/** 查询字典类型列表 */
|
||
getList() {
|
||
this.loading = true
|
||
console.log(this.queryParams)
|
||
let query = _.cloneDeep(this.queryParams)
|
||
query.startMonth = query.month[0]
|
||
query.endMonth = query.month[1]
|
||
delete query['month']
|
||
|
||
if (query.orgIdList && query.orgIdList.length > 0) {
|
||
query.orgIds = query.orgIdList.map((id) => id.toString())
|
||
} else {
|
||
query.orgIds = undefined
|
||
}
|
||
delete query['orgIdList']
|
||
|
||
console.log(query)
|
||
getAttendanceRateList(query).then((response) => {
|
||
this.typeList = response.rows
|
||
this.total = response.total
|
||
this.loading = false
|
||
})
|
||
},
|
||
/** 搜索按钮操作 */
|
||
handleQuery() {
|
||
this.queryParams.pageNum = 1
|
||
this.getList()
|
||
},
|
||
/** 重置按钮操作 */
|
||
resetQuery() {
|
||
this.getMonth()
|
||
this.resetForm('queryForm')
|
||
this.handleQuery()
|
||
},
|
||
//打开月异常详情页面
|
||
openRecord(row, titleBoss) {
|
||
this.queryRecord.leaveUnpaidRate = ''
|
||
this.queryRecord.leavePaidRate = ''
|
||
this.id = row.id
|
||
this.title = titleBoss
|
||
this.queryRecord.userId = row.userId
|
||
this.queryRecord.attCurrentMonth = row.attCurrentMonth
|
||
this.attCurrentMonth = row.attCurrentMonth
|
||
if (titleBoss == '正常打卡天数') {
|
||
this.queryRecord.attStatus = 1
|
||
} else if (titleBoss == '迟到记录') {
|
||
this.queryRecord.attStatus = 2
|
||
} else if (titleBoss == '早退记录') {
|
||
this.queryRecord.attStatus = 4
|
||
} else if (titleBoss == '旷工记录') {
|
||
this.queryRecord.attStatus = 3
|
||
} else if (titleBoss == '打卡地异常记录') {
|
||
this.queryRecord.attStatus = 9
|
||
} else if (titleBoss == '出入异常记录') {
|
||
this.queryRecord.attStatus = 8
|
||
} else if (titleBoss == '请假记录') {
|
||
this.queryRecord.attStatus = 6
|
||
} else if (titleBoss == '轮休记录') {
|
||
this.queryRecord.attStatus = 5
|
||
} else if (titleBoss == '临时外出记录') {
|
||
this.queryRecord.attStatus = 7
|
||
} else if (titleBoss == '出差天数') {
|
||
this.queryRecord.attStatus = 10
|
||
} else if (titleBoss == '外勤记录') {
|
||
this.queryRecord.attStatus = 26
|
||
} else if (titleBoss == '培训记录') {
|
||
this.queryRecord.attStatus = 28
|
||
} else if (titleBoss == '带薪1') {
|
||
this.queryRecord.attStatus = ''
|
||
this.queryRecord.leavePaidRate = 1
|
||
this.queryRecord.leaveUnpaidRate = 0
|
||
} else if (titleBoss == '带薪0') {
|
||
this.queryRecord.attStatus = ''
|
||
this.queryRecord.leaveUnpaidRate = 1
|
||
this.queryRecord.leavePaidRate = 0
|
||
}
|
||
this.showRecord = true
|
||
this.getListRecord()
|
||
},
|
||
disabledDate(time) {
|
||
const str = this.attCurrentMonth + '-01'
|
||
// 获取当前日期
|
||
var currentDate = new Date(str)
|
||
// 获取当前月份的第一天
|
||
var firstDayOfMonth = new Date(
|
||
currentDate.getFullYear(),
|
||
currentDate.getMonth(),
|
||
1,
|
||
)
|
||
// 获取当前月份的最后一天
|
||
var lastDayOfMonth = new Date(
|
||
currentDate.getFullYear(),
|
||
currentDate.getMonth() + 1,
|
||
0,
|
||
)
|
||
return time < firstDayOfMonth || time > lastDayOfMonth
|
||
},
|
||
/** 查询月异常详情列表 */
|
||
getListRecord() {
|
||
// getAttendanceRateDetail(
|
||
// this.queryRecord,
|
||
// this.dateRange
|
||
// )(this.addDateRange(this.queryRecord, this.dateRange)).then(
|
||
// (response) => {
|
||
// this.tableDataRecord = response.rows;
|
||
// this.totalTwo = response.total;
|
||
// }
|
||
// );
|
||
|
||
if (this.tabIndex == '考勤报表') {
|
||
getAttendanceRateDetail(
|
||
this.addDateRange(this.queryRecord, this.dateRange),
|
||
).then((response) => {
|
||
this.tableDataRecord = response.rows
|
||
this.totalTwo = response.total
|
||
})
|
||
} else {
|
||
getAttAbnormalDetailsList(
|
||
this.addDateRange(this.queryRecord, this.dateRange),
|
||
).then((response) => {
|
||
this.tableDataRecord = response.rows
|
||
this.totalTwo = response.total
|
||
})
|
||
}
|
||
},
|
||
|
||
/** 搜索按钮操作 */
|
||
handleQueryRecord() {
|
||
this.queryRecord.pageNum = 1
|
||
this.getListRecord()
|
||
},
|
||
|
||
cancelRecord() {
|
||
this.showRecord = false
|
||
this.resetRecord()
|
||
},
|
||
/** 重置按钮操作 */
|
||
resetRecord() {
|
||
// this.resetForm("queryFormRecord");
|
||
this.handleQueryRecord()
|
||
},
|
||
|
||
/** 导出按钮操作 */
|
||
handleExport() {
|
||
let query = _.cloneDeep(this.queryParams)
|
||
query.startMonth = query.month[0]
|
||
query.endMonth = query.month[1]
|
||
delete query['month']
|
||
|
||
if (query.orgIdList && query.orgIdList.length > 0) {
|
||
query.orgIds = query.orgIdList.map((id) => id.toString())
|
||
} else {
|
||
query.orgIds = undefined
|
||
}
|
||
delete query['orgIdList']
|
||
|
||
console.log(query)
|
||
exportAttRateTypeList(query).then((res) => {
|
||
this.downloadFile({
|
||
fileName: `考勤率报表_${new Date().getTime()}.xlsx`,
|
||
fileData: res,
|
||
fileType: 'application/vnd.ms-excel;charset=utf-8',
|
||
})
|
||
})
|
||
},
|
||
|
||
handleExportAbnormal() {
|
||
let query = _.cloneDeep(this.queryParamsAbnormal)
|
||
exportAbnormalList(query).then((res) => {
|
||
this.downloadFile({
|
||
fileName: `异常考勤统计_${new Date().getTime()}.xlsx`,
|
||
fileData: res,
|
||
fileType: 'application/vnd.ms-excel;charset=utf-8',
|
||
})
|
||
})
|
||
},
|
||
/** 更新应该出勤天数按钮操作 */
|
||
handleDays() {
|
||
// 显示加载中提示
|
||
this.$modal.loading('加载中...')
|
||
let query = _.cloneDeep(this.queryParams)
|
||
let month = query.month[0]
|
||
query.attCurrentMonth = month
|
||
getDays(query)
|
||
.then((response) => {
|
||
this.$modal.msgSuccess('更新成功')
|
||
})
|
||
.finally(() => {
|
||
// 不管请求成功或失败,最终都会关闭加载提示
|
||
this.$modal.closeLoading()
|
||
})
|
||
},
|
||
|
||
//打开工作时间外出次数
|
||
openOutCountList(row) {
|
||
this.title = '工作时间外出次数'
|
||
this.queryRecordOutCount.userId = row.userId
|
||
this.queryRecordOutCount.attCurrentDay = row.attCurrentDay
|
||
this.queryRecordOutCount.attCurrentMonth = row.attCurrentMonth
|
||
this.showOutCount = true
|
||
this.getOutCountList()
|
||
},
|
||
|
||
/** 查询工作时间外出次数列表 */
|
||
getOutCountList() {
|
||
this.loadingTwo = true
|
||
getOutCountList(this.queryRecordOutCount).then((response) => {
|
||
this.tableDataOutCount = response.rows
|
||
this.totalTwoOutCount = response.total
|
||
this.loadingTwo = false
|
||
})
|
||
},
|
||
|
||
openRequiredDaysList(row) {
|
||
this.title = '应出勤天数组成'
|
||
this.queryRequiredDays.userId = row.userId
|
||
this.queryRequiredDays.attCurrentDay = row.attCurrentDay
|
||
this.queryRequiredDays.attCurrentMonth = row.attCurrentMonth
|
||
this.showRequiredDays = true
|
||
this.getRequiredDaysList()
|
||
},
|
||
|
||
/** 查询应出勤天数组成列表 */
|
||
getRequiredDaysList() {
|
||
this.loadingTwoRequiredDays = true
|
||
getRequiredDaysList(this.queryRequiredDays).then((response) => {
|
||
this.tableDataRequiredDays = response.rows
|
||
this.totalTwoRequiredDays = response.total
|
||
this.loadingTwoRequiredDays = false
|
||
})
|
||
},
|
||
|
||
/** 导出按钮操作 */
|
||
handleExportOutCountList() {
|
||
exportOutCountList(this.queryRecordOutCount).then((res) => {
|
||
this.downloadFile({
|
||
fileName: `工作时间外出次数记录_${new Date().getTime()}.xlsx`,
|
||
fileData: res,
|
||
fileType: 'application/vnd.ms-excel;charset=utf-8',
|
||
})
|
||
})
|
||
},
|
||
|
||
//打开打卡次数记录
|
||
openAttCountList(row) {
|
||
this.title = '打卡记录'
|
||
this.queryAttCount.month = row.attCurrentMonth
|
||
this.queryAttCount.userName = row.userName
|
||
this.showAttCount = true
|
||
this.getClockingRecordListByUserId()
|
||
},
|
||
|
||
/** 查询打卡次数记录列表 */
|
||
getClockingRecordListByUserId() {
|
||
this.loadingAttCount = true
|
||
getClockingRecordListByUserId(this.queryAttCount).then(
|
||
(response) => {
|
||
this.tableDataAttCount = response.rows
|
||
this.totalAttCount = response.total
|
||
this.loadingAttCount = false
|
||
},
|
||
)
|
||
},
|
||
|
||
// 查看年数据
|
||
onHandleYearData() {
|
||
this.getYearDataList()
|
||
this.showYearDataVisible = true
|
||
},
|
||
|
||
// 获取年数据
|
||
getYearDataList() {
|
||
getYearDataListAPI(this.queryYearDataParams).then((response) => {
|
||
this.tableDataYearData = response.rows
|
||
this.totalYearData = response.total
|
||
})
|
||
},
|
||
|
||
// 重置年数据查询
|
||
resetQueryYearData() {
|
||
this.queryYearDataParams.year = String(new Date().getFullYear())
|
||
this.getYearDataList()
|
||
},
|
||
// 打开月数据
|
||
openYearDataDetail(row, dataValue) {
|
||
console.log(row, dataValue)
|
||
|
||
this.queryParams.month = [
|
||
`${this.queryYearDataParams.year}-${
|
||
dataValue > 9 ? dataValue : '0' + dataValue
|
||
}`,
|
||
`${this.queryYearDataParams.year}-${
|
||
dataValue > 9 ? dataValue : '0' + dataValue
|
||
}`,
|
||
]
|
||
|
||
this.queryParams.userName = row.userName
|
||
// this.queryParams.orgIdList = [250];
|
||
this.queryParams.orgName = row.orgName
|
||
this.handleQuery()
|
||
this.showYearDataVisible = false
|
||
},
|
||
|
||
handleExportYearDataList() {
|
||
exportYearDataListAPI(this.queryYearDataParams).then((res) => {
|
||
this.downloadFile({
|
||
fileName: `年报表记录_${new Date().getTime()}.xlsx`,
|
||
fileData: res,
|
||
fileType: 'application/vnd.ms-excel;charset=utf-8',
|
||
})
|
||
})
|
||
},
|
||
|
||
// 获取异常考勤统计列表
|
||
getAbnormalList() {
|
||
let query = _.cloneDeep(this.queryParamsAbnormal)
|
||
if (query.orgIdList && query.orgIdList.length > 0) {
|
||
query.orgIds = query.orgIdList.map((id) => id.toString())
|
||
} else {
|
||
query.orgIds = undefined
|
||
}
|
||
delete query['orgIdList']
|
||
|
||
getLateEarlyAbsentList(query).then((response) => {
|
||
this.abnormalList = response.rows
|
||
this.totalAbnormal = response.total
|
||
})
|
||
},
|
||
|
||
handleQueryAbnormal() {
|
||
this.getAbnormalList()
|
||
},
|
||
|
||
resetQueryAbnormal() {
|
||
this.queryParamsAbnormal = {
|
||
attCurrentMonth: new Date()
|
||
.toISOString()
|
||
.split('T')[0]
|
||
.slice(0, 7),
|
||
userName: undefined,
|
||
orgIdList: undefined,
|
||
orgName: undefined,
|
||
pageNum: 1,
|
||
pageSize: 10,
|
||
year: '',
|
||
}
|
||
this.getAbnormalList()
|
||
},
|
||
},
|
||
}
|
||
</script>
|