添加生成工资条功能
This commit is contained in:
@@ -237,3 +237,11 @@ export const showPayrollSheet = (data) => {
|
|||||||
data
|
data
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 生成工资条
|
||||||
|
export function calculatePayrollSheets(year, month) {
|
||||||
|
return service({
|
||||||
|
url: `/payroll/sheets/calculate/${year}/${month}`,
|
||||||
|
method: 'post'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,47 +5,33 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="title">财务查看考勤列表</span>
|
<span class="title">财务查看考勤列表</span>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-date-picker
|
<el-date-picker v-model="dateRange" type="month" placeholder="选择月份" :default-time="defaultTime"
|
||||||
v-model="dateRange"
|
:shortcuts="dateShortcuts" @change="handleDateChange" style="width: 200px; margin-right: 8px;" />
|
||||||
type="month"
|
<el-input v-model="searchKeyword" placeholder="请输入姓名搜索" clearable @input="handleSearch"
|
||||||
placeholder="选择月份"
|
style="width: 200px; margin-right: 8px;">
|
||||||
:default-time="defaultTime"
|
|
||||||
:shortcuts="dateShortcuts"
|
|
||||||
@change="handleDateChange"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="searchKeyword"
|
|
||||||
placeholder="请输入姓名搜索"
|
|
||||||
clearable
|
|
||||||
@input="handleSearch"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon>
|
||||||
|
<Search />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
<el-button type="primary" @click="handleGeneratePayroll" :loading="generating">
|
||||||
|
生成工资条
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<el-table :data="attendanceList" style="width: 100%" height="calc(100vh - 280px)" border stripe
|
||||||
:data="attendanceList"
|
|
||||||
style="width: 100%"
|
|
||||||
height="calc(100vh - 280px)"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
:header-cell-style="{
|
:header-cell-style="{
|
||||||
background: '#f5f7fa',
|
background: '#f5f7fa',
|
||||||
color: '#606266',
|
color: '#606266',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
padding: '12px 0'
|
padding: '12px 0'
|
||||||
}"
|
}" :cell-style="{
|
||||||
:cell-style="{
|
|
||||||
padding: '8px 0'
|
padding: '8px 0'
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
<el-table-column label="头像" width="80" align="center" fixed="left">
|
<el-table-column label="头像" width="80" align="center" fixed="left">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-avatar :size="40" :src="scope.row.avatar" />
|
<el-avatar :size="40" :src="scope.row.avatar" />
|
||||||
@@ -72,7 +58,8 @@
|
|||||||
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center"
|
||||||
|
show-overflow-tooltip />
|
||||||
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
||||||
@@ -84,22 +71,22 @@
|
|||||||
<el-table-column prop="workdayOvertime" label="工作日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="workdayOvertime" label="工作日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="restdayOvertime" label="休息日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="restdayOvertime" label="休息日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="holidayOvertime" label="节假日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="holidayOvertime" label="节假日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualPerformance" label="年度绩效" width="100" align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="annualPerformance" label="年度绩效" width="100" align="center"
|
||||||
<el-table-column prop="monthlyPerformance" label="月度绩效" width="100" align="center" show-overflow-tooltip></el-table-column>
|
show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="monthlyPerformance" label="月度绩效" width="100" align="center"
|
||||||
|
show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column label="签名" width="100" align="center">
|
<el-table-column label="签名" width="100" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<div class="signature-cell">
|
<div class="signature-cell">
|
||||||
<el-image
|
<el-image v-if="scope.row.signatureImg" :src="scope.row.signatureImg" fit="contain"
|
||||||
v-if="scope.row.signatureImg"
|
|
||||||
:src="scope.row.signatureImg"
|
|
||||||
fit="contain"
|
|
||||||
style="width: 40px; height: 40px; cursor: pointer;"
|
style="width: 40px; height: 40px; cursor: pointer;"
|
||||||
@click="handlePreviewSignature(scope.row.signatureImg)"
|
@click="handlePreviewSignature(scope.row.signatureImg)">
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<el-icon><Picture /></el-icon>
|
<el-icon>
|
||||||
|
<Picture />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@@ -107,89 +94,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" width="240" fixed="right" align="center">
|
<el-table-column label="操作" width="120" fixed="right" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link size="small" @click="handleViewDetail(scope.row)">
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleViewDetail(scope.row)"
|
|
||||||
>
|
|
||||||
查看详情
|
查看详情
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleViewAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
异常考勤
|
|
||||||
</el-button>
|
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 异常考勤详情对话框 -->
|
|
||||||
<el-dialog
|
|
||||||
v-model="abnormalDialogVisible"
|
|
||||||
title="异常考勤详情"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
|
||||||
<div class="date-header">{{ date }}</div>
|
|
||||||
<el-table
|
|
||||||
:data="records"
|
|
||||||
style="width: 100%"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column prop="type" label="异常类型" width="120">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
|
||||||
{{ getAbnormalTypeLabel(scope.row.type) }}
|
|
||||||
</el-tag>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="异常详情" min-width="200">
|
|
||||||
<template #default="scope">
|
|
||||||
<template v-if="scope.row.type === 'abnormal'">
|
|
||||||
<div>考勤类型:{{ scope.row.checkType === 'OnDuty' ? '上班' : '下班' }}</div>
|
|
||||||
<div>考勤时间:{{ scope.row.baseCheckTime }}</div>
|
|
||||||
<div>考勤结果:{{ getAbnormalResultLabel(scope.row.realResult) }}</div>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="scope.row.type === 'checkin'">
|
|
||||||
<div>缺卡次数:{{ scope.row.missedCount }}次</div>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="scope.row.type === 'report'">
|
|
||||||
<div>日志状态:{{ scope.row.reportCount === 0 ? '未写日志' : '正常' }}</div>
|
|
||||||
</template>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="修改记录" min-width="300">
|
|
||||||
<template #default="scope">
|
|
||||||
<div v-if="scope.row.modifications && scope.row.modifications.length > 0">
|
|
||||||
<div v-for="(mod, index) in scope.row.modifications" :key="index" class="modification-item">
|
|
||||||
<div>修改人:{{ mod.modifiedBy }}</div>
|
|
||||||
<div>修改时间:{{ mod.modifiedAt }}</div>
|
|
||||||
<div>修改前:{{ getModificationValue(mod.originalValue, scope.row.type) }}</div>
|
|
||||||
<div>修改后:{{ getModificationValue(mod.modifiedValue, scope.row.type) }}</div>
|
|
||||||
<div v-if="mod.isFinally" class="finally-tag">最终修改</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<span v-else>无修改记录</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</div>
|
|
||||||
</el-dialog>
|
|
||||||
|
|
||||||
<!-- 工资条详情对话框 -->
|
<!-- 工资条详情对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="detailDialogVisible" title="考勤详情" width="800px">
|
||||||
v-model="detailDialogVisible"
|
|
||||||
title="考勤详情"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<div v-if="currentDetail" class="attendance-detail">
|
<div v-if="currentDetail" class="attendance-detail">
|
||||||
<div class="detail-header">
|
<div class="detail-header">
|
||||||
<div class="employee-info">
|
<div class="employee-info">
|
||||||
@@ -241,15 +157,13 @@
|
|||||||
<div class="signature-item">
|
<div class="signature-item">
|
||||||
<div class="label">员工签名:</div>
|
<div class="label">员工签名:</div>
|
||||||
<div class="signature-image" v-if="currentDetail.signatureImg">
|
<div class="signature-image" v-if="currentDetail.signatureImg">
|
||||||
<el-image
|
<el-image :src="currentDetail.signatureImg" fit="contain" style="width: 100%; height: 100%;"
|
||||||
:src="currentDetail.signatureImg"
|
@click="handlePreviewSignature(currentDetail.signatureImg)">
|
||||||
fit="contain"
|
|
||||||
style="width: 100%; height: 100%;"
|
|
||||||
@click="handlePreviewSignature(currentDetail.signatureImg)"
|
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<el-icon><Picture /></el-icon>
|
<el-icon>
|
||||||
|
<Picture />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@@ -262,25 +176,16 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 签名预览对话框 -->
|
<!-- 签名预览对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="signaturePreviewVisible" title="签名预览" width="500px" :show-close="true"
|
||||||
v-model="signaturePreviewVisible"
|
:close-on-click-modal="true" :close-on-press-escape="true" class="signature-preview-dialog">
|
||||||
title="签名预览"
|
|
||||||
width="500px"
|
|
||||||
:show-close="true"
|
|
||||||
:close-on-click-modal="true"
|
|
||||||
:close-on-press-escape="true"
|
|
||||||
class="signature-preview-dialog"
|
|
||||||
>
|
|
||||||
<div class="signature-preview-content">
|
<div class="signature-preview-content">
|
||||||
<el-image
|
<el-image v-if="currentSignatureImg" :src="currentSignatureImg" fit="contain"
|
||||||
v-if="currentSignatureImg"
|
style="width: 100%; height: 300px;">
|
||||||
:src="currentSignatureImg"
|
|
||||||
fit="contain"
|
|
||||||
style="width: 100%; height: 300px;"
|
|
||||||
>
|
|
||||||
<template #error>
|
<template #error>
|
||||||
<div class="image-slot">
|
<div class="image-slot">
|
||||||
<el-icon><Picture /></el-icon>
|
<el-icon>
|
||||||
|
<Picture />
|
||||||
|
</el-icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</el-image>
|
</el-image>
|
||||||
@@ -296,26 +201,26 @@ import { Search, Picture } from '@element-plus/icons-vue';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import {
|
import {
|
||||||
getFinanceAttendanceList,
|
getFinanceAttendanceList,
|
||||||
getAbnormalAttendanceDetail,
|
calculatePayrollSheets,
|
||||||
} from "../../../../api/modules/index";
|
} from "../../../../api/modules/index";
|
||||||
|
|
||||||
// 格式化金额
|
// 格式化金额
|
||||||
const formatMoney = (value) => {
|
const formatMoney = (value) => {
|
||||||
if (value === undefined || value === null) return '0.00';
|
if (value === undefined || value === null) return '0.00';
|
||||||
|
|
||||||
// 将输入转换为数字
|
// 将输入转换为数字
|
||||||
const num = Number(value);
|
const num = Number(value);
|
||||||
|
|
||||||
// 检查是否为有效数字
|
// 检查是否为有效数字
|
||||||
if (isNaN(num)) return '0.00';
|
if (isNaN(num)) return '0.00';
|
||||||
|
|
||||||
// 使用toFixed(2)保留两位小数
|
// 使用toFixed(2)保留两位小数
|
||||||
const fixedNum = num.toFixed(2);
|
const fixedNum = num.toFixed(2);
|
||||||
|
|
||||||
// 添加千分位分隔符
|
// 添加千分位分隔符
|
||||||
const parts = fixedNum.split('.');
|
const parts = fixedNum.split('.');
|
||||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ',');
|
||||||
|
|
||||||
return parts.join('.');
|
return parts.join('.');
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -403,93 +308,11 @@ const handleSearch = () => {
|
|||||||
attendanceList.value = originalList.value;
|
attendanceList.value = originalList.value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attendanceList.value = originalList.value.filter(item =>
|
attendanceList.value = originalList.value.filter(item =>
|
||||||
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 异常考勤对话框
|
|
||||||
const abnormalDialogVisible = ref(false);
|
|
||||||
const abnormalList = ref([]);
|
|
||||||
const currentAbnormalUser = ref({
|
|
||||||
id: '',
|
|
||||||
userid: ''
|
|
||||||
});
|
|
||||||
|
|
||||||
// 获取异常类型标签
|
|
||||||
const getAbnormalTypeLabel = (type) => {
|
|
||||||
const typeMap = {
|
|
||||||
'abnormal': '考勤异常',
|
|
||||||
'checkin': '签到签退',
|
|
||||||
'report': '日志异常'
|
|
||||||
};
|
|
||||||
return typeMap[type] || '未知';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取异常类型标签样式
|
|
||||||
const getAbnormalTypeTag = (type) => {
|
|
||||||
const typeMap = {
|
|
||||||
'abnormal': 'danger',
|
|
||||||
'checkin': 'warning',
|
|
||||||
'report': 'info'
|
|
||||||
};
|
|
||||||
return typeMap[type] || '';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取异常结果标签
|
|
||||||
const getAbnormalResultLabel = (result) => {
|
|
||||||
const resultMap = {
|
|
||||||
'Normal': '正常',
|
|
||||||
'Early': '早退',
|
|
||||||
'Late': '迟到',
|
|
||||||
'SeriousLate': '严重迟到',
|
|
||||||
'Absenteeism': '旷工迟到',
|
|
||||||
'NotSigned': '未打卡'
|
|
||||||
};
|
|
||||||
return resultMap[result] || '未知';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取修改记录的值显示
|
|
||||||
const getModificationValue = (value, type) => {
|
|
||||||
if (type === 'abnormal') {
|
|
||||||
const resultMap = {
|
|
||||||
'Normal': '正常',
|
|
||||||
'Early': '早退',
|
|
||||||
'Late': '迟到',
|
|
||||||
'SeriousLate': '严重迟到',
|
|
||||||
'Absenteeism': '旷工迟到',
|
|
||||||
'NotSigned': '未打卡'
|
|
||||||
};
|
|
||||||
return resultMap[value] || value;
|
|
||||||
} else if (type === 'checkin') {
|
|
||||||
return `${value}次`;
|
|
||||||
} else if (type === 'report') {
|
|
||||||
return value == 0 ? '未写日志' : '正常';
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查看异常考勤
|
|
||||||
const handleViewAbnormal = async (row) => {
|
|
||||||
try {
|
|
||||||
const year = dateRange.value.getFullYear();
|
|
||||||
const month = dateRange.value.getMonth() + 1;
|
|
||||||
const res = await getAbnormalAttendanceDetail(row.userid, year, month);
|
|
||||||
if (res.errcode === 0) {
|
|
||||||
currentAbnormalUser.value = {
|
|
||||||
id: res.result.id,
|
|
||||||
userid: res.result.userid
|
|
||||||
};
|
|
||||||
abnormalList.value = res.result.data;
|
|
||||||
abnormalDialogVisible.value = true;
|
|
||||||
} else {
|
|
||||||
ElMessage.error(res.errmsg || "获取异常考勤数据失败");
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error("获取异常考勤数据失败");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 查看详情
|
// 查看详情
|
||||||
const handleViewDetail = (row) => {
|
const handleViewDetail = (row) => {
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
@@ -502,10 +325,34 @@ const currentSignatureImg = ref('');
|
|||||||
|
|
||||||
const handlePreviewSignature = (url) => {
|
const handlePreviewSignature = (url) => {
|
||||||
if (!url) return;
|
if (!url) return;
|
||||||
const img = new Image();
|
currentSignatureImg.value = url;
|
||||||
img.src = url;
|
signaturePreviewVisible.value = true;
|
||||||
const newWindow = window.open('');
|
};
|
||||||
newWindow.document.write(img.outerHTML);
|
|
||||||
|
// 生成工资条
|
||||||
|
const generating = ref(false);
|
||||||
|
const handleGeneratePayroll = async () => {
|
||||||
|
if (!dateRange.value) {
|
||||||
|
ElMessage.warning('请选择月份');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
generating.value = true;
|
||||||
|
const year = dateRange.value.getFullYear();
|
||||||
|
const month = dateRange.value.getMonth() + 1;
|
||||||
|
const res = await calculatePayrollSheets(year, month);
|
||||||
|
if (res.errcode === 0) {
|
||||||
|
ElMessage.success('生成工资条成功');
|
||||||
|
fetchList(); // 刷新列表
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.errmsg || '生成工资条失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('生成工资条失败');
|
||||||
|
} finally {
|
||||||
|
generating.value = false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 页面加载时设置默认日期范围并获取数据
|
// 页面加载时设置默认日期范围并获取数据
|
||||||
@@ -539,7 +386,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.el-table) {
|
:deep(.el-table) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.el-table__body-wrapper {
|
.el-table__body-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -631,37 +478,7 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.abnormal-date-group {
|
.abnormal-date-group {
|
||||||
margin-bottom: 20px;
|
display: none;
|
||||||
|
|
||||||
.date-header {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 8px;
|
|
||||||
background-color: #f5f7fa;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modification-item {
|
|
||||||
padding: 8px;
|
|
||||||
border-bottom: 1px solid #ebeef5;
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.finally-tag {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
right: 8px;
|
|
||||||
background-color: #67c23a;
|
|
||||||
color: white;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 4px;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-dialog__body) {
|
:deep(.el-dialog__body) {
|
||||||
@@ -720,7 +537,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.el-image-viewer__wrapper) {
|
:deep(.el-image-viewer__wrapper) {
|
||||||
z-index: 3000;
|
z-index: 3000;
|
||||||
|
|
||||||
.el-image-viewer__canvas {
|
.el-image-viewer__canvas {
|
||||||
background: #ffffff;
|
background: #ffffff;
|
||||||
}
|
}
|
||||||
@@ -742,7 +559,7 @@ onMounted(() => {
|
|||||||
.el-table__fixed-right {
|
.el-table__fixed-right {
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-table__fixed {
|
.el-table__fixed {
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
@@ -874,4 +691,4 @@ onMounted(() => {
|
|||||||
color: #303133;
|
color: #303133;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -5,47 +5,30 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="title">综合部考勤</span>
|
<span class="title">综合部考勤</span>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-date-picker
|
<el-date-picker v-model="dateRange" type="month" placeholder="选择月份" :default-time="defaultTime"
|
||||||
v-model="dateRange"
|
:shortcuts="dateShortcuts" @change="handleDateChange" style="width: 200px; margin-right: 8px;" />
|
||||||
type="month"
|
<el-input v-model="searchKeyword" placeholder="请输入姓名搜索" clearable @input="handleSearch"
|
||||||
placeholder="选择月份"
|
style="width: 200px; margin-right: 8px;">
|
||||||
:default-time="defaultTime"
|
|
||||||
:shortcuts="dateShortcuts"
|
|
||||||
@change="handleDateChange"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="searchKeyword"
|
|
||||||
placeholder="请输入姓名搜索"
|
|
||||||
clearable
|
|
||||||
@input="handleSearch"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon>
|
||||||
|
<Search />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<el-table :data="attendanceList" style="width: 100%" height="calc(100vh - 280px)" border stripe
|
||||||
:data="attendanceList"
|
|
||||||
style="width: 100%"
|
|
||||||
height="calc(100vh - 280px)"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
:header-cell-style="{
|
:header-cell-style="{
|
||||||
background: '#f5f7fa',
|
background: '#f5f7fa',
|
||||||
color: '#606266',
|
color: '#606266',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
padding: '12px 0'
|
padding: '12px 0'
|
||||||
}"
|
}" :cell-style="{
|
||||||
:cell-style="{
|
|
||||||
padding: '8px 0'
|
padding: '8px 0'
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
<el-table-column label="头像" width="80" align="center" fixed="left">
|
<el-table-column label="头像" width="80" align="center" fixed="left">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-avatar :size="40" :src="scope.row.avatar" />
|
<el-avatar :size="40" :src="scope.row.avatar" />
|
||||||
@@ -67,7 +50,8 @@
|
|||||||
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center"
|
||||||
|
show-overflow-tooltip />
|
||||||
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
||||||
@@ -84,20 +68,10 @@
|
|||||||
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link size="small" @click="handleViewAbnormal(scope.row)">
|
||||||
type="primary"
|
详情
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleViewAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
异常考勤
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="success" link size="small" @click="handleApprove(scope.row)">
|
||||||
type="success"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleApprove(scope.row)"
|
|
||||||
>
|
|
||||||
审批
|
审批
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -106,17 +80,8 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 修改对话框 -->
|
<!-- 修改对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="editDialogVisible" title="修改考勤" width="800px">
|
||||||
v-model="editDialogVisible"
|
<el-form :model="editForm" :rules="editRules" ref="editFormRef" label-width="120px">
|
||||||
title="修改考勤"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
:model="editForm"
|
|
||||||
:rules="editRules"
|
|
||||||
ref="editFormRef"
|
|
||||||
label-width="120px"
|
|
||||||
>
|
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="事假" prop="personalLeave">
|
<el-form-item label="事假" prop="personalLeave">
|
||||||
@@ -229,19 +194,10 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 异常考勤详情对话框 -->
|
<!-- 异常考勤详情对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="abnormalDialogVisible" title="异常考勤详情" width="800px">
|
||||||
v-model="abnormalDialogVisible"
|
|
||||||
title="异常考勤详情"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
||||||
<div class="date-header">{{ date }}</div>
|
<div class="date-header">{{ date }}</div>
|
||||||
<el-table
|
<el-table :data="records" style="width: 100%" border stripe>
|
||||||
:data="records"
|
|
||||||
style="width: 100%"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column prop="type" label="异常类型" width="120">
|
<el-table-column prop="type" label="异常类型" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
||||||
@@ -256,12 +212,8 @@
|
|||||||
<div>考勤时间:{{ scope.row.baseCheckTime }}</div>
|
<div>考勤时间:{{ scope.row.baseCheckTime }}</div>
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
考勤结果:
|
考勤结果:
|
||||||
<el-select
|
<el-select v-model="scope.row.realResult" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.realResult"
|
@change="handleUpdateAbnormal(scope.row)">
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
<el-option label="正常" value="Normal" />
|
<el-option label="正常" value="Normal" />
|
||||||
<el-option label="早退" value="Early" />
|
<el-option label="早退" value="Early" />
|
||||||
<el-option label="迟到" value="Late" />
|
<el-option label="迟到" value="Late" />
|
||||||
@@ -274,26 +226,16 @@
|
|||||||
<template v-else-if="scope.row.type === 'checkin'">
|
<template v-else-if="scope.row.type === 'checkin'">
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
缺卡次数:
|
缺卡次数:
|
||||||
<el-input-number
|
<el-input-number v-model="scope.row.missedCount" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.missedCount"
|
:min="0" :max="10" @change="handleUpdateAbnormal(scope.row)" />
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
:min="0"
|
|
||||||
:max="10"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
/>
|
|
||||||
次
|
次
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="scope.row.type === 'report'">
|
<template v-else-if="scope.row.type === 'report'">
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
日志状态:
|
日志状态:
|
||||||
<el-select
|
<el-select v-model="scope.row.reportCount" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.reportCount"
|
@change="handleUpdateAbnormal(scope.row)">
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
<el-option label="未写日志" :value="0" />
|
<el-option label="未写日志" :value="0" />
|
||||||
<el-option label="正常" :value="1" />
|
<el-option label="正常" :value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -463,7 +405,7 @@ const handleSearch = () => {
|
|||||||
attendanceList.value = originalList.value;
|
attendanceList.value = originalList.value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attendanceList.value = originalList.value.filter(item =>
|
attendanceList.value = originalList.value.filter(item =>
|
||||||
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -563,7 +505,7 @@ const handleEdit = (row) => {
|
|||||||
// 提交修改
|
// 提交修改
|
||||||
const handleEditSubmit = async () => {
|
const handleEditSubmit = async () => {
|
||||||
if (!editFormRef.value) return;
|
if (!editFormRef.value) return;
|
||||||
|
|
||||||
await editFormRef.value.validate(async (valid) => {
|
await editFormRef.value.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
try {
|
try {
|
||||||
@@ -686,7 +628,7 @@ const handleViewAbnormal = async (row) => {
|
|||||||
const handleUpdateAbnormal = async (record) => {
|
const handleUpdateAbnormal = async (record) => {
|
||||||
// 保存原始值
|
// 保存原始值
|
||||||
const originalValue = record.realResult;
|
const originalValue = record.realResult;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
'确认修改该考勤记录?',
|
'确认修改该考勤记录?',
|
||||||
@@ -697,7 +639,7 @@ const handleUpdateAbnormal = async (record) => {
|
|||||||
type: 'warning',
|
type: 'warning',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const year = dateRange.value.getFullYear();
|
const year = dateRange.value.getFullYear();
|
||||||
const month = dateRange.value.getMonth() + 1;
|
const month = dateRange.value.getMonth() + 1;
|
||||||
const data = {
|
const data = {
|
||||||
@@ -799,7 +741,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.el-table) {
|
:deep(.el-table) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.el-table__body-wrapper {
|
.el-table__body-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -916,4 +858,4 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -5,47 +5,30 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="title">主管审批列表</span>
|
<span class="title">主管审批列表</span>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-date-picker
|
<el-date-picker v-model="dateRange" type="month" placeholder="选择月份" :default-time="defaultTime"
|
||||||
v-model="dateRange"
|
:shortcuts="dateShortcuts" @change="handleDateChange" style="width: 200px; margin-right: 8px;" />
|
||||||
type="month"
|
<el-input v-model="searchKeyword" placeholder="请输入姓名搜索" clearable @input="handleSearch"
|
||||||
placeholder="选择月份"
|
style="width: 200px; margin-right: 8px;">
|
||||||
:default-time="defaultTime"
|
|
||||||
:shortcuts="dateShortcuts"
|
|
||||||
@change="handleDateChange"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="searchKeyword"
|
|
||||||
placeholder="请输入姓名搜索"
|
|
||||||
clearable
|
|
||||||
@input="handleSearch"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon>
|
||||||
|
<Search />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<el-table :data="attendanceList" style="width: 100%" height="calc(100vh - 280px)" border stripe
|
||||||
:data="attendanceList"
|
|
||||||
style="width: 100%"
|
|
||||||
height="calc(100vh - 280px)"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
:header-cell-style="{
|
:header-cell-style="{
|
||||||
background: '#f5f7fa',
|
background: '#f5f7fa',
|
||||||
color: '#606266',
|
color: '#606266',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
padding: '12px 0'
|
padding: '12px 0'
|
||||||
}"
|
}" :cell-style="{
|
||||||
:cell-style="{
|
|
||||||
padding: '8px 0'
|
padding: '8px 0'
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
<el-table-column label="头像" width="80" align="center" fixed="left">
|
<el-table-column label="头像" width="80" align="center" fixed="left">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-avatar :size="40" :src="scope.row.avatar" />
|
<el-avatar :size="40" :src="scope.row.avatar" />
|
||||||
@@ -67,7 +50,8 @@
|
|||||||
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center"
|
||||||
|
show-overflow-tooltip />
|
||||||
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
||||||
@@ -79,33 +63,20 @@
|
|||||||
<el-table-column prop="workdayOvertime" label="工作日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="workdayOvertime" label="工作日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="restdayOvertime" label="休息日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="restdayOvertime" label="休息日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="holidayOvertime" label="节假日加班" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="holidayOvertime" label="节假日加班" width="120" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualPerformance" label="年度绩效" width="100" align="center" show-overflow-tooltip></el-table-column>
|
<el-table-column prop="annualPerformance" label="年度绩效" width="100" align="center"
|
||||||
<el-table-column prop="monthlyPerformance" label="月度绩效" width="100" align="center" show-overflow-tooltip></el-table-column>
|
show-overflow-tooltip></el-table-column>
|
||||||
|
<el-table-column prop="monthlyPerformance" label="月度绩效" width="100" align="center"
|
||||||
|
show-overflow-tooltip></el-table-column>
|
||||||
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column label="操作" width="280" fixed="right" align="center">
|
<el-table-column label="操作" width="280" fixed="right" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link size="small" @click="handleViewAbnormal(scope.row)">
|
||||||
type="primary"
|
详情
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleViewAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
异常考勤
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="success" link size="small" @click="handleApprove(scope.row)">
|
||||||
type="success"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleApprove(scope.row)"
|
|
||||||
>
|
|
||||||
审批
|
审批
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="warning" link size="small" @click="handleEditPerformance(scope.row)">
|
||||||
type="warning"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleEditPerformance(scope.row)"
|
|
||||||
>
|
|
||||||
修改绩效
|
修改绩效
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -114,19 +85,10 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 异常考勤详情对话框 -->
|
<!-- 异常考勤详情对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="abnormalDialogVisible" title="异常考勤详情" width="800px">
|
||||||
v-model="abnormalDialogVisible"
|
|
||||||
title="异常考勤详情"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
||||||
<div class="date-header">{{ date }}</div>
|
<div class="date-header">{{ date }}</div>
|
||||||
<el-table
|
<el-table :data="records" style="width: 100%" border stripe>
|
||||||
:data="records"
|
|
||||||
style="width: 100%"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column prop="type" label="异常类型" width="120">
|
<el-table-column prop="type" label="异常类型" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
||||||
@@ -168,36 +130,15 @@
|
|||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
<!-- 修改绩效对话框 -->
|
<!-- 修改绩效对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="performanceDialogVisible" title="修改绩效" width="500px">
|
||||||
v-model="performanceDialogVisible"
|
<el-form ref="performanceFormRef" :model="performanceForm" label-width="100px" :rules="performanceRules">
|
||||||
title="修改绩效"
|
|
||||||
width="500px"
|
|
||||||
>
|
|
||||||
<el-form
|
|
||||||
ref="performanceFormRef"
|
|
||||||
:model="performanceForm"
|
|
||||||
label-width="100px"
|
|
||||||
:rules="performanceRules"
|
|
||||||
>
|
|
||||||
<el-form-item label="年度绩效" prop="annualPerformance">
|
<el-form-item label="年度绩效" prop="annualPerformance">
|
||||||
<el-input-number
|
<el-input-number v-model="performanceForm.annualPerformance" :min="0" :max="100" :precision="1" :step="0.5"
|
||||||
v-model="performanceForm.annualPerformance"
|
style="width: 200px" />
|
||||||
:min="0"
|
|
||||||
:max="100"
|
|
||||||
:precision="1"
|
|
||||||
:step="0.5"
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="月度绩效" prop="monthlyPerformance">
|
<el-form-item label="月度绩效" prop="monthlyPerformance">
|
||||||
<el-input-number
|
<el-input-number v-model="performanceForm.monthlyPerformance" :min="0" :max="100" :precision="1" :step="0.5"
|
||||||
v-model="performanceForm.monthlyPerformance"
|
style="width: 200px" />
|
||||||
:min="0"
|
|
||||||
:max="100"
|
|
||||||
:precision="1"
|
|
||||||
:step="0.5"
|
|
||||||
style="width: 200px"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
@@ -300,7 +241,7 @@ const handleSearch = () => {
|
|||||||
attendanceList.value = originalList.value;
|
attendanceList.value = originalList.value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attendanceList.value = originalList.value.filter(item =>
|
attendanceList.value = originalList.value.filter(item =>
|
||||||
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -480,7 +421,7 @@ const handleEditPerformance = (row) => {
|
|||||||
// 提交绩效表单
|
// 提交绩效表单
|
||||||
const submitPerformanceForm = async () => {
|
const submitPerformanceForm = async () => {
|
||||||
if (!performanceFormRef.value) return;
|
if (!performanceFormRef.value) return;
|
||||||
|
|
||||||
await performanceFormRef.value.validate(async (valid) => {
|
await performanceFormRef.value.validate(async (valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
try {
|
try {
|
||||||
@@ -530,7 +471,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.el-table) {
|
:deep(.el-table) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.el-table__body-wrapper {
|
.el-table__body-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -653,4 +594,4 @@ onMounted(() => {
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -5,47 +5,30 @@
|
|||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
<span class="title">综合部复审列表</span>
|
<span class="title">综合部复审列表</span>
|
||||||
<div class="header-right">
|
<div class="header-right">
|
||||||
<el-date-picker
|
<el-date-picker v-model="dateRange" type="month" placeholder="选择月份" :default-time="defaultTime"
|
||||||
v-model="dateRange"
|
:shortcuts="dateShortcuts" @change="handleDateChange" style="width: 200px; margin-right: 8px;" />
|
||||||
type="month"
|
<el-input v-model="searchKeyword" placeholder="请输入姓名搜索" clearable @input="handleSearch"
|
||||||
placeholder="选择月份"
|
style="width: 200px; margin-right: 8px;">
|
||||||
:default-time="defaultTime"
|
|
||||||
:shortcuts="dateShortcuts"
|
|
||||||
@change="handleDateChange"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
/>
|
|
||||||
<el-input
|
|
||||||
v-model="searchKeyword"
|
|
||||||
placeholder="请输入姓名搜索"
|
|
||||||
clearable
|
|
||||||
@input="handleSearch"
|
|
||||||
style="width: 200px; margin-right: 8px;"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
<template #prefix>
|
||||||
<el-icon><Search /></el-icon>
|
<el-icon>
|
||||||
|
<Search />
|
||||||
|
</el-icon>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-table
|
<el-table :data="attendanceList" style="width: 100%" height="calc(100vh - 280px)" border stripe
|
||||||
:data="attendanceList"
|
|
||||||
style="width: 100%"
|
|
||||||
height="calc(100vh - 280px)"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
:header-cell-style="{
|
:header-cell-style="{
|
||||||
background: '#f5f7fa',
|
background: '#f5f7fa',
|
||||||
color: '#606266',
|
color: '#606266',
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
padding: '12px 0'
|
padding: '12px 0'
|
||||||
}"
|
}" :cell-style="{
|
||||||
:cell-style="{
|
|
||||||
padding: '8px 0'
|
padding: '8px 0'
|
||||||
}"
|
}">
|
||||||
>
|
|
||||||
<el-table-column label="头像" width="80" align="center" fixed="left">
|
<el-table-column label="头像" width="80" align="center" fixed="left">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-avatar :size="40" :src="scope.row.avatar" />
|
<el-avatar :size="40" :src="scope.row.avatar" />
|
||||||
@@ -67,7 +50,8 @@
|
|||||||
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="marriageLeave" label="婚假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="bereavementLeave" label="丧假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="annualLeave" label="年休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center" show-overflow-tooltip />
|
<el-table-column prop="managementAnnualLeave" label="年休假(管理岗)" width="120" align="center"
|
||||||
|
show-overflow-tooltip />
|
||||||
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="compensatoryLeave" label="调休假" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="early" label="早退次数" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="late" label="迟到次数" width="100" align="center" show-overflow-tooltip />
|
||||||
@@ -84,20 +68,10 @@
|
|||||||
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
<el-table-column prop="penaltyAmount" label="违纪扣奖" width="100" align="center" show-overflow-tooltip />
|
||||||
<el-table-column label="操作" width="200" fixed="right" align="center">
|
<el-table-column label="操作" width="200" fixed="right" align="center">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-button
|
<el-button type="primary" link size="small" @click="handleViewAbnormal(scope.row)">
|
||||||
type="primary"
|
详情
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleViewAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
异常考勤
|
|
||||||
</el-button>
|
</el-button>
|
||||||
<el-button
|
<el-button type="success" link size="small" @click="handleApprove(scope.row)">
|
||||||
type="success"
|
|
||||||
link
|
|
||||||
size="small"
|
|
||||||
@click="handleApprove(scope.row)"
|
|
||||||
>
|
|
||||||
审批
|
审批
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
@@ -106,19 +80,10 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<!-- 异常考勤详情对话框 -->
|
<!-- 异常考勤详情对话框 -->
|
||||||
<el-dialog
|
<el-dialog v-model="abnormalDialogVisible" title="异常考勤详情" width="800px">
|
||||||
v-model="abnormalDialogVisible"
|
|
||||||
title="异常考勤详情"
|
|
||||||
width="800px"
|
|
||||||
>
|
|
||||||
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
<div v-for="(records, date) in abnormalList" :key="date" class="abnormal-date-group">
|
||||||
<div class="date-header">{{ date }}</div>
|
<div class="date-header">{{ date }}</div>
|
||||||
<el-table
|
<el-table :data="records" style="width: 100%" border stripe>
|
||||||
:data="records"
|
|
||||||
style="width: 100%"
|
|
||||||
border
|
|
||||||
stripe
|
|
||||||
>
|
|
||||||
<el-table-column prop="type" label="异常类型" width="120">
|
<el-table-column prop="type" label="异常类型" width="120">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
<el-tag :type="getAbnormalTypeTag(scope.row.type)">
|
||||||
@@ -133,12 +98,8 @@
|
|||||||
<div>考勤时间:{{ scope.row.baseCheckTime }}</div>
|
<div>考勤时间:{{ scope.row.baseCheckTime }}</div>
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
考勤结果:
|
考勤结果:
|
||||||
<el-select
|
<el-select v-model="scope.row.realResult" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.realResult"
|
@change="handleUpdateAbnormal(scope.row)">
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
<el-option label="正常" value="Normal" />
|
<el-option label="正常" value="Normal" />
|
||||||
<el-option label="早退" value="Early" />
|
<el-option label="早退" value="Early" />
|
||||||
<el-option label="迟到" value="Late" />
|
<el-option label="迟到" value="Late" />
|
||||||
@@ -151,26 +112,16 @@
|
|||||||
<template v-else-if="scope.row.type === 'checkin'">
|
<template v-else-if="scope.row.type === 'checkin'">
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
缺卡次数:
|
缺卡次数:
|
||||||
<el-input-number
|
<el-input-number v-model="scope.row.missedCount" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.missedCount"
|
:min="0" :max="10" @change="handleUpdateAbnormal(scope.row)" />
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
:min="0"
|
|
||||||
:max="10"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
/>
|
|
||||||
次
|
次
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="scope.row.type === 'report'">
|
<template v-else-if="scope.row.type === 'report'">
|
||||||
<div class="result-row">
|
<div class="result-row">
|
||||||
日志状态:
|
日志状态:
|
||||||
<el-select
|
<el-select v-model="scope.row.reportCount" size="small" style="width: 100px; margin: 0 8px;"
|
||||||
v-model="scope.row.reportCount"
|
@change="handleUpdateAbnormal(scope.row)">
|
||||||
size="small"
|
|
||||||
style="width: 100px; margin: 0 8px;"
|
|
||||||
@change="handleUpdateAbnormal(scope.row)"
|
|
||||||
>
|
|
||||||
<el-option label="未写日志" :value="0" />
|
<el-option label="未写日志" :value="0" />
|
||||||
<el-option label="正常" :value="1" />
|
<el-option label="正常" :value="1" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -289,7 +240,7 @@ const handleSearch = () => {
|
|||||||
attendanceList.value = originalList.value;
|
attendanceList.value = originalList.value;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
attendanceList.value = originalList.value.filter(item =>
|
attendanceList.value = originalList.value.filter(item =>
|
||||||
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
item.name.toLowerCase().includes(searchKeyword.value.toLowerCase())
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -440,7 +391,7 @@ const handleViewAbnormal = async (row) => {
|
|||||||
const handleUpdateAbnormal = async (record) => {
|
const handleUpdateAbnormal = async (record) => {
|
||||||
// 保存原始值
|
// 保存原始值
|
||||||
const originalValue = record.realResult;
|
const originalValue = record.realResult;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm(
|
await ElMessageBox.confirm(
|
||||||
'确认修改该考勤记录?',
|
'确认修改该考勤记录?',
|
||||||
@@ -451,7 +402,7 @@ const handleUpdateAbnormal = async (record) => {
|
|||||||
type: 'warning',
|
type: 'warning',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const year = dateRange.value.getFullYear();
|
const year = dateRange.value.getFullYear();
|
||||||
const month = dateRange.value.getMonth() + 1;
|
const month = dateRange.value.getMonth() + 1;
|
||||||
const data = {
|
const data = {
|
||||||
@@ -533,7 +484,7 @@ onMounted(() => {
|
|||||||
|
|
||||||
:deep(.el-table) {
|
:deep(.el-table) {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
.el-table__body-wrapper {
|
.el-table__body-wrapper {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
@@ -650,4 +601,4 @@ onMounted(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
margin-top: 4px;
|
margin-top: 4px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user