Commit 6996feeb authored by ‘老张’'s avatar ‘老张’

考勤管理中请假申请和请假审批(审批通过更新员工年假)以及加班列表分页问题的解决和加班申请更新员工年假

parent fab3c56d
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
placeholder="请选择姓名" placeholder="请选择姓名"
class="custom-input" class="custom-input"
@focus="loadUsernames" @focus="loadUsernames"
@change="handleUserNameChange"
> >
<el-option <el-option
v-for="user in userOptions" v-for="user in userOptions"
...@@ -230,6 +231,20 @@ const loadUsernames = () => { ...@@ -230,6 +231,20 @@ const loadUsernames = () => {
} }
}; };
// 处理姓名选择变化
const handleUserNameChange = () => {
const selectedUser = userOptions.value.find(user => user.label === form.uname);
if (selectedUser) {
const selectedUserId = selectedUser.value;
// 把选中员工的id赋值给form.userId
form.userId = selectedUserId;
getBalanceInfo(selectedUserId).then(() => {
uploadPromptMessage.value = `已获取 ${form.uname} 的余额信息`;
}).catch(() => {
uploadPromptMessage.value = `获取 ${form.uname} 的余额信息失败`;
});
}
};
// 存储后端返回的项目负责人列表 // 存储后端返回的项目负责人列表
const projectManagers = ref([]) const projectManagers = ref([])
...@@ -301,7 +316,7 @@ const handleLeaveTypeChange = (value) => { ...@@ -301,7 +316,7 @@ const handleLeaveTypeChange = (value) => {
} }
// 如果选择倒休(假设 leaveType 值为 2 表示倒休) // 如果选择倒休(假设 leaveType 值为 2 表示倒休)
else if (value == 2) { else if (value == 2) {
getBalanceInfo().then(() => { getBalanceInfo(form.userId).then(() => {
uploadPromptMessage.value = `剩余可抵消加班时长 ${form.overtimeHoursBalance} 小时`; uploadPromptMessage.value = `剩余可抵消加班时长 ${form.overtimeHoursBalance} 小时`;
}).catch(() => { }).catch(() => {
uploadPromptMessage.value = '获取加班时长失败'; uploadPromptMessage.value = '获取加班时长失败';
...@@ -309,7 +324,7 @@ const handleLeaveTypeChange = (value) => { ...@@ -309,7 +324,7 @@ const handleLeaveTypeChange = (value) => {
} }
// 如果选择年假(leaveType 值为 4 表示年假) // 如果选择年假(leaveType 值为 4 表示年假)
else if (value == 4) { else if (value == 4) {
getBalanceInfo().then(() => { getBalanceInfo(form.userId).then(() => {
uploadPromptMessage.value = `剩余可用年假 ${form.annualLeaveBalance} 天`; uploadPromptMessage.value = `剩余可用年假 ${form.annualLeaveBalance} 天`;
}).catch(() => { }).catch(() => {
uploadPromptMessage.value = '获取年假余额失败'; uploadPromptMessage.value = '获取年假余额失败';
...@@ -384,7 +399,8 @@ const handleTimeChange = () => { ...@@ -384,7 +399,8 @@ const handleTimeChange = () => {
// 如果当前请假类型需要进行余额抵扣(例如病假、倒休、年假、事假等) // 如果当前请假类型需要进行余额抵扣(例如病假、倒休、年假、事假等)
if (["0", "2", "4", "7"].includes(form.leaveType)) { if (["0", "2", "4", "7"].includes(form.leaveType)) {
// 调用余额和抵扣逻辑 // 调用余额和抵扣逻辑
getBalanceInfo().then(() => { if(form.userId){
getBalanceInfo(form.userId).then(() => {
const success = offsetLeave(); const success = offsetLeave();
uploadPromptMessage.value = success uploadPromptMessage.value = success
? `已抵消:${form.deductionOvertimeHours}` ? `已抵消:${form.deductionOvertimeHours}`
...@@ -393,6 +409,7 @@ const handleTimeChange = () => { ...@@ -393,6 +409,7 @@ const handleTimeChange = () => {
uploadPromptMessage.value = '获取余额失败'; uploadPromptMessage.value = '获取余额失败';
}); });
} }
}
}; };
...@@ -465,31 +482,23 @@ const calculateLeaveTime = (start, end, holidays) => { ...@@ -465,31 +482,23 @@ const calculateLeaveTime = (start, end, holidays) => {
return { leaveDays, leaveHours }; return { leaveDays, leaveHours };
}; };
//判断userId 是否为空 //判断userId 是否为空
function getBalanceInfo() { function getBalanceInfo(userId) {
// 如果还没有 userId,就先调用 userStore.getInfo() return fetchBalanceInfo(userId);
if (!userStore.userId) {
return userStore.getInfo().then(userInfo => {
userStore.userId = userInfo.user.userId;
return callBalanceAPI(userStore.userId);
});
} else {
return callBalanceAPI(userStore.userId);
}
} }
// 通过userId 调用 API,查询个人加班时长和年假天数 // 通过userId 调用 API,查询个人加班时长和年假天数
function callBalanceAPI(userId) { function fetchBalanceInfo(userId) {
return getDeductionOvertimeHoursByUserId(userId) return getDeductionOvertimeHoursByUserId(userId)
.then(response => { .then(response => {
console.log('接口返回:', response); console.log('接口返回:', response);
// 假设返回结构为: { "overtimeHoursBalance": 17.0, "annualLeaveBalance": 10.0 } // 假设返回结构为: { "overtimeHoursBalance": 17.0, "annualLeaveBalance": 10.0 }
form.overtimeHoursBalance = response.overtimeHoursBalance; form.overtimeHoursBalance = response.overtimeHoursBalance;
form.annualLeaveBalance = response.annualLeaveBalance; form.annualLeaveBalance = response.annualLeaveBalance;
}) })
.catch(error => { .catch(error => {
console.error('获取加班/年假余额失败', error); console.error('获取加班/年假余额失败', error);
throw error; // 抛出错误,以便在调用处捕获 throw error; // 抛出错误,以便在调用处捕获
}); });
} }
/** /**
...@@ -511,17 +520,23 @@ function offsetLeave() { ...@@ -511,17 +520,23 @@ function offsetLeave() {
let remainingGap = 0; // 不足部分(小时) let remainingGap = 0; // 不足部分(小时)
if (totalAvailableHours >= requiredHours) { if (totalAvailableHours >= requiredHours) {
if (availableOvertime >= requiredHours) { if (form.leaveType === '2') { // 如果是倒休
overtimeUsed = requiredHours; overtimeUsed = requiredHours <= availableOvertime? requiredHours : availableOvertime;
annualLeaveUsedHours = 0; annualLeaveUsedHours = 0;
} else { } else if (form.leaveType === '4') { // 如果是年假
overtimeUsed = availableOvertime; const requiredDays = requiredHours / 8;
annualLeaveUsedHours = requiredHours - availableOvertime; annualLeaveUsedHours = requiredDays <= availableAnnualLeave? requiredHours : availableAnnualLeaveInHours;
overtimeUsed = 0;
} }
remainingGap = 0; remainingGap = 0;
} else { } else {
overtimeUsed = availableOvertime; if (form.leaveType === '2') { // 如果是倒休
annualLeaveUsedHours = availableAnnualLeaveInHours; overtimeUsed = availableOvertime;
annualLeaveUsedHours = 0;
} else if (form.leaveType === '4') { // 如果是年假
annualLeaveUsedHours = availableAnnualLeaveInHours;
overtimeUsed = 0;
}
remainingGap = requiredHours - totalAvailableHours; remainingGap = requiredHours - totalAvailableHours;
} }
...@@ -539,48 +554,22 @@ function offsetLeave() { ...@@ -539,48 +554,22 @@ function offsetLeave() {
} }
/** 保存按钮操作 **/ /** 保存按钮操作 **/
const handleSubmit = () => { const handleSubmit = () => {
formRef.value.validate((valid) => { formRef.value.validate((valid) => {
if (valid) { if (valid) {
// 如果 secondApproverDisabled 为 true,说明请假天数小于等于 3 天,将 secondApprover 清空
if (secondApproverDisabled.value) { if (secondApproverDisabled.value) {
form.secondApprover = null; form.secondApprover = null;
} }
// 先提交请假申请(存储到 leave_application 表) addApplication(form)
addApplication(form) .then(response => {
.then(response => { ElMessage.success('保存成功');
// 提交成功后,根据 leaveType 判断是否需要更新余额 router.push({ path: '/attendance/leave' });
const skipTypes = ['1', '5', '6', '3', '8', '9']; // leaveType 为这些值时跳过余额更新 })
if (skipTypes.includes(String(form.leaveType))) { .catch(error => {
ElMessage.success('保存成功'); ElMessage.error('保存失败');
router.push({ path: '/attendance/leave' }); console.error(error);
} else { });
// 构造更新余额数据
const updateData = {
employeeId: form.userId, // 用登录时的 userId 作为 employeeId
overtimeHoursBalance: form.overtimeHoursBalance,
annualLeaveBalance: form.annualLeaveBalance
};
updateOvertimeHoursBalance(updateData)
.then(res => {
console.log('更新加班时长成功', res);
ElMessage.success('保存成功');
router.push({ path: '/attendance/leave' });
})
.catch(err => {
console.error('更新加班时长失败', err);
// 如果余额更新失败,但申请已提交,也提示成功,并跳转
ElMessage.success('保存成功,但余额更新失败');
router.push({ path: '/attendance/leave' });
});
}
})
.catch(error => {
ElMessage.error('保存失败');
console.error(error);
});
} else { } else {
ElMessage.error('表单验证失败,请检查输入'); ElMessage.error('表单验证失败,请检查输入');
} }
......
...@@ -516,7 +516,7 @@ const handleCancel = () => { ...@@ -516,7 +516,7 @@ const handleCancel = () => {
} }
::v-deep(.el-input__inner) { ::v-deep(.el-input__inner) {
ont-family: PingFangSC-Medium; font-family: PingFangSC-Medium;
font-weight: 500; font-weight: 500;
font-size: 16px; font-size: 16px;
color: #0062FF; color: #0062FF;
......
...@@ -176,6 +176,7 @@ import { ...@@ -176,6 +176,7 @@ import {
getOvertimeApplication getOvertimeApplication
} from '../../../api/application/overtimeApplication.js' } from '../../../api/application/overtimeApplication.js'
import { listAllUser } from '../../../api/onboardmanage/onboardmanage.js' import { listAllUser } from '../../../api/onboardmanage/onboardmanage.js'
import { getBalance, addBalance, updateBalance } from '../../../api/system/balance.js'
// 创建 formRef 引用 // 创建 formRef 引用
const formRef = ref(null) const formRef = ref(null)
const router = useRouter() // 创建路由器实例 const router = useRouter() // 创建路由器实例
...@@ -212,6 +213,7 @@ watch(() => form.employeeId, (newValue) => { ...@@ -212,6 +213,7 @@ watch(() => form.employeeId, (newValue) => {
const selectedOption = userOptions.value.find(option => option.value === newValue); const selectedOption = userOptions.value.find(option => option.value === newValue);
if (selectedOption) { if (selectedOption) {
form.uname = selectedOption.label; form.uname = selectedOption.label;
console.log('id:', form.employeeId); // 调试日志
} else { } else {
form.uname = undefined; form.uname = undefined;
} }
...@@ -392,21 +394,49 @@ const handleCancel = () => { ...@@ -392,21 +394,49 @@ const handleCancel = () => {
const handleSave = () => { const handleSave = () => {
formRef.value.validate(valid => { formRef.value.validate(valid => {
if (valid) { if (valid) {
// 保存加班申请
addOvertimeApplication(form) addOvertimeApplication(form)
.then(response => { .then(response => {
ElMessage.success('保存成功') ElMessage.success('保存成功');
// 跳转到 application/index.vue 页面 const employeeId = form.employeeId;
router.push({ path: '/attendance/overtime' }) // 查询员工余额
return getBalance(employeeId);
}) })
.catch(error => { .then(balanceResponse => {
ElMessage.error('保存失败') console.log('Balance Response:', balanceResponse.data); // 调试日志
console.error(error) if (balanceResponse.data) {
// 员工存在,更新加班时长余额
const currentOvertimeHoursBalance = parseFloat(balanceResponse.data.overtimeHoursBalance);
const overtimeHours = parseFloat(form.overtimeHours);
const newOvertimeHoursBalance = currentOvertimeHoursBalance + overtimeHours;
const updateData = {
...balanceResponse.data,
overtimeHoursBalance: newOvertimeHoursBalance
};
return updateBalance(updateData);
} else {
// 员工不存在,新增记录
const newData = {
employeeId: form.employeeId,
annualLeaveBalance: 0,
overtimeHoursBalance: parseFloat(form.overtimeHours)
};
return addBalance(newData);
}
}) })
.then(() => {
// 跳转到加班申请列表页面
router.push({ path: '/attendance/overtime' });
})
.catch(error => {
ElMessage.error('保存或更新余额失败');
console.error(error);
});
} else { } else {
ElMessage.error('表单验证失败,请检查输入') ElMessage.error('表单验证失败,请检查输入');
} }
}) });
} };
function getAllUserList() { function getAllUserList() {
listAllUser().then(response => { listAllUser().then(response => {
......
...@@ -517,7 +517,7 @@ getList() ...@@ -517,7 +517,7 @@ getList()
/* 主体样式*/ /* 主体样式*/
.main { .main {
width: 1622px; width: 1622px;
height: 823px; height: 880px;
background: #ffffff; background: #ffffff;
box-shadow: 0 2px 2px 0 #b3b3b380; box-shadow: 0 2px 2px 0 #b3b3b380;
border-radius: 2px; border-radius: 2px;
......
...@@ -82,12 +82,12 @@ ...@@ -82,12 +82,12 @@
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="唯一标识每条记录" align="center" prop="id" /> <el-table-column label="唯一标识每条记录" align="center" prop="id" />
<el-table-column label="员工ID" align="center" prop="employeeId" /> <el-table-column label="员工ID" align="center" prop="employeeId" />
<el-table-column label="年假余额" align="center" prop="annualLeaveBalance"> <el-table-column label="年假余额/天" align="center" prop="annualLeaveBalance">
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.annualLeaveBalance }}</span> <span>{{ scope.row.annualLeaveBalance }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="加班时长余额" align="center" prop="overtimeHoursBalance"> <el-table-column label="加班时长余额/小时" align="center" prop="overtimeHoursBalance">
<template #default="scope"> <template #default="scope">
<span>{{ scope.row.overtimeHoursBalance }}</span> <span>{{ scope.row.overtimeHoursBalance }}</span>
</template> </template>
...@@ -144,27 +144,11 @@ ...@@ -144,27 +144,11 @@
v-model="form.overtimeHoursBalance" v-model="form.overtimeHoursBalance"
:min="0" :min="0"
:precision="1" :precision="1"
:step="0.5" :step="0.1"
:max="999.5" :max="999.9"
placeholder="请输入加班时长余额" placeholder="请输入加班时长余额"
/> />
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="createdAt">
<el-date-picker clearable
v-model="form.createdAt"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择创建时间">
</el-date-picker>
</el-form-item>
<el-form-item label="更新时间" prop="updatedAt">
<el-date-picker clearable
v-model="form.updatedAt"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择更新时间">
</el-date-picker>
</el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment