238 lines
8.2 KiB
C#
238 lines
8.2 KiB
C#
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}"
|
||
};
|
||
}
|
||
}
|
||
} |