Commit 3667cd9c by ruyun.zhang@suvalue.com

Merge branch '多分支合并' into v2020morge

parents a45a289e fff0604a
using System;
using System.Collections.Concurrent;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Performance.Services.Queues;
using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
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
{
private readonly ILogger<QueuedHostedService> _logger;
......@@ -87,4 +55,5 @@ public class QueuedHostedService : BackgroundService
await base.StopAsync(stoppingToken);
}
}
}
\ No newline at end of file
}
......@@ -3,17 +3,14 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
namespace Performance.Api.Controllers
{
......
......@@ -11,6 +11,7 @@
using Performance.Infrastructure;
using Performance.Services;
using Performance.Services.AllotCompute;
using Performance.Services.Queues;
using System;
using System.Collections.Generic;
using System.IO;
......@@ -197,17 +198,17 @@ public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody] A
}
else
{
BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1));
//_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
//{
// using (var scope = _serviceScopeFactory.CreateScope())
// {
// var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
// scopedServices.Generate(allot, email);
// await Task.Delay(TimeSpan.FromSeconds(5), token);
// }
//});
//BackgroundJob.Schedule(() => _allotService.Generate(allot, email), TimeSpan.FromSeconds(1));
_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var scopedServices = scope.ServiceProvider.GetRequiredService<AllotService>();
scopedServices.Generate(allot, email);
await Task.Delay(TimeSpan.FromSeconds(5), token);
}
});
}
logManageService.WriteMsg("等待绩效生成", $"等待绩效生成{allot.Year}-{allot.Month.ToString().PadLeft(2, '0')}月份绩效!", 1, allot.ID, "ReceiveMessage");
......
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Services;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Performance.Api.Controllers
{
......@@ -21,6 +11,7 @@ public class AssessController : Controller
private ClaimService claimService;
private AssessService assessService;
private UserService userService;
public AssessController(ClaimService claimService,
AssessService assessService, UserService userService)
{
......@@ -32,7 +23,7 @@ public class AssessController : Controller
//考核类别列表
[HttpPost]
[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);
}
......@@ -40,7 +31,7 @@ public ApiResponse AssessList([CustomizeValidator(RuleSet = "List"), FromBody]As
//新增考核类别
[HttpPost]
[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);
}
......@@ -48,7 +39,7 @@ public ApiResponse AddAssess([CustomizeValidator(RuleSet = "Add"), FromBody]Asse
//修改考核类别
[HttpPost]
[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);
}
......@@ -56,7 +47,7 @@ public ApiResponse EditAssess([CustomizeValidator(RuleSet = "Update"), FromBody]
//删除考核类别
[HttpPost]
[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);
}
......@@ -64,7 +55,7 @@ public ApiResponse DelAssess([CustomizeValidator(RuleSet = "Del"), FromBody]Asse
//获取所有科室列表
[HttpPost]
[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);
return new ApiResponse(ResponseType.OK, "ok", department);
......@@ -73,7 +64,7 @@ public ApiResponse DepartmentList([CustomizeValidator(RuleSet = "Use"), FromBody
//设置科室考核分类
[HttpPost]
[Route("setassesstype")]
public ApiResponse SetAssessType([FromBody]SetAssessRequest request)
public ApiResponse SetAssessType([FromBody] SetAssessRequest request)
{
return assessService.SetAssessType(request);
}
......@@ -81,7 +72,7 @@ public ApiResponse SetAssessType([FromBody]SetAssessRequest request)
//考核列头列表
[HttpPost]
[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);
}
......@@ -89,7 +80,7 @@ public ApiResponse ColumnList([CustomizeValidator(RuleSet = "List"), FromBody]As
//新增考核项
[HttpPost]
[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);
}
......@@ -97,7 +88,7 @@ public ApiResponse AddColumn([CustomizeValidator(RuleSet = "Add"), FromBody]Asse
//修改考核项
[HttpPost]
[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);
}
......@@ -105,7 +96,7 @@ public ApiResponse EditColumn([CustomizeValidator(RuleSet = "Update"), FromBody]
//删除考核项
[HttpPost]
[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);
}
......@@ -113,7 +104,7 @@ public ApiResponse DelColumn([CustomizeValidator(RuleSet = "Del"), FromBody]Asse
//考核数据列表
[HttpPost]
[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);
}
......@@ -121,7 +112,7 @@ public ApiResponse DataList([CustomizeValidator(RuleSet = "List"), FromBody]Asse
//考核数据修改
[HttpPost]
[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);
}
......@@ -137,7 +128,7 @@ public ApiResponse TempAssessList()
//模板列头列表
[HttpPost]
[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);
}
......@@ -145,9 +136,9 @@ public ApiResponse TempColumnList([CustomizeValidator(RuleSet = "List"), FromBod
//使用考核模版
[HttpPost]
[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);
}
}
}
}
\ No newline at end of file
......@@ -289,20 +289,17 @@ public ApiResponse AllComputeByPM([FromBody] ComputerRequest request)
if (list == null || !list.Any())
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,
JobNumber = t.Key.JobNumber,
PerforSumFee = t.Sum(s => s.PerforSumFee),
PerforManagementFee = t.Sum(s => s.PerforManagementFee),
Adjust = t.FirstOrDefault()?.Adjust ?? 0,
AdjustLaterOtherFee = t.Sum(s => s.AdjustLaterOtherFee),
ShouldGiveFee = t.Sum(s => s.ShouldGiveFee),
OthePerfor = t.Sum(s => s.OthePerfor),
NightWorkPerfor = t.Sum(s => s.NightWorkPerfor),
RealGiveFee = t.Sum(s => s.RealGiveFee),
JobTitle = t.FirstOrDefault(f => !string.IsNullOrEmpty(f.JobTitle))?.JobTitle
//ReservedRatio = t.Sum(s => s.ReservedRatio),
//ReservedRatioFee = t.Sum(s => s.ReservedRatioFee),
});
......
......@@ -8,6 +8,7 @@
using Performance.Infrastructure;
using Performance.Services;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
......@@ -427,5 +428,39 @@ public ApiResponse Import([FromForm] IFormCollection form)
employeeService.ImpoerAprEmployees(allotid, path, claim.GetUserId());
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 Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace Performance.Api.Controllers
{
......@@ -19,4 +15,4 @@ public ActionResult<ApiResponse> Get()
return new ApiResponse(ResponseType.NotFound, "not found");
}
}
}
}
\ No newline at end of file
......@@ -21,15 +21,19 @@ public class SecondAllotController : ControllerBase
private readonly ClaimService claimService;
private readonly SecondAllotService secondAllotService;
private readonly ResultComputeService resultComputeService;
private readonly SecondAllotDetails secondAllotDetails;
public SecondAllotController(
ClaimService claimService,
SecondAllotService secondAllotService,
ResultComputeService resultComputeService)
ResultComputeService resultComputeService,
SecondAllotDetails secondAllotDetails
)
{
this.claimService = claimService;
this.secondAllotService = secondAllotService;
this.resultComputeService = resultComputeService;
this.secondAllotDetails = secondAllotDetails;
}
#region 二次绩效列表、录入数据展示,保存数据
......@@ -120,7 +124,8 @@ public ApiResponse SaveCompute([FromBody] List<ag_compute> request)
[HttpPost]
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);
}
......@@ -396,7 +401,8 @@ public ApiResponse NursingDeptAuditResult([FromBody] SecondAuditRequest request)
[HttpPost]
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
{
header = secondAllotService.OtherListHeader(request.SecondId, result?.Sum(t => t.RealAmount)),
......@@ -444,4 +450,4 @@ public ApiResponse DeptComputeDetail(int allotId)
return new ApiResponse(ResponseType.OK, new { isShowManage, data });
}
}
}
\ No newline at end of file
}
......@@ -27,6 +27,7 @@ public static void Main(string[] args)
config.AddJsonFile($"appsettings.{env.EnvironmentName}.json", true, true);
env.ConfigureNLog("nlog.config");
})
.UseUrls("http://*:5001")
.UseStartup<Startup>();
}
}
using AutoMapper;
using FluentValidation;
using FluentValidation.AspNetCore;
using Hangfire;
using Hangfire.MySql.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using NLog;
using NLog.Extensions.Logging;
using NLog.Web;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.DtoModels.AutoMapper;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services;
using Performance.Services.Queues;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Performance.Api
{
......@@ -152,16 +142,17 @@ public void ConfigureServices(IServiceCollection services)
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
services.AddSingleton<IHubNotificationQueue, HubNotificationQueue>();
#region hangfire
//#region hangfire
services.AddHangfire(config =>
{
config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
});
//services.AddHangfire(config =>
//{
// config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
// config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
//});
#endregion hangfire
//#endregion hangfire
services.AddSignalR();
services.AddCors(options =>
......@@ -243,12 +234,12 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
#endregion Swagger
#region hangfire
//#region hangfire
app.UseHangfireServer();
app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } });
//app.UseHangfireServer();
//app.UseHangfireDashboard("/hangfire", new DashboardOptions { Authorization = new[] { new HangfireAuthorizationFilter() } });
#endregion hangfire
//#endregion hangfire
app.UseCors("SignalrCore");
app.UseSignalR(routes => routes.MapHub<AllotLogHub>("/performance/allotLogHub"));
......
......@@ -54,7 +54,7 @@ public string GetUserClaim(string jwtClaimTypes)
/// <returns></returns>
public List<Claim> GetUserClaim()
{
if (contextAccessor.HttpContext.User == null)
if (contextAccessor.HttpContext?.User == null)
{
throw new PerformanceException("获取当前请求登录信息失败");
}
......
......@@ -747,6 +747,30 @@
<param name="form"></param>
<returns></returns>
</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)">
<summary>
绩效数据抽取模板
......@@ -937,6 +961,12 @@
</summary>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.ModExtractController.DownFile(System.Int32)">
<summary>
从WebAPI下载文件
</summary>
<returns></returns>
</member>
<member name="T:Performance.Api.Controllers.OriginalController">
<summary>
原始数据修改
......
......@@ -179,6 +179,13 @@
<member name="F:Performance.DtoModels.DataFormat.日期">
<summary> 日期 </summary>
</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">
<summary>
......@@ -2247,6 +2254,9 @@
<member name="P:Performance.DtoModels.UseTempRequest.IsArchive">
<summary> 是否归档 </summary>
</member>
<member name="P:Performance.DtoModels.UseTempRequest.EmployeeSource">
<summary> 人员信息来源 </summary>
</member>
<member name="P:Performance.DtoModels.WorkItemRequest.Item">
<summary>
工作量绩效项
......
......@@ -103,6 +103,9 @@
<member name="P:Performance.EntityModels.PerformanceDbContext.collect_permission">
<summary> </summary>
</member>
<member name="P:Performance.EntityModels.PerformanceDbContext.cust_script">
<summary> </summary>
</member>
<member name="P:Performance.EntityModels.PerformanceDbContext.ex_item">
<summary> </summary>
</member>
......@@ -1668,6 +1671,41 @@
0 可见 1 不可见
</summary>
</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">
<summary>
......@@ -3053,6 +3091,11 @@
0 不显示 1 显示
</summary>
</member>
<member name="P:Performance.EntityModels.per_allot.CustomExtractPath">
<summary>
自定义提取绩效数据文件生成路径
</summary>
</member>
<member name="T:Performance.EntityModels.per_apr_amount">
<summary>
......
......@@ -24,15 +24,22 @@ public HandsonTable(int sheetType, string[] cols, List<collect_permission> permi
public List<Dictionary<string, string>> Data => _data;
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)
{
var dic = CreateDataRow("编号", dt.Row.ToString());
foreach (var item in dt.CellData)
{
if (dic.ContainsKey(item.Name) && _permissions.Any(w => w.HeadName == item.Name && w.AttachLast > 0))
dic[item.Name] = item.Value?.ToString();
if (dic.ContainsKey(item.Name.ToLower()) && isTypein && _permissions.Any(w => w.HeadName.ToLower() == item.Name.ToLower()))
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);
}
......@@ -51,11 +58,12 @@ private void InitColHeaders(int sheetType, string[] cols)
var necessitys = defaluts.FirstOrDefault(w => sheetType == (int)w.SheetType)?.Necessity.ToList();
necessitys = necessitys ?? new List<string>();
foreach (var item in cols)
foreach (var col in cols)
{
var item = col.ToLower();
if (!necessitys.Contains(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);
}
ColHeaders = necessitys.ToArray();
......@@ -64,12 +72,12 @@ private void InitColHeaders(int sheetType, string[] cols)
private void InitColumns(List<collect_permission> permissions)
{
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;
columns.Add(new HandsonColumn(item, readnoly));
columns.Add(new HandsonColumn(item.ToLower(), readnoly));
}
Columns = columns.ToArray();
}
......@@ -79,7 +87,7 @@ private void InitColumns(List<collect_permission> permissions)
foreach (var item in ColHeaders)
{
if (!temp.ContainsKey(item))
temp.Add(item, "");
temp.Add(item.ToLower(), "");
}
return temp;
}
......
......@@ -9,6 +9,10 @@ public class AgOtherRequest
{
public int SecondId { get; set; }
public int IsArchive { get; set; }
public int EmployeeSource { get; set; }
public List<ag_othersource> Othersources { get; set; }
}
}
......@@ -19,7 +19,11 @@ public class UseTempRequest
/// <summary> 是否归档 </summary>
public int IsArchive { get; set; }
/// <summary> 人员信息来源 </summary>
public int EmployeeSource { get; set; }
}
public class UseTempRequestValidator : AbstractValidator<UseTempRequest>
{
public UseTempRequestValidator()
......
......@@ -9,7 +9,7 @@ public class WorkDetailRequest
{
public int AllotId { get; set; }
public int SecondId { get; set; }
public string Source { get; set; }
public string AccountingUnit { get; set; }
}
......
......@@ -18,10 +18,13 @@ public class HeadItem : ICloneable
public int Type { get; set; }
public decimal FactorValue { get; set; }
public int SourceType { get; set; }
/// <summary> 1 带出历史数据 2不带出 </summary>
public Nullable<int> IsBring { get; set; }
/// <summary> 1 value相加值为1 </summary>
public Nullable<int> SpecialAttr { get; set; }
public Nullable<int> WorkType { get; set; }
public object Clone()
......@@ -34,5 +37,22 @@ public class BodyItem : HeadItem
{
public int RowNumber { 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)
public virtual DbSet<collect_permission> collect_permission { get; set; }
/// <summary> </summary>
public virtual DbSet<cust_script> cust_script { get; set; }
/// <summary> </summary>
public virtual DbSet<ex_item> ex_item { get; set; }
/// <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
/// 0 不显示 1 显示
/// </summary>
public int ShowFormula { get; set; }
/// <summary>
/// 自定义提取绩效数据文件生成路径
/// </summary>
public string CustomExtractPath { get; set; }
}
}
......@@ -48,6 +48,7 @@ public int DeleteAllotData(int allotId)
{
List<string> tableArray = new List<string>
{
"ag_secondallot",
"cof_again",
"cof_check",
"cof_cmi",
......
......@@ -165,8 +165,7 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri
if (connection.State != ConnectionState.Open) connection.Open();
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
LEFT JOIN per_employee t2 on t1.personnelnumber = t2.jobnumber AND t2.allotid = @allotid
string clear = @"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,t1.PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1
JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName
WHERE t1.allotid = @allotid
AND t3.unittype = @unittype
......@@ -187,20 +186,19 @@ public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, stri
/// 查询门诊收入数据
/// </summary>
/// <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())
{
if (connection.State != ConnectionState.Open) connection.Open();
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
LEFT JOIN per_employee t2 on t1.personnelnumber = t2.jobnumber AND t2.allotid = @allotid
string clear = $@"SELECT DISTINCT t3.AccountingUnit as Department,ifnull(t1.DoctorName, '未知') DoctorName,t1.PersonnelNumber,t1.Category,t1.Fee FROM ex_result t1
JOIN (select distinct AccountingUnit,HISDeptName,unittype from per_dept_dic where HospitalId = @hospitalid) t3 ON t1.Department = t3.HISDeptName
WHERE t1.allotid = @allotid
AND t3.unittype = @unittype
AND t3.accountingunit = @accountingunit
AND t1.Source like '%门诊开单%'
AND t1.Source like '%{source}开单%'
AND T1.IsDelete = 0
ORDER BY t1.doctorname,t1.Category;";
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)
#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)
{
_allotRepository.UpdateAllotStates(allotId, states, remark, generate);
......
......@@ -286,7 +286,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName)
{
var allotList = perforPerallotRepository
.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();
}
if (allot == null)
......@@ -363,7 +363,7 @@ public HandsonTable GetCollectData(int userId, int allotId, string sheetName)
rowDatas = rowDatas.OrderBy(t => t.Row).ToList();
HandsonTable handson = new HandsonTable(sheet.SheetType.Value, cols, permissions);
handson.SetRowData(rowDatas);
handson.SetRowData(rowDatas, (collectdata != null));
return handson;
}
......@@ -481,7 +481,11 @@ public void SaveCollectData(int allotId, SaveCollectData request)
{
var json = JsonHelper.Serialize(item);
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.AddRange(datas.ToArray());
......
......@@ -28,6 +28,8 @@ public class EmployeeService : IAutoInjection
private PerforPerapramountRepository perapramountRepository;
private PerforImemployeelogisticsRepository perforImemployeelogisticsRepository;
private PerforUserroleRepository userroleRepository;
private PerforPeremployeeRepository peremployeeRepository;
private PerforUserRepository userRepository;
private ILogger<EmployeeService> logger;
public EmployeeService(PerforImemployeeRepository perforImemployeeRepository,
......@@ -39,6 +41,8 @@ public class EmployeeService : IAutoInjection
PerforPerapramountRepository perapramountRepository,
PerforImemployeelogisticsRepository perforImemployeelogisticsRepository,
PerforUserroleRepository userroleRepository,
PerforPeremployeeRepository peremployeeRepository,
PerforUserRepository userRepository,
ILogger<EmployeeService> logger)
{
this.perforImemployeeRepository = perforImemployeeRepository;
......@@ -50,6 +54,8 @@ public class EmployeeService : IAutoInjection
this.perapramountRepository = perapramountRepository;
this.perforImemployeelogisticsRepository = perforImemployeelogisticsRepository;
this.userroleRepository = userroleRepository;
this.peremployeeRepository = peremployeeRepository;
this.userRepository = userRepository;
this.logger = logger;
}
......@@ -568,5 +574,53 @@ public void ImpoerAprEmployees(int allotid, string path, int userid)
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 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
namespace Performance.Services.ExtractExcelService
{
......@@ -86,6 +87,25 @@ public static void SetCellValue<T>(this ICell cell, object value, T defaultValue
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)
{
......@@ -127,6 +147,7 @@ public static void SetCellOValue(this ICell cell, object value)
case "System.Byte":
int intV = 0;
int.TryParse(stringV, out intV);
cell.SetCellType(CellType.Numeric);
cell.SetCellValue(intV);
break;
......@@ -134,6 +155,7 @@ public static void SetCellOValue(this ICell cell, object value)
case "System.Double":
double doubV = 0;
double.TryParse(stringV, out doubV);
cell.SetCellType(CellType.Numeric);
cell.SetCellValue(doubV);
break;
......
......@@ -22,6 +22,13 @@ public static string GetExtractFile(int hospitalId, ref string newFilePath, stri
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)
{
var ext = FileHelper.GetExtension(originalPath);
......
......@@ -53,6 +53,7 @@ public static void WriteSheetHeader(ISheet sheet, PerSheetPoint point, SheetType
: style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.系数, CellFormat.百分比);
var columnStyle = style.SetBgkColorAndFormat(style.GetCellStyle(), StyleType.列头);
headerFirstCellNum += 1;
// 补充excel中不存在的列
foreach (var item in columns)
{
......@@ -368,4 +369,4 @@ public static void WriteCollectData(ISheet sheet, PerSheetPoint point, SheetType
#endregion CollectData
}
}
\ No newline at end of file
}
......@@ -153,7 +153,7 @@ private void WriteDataToFile(IWorkbook workbook, int allotId, Dictionary<ExDataD
if (types.Contains(sheetType) && point != null && point.DataFirstCellNum.HasValue)
ExtractHelper.ClearSheetPartialData(sheet, point, sheetType);
var customer = factory.GetWriteData(sheetType);
var customer = factory.GetWriteData(sheetType, logger);
if (customer != null)
{
string sheetName = sheet.SheetName.NoBlank();
......@@ -253,4 +253,4 @@ private List<ExtractTransDto> StandDataFormat(int hospitalId, List<ex_result> re
return groupdata.ToList();
}
}
}
\ No newline at end of file
}
......@@ -250,7 +250,6 @@ private List<ex_result> ExtractItemData(per_allot allot, string groupName, bool
foreach (var typeId in typeIds)
{
var thisItems = items.Where(t => t.TypeId == typeId).ToList();
var modulename = modules.FirstOrDefault(t => t.Id == thisItems.First().ModuleId)?.ModuleName;
ratio += 30m / typeIds.Count();
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
{
thisItems.ForEach(f =>
{
var modulename = modules.FirstOrDefault(t => t.Id == f.ModuleId)?.ModuleName;
var result = querydata.Select(t => new ex_result
{
Department = t.Department,
......@@ -404,4 +404,4 @@ private IEnumerable<ExtractDto> QueryData(sys_hospitalconfig config, per_allot a
#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.EntityModels;
using System;
......@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
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)
{
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
......@@ -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)
{
}
}
}
using NPOI.SS.UserModel;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
......@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
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)
{
if (collects == null || !collects.Any(t => !string.IsNullOrEmpty(t.TypeName))) return;
......@@ -36,13 +44,14 @@ public void WriteSheetData(ISheet sheet, PerSheetPoint point, SheetType sheetTyp
if (data is List<ExtractTransDto> extractDto && extractDto.Any())
{
var headers = extractDto.Select(t => new ExcelHeader
{
ColumnName = t.Category.Trim(),
DoctorFactor = 0,
NurseFactor = 0,
TechnicianFactor = 0
}).ToList();
var headers = extractDto.Select(t => t.Category.Trim()).Distinct()
.Select(t => new ExcelHeader
{
ColumnName = t,
DoctorFactor = 0,
NurseFactor = 0,
TechnicianFactor = 0
}).ToList();
WriteDataHelper.WriteSheetHeader(sheet, point, sheetType, style, headers);
var columns = headers.Select(t => t.ColumnName).ToList();
......@@ -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.EntityModels;
using System;
......@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
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)
{
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 Performance.DtoModels;
using Performance.EntityModels;
......@@ -12,6 +13,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
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)
{
}
......@@ -79,7 +87,7 @@ private void ClearSheetPartialData(ISheet sheet, List<string> columns, int dataF
foreach (var cellIndex in dict)
{
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
row.SetRowStyle(rowStyle);
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);
if (special != null)
......@@ -197,26 +205,33 @@ private void SupplySpecialQuantity(ISheet sheet, ExcelStyle style, List<SpecialD
/// <param name="rowIndex"></param>
/// <param name="department"></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);
if (range == null)
try
{
if (rowIndex == 0) return;
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 range = ranges.FirstOrDefault(t => t.FirstRow <= rowIndex && t.LastRow >= rowIndex);
if (range == null)
{
var columnIndex = ranges.First().FirstColumn;
ranges.Add(new SpecialCellRange(new CellRangeAddress(rowIndex, rowIndex, columnIndex, columnIndex))
if (rowIndex == 0) return;
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>
......
using NPOI.SS.UserModel;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using System;
......@@ -10,6 +11,13 @@ namespace Performance.Services.ExtractExcelService.SheetDataWrite
{
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)
{
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 System;
using System.Collections.Generic;
......@@ -8,7 +9,7 @@ namespace Performance.Services.ExtractExcelService
{
public class WriteDataFactory
{
public ISheetDataWrite GetWriteData(SheetType sheetType)
public ISheetDataWrite GetWriteData(SheetType sheetType, ILogger logger)
{
ISheetDataWrite factory;
switch (sheetType)
......@@ -21,27 +22,31 @@ public ISheetDataWrite GetWriteData(SheetType sheetType)
// break;
case SheetType.OtherIncome:
case SheetType.Expend:
factory = new OtherIncomeDataWrite();
factory = new OtherIncomeDataWrite(logger);
break;
case SheetType.Income:
factory = new IncomeDataWrite();
factory = new IncomeDataWrite(logger);
break;
case SheetType.Workload:
factory = new WorkloadDataWrite();
factory = new WorkloadDataWrite(logger);
break;
//case SheetType.AccountBasic:
// factory = new AccountBasicDataWrite();
// break;
case SheetType.SpecialUnit:
factory = new SpecialUnitDataWrite();
factory = new SpecialUnitDataWrite(logger);
break;
case SheetType.AccountExtra:
case SheetType.PersonExtra:
case SheetType.AccountScoreAverage:
case SheetType.BudgetRatio:
case SheetType.AssessBeforeOtherFee:
factory = new DepartmentDataWrite();
factory = new DepartmentDataWrite(logger);
break;
default:
return null;
}
......
......@@ -534,8 +534,11 @@ public object DeptIncomeDetail(WorkDetailRequest request, int userId)
var allot = perallotRepository.GetEntity(w => w.ID == request.AllotId);
if (allot == 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())
{
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
{ ("姓名", "FullName"), (t) => t.DoctorName },
{ ("岗位", "Post"), (t) => !string.IsNullOrEmpty(t.Duty) && (t.Duty.IndexOf("主任") > -1 || t.Duty.IndexOf("护士长") > -1) ? "主任" : "其他" },
{ ("出勤", "ActualAttendance"), (t) => t.AttendanceDay },
{ ("职称", "JobTitle"), (t) => t.JobTitle },
{ ("预留比例", "ReservedRatio"), (t) => t.ReservedRatio },
{ ("医院其他绩效","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