Commit 3667cd9c by ruyun.zhang@suvalue.com

Merge branch '多分支合并' into v2020morge

parents a45a289e fff0604a
using System; using Microsoft.Extensions.Hosting;
using System.Collections.Concurrent; using Microsoft.Extensions.Logging;
using Performance.Services.Queues;
using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace Performance.Api namespace Performance.Api
{ {
public interface IBackgroundTaskQueue
{
void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem);
Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new ConcurrentQueue<Func<CancellationToken, Task>>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
_workItems.Enqueue(workItem);
_signal.Release();
}
public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_workItems.TryDequeue(out var workItem);
return workItem;
}
}
public class QueuedHostedService : BackgroundService public class QueuedHostedService : BackgroundService
{ {
private readonly ILogger<QueuedHostedService> _logger; private readonly ILogger<QueuedHostedService> _logger;
...@@ -87,4 +55,5 @@ public class QueuedHostedService : BackgroundService ...@@ -87,4 +55,5 @@ public class QueuedHostedService : BackgroundService
await base.StopAsync(stoppingToken); await base.StopAsync(stoppingToken);
} }
} }
}
\ No newline at end of file }
...@@ -3,17 +3,14 @@ ...@@ -3,17 +3,14 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.DtoModels.AppSettings; using Performance.DtoModels.AppSettings;
using Performance.EntityModels; using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services; using Performance.Services;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Security.Claims; using System.Security.Claims;
using System.Threading.Tasks;
namespace Performance.Api.Controllers namespace Performance.Api.Controllers
{ {
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
using Performance.Infrastructure; using Performance.Infrastructure;
using Performance.Services; using Performance.Services;
using Performance.Services.AllotCompute; using Performance.Services.AllotCompute;
using Performance.Services.Queues;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
...@@ -197,17 +198,17 @@ public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody] A ...@@ -197,17 +198,17 @@ public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody] A
} }
else else
{ {
BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1)); //BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1));
//_backgroundTaskQueue.QueueBackgroundWorkItem(async token => _backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
//{ {
// using (var scope = _serviceScopeFactory.CreateScope()) using (var scope = _serviceScopeFactory.CreateScope())
// { {
// var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>(); var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
// scopedServices.Generate(allot, email); scopedServices.Generate(allot, email);
// await Task.Delay(TimeSpan.FromSeconds(5), token); await Task.Delay(TimeSpan.FromSeconds(5), token);
// } }
//}); });
} }
logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage"); logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage");
......
using FluentValidation.AspNetCore; using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services; using Performance.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Performance.Api.Controllers namespace Performance.Api.Controllers
{ {
...@@ -21,6 +11,7 @@ public class AssessController : Controller ...@@ -21,6 +11,7 @@ public class AssessController : Controller
private ClaimService claimService; private ClaimService claimService;
private AssessService assessService; private AssessService assessService;
private UserService userService; private UserService userService;
public AssessController(ClaimService claimService, public AssessController(ClaimService claimService,
AssessService assessService, UserService userService) AssessService assessService, UserService userService)
{ {
...@@ -32,7 +23,7 @@ public class AssessController : Controller ...@@ -32,7 +23,7 @@ public class AssessController : Controller
//考核类别列表 //考核类别列表
[HttpPost] [HttpPost]
[Route("assesslist")] [Route("assesslist")]
public ApiResponse AssessList([CustomizeValidator(RuleSet = "List"), FromBody]AssessRequest request) public ApiResponse AssessList([CustomizeValidator(RuleSet = "List"), FromBody] AssessRequest request)
{ {
return assessService.AssessList(request.AllotID); return assessService.AssessList(request.AllotID);
} }
...@@ -40,7 +31,7 @@ public ApiResponse AssessList([CustomizeValidator(RuleSet = "List"), FromBody]As ...@@ -40,7 +31,7 @@ public ApiResponse AssessList([CustomizeValidator(RuleSet = "List"), FromBody]As
//新增考核类别 //新增考核类别
[HttpPost] [HttpPost]
[Route("addassess")] [Route("addassess")]
public ApiResponse AddAssess([CustomizeValidator(RuleSet = "Add"), FromBody]AssessRequest request) public ApiResponse AddAssess([CustomizeValidator(RuleSet = "Add"), FromBody] AssessRequest request)
{ {
return assessService.AddAssess(request.AllotID, request.AssessName); return assessService.AddAssess(request.AllotID, request.AssessName);
} }
...@@ -48,7 +39,7 @@ public ApiResponse AddAssess([CustomizeValidator(RuleSet = "Add"), FromBody]Asse ...@@ -48,7 +39,7 @@ public ApiResponse AddAssess([CustomizeValidator(RuleSet = "Add"), FromBody]Asse
//修改考核类别 //修改考核类别
[HttpPost] [HttpPost]
[Route("editassess")] [Route("editassess")]
public ApiResponse EditAssess([CustomizeValidator(RuleSet = "Update"), FromBody]AssessRequest request) public ApiResponse EditAssess([CustomizeValidator(RuleSet = "Update"), FromBody] AssessRequest request)
{ {
return assessService.EditAssess(request.AssessID, request.AssessName); return assessService.EditAssess(request.AssessID, request.AssessName);
} }
...@@ -56,7 +47,7 @@ public ApiResponse EditAssess([CustomizeValidator(RuleSet = "Update"), FromBody] ...@@ -56,7 +47,7 @@ public ApiResponse EditAssess([CustomizeValidator(RuleSet = "Update"), FromBody]
//删除考核类别 //删除考核类别
[HttpPost] [HttpPost]
[Route("delassess")] [Route("delassess")]
public ApiResponse DelAssess([CustomizeValidator(RuleSet = "Del"), FromBody]AssessRequest request) public ApiResponse DelAssess([CustomizeValidator(RuleSet = "Del"), FromBody] AssessRequest request)
{ {
return assessService.DelAssess(request.AssessID); return assessService.DelAssess(request.AssessID);
} }
...@@ -64,7 +55,7 @@ public ApiResponse DelAssess([CustomizeValidator(RuleSet = "Del"), FromBody]Asse ...@@ -64,7 +55,7 @@ public ApiResponse DelAssess([CustomizeValidator(RuleSet = "Del"), FromBody]Asse
//获取所有科室列表 //获取所有科室列表
[HttpPost] [HttpPost]
[Route("departmentlist")] [Route("departmentlist")]
public ApiResponse DepartmentList([CustomizeValidator(RuleSet = "Use"), FromBody]AssessRequest request) public ApiResponse DepartmentList([CustomizeValidator(RuleSet = "Use"), FromBody] AssessRequest request)
{ {
var department = assessService.Department(request); var department = assessService.Department(request);
return new ApiResponse(ResponseType.OK, "ok", department); return new ApiResponse(ResponseType.OK, "ok", department);
...@@ -73,7 +64,7 @@ public ApiResponse DepartmentList([CustomizeValidator(RuleSet = "Use"), FromBody ...@@ -73,7 +64,7 @@ public ApiResponse DepartmentList([CustomizeValidator(RuleSet = "Use"), FromBody
//设置科室考核分类 //设置科室考核分类
[HttpPost] [HttpPost]
[Route("setassesstype")] [Route("setassesstype")]
public ApiResponse SetAssessType([FromBody]SetAssessRequest request) public ApiResponse SetAssessType([FromBody] SetAssessRequest request)
{ {
return assessService.SetAssessType(request); return assessService.SetAssessType(request);
} }
...@@ -81,7 +72,7 @@ public ApiResponse SetAssessType([FromBody]SetAssessRequest request) ...@@ -81,7 +72,7 @@ public ApiResponse SetAssessType([FromBody]SetAssessRequest request)
//考核列头列表 //考核列头列表
[HttpPost] [HttpPost]
[Route("columnlist")] [Route("columnlist")]
public ApiResponse ColumnList([CustomizeValidator(RuleSet = "List"), FromBody]AssessColumnRequest request) public ApiResponse ColumnList([CustomizeValidator(RuleSet = "List"), FromBody] AssessColumnRequest request)
{ {
return assessService.ColumnList(request.AssessID); return assessService.ColumnList(request.AssessID);
} }
...@@ -89,7 +80,7 @@ public ApiResponse ColumnList([CustomizeValidator(RuleSet = "List"), FromBody]As ...@@ -89,7 +80,7 @@ public ApiResponse ColumnList([CustomizeValidator(RuleSet = "List"), FromBody]As
//新增考核项 //新增考核项
[HttpPost] [HttpPost]
[Route("addcolumn")] [Route("addcolumn")]
public ApiResponse AddColumn([CustomizeValidator(RuleSet = "Add"), FromBody]AssessColumnRequest request) public ApiResponse AddColumn([CustomizeValidator(RuleSet = "Add"), FromBody] AssessColumnRequest request)
{ {
return assessService.AddColumn(request.AssessID, request.ParentID, request.ColumnName, request.Sort); return assessService.AddColumn(request.AssessID, request.ParentID, request.ColumnName, request.Sort);
} }
...@@ -97,7 +88,7 @@ public ApiResponse AddColumn([CustomizeValidator(RuleSet = "Add"), FromBody]Asse ...@@ -97,7 +88,7 @@ public ApiResponse AddColumn([CustomizeValidator(RuleSet = "Add"), FromBody]Asse
//修改考核项 //修改考核项
[HttpPost] [HttpPost]
[Route("editcolumn")] [Route("editcolumn")]
public ApiResponse EditColumn([CustomizeValidator(RuleSet = "Update"), FromBody]AssessColumnRequest request) public ApiResponse EditColumn([CustomizeValidator(RuleSet = "Update"), FromBody] AssessColumnRequest request)
{ {
return assessService.EditColumn(request.ColumnID, request.ColumnName, request.Sort); return assessService.EditColumn(request.ColumnID, request.ColumnName, request.Sort);
} }
...@@ -105,7 +96,7 @@ public ApiResponse EditColumn([CustomizeValidator(RuleSet = "Update"), FromBody] ...@@ -105,7 +96,7 @@ public ApiResponse EditColumn([CustomizeValidator(RuleSet = "Update"), FromBody]
//删除考核项 //删除考核项
[HttpPost] [HttpPost]
[Route("delcolumn")] [Route("delcolumn")]
public ApiResponse DelColumn([CustomizeValidator(RuleSet = "Del"), FromBody]AssessColumnRequest request) public ApiResponse DelColumn([CustomizeValidator(RuleSet = "Del"), FromBody] AssessColumnRequest request)
{ {
return assessService.DelColumn(request.ColumnID); return assessService.DelColumn(request.ColumnID);
} }
...@@ -113,7 +104,7 @@ public ApiResponse DelColumn([CustomizeValidator(RuleSet = "Del"), FromBody]Asse ...@@ -113,7 +104,7 @@ public ApiResponse DelColumn([CustomizeValidator(RuleSet = "Del"), FromBody]Asse
//考核数据列表 //考核数据列表
[HttpPost] [HttpPost]
[Route("datalist")] [Route("datalist")]
public ApiResponse DataList([CustomizeValidator(RuleSet = "List"), FromBody]AssessDataRequest request) public ApiResponse DataList([CustomizeValidator(RuleSet = "List"), FromBody] AssessDataRequest request)
{ {
return assessService.DataList(request.AssessID); return assessService.DataList(request.AssessID);
} }
...@@ -121,7 +112,7 @@ public ApiResponse DataList([CustomizeValidator(RuleSet = "List"), FromBody]Asse ...@@ -121,7 +112,7 @@ public ApiResponse DataList([CustomizeValidator(RuleSet = "List"), FromBody]Asse
//考核数据修改 //考核数据修改
[HttpPost] [HttpPost]
[Route("editassessdata")] [Route("editassessdata")]
public ApiResponse EditAssessData([CustomizeValidator(RuleSet = "Edit"), FromBody]AssessDataRequest request) public ApiResponse EditAssessData([CustomizeValidator(RuleSet = "Edit"), FromBody] AssessDataRequest request)
{ {
return assessService.EditAssessData(request.AssessRow); return assessService.EditAssessData(request.AssessRow);
} }
...@@ -137,7 +128,7 @@ public ApiResponse TempAssessList() ...@@ -137,7 +128,7 @@ public ApiResponse TempAssessList()
//模板列头列表 //模板列头列表
[HttpPost] [HttpPost]
[Route("tempcolumnlist")] [Route("tempcolumnlist")]
public ApiResponse TempColumnList([CustomizeValidator(RuleSet = "List"), FromBody]AssessColumnRequest request) public ApiResponse TempColumnList([CustomizeValidator(RuleSet = "List"), FromBody] AssessColumnRequest request)
{ {
return assessService.TempColumnList(request.AssessID); return assessService.TempColumnList(request.AssessID);
} }
...@@ -145,9 +136,9 @@ public ApiResponse TempColumnList([CustomizeValidator(RuleSet = "List"), FromBod ...@@ -145,9 +136,9 @@ public ApiResponse TempColumnList([CustomizeValidator(RuleSet = "List"), FromBod
//使用考核模版 //使用考核模版
[HttpPost] [HttpPost]
[Route("usetemplate")] [Route("usetemplate")]
public ApiResponse UseTemplate([CustomizeValidator(RuleSet = "Use"), FromBody]AssessRequest request) public ApiResponse UseTemplate([CustomizeValidator(RuleSet = "Use"), FromBody] AssessRequest request)
{ {
return assessService.UseTemplate(request.AllotID, request.AssessID); return assessService.UseTemplate(request.AllotID, request.AssessID);
} }
} }
} }
\ No newline at end of file
...@@ -289,20 +289,17 @@ public ApiResponse AllComputeByPM([FromBody] ComputerRequest request) ...@@ -289,20 +289,17 @@ public ApiResponse AllComputeByPM([FromBody] ComputerRequest request)
if (list == null || !list.Any()) if (list == null || !list.Any())
return new ApiResponse(ResponseType.OK, "ok", list); return new ApiResponse(ResponseType.OK, "ok", list);
var result = list.GroupBy(t => new { t.Source, t.EmployeeName, t.JobNumber }).Select(t => new ComputeResponse var result = list.GroupBy(t => new { t.EmployeeName, t.JobNumber }).Select(t => new ComputeResponse
{ {
Source = t.Key.Source,
EmployeeName = t.Key.EmployeeName, EmployeeName = t.Key.EmployeeName,
JobNumber = t.Key.JobNumber, JobNumber = t.Key.JobNumber,
PerforSumFee = t.Sum(s => s.PerforSumFee), PerforSumFee = t.Sum(s => s.PerforSumFee),
PerforManagementFee = t.Sum(s => s.PerforManagementFee), PerforManagementFee = t.Sum(s => s.PerforManagementFee),
Adjust = t.FirstOrDefault()?.Adjust ?? 0,
AdjustLaterOtherFee = t.Sum(s => s.AdjustLaterOtherFee), AdjustLaterOtherFee = t.Sum(s => s.AdjustLaterOtherFee),
ShouldGiveFee = t.Sum(s => s.ShouldGiveFee), ShouldGiveFee = t.Sum(s => s.ShouldGiveFee),
OthePerfor = t.Sum(s => s.OthePerfor), OthePerfor = t.Sum(s => s.OthePerfor),
NightWorkPerfor = t.Sum(s => s.NightWorkPerfor), NightWorkPerfor = t.Sum(s => s.NightWorkPerfor),
RealGiveFee = t.Sum(s => s.RealGiveFee), RealGiveFee = t.Sum(s => s.RealGiveFee),
JobTitle = t.FirstOrDefault(f => !string.IsNullOrEmpty(f.JobTitle))?.JobTitle
//ReservedRatio = t.Sum(s => s.ReservedRatio), //ReservedRatio = t.Sum(s => s.ReservedRatio),
//ReservedRatioFee = t.Sum(s => s.ReservedRatioFee), //ReservedRatioFee = t.Sum(s => s.ReservedRatioFee),
}); });
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
using Performance.Infrastructure; using Performance.Infrastructure;
using Performance.Services; using Performance.Services;
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
...@@ -427,5 +428,39 @@ public ApiResponse Import([FromForm] IFormCollection form) ...@@ -427,5 +428,39 @@ public ApiResponse Import([FromForm] IFormCollection form)
employeeService.ImpoerAprEmployees(allotid, path, claim.GetUserId()); employeeService.ImpoerAprEmployees(allotid, path, claim.GetUserId());
return new ApiResponse(ResponseType.OK); return new ApiResponse(ResponseType.OK);
} }
/// <summary>
/// 自动获取人员信息
/// </summary>
/// <remarks>
/// Sample request:
///
/// POST /Todo
/// {
/// "allotid": 7,
/// "personnelnumber": "***************(用户输入信息)"
/// }
///
/// </remarks>
/// <param name="request"></param>
/// <returns></returns>
[HttpPost("autocomplate")]
public ApiResponse<per_apr_amount> GetEmployeeMessage([FromBody] per_apr_amount request)
{
var result = employeeService.GetEmployeeMessage(request.AllotId, request.PersonnelNumber, claim.GetUserId());
return new ApiResponse<per_apr_amount>(ResponseType.OK, "人员信息", result);
}
/// <summary>
/// 绩效类型字典
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
[HttpPost("apr/perfortype/{allotId}")]
public ApiResponse<List<TitleValue>> GetPerforTypeDict([FromRoute] int allotId)
{
var result = employeeService.GetPerforTypeDict(allotId);
return new ApiResponse<List<TitleValue>>(ResponseType.OK, "绩效类型字典", result);
}
} }
} }
\ No newline at end of file
//using FluentValidation.AspNetCore; using Microsoft.AspNetCore.Authorization;
//using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
//using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.StaticFiles;
//using Microsoft.Extensions.Options; using Microsoft.Extensions.DependencyInjection;
//using Performance.DtoModels; using Microsoft.Extensions.Logging;
//using Performance.DtoModels.AppSettings; using Performance.DtoModels;
//using Performance.Infrastructure; using Performance.Infrastructure;
//using Performance.Services; using Performance.Services;
//using System; using Performance.Services.Queues;
//using System.Collections.Generic; using System;
//using System.Linq; using System.IO;
//using System.Threading.Tasks; using System.Threading.Tasks;
//namespace Performance.Api.Controllers namespace Performance.Api.Controllers
//{ {
// [Route("api/[controller]")] [Route("api/extract")]
// public class ModExtractController : Controller public class ModExtractController : Controller
// { {
// private readonly ILogger<ModExtractController> logger; private readonly ClaimService _claim;
// private ModExtractService modExtractService; private readonly AllotService _allotService;
// private WebapiUrl url; private readonly CustomExtractService _extractService;
// public ModExtractController( private readonly IServiceScopeFactory _serviceScopeFactory;
// ILogger<ModExtractController> logger, private readonly IHubNotificationQueue _notificationQueue;
// ModExtractService modExtractService, private readonly IBackgroundTaskQueue _backgroundTaskQueue;
// IOptions<WebapiUrl> url)
// { public ModExtractController(
// this.logger = logger; ClaimService claim,
// this.modExtractService = modExtractService; AllotService allotService,
// this.url = url.Value; CustomExtractService extractService,
// } IServiceScopeFactory serviceScopeFactory,
IHubNotificationQueue notificationQueue,
// /// <summary> IBackgroundTaskQueue backgroundTaskQueue)
// /// 绩效数据抽取模板 {
// /// </summary> _claim = claim;
// /// <returns></returns> _allotService = allotService;
// [Route("scheme")] _extractService = extractService;
// [HttpPost] _serviceScopeFactory = serviceScopeFactory;
// public ApiResponse Extract([CustomizeValidator(RuleSet = "Query"), FromBody] ModModuleRequest request) _notificationQueue = notificationQueue;
// { _backgroundTaskQueue = backgroundTaskQueue;
// if (request.HospitalId == null || request.HospitalId.Value == 0) }
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 不存在,请重新选择!");
// if (request.ExecuteType == null || !request.ExecuteType.Any()) [HttpPost("custom/{allotId}")]
// return new ApiResponse(ResponseType.ParameterError, "ExecuteType 不存在,请重新选择!"); public ApiResponse CustomExtract(int allotId)
{
// var list = modExtractService.ExtractScheme(request.HospitalId.Value, request.ExecuteType); var userId = _claim.GetUserId();
// return new ApiResponse(ResponseType.OK, list); if (!_extractService.CheckConfigScript(userId, allotId))
// } return new ApiResponse(ResponseType.Fail, "配置信息错误");
// /// <summary> _backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
// /// 费用类型 {
// /// </summary> using (var scope = _serviceScopeFactory.CreateScope())
// /// <returns></returns> {
// [Route("type")] var scopedServices = scope.ServiceProvider.GetRequiredService<CustomExtractService>();
// [HttpPost] var scopedAllotService = scope.ServiceProvider.GetRequiredService<AllotService>();
// public ApiResponse FeeType() var scopedQueue = scope.ServiceProvider.GetRequiredService<IHubNotificationQueue>();
// {
// var list = modExtractService.FeeType(); if (scopedServices.ExtractData(userId, allotId, out string resultFilePath))
// return new ApiResponse(ResponseType.OK, list); {
// } scopedAllotService.UpdateAllotCustomExtractPath(allotId, resultFilePath);
scopedQueue.Send(new Notification(allotId, "CustomDowoload", new CustomDownloadContent("自定义数据提取数据成功,是否立即下载", allotId)));
// /// <summary> }
// /// 绩效考核项费用来源 else
// /// </summary> {
// /// <returns></returns> scopedQueue.Send(new Notification(allotId, "Notification", new TextContent("自定义数据提取数据失败", NotificationLevel.ERR)));
// [Route("source")] }
// [HttpPost]
// public ApiResponse FeeSource([FromBody] ModModuleRequest request) await Task.Delay(TimeSpan.FromSeconds(5), token);
// { }
// if (request.HospitalId == null || request.HospitalId.Value == 0) });
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 参数错误!"); _notificationQueue.Send(new Notification(allotId, "Notification", new TextContent("自定义数据提取任务开始执行")));
// string retJson = HttpHelper.HttpPost(url.HttpPost + "/modextract/source", JsonHelper.Serialize(request), true);
// var ret = JsonHelper.Deserialize<ApiResponse>(retJson); return new ApiResponse(ResponseType.OK);
// return new ApiResponse(ResponseType.OK, ret.Data); }
// }
/// <summary>
// /// <summary> /// 从WebAPI下载文件
// /// 费用字典新增 /// </summary>
// /// </summary> /// <returns></returns>
// /// <returns></returns> [Route("down/{allotId}")]
// [Route("addmodule")] [HttpGet]
// [HttpPost] [AllowAnonymous]
// public ApiResponse AddModule([CustomizeValidator(RuleSet = "Add"), FromBody] ModModuleRequest request) public IActionResult DownFile(int allotId)
// { {
// if (request.HospitalId == null || request.HospitalId.Value == 0) var allot = _allotService.GetAllot(allotId);
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 参数错误!"); if (allot == null || string.IsNullOrWhiteSpace(allot.CustomExtractPath) || !FileHelper.IsExistFile(allot.CustomExtractPath))
{
// var entity = modExtractService.AddModule(request); return new ObjectResult(new ApiResponse(ResponseType.Fail, "文件不存在"));
// return new ApiResponse(ResponseType.OK, "添加成功!", entity); }
// }
var memoryStream = new MemoryStream();
// /// <summary> using (var stream = new FileStream(allot.CustomExtractPath, FileMode.Open))
// /// 费用字典(绩效模板) {
// /// </summary> stream.CopyToAsync(memoryStream).Wait();
// /// <returns></returns> }
// [Route("modules")] memoryStream.Seek(0, SeekOrigin.Begin);
// [HttpPost] string fileExt = Path.GetExtension(allot.CustomExtractPath);
// public ApiResponse Module([CustomizeValidator(RuleSet = "Query"), FromBody] ModModuleRequest request) var provider = new FileExtensionContentTypeProvider();
// { var memi = provider.Mappings[fileExt];
// if (request.HospitalId == null || request.HospitalId.Value == 0) return File(memoryStream, memi, Path.GetFileName(allot.CustomExtractPath));
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 不存在,请重新选择!"); }
}
// var list = modExtractService.Module(request.HospitalId.Value); }
// return new ApiResponse(ResponseType.OK, list); \ No newline at end of file
// }
// /// <summary>
// /// 绩效模板修改
// /// </summary>
// /// <returns></returns>
// [Route("editmodule")]
// [HttpPost]
// public ApiResponse EditModule([FromBody] ModModuleRequest request)
// {
// if (request.ModuleId == null || request.ModuleId == 0)
// return new ApiResponse(ResponseType.ParameterError, "ModuleId 参数错误!");
// var entity = modExtractService.EditModule(request);
// return new ApiResponse(ResponseType.OK, "修改成功!", entity);
// }
// /// <summary>
// /// 绩效模板删除
// /// </summary>
// /// <returns></returns>
// [Route("deletemodule")]
// [HttpPost]
// public ApiResponse DelModule([FromBody] ModModuleRequest request)
// {
// if (request.ModuleId == null || request.ModuleId == 0)
// return new ApiResponse(ResponseType.ParameterError, "ModuleId 参数错误!");
// modExtractService.DelModule(request.ModuleId.Value);
// return new ApiResponse(ResponseType.OK, "删除成功!");
// }
// /// <summary>
// /// 绩效收入模板配置项新增
// /// </summary>
// /// <returns></returns>
// [Route("additem")]
// [HttpPost]
// public ApiResponse AddItem([FromBody] ItemListRequest request)
// {
// if (request.ModuleId == null && request.ModuleId == 0)
// return new ApiResponse(ResponseType.ParameterError, "ModuleId 参数错误!");
// if (request.Items == null && !request.Items.Any())
// return new ApiResponse(ResponseType.ParameterError, "Items 未发现任添加何项!");
// var list = modExtractService.AddItem(request);
// return new ApiResponse(ResponseType.OK, "添加成功!", list);
// }
// /// <summary>
// /// 绩效收入模板配置项列表
// /// </summary>
// /// <returns></returns>
// [Route("items")]
// [HttpPost]
// public ApiResponse Items([FromBody] ModItemRequest request)
// {
// logger.LogInformation($"绩效收入模板配置项列表 : 请求地址 {url.HttpPost}/modextract/items");
// HttpHelper.HttpPost(url.HttpPost + "/modextract/items", JsonHelper.Serialize(request), true);
// logger.LogInformation($"绩效收入模板配置项列表在{DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss完成请求")}");
// var list = modExtractService.Items(request.ModuleId.Value);
// return new ApiResponse(ResponseType.OK, list);
// }
// /// <summary>
// /// 绩效收入模板配置项修改
// /// </summary>
// /// <returns></returns>
// [Route("edititem")]
// [HttpPost]
// public ApiResponse EditItem([FromBody] ItemListRequest request)
// {
// if (request.Items == null || !request.Items.Any())
// return new ApiResponse(ResponseType.ParameterError, "请选择需要修改的数据!");
// var entity = 0;//= modExtractService.EditItem(request.Items[0]);
// return new ApiResponse(ResponseType.OK, "修改成功!", entity);
// }
// /// <summary>
// /// 绩效收入模板配置项删除
// /// </summary>
// /// <returns></returns>
// [Route("deleteitem")]
// [HttpPost]
// public ApiResponse DelItem([FromBody] ModItemRequest request)
// {
// if (request.ItemId == null && request.ItemId == 0)
// return new ApiResponse(ResponseType.ParameterError, "ItemId 参数错误!");
// modExtractService.DelItem(request.ItemId.Value);
// return new ApiResponse(ResponseType.OK, "删除成功!");
// }
// #region 特殊科室模板
// /// <summary>
// /// 特殊科室模板配置项新增
// /// </summary>
// /// <returns></returns>
// [Route("addspecial")]
// [HttpPost]
// public ApiResponse AddSpecial([FromBody] SpecialListRequest request)
// {
// if (request.HospitalId == 0)
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 参数错误!");
// if (request.Items == null && !request.Items.Any())
// return new ApiResponse(ResponseType.ParameterError, "Items 未发现任添加何项!");
// var list = modExtractService.AddSpecial(request);
// return new ApiResponse(ResponseType.OK, "添加成功!", list);
// }
// /// <summary>
// /// 特殊科室模板配置项列表
// /// </summary>
// /// <returns></returns>
// [Route("specials")]
// [HttpPost]
// public ApiResponse Specials([FromBody] ModSpecialRequest request)
// {
// var list = modExtractService.Special(request.HospitalId.Value);
// return new ApiResponse(ResponseType.OK, list);
// }
// /// <summary>
// /// 特殊科室模板配置项修改
// /// </summary>
// /// <returns></returns>
// [Route("editspecial")]
// [HttpPost]
// public ApiResponse EditSpecial([FromBody] SpecialListRequest request)
// {
// if (request.Items == null || !request.Items.Any())
// return new ApiResponse(ResponseType.ParameterError, "请选择需要修改的数据!");
// var entity = modExtractService.EditSpecial(request.Items[0]);
// return new ApiResponse(ResponseType.OK, "修改成功!", entity);
// }
// /// <summary>
// /// 特殊科室模板配置项删除
// /// </summary>
// /// <returns></returns>
// [Route("deletespecial")]
// [HttpPost]
// public ApiResponse DelSpecial([FromBody] ModSpecialRequest request)
// {
// if (request.SpecialId == null && request.SpecialId == 0)
// return new ApiResponse(ResponseType.ParameterError, "SpecialId 参数错误!");
// modExtractService.DelSpecial(request.SpecialId.Value);
// return new ApiResponse(ResponseType.OK, "删除成功!");
// }
// /// <summary>
// /// 特殊科室人均
// /// </summary>
// /// <returns></returns>
// [Route("perfortype")]
// [HttpPost]
// public ApiResponse PerforType()
// {
// var list = modExtractService.PerforType();
// return new ApiResponse(ResponseType.OK, list);
// }
// #endregion
// /// <summary>
// /// 数据配置项
// /// </summary>
// /// <returns></returns>
// [Route("config")]
// [HttpPost]
// public ApiResponse Config([FromBody] ModModuleRequest request)
// {
// if (request.HospitalId == null || request.HospitalId.Value == 0)
// return new ApiResponse(ResponseType.ParameterError, "HospitalId 不存在,请重新选择!");
// var configs = modExtractService.GetHospitalconfigs(request.HospitalId.Value);
// return new ApiResponse(ResponseType.OK, "绩效抽取数据地址!", configs);
// }
// }
//}
\ No newline at end of file
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels; using Performance.DtoModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Performance.Api.Controllers namespace Performance.Api.Controllers
{ {
...@@ -19,4 +15,4 @@ public ActionResult<ApiResponse> Get() ...@@ -19,4 +15,4 @@ public ActionResult<ApiResponse> Get()
return new ApiResponse(ResponseType.NotFound, "not found"); return new ApiResponse(ResponseType.NotFound, "not found");
} }
} }
} }
\ No newline at end of file
...@@ -21,15 +21,19 @@ public class SecondAllotController : ControllerBase ...@@ -21,15 +21,19 @@ public class SecondAllotController : ControllerBase
private readonly ClaimService claimService; private readonly ClaimService claimService;
private readonly SecondAllotService secondAllotService; private readonly SecondAllotService secondAllotService;
private readonly ResultComputeService resultComputeService; private readonly ResultComputeService resultComputeService;
private readonly SecondAllotDetails secondAllotDetails;
public SecondAllotController( public SecondAllotController(
ClaimService claimService, ClaimService claimService,
SecondAllotService secondAllotService, SecondAllotService secondAllotService,
ResultComputeService resultComputeService) ResultComputeService resultComputeService,
SecondAllotDetails secondAllotDetails
)
{ {
this.claimService = claimService; this.claimService = claimService;
this.secondAllotService = secondAllotService; this.secondAllotService = secondAllotService;
this.resultComputeService = resultComputeService; this.resultComputeService = resultComputeService;
this.secondAllotDetails = secondAllotDetails;
} }
#region 二次绩效列表、录入数据展示,保存数据 #region 二次绩效列表、录入数据展示,保存数据
...@@ -120,7 +124,8 @@ public ApiResponse SaveCompute([FromBody] List<ag_compute> request) ...@@ -120,7 +124,8 @@ public ApiResponse SaveCompute([FromBody] List<ag_compute> request)
[HttpPost] [HttpPost]
public ApiResponse SecondDetail([CustomizeValidator(RuleSet = "Refresh"), FromBody] UseTempRequest request) public ApiResponse SecondDetail([CustomizeValidator(RuleSet = "Refresh"), FromBody] UseTempRequest request)
{ {
var result = secondAllotService.GetSecondDetail(request, claimService.GetUserId()); //var result = secondAllotService.GetSecondDetail(request, claimService.GetUserId());
var result = secondAllotDetails.GetSecondDetails(claimService.GetUserId(), request.SecondId, request.HospitalId, request.IsArchive, request.EmployeeSource);
return new ApiResponse(ResponseType.OK, result); return new ApiResponse(ResponseType.OK, result);
} }
...@@ -396,7 +401,8 @@ public ApiResponse NursingDeptAuditResult([FromBody] SecondAuditRequest request) ...@@ -396,7 +401,8 @@ public ApiResponse NursingDeptAuditResult([FromBody] SecondAuditRequest request)
[HttpPost] [HttpPost]
public ApiResponse OtherList([FromBody] AgOtherRequest request) public ApiResponse OtherList([FromBody] AgOtherRequest request)
{ {
var result = secondAllotService.OtherList(request.SecondId, claimService.GetUserId()); //var result = secondAllotService.OtherList(request.SecondId, claimService.GetUserId());
var result = secondAllotDetails.GetOtherTempDetails(claimService.GetUserId(), request.SecondId, request.IsArchive, request.EmployeeSource);
var obj = new var obj = new
{ {
header = secondAllotService.OtherListHeader(request.SecondId, result?.Sum(t => t.RealAmount)), header = secondAllotService.OtherListHeader(request.SecondId, result?.Sum(t => t.RealAmount)),
...@@ -444,4 +450,4 @@ public ApiResponse DeptComputeDetail(int allotId) ...@@ -444,4 +450,4 @@ public ApiResponse DeptComputeDetail(int allotId)
return new ApiResponse(ResponseType.OK, new { isShowManage, data }); return new ApiResponse(ResponseType.OK, new { isShowManage, data });
} }
} }
} }
\ No newline at end of file
...@@ -27,6 +27,7 @@ public static void Main(string[] args) ...@@ -27,6 +27,7 @@ public static void Main(string[] args)
config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true); config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
env.ConfigureNLog("nlog.config"); env.ConfigureNLog("nlog.config");
}) })
.UseUrls("http://*:5001")
.UseStartup<Startup>(); .UseStartup<Startup>();
} }
} }
using AutoMapper; using AutoMapper;
using FluentValidation; using FluentValidation;
using FluentValidation.AspNetCore; using FluentValidation.AspNetCore;
using Hangfire;
using Hangfire.MySql.Core;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using NLog;
using NLog.Extensions.Logging; using NLog.Extensions.Logging;
using NLog.Web;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings; using Performance.DtoModels.AppSettings;
using Performance.DtoModels.AutoMapper; using Performance.DtoModels.AutoMapper;
using Performance.EntityModels; using Performance.EntityModels;
using Performance.Infrastructure; using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services; using Performance.Services;
using Performance.Services.Queues;
using Swashbuckle.AspNetCore.Swagger; using Swashbuckle.AspNetCore.Swagger;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection; using System.Reflection;
using System.Text; using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Performance.Api namespace Performance.Api
{ {
...@@ -152,16 +142,17 @@ public void ConfigureServices(IServiceCollection services) ...@@ -152,16 +142,17 @@ public void ConfigureServices(IServiceCollection services)
services.AddHostedService<QueuedHostedService>(); services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>(); services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
services.AddSingleton<IHubNotificationQueue, HubNotificationQueue>();
#region hangfire //#region hangfire
services.AddHangfire(config => //services.AddHangfire(config =>
{ //{
config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 }); // config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString)); // config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
}); //});
#endregion hangfire //#endregion hangfire
services.AddSignalR(); services.AddSignalR();
services.AddCors(options => services.AddCors(options =>
...@@ -243,12 +234,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF ...@@ -243,12 +234,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
#endregion Swagger #endregion Swagger
#region hangfire //#region hangfire
app.UseHangfireServer(); //app.UseHangfireServer();
app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } }); //app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } });
#endregion hangfire //#endregion hangfire
app.UseCors("SignalrCore"); app.UseCors("SignalrCore");
app.UseSignalR(routes => routes.MapHub<AllotLogHub>("/performance/allotLogHub")); app.UseSignalR(routes => routes.MapHub<AllotLogHub>("/performance/allotLogHub"));
......
...@@ -54,7 +54,7 @@ public string GetUserClaim(string jwtClaimTypes) ...@@ -54,7 +54,7 @@ public string GetUserClaim(string jwtClaimTypes)
/// <returns></returns> /// <returns></returns>
public List<Claim> GetUserClaim() public List<Claim> GetUserClaim()
{ {
if (contextAccessor.HttpContext.User == null) if (contextAccessor.HttpContext?.User == null)
{ {
throw new PerformanceException("获取当前请求登录信息失败"); throw new PerformanceException("获取当前请求登录信息失败");
} }
......
...@@ -747,6 +747,30 @@ ...@@ -747,6 +747,30 @@
<param name="form"></param> <param name="form"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Performance.Api.Controllers.EmployeeController.GetEmployeeMessage(Performance.EntityModels.per_apr_amount)">
<summary>
自动获取人员信息
</summary>
<remarks>
Sample request:
POST /Todo
{
"allotid": 7,
"personnelnumber": "***************(用户输入信息)"
}
</remarks>
<param name="request"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.EmployeeController.GetPerforTypeDict(System.Int32)">
<summary>
绩效类型字典
</summary>
<param name="allotId"></param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ExConfigController.Extract(Performance.DtoModels.ModModuleRequest)"> <member name="M:Performance.Api.Controllers.ExConfigController.Extract(Performance.DtoModels.ModModuleRequest)">
<summary> <summary>
绩效数据抽取模板 绩效数据抽取模板
...@@ -937,6 +961,12 @@ ...@@ -937,6 +961,12 @@
</summary> </summary>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:Performance.Api.Controllers.ModExtractController.DownFile(System.Int32)">
<summary>
从WebAPI下载文件
</summary>
<returns></returns>
</member>
<member name="T:Performance.Api.Controllers.OriginalController"> <member name="T:Performance.Api.Controllers.OriginalController">
<summary> <summary>
原始数据修改 原始数据修改
......
...@@ -179,6 +179,13 @@ ...@@ -179,6 +179,13 @@
<member name="F:Performance.DtoModels.DataFormat.日期"> <member name="F:Performance.DtoModels.DataFormat.日期">
<summary> 日期 </summary> <summary> 日期 </summary>
</member> </member>
<member name="M:Performance.DtoModels.HandsonTable.SetRowData(System.Collections.Generic.IEnumerable{Performance.DtoModels.HandsonRowData},System.Boolean)">
<summary>
</summary>
<param name="datas"></param>
<param name="isTypein">是否是用户录入的 是:true 不是:false</param>
</member>
<member name="P:Performance.DtoModels.HistoryData.Year"> <member name="P:Performance.DtoModels.HistoryData.Year">
<summary> <summary>
...@@ -2247,6 +2254,9 @@ ...@@ -2247,6 +2254,9 @@
<member name="P:Performance.DtoModels.UseTempRequest.IsArchive"> <member name="P:Performance.DtoModels.UseTempRequest.IsArchive">
<summary> 是否归档 </summary> <summary> 是否归档 </summary>
</member> </member>
<member name="P:Performance.DtoModels.UseTempRequest.EmployeeSource">
<summary> 人员信息来源 </summary>
</member>
<member name="P:Performance.DtoModels.WorkItemRequest.Item"> <member name="P:Performance.DtoModels.WorkItemRequest.Item">
<summary> <summary>
工作量绩效项 工作量绩效项
......
...@@ -103,6 +103,9 @@ ...@@ -103,6 +103,9 @@
<member name="P:Performance.EntityModels.PerformanceDbContext.collect_permission"> <member name="P:Performance.EntityModels.PerformanceDbContext.collect_permission">
<summary> </summary> <summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.PerformanceDbContext.cust_script">
<summary> </summary>
</member>
<member name="P:Performance.EntityModels.PerformanceDbContext.ex_item"> <member name="P:Performance.EntityModels.PerformanceDbContext.ex_item">
<summary> </summary> <summary> </summary>
</member> </member>
...@@ -1668,6 +1671,41 @@ ...@@ -1668,6 +1671,41 @@
0 可见 1 不可见 0 可见 1 不可见
</summary> </summary>
</member> </member>
<member name="T:Performance.EntityModels.cust_script">
<summary>
自定义导出
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.ID">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.HospitalId">
<summary>
医院ID
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.IsOnceAllot">
<summary>
是否允许一次分配下载 1 允许 2 禁止
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.IsSecondAllot">
<summary>
是否允许二次分配下载 1 允许 2 禁止
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.ConfigId">
<summary>
配置Id
</summary>
</member>
<member name="P:Performance.EntityModels.cust_script.IsEnable">
<summary>
是否可用 1 可用 2 不可用
</summary>
</member>
<member name="T:Performance.EntityModels.ex_item"> <member name="T:Performance.EntityModels.ex_item">
<summary> <summary>
...@@ -3053,6 +3091,11 @@ ...@@ -3053,6 +3091,11 @@
0 不显示 1 显示 0 不显示 1 显示
</summary> </summary>
</member> </member>
<member name="P:Performance.EntityModels.per_allot.CustomExtractPath">
<summary>
自定义提取绩效数据文件生成路径
</summary>
</member>
<member name="T:Performance.EntityModels.per_apr_amount"> <member name="T:Performance.EntityModels.per_apr_amount">
<summary> <summary>
......
...@@ -24,15 +24,22 @@ public HandsonTable(int sheetType, string[] cols, List<collect_permission> permi ...@@ -24,15 +24,22 @@ public HandsonTable(int sheetType, string[] cols, List<collect_permission> permi
public List<Dictionary<string, string>> Data => _data; public List<Dictionary<string, string>> Data => _data;
public HandsonColumn[] Columns { get; private set; } public HandsonColumn[] Columns { get; private set; }
public void SetRowData(IEnumerable<HandsonRowData> datas) /// <summary>
///
/// </summary>
/// <param name="datas"></param>
/// <param name="isTypein">是否是用户录入的 是:true 不是:false</param>
public void SetRowData(IEnumerable<HandsonRowData> datas, bool isTypein)
{ {
foreach (var dt in datas) foreach (var dt in datas)
{ {
var dic = CreateDataRow("编号", dt.Row.ToString()); var dic = CreateDataRow("编号", dt.Row.ToString());
foreach (var item in dt.CellData) foreach (var item in dt.CellData)
{ {
if (dic.ContainsKey(item.Name) && _permissions.Any(w => w.HeadName == item.Name && w.AttachLast > 0)) if (dic.ContainsKey(item.Name.ToLower()) && isTypein && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower()))
dic[item.Name] = item.Value?.ToString(); dic[item.Name.ToLower()] = item.Value?.ToString() ?? "";
else if (dic.ContainsKey(item.Name.ToLower()) && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower() && w.AttachLast > 0))
dic[item.Name.ToLower()] = item.Value?.ToString() ?? "";
} }
_data.Add(dic); _data.Add(dic);
} }
...@@ -51,11 +58,12 @@ private void InitColHeaders(int sheetType, string[] cols) ...@@ -51,11 +58,12 @@ private void InitColHeaders(int sheetType, string[] cols)
var necessitys = defaluts.FirstOrDefault(w => sheetType == (int)w.SheetType)?.Necessity.ToList(); var necessitys = defaluts.FirstOrDefault(w => sheetType == (int)w.SheetType)?.Necessity.ToList();
necessitys = necessitys ?? new List<string>(); necessitys = necessitys ?? new List<string>();
foreach (var item in cols) foreach (var col in cols)
{ {
var item = col.ToLower();
if (!necessitys.Contains(item)) if (!necessitys.Contains(item))
necessitys.Add(item); necessitys.Add(item);
if (!_permissions.Any(w => w.HeadName == item && w.Visible == 1)) if (!_permissions.Any(w => w.HeadName.ToLower() == item && w.Visible == 1))
necessitys.Remove(item); necessitys.Remove(item);
} }
ColHeaders = necessitys.ToArray(); ColHeaders = necessitys.ToArray();
...@@ -64,12 +72,12 @@ private void InitColHeaders(int sheetType, string[] cols) ...@@ -64,12 +72,12 @@ private void InitColHeaders(int sheetType, string[] cols)
private void InitColumns(List<collect_permission> permissions) private void InitColumns(List<collect_permission> permissions)
{ {
List<HandsonColumn> columns = new List<HandsonColumn>(); List<HandsonColumn> columns = new List<HandsonColumn>();
foreach (var item in ColHeaders) foreach (var col in ColHeaders)
{ {
var item = col.ToLower();
var readnoly = _permissions.FirstOrDefault(f => f.HeadName == item)?.Readnoly == 1; var readnoly = _permissions.FirstOrDefault(f => f.HeadName == item)?.Readnoly == 1;
columns.Add(new HandsonColumn(item, readnoly)); columns.Add(new HandsonColumn(item.ToLower(), readnoly));
} }
Columns = columns.ToArray(); Columns = columns.ToArray();
} }
...@@ -79,7 +87,7 @@ private void InitColumns(List<collect_permission> permissions) ...@@ -79,7 +87,7 @@ private void InitColumns(List<collect_permission> permissions)
foreach (var item in ColHeaders) foreach (var item in ColHeaders)
{ {
if (!temp.ContainsKey(item)) if (!temp.ContainsKey(item))
temp.Add(item, ""); temp.Add(item.ToLower(), "");
} }
return temp; return temp;
} }
......
...@@ -9,6 +9,10 @@ public class AgOtherRequest ...@@ -9,6 +9,10 @@ public class AgOtherRequest
{ {
public int SecondId { get; set; } public int SecondId { get; set; }
public int IsArchive { get; set; }
public int EmployeeSource { get; set; }
public List<ag_othersource> Othersources { get; set; } public List<ag_othersource> Othersources { get; set; }
} }
} }
...@@ -19,7 +19,11 @@ public class UseTempRequest ...@@ -19,7 +19,11 @@ public class UseTempRequest
/// <summary> 是否归档 </summary> /// <summary> 是否归档 </summary>
public int IsArchive { get; set; } public int IsArchive { get; set; }
/// <summary> 人员信息来源 </summary>
public int EmployeeSource { get; set; }
} }
public class UseTempRequestValidator : AbstractValidator<UseTempRequest> public class UseTempRequestValidator : AbstractValidator<UseTempRequest>
{ {
public UseTempRequestValidator() public UseTempRequestValidator()
......
...@@ -9,7 +9,7 @@ public class WorkDetailRequest ...@@ -9,7 +9,7 @@ public class WorkDetailRequest
{ {
public int AllotId { get; set; } public int AllotId { get; set; }
public int SecondId { get; set; } public int SecondId { get; set; }
public string Source { get; set; }
public string AccountingUnit { get; set; } public string AccountingUnit { get; set; }
} }
......
...@@ -18,10 +18,13 @@ public class HeadItem : ICloneable ...@@ -18,10 +18,13 @@ public class HeadItem : ICloneable
public int Type { get; set; } public int Type { get; set; }
public decimal FactorValue { get; set; } public decimal FactorValue { get; set; }
public int SourceType { get; set; } public int SourceType { get; set; }
/// <summary> 1 带出历史数据 2不带出 </summary> /// <summary> 1 带出历史数据 2不带出 </summary>
public Nullable<int> IsBring { get; set; } public Nullable<int> IsBring { get; set; }
/// <summary> 1 value相加值为1 </summary> /// <summary> 1 value相加值为1 </summary>
public Nullable<int> SpecialAttr { get; set; } public Nullable<int> SpecialAttr { get; set; }
public Nullable<int> WorkType { get; set; } public Nullable<int> WorkType { get; set; }
public object Clone() public object Clone()
...@@ -34,5 +37,22 @@ public class BodyItem : HeadItem ...@@ -34,5 +37,22 @@ public class BodyItem : HeadItem
{ {
public int RowNumber { get; set; } public int RowNumber { get; set; }
public string Value { get; set; } public string Value { get; set; }
public BodyItem()
{
}
public BodyItem(HeadItem headItem)
{
FiledId = headItem.FiledId;
FiledName = headItem.FiledName;
Sort = headItem.Sort;
Type = headItem.Type;
FactorValue = headItem.FactorValue;
SourceType = headItem.SourceType;
IsBring = headItem.IsBring;
SpecialAttr = headItem.SpecialAttr;
WorkType = headItem.WorkType;
}
} }
} }
...@@ -111,6 +111,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options) ...@@ -111,6 +111,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options)
public virtual DbSet<collect_permission> collect_permission { get; set; } public virtual DbSet<collect_permission> collect_permission { get; set; }
/// <summary> </summary> /// <summary> </summary>
public virtual DbSet<cust_script> cust_script { get; set; }
/// <summary> </summary>
public virtual DbSet<ex_item> ex_item { get; set; } public virtual DbSet<ex_item> ex_item { get; set; }
/// <summary> </summary> /// <summary> </summary>
......
//-----------------------------------------------------------------------
// <copyright file="cust_script.cs">
// * FileName: cust_script.cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Performance.EntityModels
{
/// <summary>
/// 自定义导出
/// </summary>
[Table("cust_script")]
public class cust_script
{
/// <summary>
///
/// </summary>
[Key]
public int ID { get; set; }
/// <summary>
/// 医院ID
/// </summary>
public int HospitalId { get; set; }
/// <summary>
/// 是否允许一次分配下载 1 允许 2 禁止
/// </summary>
public int IsOnceAllot { get; set; }
/// <summary>
/// 是否允许二次分配下载 1 允许 2 禁止
/// </summary>
public int IsSecondAllot { get; set; }
public string Name { get; set; }
public string Script { get; set; }
/// <summary>
/// 配置Id
/// </summary>
public int ConfigId { get; set; }
/// <summary>
/// 是否可用 1 可用 2 不可用
/// </summary>
public int IsEnable { get; set; }
}
}
...@@ -90,5 +90,10 @@ public class per_allot ...@@ -90,5 +90,10 @@ public class per_allot
/// 0 不显示 1 显示 /// 0 不显示 1 显示
/// </summary> /// </summary>
public int ShowFormula { get; set; } public int ShowFormula { get; set; }
/// <summary>
/// 自定义提取绩效数据文件生成路径
/// </summary>
public string CustomExtractPath { get; set; }
} }
} }
...@@ -48,6 +48,7 @@ public int DeleteAllotData(int allotId) ...@@ -48,6 +48,7 @@ public int DeleteAllotData(int allotId)
{ {
List<string> tableArray = new List<string> List<string> tableArray = new List<string>
{ {
"ag_secondallot",
"cof_again", "cof_again",
"cof_check", "cof_check",
"cof_cmi", "cof_cmi",
......
...@@ -165,8 +165,7 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri ...@@ -165,8 +165,7 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri
if (connection.State != ConnectionState.Open) connection.Open(); if (connection.State != ConnectionState.Open) connection.Open();
try try
{ {
string clear = @"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,if(ifnull(t2.PersonnelNumber,'')='', ifnull(t2.JobNumber,ifnull(t1.DoctorName, '未知')), t2.PersonnelNumber) PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1 string clear = @"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,t1.PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1
LEFT JOIN per_employee t2 on t1.personnelnumber = t2.jobnumber AND t2.allotid = @allotid
JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName
WHERE t1.allotid = @allotid WHERE t1.allotid = @allotid
AND t3.unittype = @unittype AND t3.unittype = @unittype
...@@ -187,20 +186,19 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri ...@@ -187,20 +186,19 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri
/// 查询门诊收入数据 /// 查询门诊收入数据
/// </summary> /// </summary>
/// <param name="allotid"></param> /// <param name="allotid"></param>
public IEnumerable<ex_result> QueryIncomeData(int allotid, string accountingunit, string unittype, int hospitalid) public IEnumerable<ex_result> QueryIncomeData(int allotid, string source, string accountingunit, string unittype, int hospitalid)
{ {
using (var connection = context.Database.GetDbConnection()) using (var connection = context.Database.GetDbConnection())
{ {
if (connection.State != ConnectionState.Open) connection.Open(); if (connection.State != ConnectionState.Open) connection.Open();
try try
{ {
string clear = @"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,if(ifnull(t2.PersonnelNumber,'')='',ifnull(t2.JobNumber,ifnull(t1.DoctorName, '未知')), t2.PersonnelNumber) PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1 string clear = $@"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,t1.PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1
LEFT JOIN per_employee t2 on t1.personnelnumber = t2.jobnumber AND t2.allotid = @allotid
JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName
WHERE t1.allotid = @allotid WHERE t1.allotid = @allotid
AND t3.unittype = @unittype AND t3.unittype = @unittype
AND t3.accountingunit = @accountingunit AND t3.accountingunit = @accountingunit
AND t1.Source like '%门诊开单%' AND t1.Source like '%{source}开单%'
AND T1.IsDelete = 0 AND T1.IsDelete = 0
ORDER BY t1.doctorname,t1.Category;"; ORDER BY t1.doctorname,t1.Category;";
return connection.Query<ex_result>(clear, new { allotid, accountingunit, unittype, hospitalid }, commandTimeout: 60 * 60); return connection.Query<ex_result>(clear, new { allotid, accountingunit, unittype, hospitalid }, commandTimeout: 60 * 60);
......
//-----------------------------------------------------------------------
// <copyright file=" ag_againsituation.cs">
// * FileName: ag_againsituation.cs
// </copyright>
//-----------------------------------------------------------------------
using Performance.EntityModels;
using System;
namespace Performance.Repository
{
/// <summary>
/// collect_data Repository
/// </summary>
public partial class PerforcustscriptRepository : PerforRepository<cust_script>
{
public PerforcustscriptRepository(PerformanceDbContext context) : base(context)
{
}
}
}
...@@ -261,6 +261,18 @@ public bool Update(per_allot allot) ...@@ -261,6 +261,18 @@ public bool Update(per_allot allot)
#endregion 基础功能 #endregion 基础功能
/// <summary>
/// 修改自定义提取结果地址
/// </summary>
/// <param name="allotId"></param>
/// <param name="path"></param>
public void UpdateAllotCustomExtractPath(int allotId, string path)
{
var allot = _allotRepository.GetEntity(w => w.ID == allotId);
allot.CustomExtractPath = path;
_allotRepository.Update(allot);
}
public void UpdateAllotStates(int allotId, int states, string remark, int generate = 0) public void UpdateAllotStates(int allotId, int states, string remark, int generate = 0)
{ {
_allotRepository.UpdateAllotStates(allotId, states, remark, generate); _allotRepository.UpdateAllotStates(allotId, states, remark, generate);
......
...@@ -286,7 +286,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName) ...@@ -286,7 +286,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName)
{ {
var allotList = perforPerallotRepository var allotList = perforPerallotRepository
.GetEntities(w => w.HospitalId == allot.HospitalId && states.Contains(w.States)) .GetEntities(w => w.HospitalId == allot.HospitalId && states.Contains(w.States))
?.OrderBy(w => w.Year).ThenBy(w => w.Month).ToList(); ?.OrderBy(w => w.Year).ThenByDescending(w => w.Month).ToList();
allot = allotList?.First(); allot = allotList?.First();
} }
if (allot == null) if (allot == null)
...@@ -363,7 +363,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName) ...@@ -363,7 +363,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName)
rowDatas = rowDatas.OrderBy(t => t.Row).ToList(); rowDatas = rowDatas.OrderBy(t => t.Row).ToList();
HandsonTable handson = new HandsonTable(sheet.SheetType.Value, cols, permissions); HandsonTable handson = new HandsonTable(sheet.SheetType.Value, cols, permissions);
handson.SetRowData(rowDatas); handson.SetRowData(rowDatas, (collectdata != null));
return handson; return handson;
} }
...@@ -481,7 +481,11 @@ public void SaveCollectData(int allotId, SaveCollectData request) ...@@ -481,7 +481,11 @@ public void SaveCollectData(int allotId, SaveCollectData request)
{ {
var json = JsonHelper.Serialize(item); var json = JsonHelper.Serialize(item);
var data = JsonHelper.Deserialize<collect_data>(json); var data = JsonHelper.Deserialize<collect_data>(json);
datas.Add(data); if (!string.IsNullOrEmpty(data.AccountingUnitTechnician)
|| !string.IsNullOrEmpty(data.AccountingUnitNurse)
|| !string.IsNullOrEmpty(data.AccountingUnitDoctor)
|| !string.IsNullOrEmpty(data.Department))
datas.Add(data);
} }
perforcollectdataRepository.Execute("delete from collect_data where allotid = @allotid and sheetname=@sheetname", new { allotId, request.SheetName }); perforcollectdataRepository.Execute("delete from collect_data where allotid = @allotid and sheetname=@sheetname", new { allotId, request.SheetName });
perforcollectdataRepository.AddRange(datas.ToArray()); perforcollectdataRepository.AddRange(datas.ToArray());
......
using Dapper;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services.ExtractExcelService;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Performance.Services
{
public class CustomExtractService : IAutoInjection
{
private readonly ILogger<CustomExtractService> _logger;
private readonly IOptions<Application> _options;
private readonly UserService _userService;
private readonly RoleService _roleService;
private readonly PerforPerallotRepository _perallotRepository;
private readonly PerforPerdeptdicRepository _perforPerdeptdicRepository;
private readonly PerforHospitalconfigRepository _perforHospitalconfigRepository;
private readonly PerforcustscriptRepository _perforcustscriptRepository;
public CustomExtractService(
ILogger<CustomExtractService> logger,
IOptions<Application> options,
UserService userService,
RoleService roleService,
PerforPerallotRepository perallotRepository,
PerforPerdeptdicRepository perforPerdeptdicRepository,
PerforHospitalconfigRepository perforHospitalconfigRepository,
PerforcustscriptRepository perforcustscriptRepository)
{
_logger = logger;
_options = options;
_userService = userService;
_roleService = roleService;
_perallotRepository = perallotRepository;
_perforPerdeptdicRepository = perforPerdeptdicRepository;
_perforHospitalconfigRepository = perforHospitalconfigRepository;
_perforcustscriptRepository = perforcustscriptRepository;
}
public bool CheckConfigScript(int userId, int allotId)
{
var allot = _perallotRepository.GetEntity(w => w.ID == allotId)
?? throw new PerformanceException("绩效ID无效");
var scripts = _perforcustscriptRepository.GetEntities(w => w.HospitalId == allot.HospitalId && w.IsEnable == 1);
scripts = (IsSecondAdmin(userId, out string[] unitType))
? scripts?.Where(w => w.IsSecondAllot == 1).ToList()
: scripts?.Where(w => w.IsOnceAllot == 1).ToList();
return scripts?.Count() > 0;
}
public bool ExtractData(int userId, int allotId, out string resultFilePath)
{
bool result = true;
var allot = _perallotRepository.GetEntity(w => w.ID == allotId)
?? throw new PerformanceException("绩效ID无效");
var filePath = ExtractHelper.GetExtractFile(allot.HospitalId);
resultFilePath = filePath;
var scripts = _perforcustscriptRepository.GetEntities(w => w.HospitalId == allot.HospitalId && w.IsEnable == 1);
scripts = (IsSecondAdmin(userId, out string[] unitType))
? scripts?.Where(w => w.IsSecondAllot == 1).ToList()
: scripts?.Where(w => w.IsOnceAllot == 1).ToList();
if (scripts == null || scripts.Count == 0)
{
result = false;
return result;
}
var depts = _perforPerdeptdicRepository.GetEntities(w => w.HospitalId == allot.HospitalId);
IWorkbook workbook = null;
try
{
workbook = new NPOI.HSSF.UserModel.HSSFWorkbook();
ExcelStyle style = new ExcelStyle(workbook);
WriteDataToFile(userId, allot, scripts, workbook, depts);
}
catch (Exception ex)
{
allot.IsExtracting = 3;
resultFilePath = "";
result = false;
_logger.LogError("提取数据中发生异常: " + ex.ToString());
}
finally
{
using (FileStream file = new FileStream(filePath, FileMode.OpenOrCreate))
{
workbook.Write(file);
}
workbook.Close();
}
return result;
}
/// <summary>
/// 返回需要关注的列头索引,找不到-1
/// </summary>
/// <param name="heads"></param>
/// <returns></returns>
private (int deptIndex, int sourceIndex, int unitIndex) GetCruxHeader(IEnumerable<string> heads)
{
var deptIndex = heads.ToList().IndexOf("科室名称");
var sourceIndex = heads.ToList().IndexOf("来源");
var unitIndex = heads.ToList().IndexOf("组别");
return (deptIndex, sourceIndex, unitIndex);
}
private void WriteDataToFile(int userId, per_allot allot, List<cust_script> scripts, IWorkbook workbook, List<per_dept_dic> depts)
{
var configs = _perforHospitalconfigRepository.GetEntities(t => t.HospitalId == allot.HospitalId)
?? throw new PerformanceException("当前医院没有数据库地址配置");
var parameters = GetParameters(allot);
var (isSecondAdmin, department, unitType) = GetUserDepartment(userId);
parameters.Add("@department", $"'{department}'");
foreach (var item in scripts)
{
var conf = configs.FirstOrDefault(w => w.Id == item.ConfigId);
if (conf != null)
{
var execsql = item.Script;
var dynamics = QueryData(conf, execsql, parameters);
try
{
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
if (item.Name == workbook.GetSheetAt(i).SheetName)
workbook.RemoveSheetAt(i);
}
var sheet = workbook.CreateSheet(item.Name);
// 没数据跳过
if (dynamics == null || dynamics.Count() == 0)
continue;
var headers = ((IDictionary<string, object>)dynamics.ElementAt(0)).Keys;
for (int col = 0; col < headers.Count; col++)
{
sheet.SetValue(1, col + 4, headers.ElementAt(col));
}
// 列头坐标信息
var (deptIndex, sourceIndex, unitIndex) = GetCruxHeader(headers);
int row = 2;
for (int r = 0; r < dynamics.Count(); r++)
{
var temp = (IDictionary<string, object>)dynamics.ElementAt(r); // 行数据
#region 替换原始科室名称及跳过写入EXCEL逻辑
string accountUnit = "";
// “科室名称”必须存在 “来源”必须存在
if (deptIndex > -1)
{
string atDepartment = temp.ElementAt(deptIndex).Value?.ToString() ?? ""; // 当前行“科室名称”
string atUnitType = (unitIndex > -1) ? temp.ElementAt(unitIndex).Value?.ToString() : ""; // 当前行“核算单元类别”
// 如果是科主任护士长 则取角色的 核算单元类别
// 如果是核算办 则取数据中 核算单元类别
string[] atUnitTypeList = new string[] { };
if (isSecondAdmin && unitType.Any())
atUnitTypeList = unitType;
else if (unitIndex > -1)
atUnitTypeList = new string[] { atUnitType };
// 替换原始科室名称
if (atUnitTypeList.Any() && !string.IsNullOrEmpty(atDepartment))
{
var tempDepts = depts.Where(w => atUnitTypeList.Contains(w.UnitType) && w.HISDeptName == atDepartment);
if (isSecondAdmin && unitType.Any(w => w == UnitType.特殊核算组.ToString() || w == UnitType.行政后勤.ToString()))
{
accountUnit = tempDepts.FirstOrDefault()?.AccountingUnit ?? "";
}
else
{
string atSource = temp.ElementAt(sourceIndex).Value?.ToString() ?? ""; // 当前行“来源”
accountUnit = tempDepts.FirstOrDefault(w => w.Source == atSource)?.AccountingUnit ?? "";
}
}
// 跳过写入EXCEL逻辑
if (isSecondAdmin)
{
if (string.IsNullOrEmpty(accountUnit) || accountUnit != department) continue;
if (string.IsNullOrEmpty(atUnitType) || !atUnitTypeList.Contains(atUnitType)) continue;
}
}
#endregion
int col = 4;
for (int c = 0; c < headers.Count; c++)
{
var value = temp.ElementAt(c).Value;
// 替换原始科室名称
if (deptIndex > -1 && deptIndex == c)
value = accountUnit;
sheet.SetValue(row, col, value);
col++;
}
row++;
}
}
catch (Exception ex)
{
_logger.LogError($"提取绩效数据写入错误:{item.Name}{ex}");
}
}
}
}
/// <summary>
/// 查询数据
/// </summary>
/// <param name="config"></param>
/// <param name="allot"></param>
/// <param name="execsql"></param>
/// <param name="source"></param>
/// <param name="category"></param>
/// <returns></returns>
public IEnumerable<dynamic> QueryData(sys_hospitalconfig config, string execsql, Dictionary<string, string> parameters)
{
try
{
using (var connection = ConnectionBuilder.Create((DatabaseType)config.DataBaseType, config.DbSource, config.DbName, config.DbUser, config.DbPassword))
{
foreach (var item in parameters)
{
execsql = Regex.Replace(execsql, item.Key, item.Value, RegexOptions.IgnoreCase);
}
_logger.LogInformation($"提取绩效数据SQL脚本{execsql}");
var result = connection.Query(execsql, commandTimeout: 20000);
_logger.LogInformation($"提取绩效数据执行脚本获取数据{result?.Count() ?? 0}条记录");
return result;
}
}
catch (Exception ex)
{
_logger.LogError($"提取绩效数据SQL脚本查询错误:{execsql} 错误原因:{ex}");
}
return null;
}
/// <summary>
/// 获取参数
/// </summary>
/// <param name="allot"></param>
/// <returns></returns>
private Dictionary<string, string> GetParameters(per_allot allot)
{
DateTime beginTime = new DateTime(allot.Year, allot.Month, 1);
Dictionary<string, string> pairs = new Dictionary<string, string>
{
{ "@beginTime", $"'{beginTime.ToString("yyyy-MM-dd")}'" },
{ "@endTime", $"'{beginTime.AddMonths(1).ToString("yyyy-MM-dd")}'"},
};
return pairs;
}
/// <summary>
/// 是否是二次分配管理员 是 true 否 false
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
private bool IsSecondAdmin(int userId, out string[] unitType)
{
Dictionary<int, string[]> pairs = new Dictionary<int, string[]>
{
{ _options.Value.NurseRole, new string[] { UnitType.护理组.ToString() } },
{ _options.Value.DirectorRole, new string[] { UnitType.医生组.ToString(), UnitType.医技组.ToString() } },
{ _options.Value.SpecialRole, new string[] { UnitType.特殊核算组.ToString() } },
{ _options.Value.OfficeRole, new string[] { UnitType.行政后勤.ToString() } },
};
var roleId = _roleService.GetRole(userId)?.FirstOrDefault().ID ?? 0;
if (pairs.ContainsKey(roleId))
{
unitType = pairs[roleId];
return true;
}
unitType = new string[] { };
return false;
}
/// <summary>
/// 返回二次分配管理科室 默认 返回 空值
/// </summary>
/// <param name="userId"></param>
/// <returns></returns>
private (bool isSecondAdmin, string department, string[] unitType) GetUserDepartment(int userId)
{
var user = _userService.GetUser(userId)
?? throw new PerformanceException("当前用户信息无效");
var isSecondAdmin = IsSecondAdmin(userId, out string[] unitType);
var department = isSecondAdmin ? (user.Department ?? "") : string.Empty;
return (isSecondAdmin, department, unitType);
}
}
}
\ No newline at end of file
using AutoMapper;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Performance.Services
{
public class SecondAllotDetails : IAutoInjection
{
private readonly PerforAgsecondallotRepository agsecondallotRepository;
private readonly PerforAgusetempRepository agusetempRepository;
private readonly PerforAgtempitemRepository agtempitemRepository;
private readonly PerforAgworkloadRepository agworkloadRepository;
private readonly PerforAgworkloadtypeRepository agworkloadtypeRepository;
private readonly PerforAgfixatitemRepository agfixatitemRepository;
private readonly PerforAgothersourceRepository agothersourceRepository;
private readonly PerforPerallotRepository perallotRepository;
private readonly PerforCofagainRepository cofagainRepository;
private readonly PerforPerapramountRepository perapramountRepository;
private readonly PerforRescomputeRepository rescomputeRepository;
private readonly PersonService personService;
public SecondAllotDetails(
PerforAgsecondallotRepository agsecondallotRepository,
PerforAgusetempRepository agusetempRepository,
PerforAgtempitemRepository agtempitemRepository,
PerforAgworkloadRepository agworkloadRepository,
PerforAgworkloadtypeRepository agworkloadtypeRepository,
PerforAgfixatitemRepository agfixatitemRepository,
PerforAgothersourceRepository agothersourceRepository,
PerforPerallotRepository perallotRepository,
PerforCofagainRepository cofagainRepository,
PerforPerapramountRepository perapramountRepository,
PerforRescomputeRepository rescomputeRepository,
PersonService personService
)
{
this.agsecondallotRepository = agsecondallotRepository;
this.agusetempRepository = agusetempRepository;
this.agtempitemRepository = agtempitemRepository;
this.agworkloadRepository = agworkloadRepository;
this.agworkloadtypeRepository = agworkloadtypeRepository;
this.agfixatitemRepository = agfixatitemRepository;
this.agothersourceRepository = agothersourceRepository;
this.perallotRepository = perallotRepository;
this.cofagainRepository = cofagainRepository;
this.perapramountRepository = perapramountRepository;
this.rescomputeRepository = rescomputeRepository;
this.personService = personService;
}
#region 横向纵向模板详情
/// <summary>
/// 二次绩效详情
/// </summary>
/// <param name="userId"></param>
/// <param name="secondId"></param>
/// <param name="hospitalId"></param>
/// <param name="isArchive"></param>
/// <returns></returns>
public SecondResponse GetSecondDetails(int userId, int secondId, int hospitalId, int isArchive, int employeeSource)
{
var secondAllot = agsecondallotRepository.GetEntity(w => w.Id == secondId);
if (secondAllot == null) throw new PerformanceException("未查询到二次绩效信息");
var prevSecondAllot = GetPreviousSecondAllot(hospitalId, secondAllot);
int tempId = (int)Temp.other;
var userTemp = agusetempRepository.GetEntity(w => w.HospitalId == hospitalId && w.Department == secondAllot.Department && w.UnitType == secondAllot.UnitType);
if (userTemp != null) tempId = userTemp.UseTempId ?? (int)Temp.other;
if (tempId == (int)Temp.other) return new SecondResponse();
if (isArchive == 1 || new List<int> { (int)SecondAllotStatus.WaitReview, (int)SecondAllotStatus.PassAudit }.Contains(secondAllot.Status ?? (int)SecondAllotStatus.Uncommitted))
employeeSource = (int)EmployeeSource.Initial;
// 历史保存过的数据
var savedDataList = agfixatitemRepository.GetEntities(w => w.SecondId == secondAllot.Id);
var header = GetHeadItems(hospitalId, tempId, secondAllot);
var body = GetBodyItems(userId, employeeSource, secondAllot, prevSecondAllot, header, savedDataList);
var result = new SecondResponse { HeadItems = header, BodyItems = body };
SupplyHeaderByWorkItem(hospitalId, result, secondAllot, savedDataList);
result.HeadItems = result.HeadItems.OrderBy(t => t.Type).ThenBy(t => t.WorkType).ThenBy(t => t.Sort).ThenBy(t => t.FiledName).ToList();
result.BodyItems = result.BodyItems.OrderBy(t => t.RowNumber).ThenBy(t => t.Type).ThenBy(t => t.Sort).ToList();
return result;
}
/// <summary>
/// 获取显示列
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="tempId"></param>
/// <param name="secondAllot"></param>
/// <returns></returns>
public List<HeadItem> GetHeadItems(int hospitalId, int tempId, ag_secondallot secondAllot)
{
// 数据库配置固定的列
var fixedHeaders = agtempitemRepository.GetEntities(w => w.TempId == tempId);
// 用户自定义的工作量、单项奖励
var configHeaders = agworkloadRepository.GetEntities(w => w.HospitalId == hospitalId && w.Department == secondAllot.Department && w.UnitType == secondAllot.UnitType);
// 初始化固定列
var headItems = Mapper.Map<List<HeadItem>>(fixedHeaders) ?? new List<HeadItem>();
//获取工作量、单项奖励列
if (configHeaders != null && configHeaders.Any())
{
var workDtos = Mapper.Map<List<HeadItem>>(configHeaders.Where(t => t.WorkTypeId == (int)AgWorkloadType.Workload));
workDtos.ForEach(t => { t.Type = (int)TempColumnType.WorkloadColumns; });
headItems.AddRange(workDtos);
workDtos = Mapper.Map<List<HeadItem>>(configHeaders.Where(t => t.WorkTypeId == (int)AgWorkloadType.SingleAwards));
workDtos.ForEach(t => { t.Type = (int)TempColumnType.SingleAwardsColumns; });
headItems.AddRange(workDtos);
}
if (headItems != null && headItems.Any())
headItems = headItems.OrderBy(s => s.Type).ThenBy(s => s.Sort).ToList();
return headItems;
}
/// <summary>
/// 获取显示的数据
/// </summary>
/// <param name="userId"></param>
/// <param name="employeeSource"></param>
/// <param name="secondAllot"></param>
/// <param name="prevSecondAllot"></param>
/// <param name="headItems"></param>
/// <returns></returns>
public List<BodyItem> GetBodyItems(int userId, int employeeSource, ag_secondallot secondAllot, ag_secondallot prevSecondAllot, List<HeadItem> headItems, List<ag_fixatitem> savedDataList)
{
var bodyItems = new List<BodyItem>();
if (headItems == null || !headItems.Any()) return bodyItems;
var topFixedColumns = headItems.Where(w => w.Type == (int)TempColumnType.TopFixedColumns)?.ToList();
if (topFixedColumns != null)
{
var topFixedDataList = new List<BodyItem>();
foreach (var column in topFixedColumns)
{
var topFixedData = new BodyItem(column);
var savedData = savedDataList?.FirstOrDefault(w => w.RowNumber == -1 && w.Type == (int)TempColumnType.TopFixedColumns && w.ItemName == column.FiledName);
if (savedData != null)
{
topFixedData.Value = savedData.ItemValue;
}
topFixedData.RowNumber = -1;
topFixedDataList.Add(topFixedData);
}
SupplementFixedData(secondAllot, topFixedDataList);
bodyItems.AddRange(topFixedDataList);
}
var otherShowColumns = headItems.Where(w => w.Type != (int)TempColumnType.TopFixedColumns)?.ToList();
if (otherShowColumns != null)
{
if (employeeSource == (int)EmployeeSource.Initial)
{
// 保存过数据,从保存的数据中心带出信息
// 未保存过数据,带入初始数据(首次填写二次绩效,人员信息来自人员字典,有历史二次绩效记录时,人员信息来自上次二次绩效填写记录)
if (savedDataList == null || !savedDataList.Any())
{
employeeSource = prevSecondAllot == null ? (int)EmployeeSource.EmployeeDict : (int)EmployeeSource.PrevSecondAllot;
}
}
var tableFixedDataList = GetBodyItemsByEmployeeSource(userId, employeeSource, secondAllot, prevSecondAllot, savedDataList, otherShowColumns);
bodyItems.AddRange(tableFixedDataList);
}
return bodyItems;
}
private List<BodyItem> GetBodyItemsByEmployeeSource(int userId, int employeeSource, ag_secondallot secondAllot, ag_secondallot prevSecondAllot,
List<ag_fixatitem> savedDataList, List<HeadItem> otherShowColumns)
{
switch (employeeSource)
{
case (int)EmployeeSource.Initial:
return GetEmployeeFromSavedData(secondAllot, savedDataList, otherShowColumns);
case (int)EmployeeSource.EmployeeDict:
return GetEmployeeFromEmployeeDict(userId, secondAllot, otherShowColumns);
case (int)EmployeeSource.PrevSecondAllot:
return GetEmployeeFromPrevData(userId, secondAllot, prevSecondAllot, otherShowColumns);
default:
return new List<BodyItem>();
}
}
/// <summary>
/// 从保存过的数据中获取人员信息
/// </summary>
/// <param name="savedDataList"></param>
/// <param name="otherShowColumns"></param>
/// <returns></returns>
public List<BodyItem> GetEmployeeFromSavedData(ag_secondallot secondAllot, List<ag_fixatitem> savedDataList, List<HeadItem> otherShowColumns)
{
var tableFixedDataList = new List<BodyItem>();
if (otherShowColumns == null || savedDataList == null || !savedDataList.Any(w => w.RowNumber.HasValue && w.RowNumber > -1))
return tableFixedDataList;
var rowNumberList = savedDataList.Where(w => w.RowNumber.HasValue && w.RowNumber > -1)?.Select(w => w.RowNumber.Value).Distinct().OrderBy(t => t).ToList();
if (rowNumberList != null && rowNumberList.Any())
{
foreach (var rowNumber in rowNumberList)
{
foreach (var column in otherShowColumns)
{
var tableFixedData = new BodyItem(column);
var savedData = savedDataList.FirstOrDefault(w => w.RowNumber == rowNumber && w.Type == column.Type && w.ItemName == column.FiledName);
if (savedData != null)
{
tableFixedData.Value = savedData.ItemValue;
tableFixedData.RowNumber = rowNumber;
}
tableFixedDataList.Add(tableFixedData);
}
}
SupplementOtherPerfor(secondAllot, tableFixedDataList);
}
return tableFixedDataList;
}
/// <summary>
/// 从人员字典中获取人员信息
/// </summary>
/// <param name="userId"></param>
/// <param name="secondAllot"></param>
/// <param name="otherShowColumns"></param>
/// <returns></returns>
public List<BodyItem> GetEmployeeFromEmployeeDict(int userId, ag_secondallot secondAllot, List<HeadItem> otherShowColumns)
{
var tableFixedDataList = new List<BodyItem>();
if (otherShowColumns == null || !otherShowColumns.Any()) return tableFixedDataList;
var employeeList = personService.GetPersons(secondAllot.AllotId.Value, userId);
if (employeeList == null || !employeeList.Any()) return tableFixedDataList;
//var perapramounts = perapramountRepository.GetEntities(t => t.AllotId == secondAllot.AllotId && t.Status == 3);
//Func<per_employee, decimal?> getAprAmount = (t) => perapramounts
// ?.Where(w => w.AccountingUnit?.Trim() == secondAllot.Department?.Trim() && w.DoctorName?.Trim() == t.DoctorName?.Trim() && w.PersonnelNumber?.Trim() == t.JobNumber?.Trim())
// ?.Sum(w => w.Amount);
var employeeColumns = new List<Tuple<string, string, Func<per_employee, object>>>
{
new Tuple<string, string, Func<per_employee, object>>("人员工号", "PersonnelNumber", (t) => t.JobNumber),
new Tuple<string, string, Func<per_employee, object>>("姓名", "FullName", (t) => t.DoctorName),
new Tuple<string, string, Func<per_employee, object>>(
"岗位", "Post",
(t) => (t.Duty?.IndexOf("主任") > -1 || t.Duty?.IndexOf("护士长") > -1) ? "科主任/护士长" : "其他"),
new Tuple<string, string, Func<per_employee, object>>("出勤", "ActualAttendance", (t) => t.AttendanceDay),
new Tuple<string, string, Func<per_employee, object>>("人员系数", "StaffCoefficient", (t) => 1),
new Tuple<string, string, Func<per_employee, object>>("职称", "JobTitle", (t) => t.JobTitle),
new Tuple<string, string, Func<per_employee, object>>("预留比例", "ReservedRatio", (t) => t.ReservedRatio),
new Tuple<string, string, Func<per_employee, object>>("医院其他绩效", "OtherPerformance", (t) => 0)
};
int rowNumber = 0;
foreach (var employee in employeeList)
{
foreach (var column in employeeColumns)
{
var headItem = otherShowColumns.FirstOrDefault(w => w.FiledName == column.Item1 && w.FiledId == column.Item2 && w.Type == (int)TempColumnType.TableFixedColumns);
if (headItem == null) continue;
var tableFixedData = new BodyItem(headItem);
var value = column.Item3.Invoke(employee);
tableFixedData.Value = value?.ToString();
tableFixedData.RowNumber = rowNumber;
tableFixedDataList.Add(tableFixedData);
}
rowNumber++;
}
SupplementOtherPerfor(secondAllot, tableFixedDataList);
return tableFixedDataList;
}
/// <summary>
/// 从上一次的保存信息中获取人员信息
/// </summary>
/// <param name="prevSecondAllot"></param>
/// <param name="otherShowColumns"></param>
/// <returns></returns>
public List<BodyItem> GetEmployeeFromPrevData(int userId, ag_secondallot secondAllot, ag_secondallot prevSecondAllot, List<HeadItem> otherShowColumns)
{
var tableFixedDataList = new List<BodyItem>();
if (prevSecondAllot == null || otherShowColumns == null || !otherShowColumns.Any()) return tableFixedDataList;
var savedDataList = agfixatitemRepository.GetEntities(w => w.SecondId == prevSecondAllot.Id && w.RowNumber.HasValue && w.RowNumber > -1);
if (savedDataList == null || !savedDataList.Any()) return tableFixedDataList;
var employeeList = personService.GetPersons(secondAllot.AllotId.Value, userId);
var employeeColumns = new List<Tuple<string, string>>
{
new Tuple<string, string>("人员工号", "PersonnelNumber"),
new Tuple<string, string>("姓名", "FullName"),
new Tuple<string, string>("岗位", "Post"),
new Tuple<string, string>("人员系数", "StaffCoefficient"),
new Tuple<string, string>("职称", "JobTitle"),
new Tuple<string, string>("职称系数", "TitleCoefficient")
};
var rowNumberList = savedDataList.Select(w => w.RowNumber.Value).Distinct().OrderBy(t => t).ToList();
if (rowNumberList != null && rowNumberList.Any())
{
foreach (var rowNumber in rowNumberList)
{
foreach (var column in employeeColumns)
{
var headItem = otherShowColumns.FirstOrDefault(w => w.FiledName == column.Item1 && w.FiledId == column.Item2 && w.Type == (int)TempColumnType.TableFixedColumns);
if (headItem == null) continue;
var tableFixedData = new BodyItem(headItem);
var savedData = savedDataList.FirstOrDefault(w => w.RowNumber == rowNumber && w.Type == (int)TempColumnType.TableFixedColumns && w.ItemName == column.Item1);
if (savedData != null)
{
tableFixedData.Value = savedData.ItemValue;
tableFixedData.RowNumber = rowNumber;
}
tableFixedDataList.Add(tableFixedData);
}
#region 获取人员字典中录入的出勤
var attenItem = otherShowColumns.FirstOrDefault(w => w.FiledName == "出勤" && w.FiledId == "ActualAttendance" && w.Type == (int)TempColumnType.TableFixedColumns);
if (attenItem == null) continue;
var attendance = new BodyItem(attenItem);
var jobNumber = savedDataList.FirstOrDefault(w => w.RowNumber == rowNumber && w.ItemName == "人员工号")?.ItemValue;
var personName = savedDataList.FirstOrDefault(w => w.RowNumber == rowNumber && w.ItemName == "姓名")?.ItemValue;
var employeeAttendance = employeeList.FirstOrDefault(w => w.JobNumber == jobNumber && w.DoctorName == personName)?.AttendanceDay.ToString();
attendance.Value = employeeAttendance;
attendance.RowNumber = rowNumber;
tableFixedDataList.Add(attendance);
#endregion 获取人员字典中录入的出勤
}
SupplementOtherPerfor(secondAllot, tableFixedDataList);
}
return tableFixedDataList;
}
/// <summary>
/// 补充顶部数据中的固定信息
/// </summary>
/// <param name="secondAllot"></param>
/// <param name="bodyItems"></param>
private void SupplementFixedData(ag_secondallot secondAllot, List<BodyItem> bodyItems)
{
if (bodyItems == null || !bodyItems.Any(w => w.RowNumber == -1)) return;
var keyValue = new Dictionary<string, string>
{
{ "发放月份", $"{secondAllot.Year}{secondAllot.Month.ToString().PadLeft(2, '0')}月" },
{ "可分配绩效", secondAllot.RealGiveFee.ToString() },
{ "满勤天数", DateTime.DaysInMonth(secondAllot.Year.Value, secondAllot.Month.Value).ToString() },
};
var configs = cofagainRepository.GetEntities(t => t.AllotID == secondAllot.AllotId);
if (configs != null && configs.Any())
{
var pairs = new Dictionary<string, string>
{
{ "职称绩效", "年资职称绩效占比" },
{ "工作量绩效", "工作量绩效占比" },
};
foreach (var config in configs)
{
var key = pairs.ContainsKey(config.TypeName) ? pairs[config.TypeName] : config.TypeName;
if (!keyValue.Keys.Contains(key)) keyValue.Add(key, config.Value.ToString());
}
}
foreach (var item in keyValue)
{
var field = bodyItems.FirstOrDefault(w => w.RowNumber == -1 && w.FiledName == item.Key);
if (field != null && string.IsNullOrEmpty(field.Value) && !string.IsNullOrEmpty(item.Value)) field.Value = item.Value;
}
}
/// <summary>
/// 补充 医院其他绩效
/// </summary>
/// <param name="result"></param>
private void SupplementOtherPerfor(ag_secondallot secondAllot, List<BodyItem> bodyItems)
{
if (bodyItems == null || !bodyItems.Any(w => w.RowNumber > -1)) return;
var perapramounts = perapramountRepository.GetEntities(t => t.AllotId == secondAllot.AllotId && t.Status == 3);
var rowNumberList = bodyItems.Where(w => w.RowNumber > -1).Select(w => w.RowNumber).Distinct().OrderBy(t => t).ToList();
foreach (var rownum in rowNumberList)
{
var rowData = bodyItems.Where(w => w.RowNumber == rownum);
var personnelNumber = rowData.FirstOrDefault(w => w.FiledId == "PersonnelNumber")?.Value;
var fullName = rowData.FirstOrDefault(w => w.FiledId == "FullName")?.Value;
var amount = perapramounts
?.Where(w => w.AccountingUnit?.Trim() == secondAllot.Department?.Trim() && w.PersonnelNumber?.Trim() == personnelNumber?.Trim())
?.Sum(w => w.Amount);
var otherPerfor = rowData.FirstOrDefault(w => w.FiledId == "OtherPerformance");
if (otherPerfor != null)
otherPerfor.Value = amount?.ToString();
}
}
/// <summary>
/// 根绝添加工作量类型判断是否添加
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="result"></param>
/// <param name="secondAllot"></param>
/// <param name="fixatitems"></param>
private void SupplyHeaderByWorkItem(int hospitalId, SecondResponse result, ag_secondallot secondAllot, List<ag_fixatitem> fixatitems)
{
//不包含工作量绩效
if (!result.HeadItems.Select(t => t.FiledId).Contains("PerformanceShareTheWorkload")) return;
var maxSortValue = result.HeadItems.Where(t => t.Type == 1).Max(t => t.Sort);
var headers = new HeadItem[]
{
new HeadItem { FiledId = "ThePerformanceOf", Type = 1, SourceType = 1, IsBring = 2, SpecialAttr = 1 },
new HeadItem { FiledId = "ThePerformanceAmountOf", Type = 1, SourceType = 1, IsBring = 2, SpecialAttr = 2 }
};
var headerItems = new List<HeadItem>();
var unit = secondAllot.UnitType == UnitType.医技组.ToString() ? UnitType.医生组.ToString() : secondAllot.UnitType;
var deptHeader = agworkloadtypeRepository.GetEntities(t => t.HospitalId == hospitalId && t.Department == secondAllot.Department && t.UnitType == unit);
if (deptHeader != null && deptHeader.Any())
{
int sortindex = 1;
foreach (var item in deptHeader)
{
if (item.HospitalId == 0) continue;
for (int i = 0; i < headers.Length; i++)
{
var headItem = (HeadItem)headers[i].Clone();
headItem.FiledName = (i % 2 == 0) ? item.TypeName : item.TypeName.Replace("占比", "金额");
if (i % 2 != 0 && !headItem.FiledName.EndsWith("金额"))
headItem.FiledName += "金额";
headItem.FiledId += item.Id;
headItem.Sort = maxSortValue + sortindex;
headItem.WorkType = item.Id;
headerItems.Add(headItem);
sortindex++;
}
}
}
var defauleHeader = new List<ag_workload_type>
{
new ag_workload_type { Id = 2, TypeName = "工作量绩效占比", },
new ag_workload_type { Id = 2, TypeName = "工作量分配绩效金额" },
};
foreach (var item in defauleHeader)
{
result.HeadItems.Where(t => t.FiledName == item.TypeName).ToList()?.ForEach(t =>
{
t.WorkType = item.Id;
t.SpecialAttr = item.TypeName.IndexOf("占比") > -1 ? 1 : 2;
});
result.BodyItems.Where(t => t.FiledName == item.TypeName).ToList()?.ForEach(t =>
{
t.WorkType = item.Id;
t.SpecialAttr = item.TypeName.IndexOf("占比") > -1 ? 1 : 2;
});
}
var rownumber = result.BodyItems.Any(t => t.RowNumber == -1) ? -1 : 0;
foreach (var item in headerItems)
{
if (!result.HeadItems.Select(t => t.FiledId).Contains(item.FiledId))
{
result.HeadItems.Add(item);
var body = Mapper.Map<BodyItem>(item);
body.RowNumber = rownumber;
if (fixatitems != null && fixatitems.Any(t => t.ItemName == item.FiledName))
body.Value = fixatitems.FirstOrDefault(t => t.ItemName == item.FiledName).ItemValue;
result.BodyItems.Add(body);
}
}
}
#endregion 横向纵向模板详情
#region 其他模板详情
public List<ag_othersource> GetOtherTempDetails(int userId, int secondId, int isArchive, int employeeSource)
{
var secondAllot = agsecondallotRepository.GetEntity(t => t.Id == secondId);
if (secondAllot == null) throw new PerformanceException("二次绩效信息无效!");
var allot = perallotRepository.GetEntity(w => w.ID == secondAllot.AllotId);
if (allot == null) throw new PerformanceException("未查询到匹配的绩效信息");
var prevSecondAllot = GetPreviousSecondAllot(allot.HospitalId, secondAllot);
var result = new List<ag_othersource>();
var savedDataList = agothersourceRepository.GetEntities(t => t.SecondId == secondId);
var isSupplementTitlePerformance = savedDataList == null || !savedDataList.Any();
if (employeeSource == (int)EmployeeSource.Initial)
{
employeeSource = (savedDataList == null || !savedDataList.Any()) && prevSecondAllot == null
? (int)EmployeeSource.EmployeeDict
: (int)EmployeeSource.PrevSecondAllot;
}
if (isArchive == 1 || new List<int> { (int)SecondAllotStatus.WaitReview, (int)SecondAllotStatus.PassAudit }.Contains(secondAllot.Status ?? (int)SecondAllotStatus.Uncommitted))
employeeSource = (int)EmployeeSource.Initial;
var employees = personService.GetPersons(secondAllot.AllotId.Value, userId)?.Where(t => t.UnitType == secondAllot.UnitType).ToList();
switch (employeeSource)
{
case (int)EmployeeSource.Initial:
result = savedDataList.OrderBy(t => t.Id).ToList();
break;
case (int)EmployeeSource.EmployeeDict:
if (employees == null || !employees.Any()) return new List<ag_othersource>();
result = employees.Select(t => new ag_othersource
{
SecondId = secondId,
WorkNumber = t.JobNumber /*?? t.PersonnelNumber*/,
Name = t.DoctorName,
Department = t.Department,
WorkPost = t.JobTitle,
}).ToList();
break;
case (int)EmployeeSource.PrevSecondAllot:
var prevSavedDataList = agothersourceRepository.GetEntities(t => t.SecondId == prevSecondAllot.Id);
isSupplementTitlePerformance = prevSavedDataList == null || !prevSavedDataList.Any();
if (prevSavedDataList != null && prevSavedDataList.Any())
{
result = prevSavedDataList.OrderBy(t => t.Id)
.Select(t => new ag_othersource
{
SecondId = secondId,
WorkNumber = t.WorkNumber,
Name = t.Name,
Department = t.Department,
WorkPost = t.WorkPost,
}).ToList();
}
break;
default:
break;
}
SupplementSecondDetail(secondAllot, employees, result, isSupplementTitlePerformance);
return result;
}
/// <summary>
/// 补充二次分配 人员明细
/// </summary>
/// <param name="second"></param>
/// <param name="employees"></param>
/// <param name="result"></param>
/// <param name="isTitlePerformance">是否补全职称绩效</param>
private void SupplementSecondDetail(ag_secondallot second, List<per_employee> employees, List<ag_othersource> result, bool isTitlePerformance = true)
{
if (employees == null || !employees.Any(t => t.UnitType == second.UnitType))
return;
// 补充医院其他绩效 及 预留比例
var perapramounts = perapramountRepository.GetEntities(t => t.AllotId == second.AllotId && t.Status == 3);
Func<per_employee, decimal?> getAprAmount = (t) => perapramounts
?.Where(w => w.AccountingUnit?.Trim() == second.Department?.Trim() && w.DoctorName?.Trim() == t.DoctorName?.Trim() && w.PersonnelNumber?.Trim() == t.PersonnelNumber?.Trim())
?.Sum(w => w.Amount);
var distPerformance = rescomputeRepository.GetEntities(t => t.AllotID == second.AllotId && employees.Select(s => s.DoctorName).Contains(t.EmployeeName));
Func<per_employee, decimal?> getDistPerformance = (t) => 0;
if (second.UnitType == UnitType.行政后勤.ToString())
getDistPerformance = (t) => distPerformance
?.Where(w => w.AccountingUnit?.Trim() == second.Department?.Trim() && w.EmployeeName?.Trim() == t.DoctorName?.Trim() && w.JobNumber?.Trim() == t.PersonnelNumber?.Trim())
?.Sum(w => w.GiveFee);
foreach (var item in result)
{
var empl = employees.FirstOrDefault(w => w.PersonnelNumber?.Trim() == item.WorkNumber?.Trim() && w.DoctorName?.Trim() == item.Name?.Trim());
if (empl != null)
{
item.ReservedRatio = empl.ReservedRatio;
item.OtherPerformance = getAprAmount(empl);
if (isTitlePerformance)
item.TitlePerformance = getDistPerformance(empl);
}
}
}
#endregion 其他模板详情
/// <summary>
/// 获取上一次的二次绩效
/// </summary>
/// <param name="hospitalId"></param>
/// <param name="secondAllot"></param>
/// <returns></returns>
private ag_secondallot GetPreviousSecondAllot(int hospitalId, ag_secondallot secondAllot)
{
// 历史删除绩效时,未删除对应的二次绩效记录
var allotList = perallotRepository.GetEntities(w => w.HospitalId == hospitalId)?.OrderBy(s => s.Year).ThenBy(s => s.Month).ToList();
if (allotList == null || !allotList.Any()) throw new PerformanceException("未查询到符合的绩效记录");
var allot = allotList.FirstOrDefault(w => w.ID == secondAllot.AllotId);
if (allot == null) throw new PerformanceException("未查询到符合的绩效记录");
var index = allotList.IndexOf(allot);
if (index == 0) return null;
var prevAllot = allotList[index - 1];
var prevSecondAllot = agsecondallotRepository.GetEntity(w => w.AllotId == prevAllot.ID && w.UnitType == secondAllot.UnitType && w.Department == secondAllot.Department);
return prevSecondAllot;
}
}
/// <summary>
/// 二次绩效模板
/// </summary>
public enum Temp
{
/// <summary>
/// 临床科室二次分配_其他来源
/// </summary>
other = 6,
/// <summary>
/// 二次分配_横向
/// </summary>
crosswise = 7,
/// <summary>
/// 二次分配_纵向
/// </summary>
lengthways = 8
}
/// <summary>
/// 模板中显示项类型
/// </summary>
public enum TempColumnType
{
/// <summary>
/// 顶部固定列
/// </summary>
TopFixedColumns = 1,
/// <summary>
/// 表格固定显示列
/// </summary>
TableFixedColumns = 2,
/// <summary>
/// 工作量配置列
/// </summary>
WorkloadColumns = 3,
/// <summary>
/// 单项奖励配置列
/// </summary>
SingleAwardsColumns = 4,
}
/// <summary>
/// 人员信息来源
/// </summary>
public enum EmployeeSource
{
/// <summary>
/// 初始化(用户保存后的数据)
/// </summary>
Initial = 0,
/// <summary>
/// 上一个二次绩效记录
/// </summary>
PrevSecondAllot = 1,
/// <summary>
/// 人员字典
/// </summary>
EmployeeDict = 2
}
/// <summary>
/// 二次绩效状态
/// 1 未提交 2 等待审核 3 审核通过 4 驳回
/// </summary>
public enum SecondAllotStatus
{
Uncommitted = 1,
WaitReview = 2,
PassAudit = 3,
Reject = 4
}
}
...@@ -28,6 +28,8 @@ public class EmployeeService : IAutoInjection ...@@ -28,6 +28,8 @@ public class EmployeeService : IAutoInjection
private PerforPerapramountRepository perapramountRepository; private PerforPerapramountRepository perapramountRepository;
private PerforImemployeelogisticsRepository perforImemployeelogisticsRepository; private PerforImemployeelogisticsRepository perforImemployeelogisticsRepository;
private PerforUserroleRepository userroleRepository; private PerforUserroleRepository userroleRepository;
private PerforPeremployeeRepository peremployeeRepository;
private PerforUserRepository userRepository;
private ILogger<EmployeeService> logger; private ILogger<EmployeeService> logger;
public EmployeeService(PerforImemployeeRepository perforImemployeeRepository, public EmployeeService(PerforImemployeeRepository perforImemployeeRepository,
...@@ -39,6 +41,8 @@ public class EmployeeService : IAutoInjection ...@@ -39,6 +41,8 @@ public class EmployeeService : IAutoInjection
PerforPerapramountRepository perapramountRepository, PerforPerapramountRepository perapramountRepository,
PerforImemployeelogisticsRepository perforImemployeelogisticsRepository, PerforImemployeelogisticsRepository perforImemployeelogisticsRepository,
PerforUserroleRepository userroleRepository, PerforUserroleRepository userroleRepository,
PerforPeremployeeRepository peremployeeRepository,
PerforUserRepository userRepository,
ILogger<EmployeeService> logger) ILogger<EmployeeService> logger)
{ {
this.perforImemployeeRepository = perforImemployeeRepository; this.perforImemployeeRepository = perforImemployeeRepository;
...@@ -50,6 +54,8 @@ public class EmployeeService : IAutoInjection ...@@ -50,6 +54,8 @@ public class EmployeeService : IAutoInjection
this.perapramountRepository = perapramountRepository; this.perapramountRepository = perapramountRepository;
this.perforImemployeelogisticsRepository = perforImemployeelogisticsRepository; this.perforImemployeelogisticsRepository = perforImemployeelogisticsRepository;
this.userroleRepository = userroleRepository; this.userroleRepository = userroleRepository;
this.peremployeeRepository = peremployeeRepository;
this.userRepository = userRepository;
this.logger = logger; this.logger = logger;
} }
...@@ -568,5 +574,53 @@ public void ImpoerAprEmployees(int allotid, string path, int userid) ...@@ -568,5 +574,53 @@ public void ImpoerAprEmployees(int allotid, string path, int userid)
logger.LogError(ex.ToString()); logger.LogError(ex.ToString());
} }
} }
/// <summary>
/// 根据人员工号获取人员信息
/// </summary>
/// <param name="allotId"></param>
/// <param name="jobNumber"></param>
/// <returns></returns>
public per_apr_amount GetEmployeeMessage(int allotId, string jobNumber, int userId)
{
if (string.IsNullOrEmpty(jobNumber)) return new per_apr_amount();
var user = userRepository.GetEntity(w => w.ID == userId && w.IsDelete == 1);
if (user == null) throw new PerformanceException("操作用户不存在或用户信息错误!");
var employee = peremployeeRepository.GetEntity(w => w.AllotId == allotId && w.JobNumber.Trim() == jobNumber.Trim());
if (employee == null) return new per_apr_amount();
return new per_apr_amount
{
AllotId = allotId,
PersonnelNumber = employee.JobNumber,
DoctorName = employee.DoctorName,
TypeInDepartment = user.Department,
AccountingUnit = employee.AccountingUnit
};
}
/// <summary>
/// 获取绩效类型字典
/// </summary>
/// <param name="allotId"></param>
/// <returns></returns>
public List<TitleValue> GetPerforTypeDict(int allotId)
{
var defaultTypes = new List<string> { "基础绩效", "管理绩效" };
var aprAmountList = perapramountRepository.GetEntities(w => w.AllotId == allotId);
if (aprAmountList != null && aprAmountList.Any(w => !defaultTypes.Contains(w.PerforType)))
{
var savedTypes = aprAmountList.Where(w => !defaultTypes.Contains(w.PerforType)).Select(t => t.PerforType).Distinct().OrderBy(t => t).ToList();
defaultTypes.AddRange(savedTypes);
}
return defaultTypes.Select(t => new TitleValue
{
Title = t,
Value = t
}).ToList();
}
} }
} }
\ No newline at end of file
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions;
namespace Performance.Services.ExtractExcelService namespace Performance.Services.ExtractExcelService
{ {
...@@ -86,6 +87,25 @@ public static void SetCellValue<T>(this ICell cell, object value, T defaultValue ...@@ -86,6 +87,25 @@ public static void SetCellValue<T>(this ICell cell, object value, T defaultValue
cell.SetCellValue(""); cell.SetCellValue("");
} }
} }
public static void SetValue(this ISheet sheet, int row, int column, object value)
{
var icell = sheet.GetOrCreate(row).GetOrCreate(column);
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
switch (value)
{
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*[.]?\d*$"):
value = ConvertHelper.To<double>(value);
break;
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*$"):
value = ConvertHelper.To<int>(value);
break;
}
}
SetCellOValue(icell, value);
}
public static void SetCellOValue(this ICell cell, object value) public static void SetCellOValue(this ICell cell, object value)
{ {
...@@ -127,6 +147,7 @@ public static void SetCellOValue(this ICell cell, object value) ...@@ -127,6 +147,7 @@ public static void SetCellOValue(this ICell cell, object value)
case "System.Byte": case "System.Byte":
int intV = 0; int intV = 0;
int.TryParse(stringV, out intV); int.TryParse(stringV, out intV);
cell.SetCellType(CellType.Numeric);
cell.SetCellValue(intV); cell.SetCellValue(intV);
break; break;
...@@ -134,6 +155,7 @@ public static void SetCellOValue(this ICell cell, object value) ...@@ -134,6 +155,7 @@ public static void SetCellOValue(this ICell cell, object value)
case "System.Double": case "System.Double":
double doubV = 0; double doubV = 0;
double.TryParse(stringV, out doubV); double.TryParse(stringV, out doubV);
cell.SetCellType(CellType.Numeric);
cell.SetCellValue(doubV); cell.SetCellValue(doubV);
break; break;
......
...@@ -22,6 +22,13 @@ public static string GetExtractFile(int hospitalId, ref string newFilePath, stri ...@@ -22,6 +22,13 @@ public static string GetExtractFile(int hospitalId, ref string newFilePath, stri
return tempPath; return tempPath;
} }
public static string GetExtractFile(int hospitalId, string prefix = "绩效提取数据")
{
var dpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", $"{hospitalId}", "autoextract");
FileHelper.CreateDirectory(dpath);
return Path.Combine(dpath, $"{prefix}{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xls");
}
private static (string TempPath, string FilePath) CopyOriginalFile(int hospitalId, string originalPath) private static (string TempPath, string FilePath) CopyOriginalFile(int hospitalId, string originalPath)
{ {
var ext = FileHelper.GetExtension(originalPath); var ext = FileHelper.GetExtension(originalPath);
......
...@@ -53,6 +53,7 @@ public static void WriteSheetHeader(ISheet sheet, PerSheetPoint point, SheetType ...@@ -53,6 +53,7 @@ public static void WriteSheetHeader(ISheet sheet, PerSheetPoint point, SheetType
: style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.系数, CellFormat.百分比); : style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.系数, CellFormat.百分比);
var columnStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.列头); var columnStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.列头);
headerFirstCellNum += 1;
// 补充excel中不存在的列 // 补充excel中不存在的列
foreach (var item in columns) foreach (var item in columns)
{ {
...@@ -368,4 +369,4 @@ public static void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType ...@@ -368,4 +369,4 @@ public static void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType
#endregion CollectData #endregion CollectData
} }
} }
\ No newline at end of file
...@@ -153,7 +153,7 @@ private void WriteDataToFile(IWorkbook workbook, int allotId, Dictionary<ExDataD ...@@ -153,7 +153,7 @@ private void WriteDataToFile(IWorkbook workbook, int allotId, Dictionary<ExDataD
if (types.Contains(sheetType) && point != null && point.DataFirstCellNum.HasValue) if (types.Contains(sheetType) && point != null && point.DataFirstCellNum.HasValue)
ExtractHelper.ClearSheetPartialData(sheet, point, sheetType); ExtractHelper.ClearSheetPartialData(sheet, point, sheetType);
var customer = factory.GetWriteData(sheetType); var customer = factory.GetWriteData(sheetType, logger);
if (customer != null) if (customer != null)
{ {
string sheetName = sheet.SheetName.NoBlank(); string sheetName = sheet.SheetName.NoBlank();
...@@ -253,4 +253,4 @@ private List<ExtractTransDto> StandDataFormat(int hospitalId, List<ex_result> re ...@@ -253,4 +253,4 @@ private List<ExtractTransDto> StandDataFormat(int hospitalId, List<ex_result> re
return groupdata.ToList(); return groupdata.ToList();
} }
} }
} }
\ No newline at end of file
...@@ -250,7 +250,6 @@ private List<ex_result> ExtractItemData(per_allot allot, string groupName, bool ...@@ -250,7 +250,6 @@ private List<ex_result> ExtractItemData(per_allot allot, string groupName, bool
foreach (var typeId in typeIds) foreach (var typeId in typeIds)
{ {
var thisItems = items.Where(t => t.TypeId == typeId).ToList(); var thisItems = items.Where(t => t.TypeId == typeId).ToList();
var modulename = modules.FirstOrDefault(t => t.Id == thisItems.First().ModuleId)?.ModuleName;
ratio += 30m / typeIds.Count(); ratio += 30m / typeIds.Count();
logService.ReturnTheLog(allot.ID, groupName, 3, "", ratio > 50 ? 50 : ratio, 1, isSingle); logService.ReturnTheLog(allot.ID, groupName, 3, "", ratio > 50 ? 50 : ratio, 1, isSingle);
...@@ -266,6 +265,7 @@ private List<ex_result> ExtractItemData(per_allot allot, string groupName, bool ...@@ -266,6 +265,7 @@ private List<ex_result> ExtractItemData(per_allot allot, string groupName, bool
{ {
thisItems.ForEach(f => thisItems.ForEach(f =>
{ {
var modulename = modules.FirstOrDefault(t => t.Id == f.ModuleId)?.ModuleName;
var result = querydata.Select(t => new ex_result var result = querydata.Select(t => new ex_result
{ {
Department = t.Department, Department = t.Department,
...@@ -404,4 +404,4 @@ private IEnumerable<ExtractDto> QueryData(sys_hospitalconfig config, per_allot a ...@@ -404,4 +404,4 @@ private IEnumerable<ExtractDto> QueryData(sys_hospitalconfig config, per_allot a
#endregion QueryData #endregion QueryData
} }
} }
\ No newline at end of file
using NPOI.SS.UserModel; using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
using System; using System;
...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite ...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{ {
public class DepartmentDataWrite : ISheetDataWrite public class DepartmentDataWrite : ISheetDataWrite
{ {
private readonly ILogger logger;
public DepartmentDataWrite(ILogger logger)
{
this.logger = logger;
}
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects) public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{ {
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return; if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
...@@ -39,7 +47,6 @@ public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetT ...@@ -39,7 +47,6 @@ public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetT
public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null) public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, object data, Dictionary<ExDataDict, object> exdict = null)
{ {
} }
} }
} }
using NPOI.SS.UserModel; using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
using System; using System;
...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite ...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{ {
public class IncomeDataWrite : ISheetDataWrite public class IncomeDataWrite : ISheetDataWrite
{ {
private readonly ILogger logger;
public IncomeDataWrite(ILogger logger)
{
this.logger = logger;
}
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects) public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{ {
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return; if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
...@@ -36,13 +44,14 @@ public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetTyp ...@@ -36,13 +44,14 @@ public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetTyp
if (data is List<ExtractTransDto> extractDto && extractDto.Any()) if (data is List<ExtractTransDto> extractDto && extractDto.Any())
{ {
var headers = extractDto.Select(t => new ExcelHeader var headers = extractDto.Select(t => t.Category.Trim()).Distinct()
{ .Select(t => new ExcelHeader
ColumnName = t.Category.Trim(), {
DoctorFactor = 0, ColumnName = t,
NurseFactor = 0, DoctorFactor = 0,
TechnicianFactor = 0 NurseFactor = 0,
}).ToList(); TechnicianFactor = 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers); WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
var columns = headers.Select(t => t.ColumnName).ToList(); var columns = headers.Select(t => t.ColumnName).ToList();
...@@ -50,4 +59,4 @@ public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetTyp ...@@ -50,4 +59,4 @@ public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetTyp
} }
} }
} }
} }
\ No newline at end of file
using NPOI.SS.UserModel; using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
using System; using System;
...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite ...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{ {
public class OtherIncomeDataWrite : ISheetDataWrite public class OtherIncomeDataWrite : ISheetDataWrite
{ {
private readonly ILogger logger;
public OtherIncomeDataWrite(ILogger logger)
{
this.logger = logger;
}
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects) public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{ {
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return; if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
......
using NPOI.SS.UserModel; using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.SS.Util; using NPOI.SS.Util;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
...@@ -12,6 +13,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite ...@@ -12,6 +13,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{ {
public class SpecialUnitDataWrite : ISheetDataWrite public class SpecialUnitDataWrite : ISheetDataWrite
{ {
private readonly ILogger logger;
public SpecialUnitDataWrite(ILogger logger)
{
this.logger = logger;
}
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects) public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{ {
} }
...@@ -79,7 +87,7 @@ private void ClearSheetPartialData(ISheet sheet, List<string> columns, int dataF ...@@ -79,7 +87,7 @@ private void ClearSheetPartialData(ISheet sheet, List<string> columns, int dataF
foreach (var cellIndex in dict) foreach (var cellIndex in dict)
{ {
var cell = row.GetCell(cellIndex); var cell = row.GetCell(cellIndex);
if (cell != null) row.RemoveCell(cell); if (cell != null && cell.CellType != CellType.Formula) row.RemoveCell(cell);
} }
} }
} }
...@@ -174,7 +182,7 @@ private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialD ...@@ -174,7 +182,7 @@ private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialD
row.SetRowStyle(rowStyle); row.SetRowStyle(rowStyle);
var department = row.GetCell(dict[SpecialUnitColumns.Department]).GetDecodeEscapes(); var department = row.GetCell(dict[SpecialUnitColumns.Department]).GetDecodeEscapes();
CheckMergedRegions(rowIndex, department, ranges); CheckMergedRegions(rowIndex, department, ranges, dict[SpecialUnitColumns.Department]);
var special = specials.FirstOrDefault(t => t.Department == department && t.Target == target); var special = specials.FirstOrDefault(t => t.Department == department && t.Target == target);
if (special != null) if (special != null)
...@@ -197,26 +205,33 @@ private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialD ...@@ -197,26 +205,33 @@ private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialD
/// <param name="rowIndex"></param> /// <param name="rowIndex"></param>
/// <param name="department"></param> /// <param name="department"></param>
/// <param name="ranges"></param> /// <param name="ranges"></param>
private void CheckMergedRegions(int rowIndex, string department, List<SpecialCellRange> ranges) private void CheckMergedRegions(int rowIndex, string department, List<SpecialCellRange> ranges, int departmentColumnIndex)
{ {
var range = ranges.FirstOrDefault(t => t.FirstRow <= rowIndex && t.LastRow >= rowIndex); try
if (range == null)
{ {
if (rowIndex == 0) return; var range = ranges.FirstOrDefault(t => t.FirstRow <= rowIndex && t.LastRow >= rowIndex);
if (range == null)
int prevRowIndex = rowIndex - 1;
range = ranges.FirstOrDefault(t => t.FirstRow <= prevRowIndex && t.LastRow >= prevRowIndex);
if (range != null && range.Single == department)
range.LastRow = rowIndex;
else
{ {
var columnIndex = ranges.First().FirstColumn; if (rowIndex == 0) return;
ranges.Add(new SpecialCellRange(new CellRangeAddress(rowIndex, rowIndex, columnIndex, columnIndex))
int prevRowIndex = rowIndex - 1;
range = ranges.FirstOrDefault(t => t.FirstRow <= prevRowIndex && t.LastRow >= prevRowIndex);
if (range != null && range.Single == department)
range.LastRow = rowIndex;
else
{ {
Single = department var columnIndex = ranges.FirstOrDefault()?.FirstColumn ?? departmentColumnIndex;
}); ranges.Add(new SpecialCellRange(new CellRangeAddress(rowIndex, rowIndex, columnIndex, columnIndex))
{
Single = department
});
}
} }
} }
catch (Exception ex)
{
logger.LogError("CheckMergedRegions: " + ex);
}
} }
/// <summary> /// <summary>
......
using NPOI.SS.UserModel; using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels; using Performance.DtoModels;
using Performance.EntityModels; using Performance.EntityModels;
using System; using System;
...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite ...@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{ {
public class WorkloadDataWrite : ISheetDataWrite public class WorkloadDataWrite : ISheetDataWrite
{ {
private readonly ILogger logger;
public WorkloadDataWrite(ILogger logger)
{
this.logger = logger;
}
public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects) public void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType sheetType, ExcelStyle style, List<collect_data> collects)
{ {
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return; if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
......
using Performance.DtoModels; using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.Services.ExtractExcelService.SheetDataWrite; using Performance.Services.ExtractExcelService.SheetDataWrite;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
...@@ -8,7 +9,7 @@ namespace Performance.Services.ExtractExcelService ...@@ -8,7 +9,7 @@ namespace Performance.Services.ExtractExcelService
{ {
public class WriteDataFactory public class WriteDataFactory
{ {
public ISheetDataWrite GetWriteData(SheetType sheetType) public ISheetDataWrite GetWriteData(SheetType sheetType, ILogger logger)
{ {
ISheetDataWrite factory; ISheetDataWrite factory;
switch (sheetType) switch (sheetType)
...@@ -21,27 +22,31 @@ public ISheetDataWrite GetWriteData(SheetType sheetType) ...@@ -21,27 +22,31 @@ public ISheetDataWrite GetWriteData(SheetType sheetType)
// break; // break;
case SheetType.OtherIncome: case SheetType.OtherIncome:
case SheetType.Expend: case SheetType.Expend:
factory = new OtherIncomeDataWrite(); factory = new OtherIncomeDataWrite(logger);
break; break;
case SheetType.Income: case SheetType.Income:
factory = new IncomeDataWrite(); factory = new IncomeDataWrite(logger);
break; break;
case SheetType.Workload: case SheetType.Workload:
factory = new WorkloadDataWrite(); factory = new WorkloadDataWrite(logger);
break; break;
//case SheetType.AccountBasic: //case SheetType.AccountBasic:
// factory = new AccountBasicDataWrite(); // factory = new AccountBasicDataWrite();
// break; // break;
case SheetType.SpecialUnit: case SheetType.SpecialUnit:
factory = new SpecialUnitDataWrite(); factory = new SpecialUnitDataWrite(logger);
break; break;
case SheetType.AccountExtra: case SheetType.AccountExtra:
case SheetType.PersonExtra: case SheetType.PersonExtra:
case SheetType.AccountScoreAverage: case SheetType.AccountScoreAverage:
case SheetType.BudgetRatio: case SheetType.BudgetRatio:
case SheetType.AssessBeforeOtherFee: case SheetType.AssessBeforeOtherFee:
factory = new DepartmentDataWrite(); factory = new DepartmentDataWrite(logger);
break; break;
default: default:
return null; return null;
} }
......
...@@ -534,8 +534,11 @@ public object DeptIncomeDetail(WorkDetailRequest request, int userId) ...@@ -534,8 +534,11 @@ public object DeptIncomeDetail(WorkDetailRequest request, int userId)
var allot = perallotRepository.GetEntity(w => w.ID == request.AllotId); var allot = perallotRepository.GetEntity(w => w.ID == request.AllotId);
if (allot == null) if (allot == null)
return null; return null;
var sources = new[] { "门诊", "住院" };
if (!sources.Contains(request.Source))
throw new PerformanceException($"数据来源错误,只支持:{string.Join(";", sources)}");
var data = perallotRepository.QueryIncomeData(request.AllotId, request.AccountingUnit, second.UnitType, allot.HospitalId); var data = perallotRepository.QueryIncomeData(request.AllotId, request.Source, request.AccountingUnit, second.UnitType, allot.HospitalId);
if (data != null && data.Any()) if (data != null && data.Any())
{ {
return data.GroupBy(t => new { t.Department, t.DoctorName, t.PersonnelNumber, t.Category }) return data.GroupBy(t => new { t.Department, t.DoctorName, t.PersonnelNumber, t.Category })
......
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace Performance.Services.Queues
{
public interface IBackgroundTaskQueue
{
void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem);
Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken);
}
public class BackgroundTaskQueue : IBackgroundTaskQueue
{
private readonly ConcurrentQueue<Func<CancellationToken, Task>> _workItems = new ConcurrentQueue<Func<CancellationToken, Task>>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(0);
public void QueueBackgroundWorkItem(Func<CancellationToken, Task> workItem)
{
if (workItem == null)
{
throw new ArgumentNullException(nameof(workItem));
}
_workItems.Enqueue(workItem);
_signal.Release();
}
public async Task<Func<CancellationToken, Task>> DequeueAsync(CancellationToken cancellationToken)
{
await _signal.WaitAsync(cancellationToken);
_workItems.TryDequeue(out var workItem);
return workItem;
}
}
}
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Logging;
using Performance.Infrastructure;
using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
namespace Performance.Services.Queues
{
public interface IHubNotificationQueue
{
/// <summary>
/// 发送消息
/// </summary>
/// <param name="message"></param>
void Send(Notification message);
}
public class HubNotificationQueue : IHubNotificationQueue
{
private readonly ILogger<HubNotificationQueue> _logger;
private IHubContext<AllotLogHub> _hubContext;
private BlockingCollection<Notification> _queue;
public HubNotificationQueue(
ILogger<HubNotificationQueue> logger,
IHubContext<AllotLogHub> hubContext)
{
_logger = logger;
_hubContext = hubContext;
_queue = new BlockingCollection<Notification>();
Task.Factory.StartNew(() => Consumer());
}
public void Send(Notification message)
{
_queue.TryAdd(message);
}
private void Consumer()
{
foreach (var item in _queue.GetConsumingEnumerable())
{
_logger.LogInformation(
"ConectionId GroupName:{ConectionId};消息推送:{Method};内容:{Body}",
item.UserId.ToString(),
item.Method,
JsonHelper.Serialize(item.Body));
_hubContext.Clients.Group(item.UserId.ToString()).SendAsync(item.Method, item.Body);
}
}
}
public enum NotificationLevel
{
[Description("通知")] INF,
[Description("警告")] WAR,
[Description("错误")] ERR,
}
public class Notification
{
public Notification(int userId, string method, PushContent body)
{
UserId = userId;
Method = method;
Body = body;
}
public int UserId { get; set; }
public string Method { get; set; }
public PushContent Body { get; set; }
public abstract class PushContent
{
protected PushContent(string subject, NotificationLevel level)
{
Subject = subject;
LogLevel = level.ToString();
}
public abstract string Type { get; }
public string LogLevel { get; }
public string Time { get => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }
public string Subject { get; set; }
}
}
public class EventContent : Notification.PushContent
{
public EventContent(object eventId, string subject, string content, NotificationLevel level = NotificationLevel.INF)
: base(subject, level)
{
EventId = eventId;
Content = content;
}
public object EventId { get; set; }
public string Content { get; set; }
public override string Type => "Event";
}
public class TextContent : Notification.PushContent
{
public TextContent(string content, NotificationLevel level = NotificationLevel.INF)
: base(content, level)
{
}
public override string Type => "Text";
}
public class UrlContent : Notification.PushContent
{
public UrlContent(string subject, string url, NotificationLevel level = NotificationLevel.INF)
: base(subject, level)
{
Content = url;
}
public string Content { get; set; }
public override string Type => "Url";
}
public class CustomDownloadContent : Notification.PushContent
{
public CustomDownloadContent(string subject,object @object ,NotificationLevel level = NotificationLevel.INF)
: base(subject, level)
{
Arguments = @object;
}
public override string Type => "CustomDownload";
public object Arguments { get; set; }
}
}
...@@ -419,6 +419,7 @@ private List<BodyItem> GetEmployees(List<per_employee> employees, int allotId, i ...@@ -419,6 +419,7 @@ private List<BodyItem> GetEmployees(List<per_employee> employees, int allotId, i
{ ("姓名", "FullName"), (t) => t.DoctorName }, { ("姓名", "FullName"), (t) => t.DoctorName },
{ ("岗位", "Post"), (t) => !string.IsNullOrEmpty(t.Duty) && (t.Duty.IndexOf("主任") > -1 || t.Duty.IndexOf("护士长") > -1) ? "主任" : "其他" }, { ("岗位", "Post"), (t) => !string.IsNullOrEmpty(t.Duty) && (t.Duty.IndexOf("主任") > -1 || t.Duty.IndexOf("护士长") > -1) ? "主任" : "其他" },
{ ("出勤", "ActualAttendance"), (t) => t.AttendanceDay }, { ("出勤", "ActualAttendance"), (t) => t.AttendanceDay },
{ ("职称", "JobTitle"), (t) => t.JobTitle },
{ ("预留比例", "ReservedRatio"), (t) => t.ReservedRatio }, { ("预留比例", "ReservedRatio"), (t) => t.ReservedRatio },
{ ("医院其他绩效","OtherPerformance"), (t) => getAprAmount(t)}, { ("医院其他绩效","OtherPerformance"), (t) => getAprAmount(t)},
}; };
......
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