paiban/NPP.SmartSchedue.Api/Services/Time/EmployeeLeaveService.cs
Asoka.Wang 21f044712c 1
2025-08-27 18:39:19 +08:00

238 lines
8.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using NPP.SmartSchedue.Api.Contracts.Services.Time;
using NPP.SmartSchedue.Api.Contracts.Services.Time.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Time.Output;
using NPP.SmartSchedue.Api.Repositories.Time;
using NPP.SmartSchedue.Api.Contracts.Domain.Time;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
namespace NPP.SmartSchedue.Api.Services.Time;
/// <summary>
/// 员工休假服务
/// </summary>
[DynamicApi(Area = "app")]
public class EmployeeLeaveService : BaseService, IEmployeeLeaveService, IDynamicApi
{
private readonly EmployeeLeaveRepository _employeeLeaveRepository;
public EmployeeLeaveService(EmployeeLeaveRepository employeeLeaveRepository)
{
_employeeLeaveRepository = employeeLeaveRepository;
}
/// <summary>
/// 查询
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<EmployeeLeaveGetOutput> GetAsync(long id)
{
var output = await _employeeLeaveRepository.Select
.WhereDynamic(id)
.ToOneAsync<EmployeeLeaveGetOutput>();
return output;
}
/// <summary>
/// 查询分页
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<EmployeeLeaveGetPageOutput>> GetPageAsync(PageInput<EmployeeLeaveGetPageInput> input)
{
var list = await _employeeLeaveRepository.Select
.WhereIf(input.Filter?.EmployeeId.HasValue == true, a => a.EmployeeId == input.Filter.EmployeeId.Value)
.WhereIf(!string.IsNullOrEmpty(input.Filter?.LeaveType), a => a.LeaveType.Contains(input.Filter.LeaveType))
.WhereIf(!string.IsNullOrEmpty(input.Filter?.Status), a => a.Status.Contains(input.Filter.Status))
.Count(out var total)
.OrderByDescending(a => a.Id)
.Page(input.CurrentPage, input.PageSize)
.ToListAsync<EmployeeLeaveGetPageOutput>();
var data = new PageOutput<EmployeeLeaveGetPageOutput>()
{
List = list,
Total = total
};
return data;
}
/// <summary>
/// 添加
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<long> AddAsync(EmployeeLeaveAddInput input)
{
var entity = Mapper.Map<EmployeeLeaveEntity>(input);
entity.Status = "approved";
var result = await _employeeLeaveRepository.InsertAsync(entity);
return result.Id;
}
/// <summary>
/// 修改
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task UpdateAsync(EmployeeLeaveUpdateInput input)
{
var entity = await _employeeLeaveRepository.GetAsync(input.Id);
Mapper.Map(input, entity);
entity.Status = "approved";
await _employeeLeaveRepository.UpdateAsync(entity);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task DeleteAsync(long id)
{
await _employeeLeaveRepository.DeleteAsync(id);
}
/// <summary>
/// 软删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task SoftDeleteAsync(long id)
{
await _employeeLeaveRepository.SoftDeleteAsync(id);
}
/// <summary>
/// 批量软删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task BatchSoftDeleteAsync(long[] ids)
{
await _employeeLeaveRepository.SoftDeleteAsync(ids);
}
/// <summary>
/// 获取员工在指定时间段内的已批准请假记录
/// </summary>
/// <param name="employeeId">员工ID</param>
/// <param name="startTime">开始时间</param>
/// <param name="endTime">结束时间</param>
/// <returns></returns>
public async Task<List<EmployeeLeaveGetPageOutput>> GetApprovedLeavesByEmployeeAndTimeRangeAsync(
long employeeId,
DateTime startTime,
DateTime endTime)
{
var leaves = await _employeeLeaveRepository.Select
.Where(a => a.EmployeeId == employeeId)
.Where(a => a.Status == "Approved") // 只查询已批准的请假
.Where(a => a.StartTime <= endTime && a.EndTime >= startTime) // 时间段重叠判断
.ToListAsync<EmployeeLeaveGetPageOutput>();
return leaves;
}
/// <summary>
/// 检查员工在指定时间段内是否有请假
/// </summary>
/// <param name="employeeId">员工ID</param>
/// <param name="startTime">开始时间</param>
/// <param name="endTime">结束时间</param>
/// <returns></returns>
public async Task<bool> HasApprovedLeaveInTimeRangeAsync(
long employeeId,
DateTime startTime,
DateTime endTime)
{
var hasLeave = await _employeeLeaveRepository.Select
.Where(a => a.EmployeeId == employeeId)
.Where(a => a.Status == "Approved") // 只查询已批准的请假
.Where(a => a.StartTime <= endTime && a.EndTime >= startTime) // 时间段重叠判断
.AnyAsync();
return hasLeave;
}
/// <summary>
/// 检查员工在指定日期是否在请假
/// 智能分配系统专用方法,返回详细的请假信息
/// 深度业务思考:全面检查员工在指定日期的请假状态,支持多个重叠请假记录的场景
/// </summary>
/// <param name="employeeId">员工ID</param>
/// <param name="checkDate">检查日期</param>
/// <returns>请假状态信息</returns>
public async Task<EmployeeLeaveStatusResult> IsOnLeaveAsync(long employeeId, DateTime checkDate)
{
try
{
// 将检查日期标准化为当天的日期范围00:00:00 到 23:59:59
var checkDateStart = checkDate.Date;
var checkDateEnd = checkDateStart.AddDays(1).AddTicks(-1);
// 查询该员工在指定日期范围内所有已批准的请假记录
var leaveRecords = await _employeeLeaveRepository.Select
.Where(a => a.EmployeeId == employeeId)
.Where(a => a.Status == "approved" || a.Status == "Approved") // 兼容不同的状态值格式
.Where(a => a.StartTime <= checkDateEnd && a.EndTime >= checkDateStart) // 时间段重叠判断
.OrderBy(a => a.StartTime)
.ToListAsync();
var result = new EmployeeLeaveStatusResult
{
CheckDate = checkDate,
IsOnLeave = leaveRecords.Any(),
LeaveRecords = new List<EmployeeLeaveInfo>()
};
if (!leaveRecords.Any())
{
// 没有请假记录
return result;
}
// 转换请假记录到简化格式
result.LeaveRecords = leaveRecords.Select(record => new EmployeeLeaveInfo
{
Id = record.Id,
LeaveType = record.LeaveType,
StartTime = record.StartTime,
EndTime = record.EndTime,
Reason = record.Reason
}).ToList();
// 设置主要请假信息(如果有多个重叠请假,取最早开始的一个作为主要信息)
var primaryLeave = leaveRecords.First();
result.LeaveType = primaryLeave.LeaveType;
result.LeaveStartTime = primaryLeave.StartTime;
result.LeaveEndTime = primaryLeave.EndTime;
result.LeaveReason = primaryLeave.Reason;
result.LeaveRecordId = primaryLeave.Id;
return result;
}
catch (Exception ex)
{
// 异常情况下返回安全的默认结果
return new EmployeeLeaveStatusResult
{
CheckDate = checkDate,
IsOnLeave = false,
LeaveRecords = new List<EmployeeLeaveInfo>(),
LeaveReason = $"请假状态检查异常:{ex.Message}"
};
}
}
}