自定义导出完善

parent 21c2af3d
......@@ -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;
......
......@@ -3,6 +3,7 @@
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.Services;
using Performance.Services.Queues;
using System;
using System.Threading.Tasks;
......@@ -13,40 +14,47 @@ public class ModExtractController : Controller
{
private readonly ClaimService _claim;
private readonly IServiceScopeFactory _serviceScopeFactory;
private readonly IHubNotificationQueue _notificationQueue;
private readonly IBackgroundTaskQueue _backgroundTaskQueue;
public ModExtractController(
ClaimService claim,
IServiceScopeFactory serviceScopeFactory,
IHubNotificationQueue notificationQueue,
IBackgroundTaskQueue backgroundTaskQueue)
{
_claim = claim;
_serviceScopeFactory = serviceScopeFactory;
_notificationQueue = notificationQueue;
_backgroundTaskQueue = backgroundTaskQueue;
}
[HttpPost("custom/{allotId}")]
public ApiResponse CustomExtract(int allotId)
{
var userId = _claim.GetUserId();
_backgroundTaskQueue.QueueBackgroundWorkItem(async token =>
{
using (var scope = _serviceScopeFactory.CreateScope())
{
var scopedServices = scope.ServiceProvider.GetRequiredService<CustomExtractService>();
var scopedAllotService = scope.ServiceProvider.GetRequiredService<AllotService>();
var scopedQueue = scope.ServiceProvider.GetRequiredService<IHubNotificationQueue>();
if (scopedServices.ExtractData(_claim.GetUserId(), allotId, out string resultFilePath))
if (scopedServices.ExtractData(userId, allotId, out string resultFilePath))
{
new ApiResponse(ResponseType.OK, new { path = resultFilePath });
scopedQueue.Send(new Notification(allotId, "Notification", new UrlContent("自定义数据提取数据成功", resultFilePath)));
scopedAllotService.UpdateAllotCustomExtractPath(allotId, resultFilePath);
}
else
{
scopedQueue.Send(new Notification(allotId, "Notification", new UrlContent("自定义数据提取数据失败", resultFilePath, NotificationLevel.ERR)));
}
await Task.Delay(TimeSpan.FromSeconds(5), token);
}
});
_notificationQueue.Send(new Notification(allotId, "Notification", new TextContent("自定义数据提取任务开始执行")));
return new ApiResponse(ResponseType.OK);
......
......@@ -22,6 +22,7 @@
using Performance.Infrastructure;
using Performance.Repository;
using Performance.Services;
using Performance.Services.Queues;
using Swashbuckle.AspNetCore.Swagger;
using System;
using System.Collections.Generic;
......@@ -152,16 +153,17 @@ public void ConfigureServices(IServiceCollection services)
services.AddHostedService<QueuedHostedService>();
services.AddSingleton<IBackgroundTaskQueue, BackgroundTaskQueue>();
// #region hangfire
//
// services.AddHangfire(config =>
// {
// config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
// config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
// });
//
// #endregion hangfire
services.AddSingleton<IHubNotificationQueue, HubNotificationQueue>();
// #region hangfire
//
// services.AddHangfire(config =>
// {
// config.UseFilter(new AutomaticRetryAttribute { Attempts = 0 });
// config.UseStorage(new MySqlStorage(connection.Value.HangfireConnectionString));
// });
//
// #endregion hangfire
services.AddSignalR();
services.AddCors(options =>
......
......@@ -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("获取当前请求登录信息失败");
}
......
......@@ -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>
......@@ -3088,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>
......
......@@ -79,6 +79,8 @@ public PerformanceDbContext(DbContextOptions<PerformanceDbContext> options)
/// <summary> </summary>
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>
public virtual DbSet<ex_module> ex_module { 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; }
}
}
......@@ -256,6 +256,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);
......
......@@ -12,7 +12,6 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Performance.Services
......@@ -56,22 +55,20 @@ public bool ExtractData(int userId, int allotId, out string resultFilePath)
var scripts = _perforcustscriptRepository.GetEntities(w => w.HospitalId == allot.HospitalId && w.IsEnable == 1);
if (scripts != null)
scripts = (IsSecondAdmin(userId))
? scripts?.Where(w => w.IsSecondAllot == 1).ToList()
: scripts?.Where(w => w.IsOnceAllot == 1).ToList();
if (scripts == null && scripts.Count > 0)
{
result = false;
return result;
}
if (IsSecondAdmin(userId))
scripts = scripts.Where(w => w.IsOnceAllot == 2 && w.IsSecondAllot == 1).ToList();
else
scripts = scripts.Where(w => w.IsOnceAllot == 1 && w.IsSecondAllot == 2).ToList();
IWorkbook workbook = null;
try
{
workbook = ExcelHelper.GetWorkbook(filePath);
workbook = new NPOI.HSSF.UserModel.HSSFWorkbook();
ExcelStyle style = new ExcelStyle(workbook);
WriteDataToFile(userId, allot, scripts, workbook);
......@@ -99,6 +96,7 @@ private void WriteDataToFile(int userId, per_allot allot, List<cust_script> scri
var configs = _perforHospitalconfigRepository.GetEntities(t => t.HospitalId == allot.HospitalId)
?? throw new PerformanceException("当前医院没有数据库地址配置");
var parameters = GetParameters(allot, userId);
foreach (var item in scripts)
{
......@@ -110,12 +108,18 @@ private void WriteDataToFile(int userId, per_allot allot, List<cust_script> scri
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);
var headers = ((IDictionary<string, object>)dynamics.ElementAt(0)).Keys;
var hrow = sheet.GetOrCreate(0);
for (int col = 0; col < headers.Count; col++)
{
var cell = hrow.CreateCell(col + 1);
var cell = hrow.CreateCell(col);
cell.SetCellOValue(headers.ElementAt(col));
}
......@@ -131,8 +135,8 @@ private void WriteDataToFile(int userId, per_allot allot, List<cust_script> scri
var value = temp[key]?.ToString() ?? "";
var srow = sheet.GetOrCreate(row + 1);
var cell = srow.CreateCell(col + 1);
cell.SetCellOValue(value);
var cell = srow.CreateCell(col);
SetCellValue(cell, value);
}
}
}
......@@ -143,6 +147,21 @@ private void WriteDataToFile(int userId, per_allot allot, List<cust_script> scri
}
}
}
public void SetCellValue(ICell cell, string value)
{
switch (value)
{
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*[.]?\d*$"):
cell.SetCellValue(ConvertHelper.To<double>(value));
break;
case string reg when Regex.IsMatch(reg, @"^[+-]?\d*$"):
cell.SetCellValue(ConvertHelper.To<int>(value));
break;
default:
cell.SetCellValue(value);
break;
}
}
/// <summary>
/// 查询数据
......@@ -191,7 +210,7 @@ public IEnumerable<dynamic> QueryData(sys_hospitalconfig config, string execsql,
{
{ "@beginTime", $"'{beginTime.ToString("yyyy-MM-dd")}'" },
{ "@endTime", $"'{beginTime.AddMonths(1).ToString("yyyy-MM-dd")}'"},
{ "@department", GetUserDepartment(userId) },
{ "@department", $"'{GetUserDepartment(userId)}'" },
};
return pairs;
}
......@@ -219,7 +238,8 @@ private string GetUserDepartment(int userId)
var user = _userService.GetUser(userId)
?? throw new PerformanceException("当前用户信息无效");
return IsSecondAdmin(userId) ? string.Empty : user.Department;
return IsSecondAdmin(userId) ? string.Empty : (user.Department ?? "");
//return "妇产科";
}
}
}
\ No newline at end of file
......@@ -127,6 +127,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 +135,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;
......
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 class HubNotificationQueue
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;
......@@ -31,9 +42,80 @@ private void Consumer()
{
foreach (var item in _queue.GetConsumingEnumerable())
{
_logger.LogInformation("ConectionId GroupName:{ConectionId};消息推送:{Method};内容:{Body}", item.UserId.ToString(), item.Method, _converter.Serialize(item.Body));
_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 content, NotificationLevel level)
{
Content = content;
LogLevel = level;
}
public abstract string Type { get; }
public NotificationLevel LogLevel { get; set; }
public string Time { get => DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"); }
public string Content { get; set; }
}
}
public class EventContent : Notification.PushContent
{
public EventContent(object eventId, string subject, string content, NotificationLevel level = NotificationLevel.INF)
: base(content, level)
{
EventId = eventId;
Subject = subject;
}
public object EventId { get; set; }
public string Subject { 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(url, level)
{
Subject = subject;
}
public string Subject { get; set; }
public override string Type => "Url";
}
}
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