Commit 400adca2 authored by ‘老张’'s avatar ‘老张’

员工年假和填报工时优化

parent 8d8af891
import request from '@/utils/request' import request from '@/utils/request'
// 查询员工年假列表 // 查询员工余额列表
export function listAnnualleave(query) { export function listBalance(query) {
return request({ return request({
url: '/system/annualleave/list', url: '/system/balance/list',
method: 'get', method: 'get',
params: query params: query
}) })
} }
// 查询员工年假详细 // 查询员工余额详细
export function getAnnualleave(id) { export function getBalance(id) {
return request({ return request({
url: '/system/annualleave/' + id, url: '/system/balance/' + id,
method: 'get' method: 'get'
}) })
} }
// 新增员工年假 // 新增员工余额
export function addAnnualleave(data) { export function addBalance(data) {
return request({ return request({
url: '/system/annualleave', url: '/system/balance',
method: 'post', method: 'post',
data: data data: data
}) })
} }
// 修改员工年假 // 修改员工余额
export function updateAnnualleave(data) { export function updateBalance(data) {
return request({ return request({
url: '/system/annualleave', url: '/system/balance',
method: 'put', method: 'put',
data: data data: data
}) })
} }
// 删除员工年假 // 删除员工余额
export function delAnnualleave(id) { export function delBalance(id) {
return request({ return request({
url: '/system/annualleave/' + id, url: '/system/balance/' + id,
method: 'delete' method: 'delete'
}) })
} }
...@@ -3,20 +3,43 @@ ...@@ -3,20 +3,43 @@
<!-- 搜索框容器 --> <!-- 搜索框容器 -->
<div class="search-container"> <div class="search-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px"> <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
<el-form-item label="姓名" prop="uname"> <el-form-item label="员工ID" prop="employeeId">
<el-input v-model="queryParams.uname" placeholder="请输入姓名" clearable @keyup.enter="handleQuery" /> <el-input
v-model="queryParams.employeeId"
placeholder="请输入员工ID"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item> </el-form-item>
<el-form-item label="年份" prop="year"> <el-form-item label="年假余额" prop="annualLeaveBalance">
<el-date-picker v-model="queryParams.year" type="year" value-format="YYYY" placeholder="请选择年份" <el-input
:editable="false" @change="handleYearChange" :picker-options="pickerOptions" /> v-model="queryParams.annualLeaveBalance"
placeholder="请输入年假余额"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item> </el-form-item>
<el-form-item label="创建时间" prop="createdTime"> <el-form-item label="加班时长余额" prop="overtimeHoursBalance">
<el-date-picker clearable v-model="queryParams.createdTime" type="date" value-format="YYYY-MM-DD" <el-input
v-model="queryParams.overtimeHoursBalance"
placeholder="请输入加班时长余额"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
<el-form-item label="创建时间" prop="createdAt">
<el-date-picker clearable
v-model="queryParams.createdAt"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择创建时间"> placeholder="请选择创建时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="更新时间" prop="updatedTime"> <el-form-item label="更新时间" prop="updatedAt">
<el-date-picker clearable v-model="queryParams.updatedTime" type="date" value-format="YYYY-MM-DD" <el-date-picker clearable
v-model="queryParams.updatedAt"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择更新时间"> placeholder="请选择更新时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
...@@ -34,54 +57,60 @@ ...@@ -34,54 +57,60 @@
<div class="table - title - container"> <div class="table - title - container">
<div class="table-container"> <div class="table-container">
<div class="div1"></div> <div class="div1"></div>
<span class="leave-application-title">员工年假</span> <span class="leave-application-title">员工余额</span>
<span class="add"> <span class="add">
<el-tooltip content="新增" placement="top" > <el-tooltip content="新增" placement="top" >
<el-button <el-button
type="text" type="text"
plain plain
@click="handleAdd" @click="handleAdd"
v-hasPermi="['psa:annualleave:add']" v-hasPermi="['system:balance:add']"
>新增</el-button> >新增</el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="导出" placement="top" > <el-tooltip content="导出" placement="top" >
<el-button <el-button
type="text" type="text"
plain plain
@click="handleExport" @click="handleExport"
v-hasPermi="['system:project:export']" v-hasPermi="['system:balance:export']"
><img src="../../../assets/icons/common/export2.png" height="35" width="35"/> ><img src="../../../assets/icons/common/export2.png" height="35" width="35"/>
</el-button> </el-button>
</el-tooltip> </el-tooltip>
</span> </span>
<div class="leave-application-line"></div>
<div class="leave-application-line"></div> <el-table v-loading="loading" :data="balanceList" @selection-change="handleSelectionChange" border>
<el-table v-loading="loading" :data="annualleaveList" @selection-change="handleSelectionChange" border>
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="姓名" align="center" width="120" prop="uname" /> <el-table-column label="唯一标识每条记录" align="center" prop="id" />
<el-table-column label="年份" align="center" width="120" prop="year" /> <el-table-column label="员工ID" align="center" prop="employeeId" />
<el-table-column label="总年假天数" align="center" width="120" prop="totalDays" /> <el-table-column label="年假余额" align="center" prop="annualLeaveBalance">
<el-table-column label="已使用年假天数" align="center" width="120" prop="usedDays" /> <template #default="scope">
<el-table-column label="剩余年假天数" align="center" width="120" prop="remainingDays" /> <span>{{ scope.row.annualLeaveBalance }}</span>
<el-table-column label="创建时间" align="center" width="180" prop="createdTime"> </template>
</el-table-column>
<el-table-column label="加班时长余额" align="center" prop="overtimeHoursBalance">
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.createdTime, '{y}-{m}-{d}') }}</span> <span>{{ scope.row.overtimeHoursBalance }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="更新时间" align="center" width="180" prop="updatedTime"> <el-table-column label="创建时间" align="center" prop="createdAt" width="180">
<template #default="scope"> <template #default="scope">
<span>{{ parseTime(scope.row.updatedTime, '{y}-{m}-{d}') }}</span> <span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d}') }}</span>
</template>
</el-table-column>
<el-table-column label="更新时间" align="center" prop="updatedAt" width="180">
<template #default="scope">
<span>{{ parseTime(scope.row.updatedAt, '{y}-{m}-{d}') }}</span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-tooltip content="编辑" placement="top"> <el-tooltip content="编辑" placement="top">
<a class="icon-margin" @click="handleUpdate(scope.row)" v-hasPermi="['psa:annualleave:edit']"> <a class="icon-margin" @click="handleUpdate(scope.row)" v-hasPermi="['system:balance:edit']">
<img src="@/assets/icons/common/edit.png" alt="修改图标" /> <img src="@/assets/icons/common/edit.png" alt="修改图标" />
</a> </a>
</el-tooltip> </el-tooltip>
<el-tooltip content="删除" placement="top"> <el-tooltip content="删除" placement="top">
<a class="icon-margin2" @click="handleDelete(scope.row)" v-hasPermi="['psa:annualleave:remove']"> <a class="icon-margin2" @click="handleDelete(scope.row)" v-hasPermi="['system:balance:remove']">
<img src="@/assets/icons/common/delete.png" alt="删除图标"> <img src="@/assets/icons/common/delete.png" alt="删除图标">
</a> </a>
</el-tooltip> </el-tooltip>
...@@ -94,28 +123,45 @@ ...@@ -94,28 +123,45 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 添加或修改员工余额对话框 -->
<el-dialog :title="title" v-model="open" width="500px" append-to-body> <el-dialog :title="title" v-model="open" width="500px" append-to-body>
<el-form ref="annualleaveRef" :model="form" :rules="rules" label-width="80px"> <el-form ref="balanceRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="姓名" prop="uname"> <el-form-item label="员工ID" prop="employeeId">
<el-input v-model="form.uname" placeholder="请输入姓名" /> <el-input v-model="form.employeeId" placeholder="请输入员工ID" />
</el-form-item> </el-form-item>
<el-form-item label="年份" prop="year"> <el-form-item label="年假余额" prop="annualLeaveBalance">
<el-date-picker v-model="form.year" type="year" value-format="YYYY" placeholder="请选择年份" :editable="false" <el-input-number
@change="handleYearChange" :picker-options="pickerOptions" /> v-model="form.annualLeaveBalance"
:min="0"
:precision="1"
:step="0.5"
:max="999.5"
placeholder="请输入年假余额"
/>
</el-form-item> </el-form-item>
<el-form-item label="总年假天数" prop="totalDays"> <el-form-item label="加班时长余额" prop="overtimeHoursBalance">
<el-input-number v-model="form.totalDays" :min="0" placeholder="请输入总年假天数" /> <el-input-number
v-model="form.overtimeHoursBalance"
:min="0"
:precision="1"
:step="0.5"
:max="999.5"
placeholder="请输入加班时长余额"
/>
</el-form-item> </el-form-item>
<el-form-item label="已使用年假天数" prop="usedDays"> <el-form-item label="创建时间" prop="createdAt">
<el-input-number v-model="form.usedDays" :min="0" placeholder="请输入已使用年假天数" /> <el-date-picker clearable
</el-form-item> v-model="form.createdAt"
<el-form-item label="创建时间" prop="createdTime"> type="date"
<el-date-picker clearable v-model="form.createdTime" type="date" value-format="YYYY-MM-DD" value-format="YYYY-MM-DD"
placeholder="请选择创建时间"> placeholder="请选择创建时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
<el-form-item label="更新时间" prop="updatedTime"> <el-form-item label="更新时间" prop="updatedAt">
<el-date-picker clearable v-model="form.updatedTime" type="date" value-format="YYYY-MM-DD" <el-date-picker clearable
v-model="form.updatedAt"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择更新时间"> placeholder="请选择更新时间">
</el-date-picker> </el-date-picker>
</el-form-item> </el-form-item>
...@@ -130,13 +176,13 @@ ...@@ -130,13 +176,13 @@
</div> </div>
</template> </template>
<script setup name="Annualleave"> <script setup name="Balance">
import { listAnnualleave, getAnnualleave, delAnnualleave, addAnnualleave, updateAnnualleave } from "@/api/system/annualleave"; import { listBalance, getBalance, delBalance, addBalance, updateBalance } from "@/api/system/balance";
import { getCurrentInstance, ref, reactive, toRefs, onMounted } from 'vue'; import { getCurrentInstance, ref, reactive, toRefs, onMounted } from 'vue';
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const annualleaveList = ref([]); const balanceList = ref([]);
const open = ref(false); const open = ref(false);
const loading = ref(true); const loading = ref(true);
const showSearch = ref(true); const showSearch = ref(true);
...@@ -151,57 +197,33 @@ const data = reactive({ ...@@ -151,57 +197,33 @@ const data = reactive({
queryParams: { queryParams: {
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
userId: null, employeeId: null,
uname: null, annualLeaveBalance: null,
year: null, overtimeHoursBalance: null,
createdTime: null, createdAt: null,
updatedTime: null updatedAt: null
}, },
rules: { rules: {
uname: [ employeeId: [
{ required: true, message: "姓名不能为空", trigger: "blur" } { required: true, message: "员工ID不能为空", trigger: "blur" }
],
year: [
{ required: true, message: "年份不能为空", trigger: "blur" }
], ],
totalDays: [ annualLeaveBalance: [
{ required: true, message: "总年假天数不能为空", trigger: "blur" } { required: true, message: "年假余额不能为空", trigger: "blur" }
], ],
usedDays: [ overtimeHoursBalance: [
{ required: true, message: "已使用年假天数不能为空", trigger: "blur" } { required: true, message: "加班时长余额不能为空", trigger: "blur" }
],
remainingDays: [
{ required: true, message: "剩余年假天数不能为空", trigger: "blur" }
], ],
} }
}); });
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
// 日期选择器的配置项
const pickerOptions = {
shortcuts: false,
format: 'YYYY',
valueFormat: 'YYYY',
startDate: '1900-01-01',
endDate: new Date().toISOString().split('T')[0],
onPick: (date) => {
queryParams.value.year = date.getFullYear();
}
};
// 年份选择改变时的处理函数
const handleYearChange = (val) => {
queryParams.value.year = val;
form.value.year = val;
};
/** 查询员工余额列表 */
/** 查询员工年假列表 */
function getList() { function getList() {
loading.value = true; loading.value = true;
listAnnualleave(queryParams.value).then(response => { listBalance(queryParams.value).then(response => {
annualleaveList.value = response.rows; balanceList.value = response.rows;
total.value = response.total; total.value = response.total;
loading.value = false; loading.value = false;
}); });
...@@ -217,16 +239,13 @@ function cancel() { ...@@ -217,16 +239,13 @@ function cancel() {
function reset() { function reset() {
form.value = { form.value = {
id: null, id: null,
userId: null, employeeId: null,
year: null, annualLeaveBalance: null,
totalDays: null, overtimeHoursBalance: null,
usedDays: null, createdAt: null,
remainingDays: null, updatedAt: null
createdTime: null,
updatedTime: null,
uname: null
}; };
proxy.resetForm("annualleaveRef"); proxy.resetForm("balanceRef");
} }
/** 搜索按钮操作 */ /** 搜索按钮操作 */
...@@ -237,14 +256,16 @@ function handleQuery() { ...@@ -237,14 +256,16 @@ function handleQuery() {
/** 重置按钮操作 */ /** 重置按钮操作 */
function resetQuery() { function resetQuery() {
// 重置姓名搜索框 // 重置员工ID搜索框
queryParams.value.uname = null; queryParams.value.employeeId = null;
// 重置年假余额搜索框
queryParams.value.annualLeaveBalance = null;
// 重置加班时长余额搜索框
queryParams.value.overtimeHoursBalance = null;
// 重置创建时间搜索框 // 重置创建时间搜索框
queryParams.value.createdTime = null; queryParams.value.createdAt = null;
// 重置更新时间搜索框 // 重置更新时间搜索框
queryParams.value.updatedTime = null; queryParams.value.updatedAt = null;
// 设置年份为当前年份
queryParams.value.year = new Date().getFullYear();
getList(); getList();
} }
...@@ -258,54 +279,33 @@ function handleSelectionChange(selection) { ...@@ -258,54 +279,33 @@ function handleSelectionChange(selection) {
/** 新增按钮操作 */ /** 新增按钮操作 */
function handleAdd() { function handleAdd() {
reset(); reset();
// 设置默认年份为当前年份
const currentYear = new Date().getFullYear();
form.value.year = currentYear;
// 设置默认年假天数为10天
form.value.totalDays = 10;
open.value = true; open.value = true;
title.value = "添加员工年假"; title.value = "添加员工余额";
} }
/** 修改按钮操作 */ /** 修改按钮操作 */
function handleUpdate(row) { function handleUpdate(row) {
reset(); reset();
const _id = row.id || ids.value; const _id = row.id || ids.value
getAnnualleave(_id).then(response => { getBalance(_id).then(response => {
form.value = response.data; form.value = response.data;
// 确保年份格式正确
if (form.value.year) {
form.value.year = String(form.value.year); // 转换为字符串格式,确保和日期选择器兼容
}
open.value = true; open.value = true;
title.value = "修改员工年假"; title.value = "修改员工余额";
}); });
} }
/** 提交按钮 */ /** 提交按钮 */
function submitForm() { function submitForm() {
proxy.$refs["annualleaveRef"].validate(valid => { proxy.$refs["balanceRef"].validate(valid => {
if (valid) { if (valid) {
// 验证返回值为 -2 时,显示员工不存在
if (form.value.userId == -2) {
proxy.$modal.msgError("员工不存在,请重新选择员工");
return;
}
// 验证已使用天数不能超过总天数
if (form.value.usedDays > form.value.totalDays) {
proxy.$modal.msgError("已使用年假天数不能超过总年假天数");
return;
}
if (form.value.id != null) { if (form.value.id != null) {
updateAnnualleave(form.value).then(response => { updateBalance(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功"); proxy.$modal.msgSuccess("修改成功");
open.value = false; open.value = false;
getList(); getList();
}); });
} else { } else {
addAnnualleave(form.value).then(response => { addBalance(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功"); proxy.$modal.msgSuccess("新增成功");
open.value = false; open.value = false;
getList(); getList();
...@@ -318,26 +318,23 @@ function submitForm() { ...@@ -318,26 +318,23 @@ function submitForm() {
/** 删除按钮操作 */ /** 删除按钮操作 */
function handleDelete(row) { function handleDelete(row) {
const _ids = row.id || ids.value; const _ids = row.id || ids.value;
proxy.$modal.confirm('是否确认删除员工年假编号为"' + _ids + '"的数据项?').then(function () { proxy.$modal.confirm('是否确认删除员工余额编号为"' + _ids + '"的数据项?').then(function() {
return delAnnualleave(_ids); return delBalance(_ids);
}).then(() => { }).then(() => {
getList(); getList();
proxy.$modal.msgSuccess("删除成功"); proxy.$modal.msgSuccess("删除成功");
}).catch(() => { }); }).catch(() => {});
} }
/** 导出按钮操作 */ /** 导出按钮操作 */
function handleExport() { function handleExport() {
proxy.download('system/annualleave/export', { proxy.download('system/balance/export', {
...queryParams.value ...queryParams.value
}, `annualleave_${new Date().getTime()}.xlsx`); }, `balance_${new Date().getTime()}.xlsx`)
} }
// 进入页面时自动设置查询参数为当前年份 // 进入页面时自动设置查询参数
onMounted(() => { onMounted(() => {
const currentYear = new Date().getFullYear();
queryParams.value.year = currentYear;
form.value.year = currentYear;
getList(); getList();
}); });
...@@ -403,4 +400,4 @@ onMounted(() => { ...@@ -403,4 +400,4 @@ onMounted(() => {
height: 22px; height: 22px;
width: 200px; width: 200px;
} }
</style> </style>
\ No newline at end of file \ No newline at end of file
...@@ -284,30 +284,46 @@ const submitProject = async () => { ...@@ -284,30 +284,46 @@ const submitProject = async () => {
/** 查询工时记录列表 */ /** 查询工时记录列表 */
function getList(employId) { function getList(employId) {
loading.value = true; loading.value = true;
getPersonalTimesheet(employId).then(response => {
console.log(response) // 从本地存储获取缓存数据
if (Array.isArray(response)) { // 检查是否为数组 const cachedData = localStorage.getItem(`timesheet_${employId}`);
personalTimesheetList.value = response.map(project => ({ if (cachedData) {
...project, personalTimesheetList.value = JSON.parse(cachedData);
addWorkList: project.addWorkList.map(day => ({ }
...day,
hours: Number(day.hours) || 0, getPersonalTimesheet(employId).then(response => {
})), console.log(response);
totalHours: project.totalHours || 0, if (Array.isArray(response)) {
approvalState: parseInt(project.approvalState), const newData = response.map(project => ({
departmentLeaderName: project.departmentLeaderName || '', ...project,
})); addWorkList: project.addWorkList.map(day => ({
...day,
hours: Number(day.hours) || 0,
})),
totalHours: project.totalHours || 0,
approvalState: parseInt(project.approvalState),
departmentLeaderName: project.departmentLeaderName || '',
}));
// 对比数据是否相同
const isSame = JSON.stringify(newData) === cachedData;
if (!isSame) {
personalTimesheetList.value = newData;
// 将新数据存入本地存储
localStorage.setItem(`timesheet_${employId}`, JSON.stringify(newData));
}
} else { } else {
console.error("Invalid response format:", response); console.error("Invalid response format:", response);
} }
loading.value = false; loading.value = false;
}) })
.catch(error => { .catch(error => {
// console.error("API error:", error); console.error("API error:", error);
loading.value = false; loading.value = false;
}); });
} }
const A =(data)=>{ const A =(data)=>{
getPersonalTimesheet(data).then(response => { getPersonalTimesheet(data).then(response => {
if (response.code === 200) { if (response.code === 200) {
......
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