Asoka.Wang 21f044712c 1
2025-08-27 18:39:19 +08:00

214 lines
6.9 KiB
C#

using System.Threading.Tasks;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Microsoft.AspNetCore.Mvc;
using ZhonTai.Admin.Core.Dto;
using ZhonTai.Admin.Services;
using NPP.SmartSchedue.Api.Contracts.Services.Work;
using NPP.SmartSchedue.Api.Contracts.Services.Work.Input;
using NPP.SmartSchedue.Api.Contracts.Services.Work.Output;
using NPP.SmartSchedue.Api.Repositories.Work;
using NPP.SmartSchedue.Api.Contracts.Domain.Work;
using ZhonTai.DynamicApi;
using ZhonTai.DynamicApi.Attributes;
namespace NPP.SmartSchedue.Api.Services.Work;
/// <summary>
/// 工序服务
/// </summary>
[DynamicApi(Area = "app")]
public class ProcessService : BaseService, IProcessService, IDynamicApi
{
private readonly ProcessRepository _processRepository;
private readonly ProcessGroupRelationRepository _processGroupRelationRepository;
/// <summary>
/// 【线程安全修复】静态锁对象,用于避免 FreeSql RepositoryDbContext 并发键冲突
/// </summary>
private static readonly SemaphoreSlim _dbAccessSemaphore = new(5, 5); // 允许最多5个并发数据库访问
public ProcessService(ProcessRepository processRepository, ProcessGroupRelationRepository processGroupRelationRepository)
{
_processRepository = processRepository;
_processGroupRelationRepository = processGroupRelationRepository;
}
/// <summary>
/// 查询
/// 【线程安全修复】使用信号量控制并发访问,避免 FreeSql RepositoryDbContext 键冲突
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task<ProcessGetOutput> GetAsync(long id)
{
await _dbAccessSemaphore.WaitAsync();
try
{
var output = await _processRepository.Select
.WhereDynamic(id)
.ToOneAsync<ProcessGetOutput>();
return output;
}
finally
{
_dbAccessSemaphore.Release();
}
}
/// <summary>
/// 查询分页
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost]
public async Task<PageOutput<ProcessGetPageOutput>> GetPageAsync(PageInput<ProcessGetPageInput> input)
{
var list = await _processRepository.Select
.WhereIf(!string.IsNullOrEmpty(input.Filter?.ProcessCode), a => a.ProcessCode.Contains(input.Filter.ProcessCode))
.WhereIf(!string.IsNullOrEmpty(input.Filter?.ProcessName), a => a.ProcessName.Contains(input.Filter.ProcessName))
.WhereIf(!string.IsNullOrEmpty(input.Filter?.ProcessCategory), a => a.ProcessCategory.Contains(input.Filter.ProcessCategory))
.WhereIf(input.Filter?.IsEnabled.HasValue == true, a => a.IsEnabled == input.Filter.IsEnabled.Value)
.Count(out var total)
.OrderByDescending(a => a.Id)
.Page(input.CurrentPage, input.PageSize)
.ToListAsync<ProcessGetPageOutput>();
var data = new PageOutput<ProcessGetPageOutput>()
{
List = list,
Total = total
};
return data;
}
/// <summary>
/// 添加
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task<long> AddAsync(ProcessAddInput input)
{
var entity = Mapper.Map<ProcessEntity>(input);
var result = await _processRepository.InsertAsync(entity);
return result.Id;
}
/// <summary>
/// 修改
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public async Task UpdateAsync(ProcessUpdateInput input)
{
var entity = await _processRepository.GetAsync(input.Id);
Mapper.Map(input, entity);
await _processRepository.UpdateAsync(entity);
}
/// <summary>
/// 删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task DeleteAsync(long id)
{
await _processRepository.DeleteAsync(id);
}
/// <summary>
/// 软删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task SoftDeleteAsync(long id)
{
await _processRepository.SoftDeleteAsync(id);
}
/// <summary>
/// 批量软删除
/// </summary>
/// <param name="ids"></param>
/// <returns></returns>
public async Task BatchSoftDeleteAsync(long[] ids)
{
await _processRepository.SoftDeleteAsync(ids);
}
/// <summary>
/// 启用工序
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task EnableAsync(long id)
{
var entity = await _processRepository.GetAsync(id);
if (entity != null)
{
entity.IsEnabled = true;
await _processRepository.UpdateAsync(entity);
}
}
/// <summary>
/// 禁用工序
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public async Task DisableAsync(long id)
{
var entity = await _processRepository.GetAsync(id);
if (entity != null)
{
entity.IsEnabled = false;
await _processRepository.UpdateAsync(entity);
}
}
/// <summary>
/// 根据工序组ID获取工序列表
/// </summary>
/// <param name="processGroupId">工序组ID</param>
/// <returns>工序列表</returns>
public async Task<List<ProcessInfo>> GetProcessesByGroupIdAsync(long processGroupId)
{
var relations = await _processGroupRelationRepository.Select
.Where(a => a.ProcessGroupId == processGroupId && a.IsEnabled)
.OrderBy(a => a.RelationOrder)
.ToListAsync();
var processIds = relations.Select(r => r.ProcessId).ToArray();
var processes = await _processRepository.Select
.Where(a => processIds.Contains(a.Id))
.ToListAsync();
var result = new List<ProcessInfo>();
foreach (var relation in relations)
{
var process = processes.FirstOrDefault(p => p.Id == relation.ProcessId);
if (process != null)
{
result.Add(new ProcessInfo
{
ProcessGroupId = relation.ProcessGroupId,
ProcessId = relation.ProcessId,
ProcessCode = process.ProcessCode,
ProcessName = process.ProcessName,
ProcessCategory = process.ProcessCategory,
EquipmentType = process.EquipmentType,
TheoreticalDuration = process.TheoreticalDuration,
RelationOrder = relation.RelationOrder,
RelationType = relation.RelationType,
PredecessorProcessId = relation.PredecessorProcessId,
SuccessorProcessId = relation.SuccessorProcessId,
});
}
}
return result;
}
}