Commit 738cc72f by lcx

Merge branch 'v2020income' into v2020calculate

parents c557bb9a 30c73c61
...@@ -25,6 +25,7 @@ public class TemplateController : Controller ...@@ -25,6 +25,7 @@ public class TemplateController : Controller
{ {
private readonly TemplateService templateService; private readonly TemplateService templateService;
private readonly DFExtractService extractService; private readonly DFExtractService extractService;
private readonly ExtractIncomeService extractIncomeService;
private HospitalService hospitalService; private HospitalService hospitalService;
private IHostingEnvironment env; private IHostingEnvironment env;
private ClaimService claim; private ClaimService claim;
...@@ -37,6 +38,7 @@ public class TemplateController : Controller ...@@ -37,6 +38,7 @@ public class TemplateController : Controller
public TemplateController(TemplateService templateService, public TemplateController(TemplateService templateService,
HospitalService hospitalService, HospitalService hospitalService,
DFExtractService extractService, DFExtractService extractService,
ExtractIncomeService extractIncomeService,
IHostingEnvironment env, IHostingEnvironment env,
ClaimService claim, ClaimService claim,
IOptions<Application> options, IOptions<Application> options,
...@@ -47,6 +49,7 @@ public class TemplateController : Controller ...@@ -47,6 +49,7 @@ public class TemplateController : Controller
{ {
this.templateService = templateService; this.templateService = templateService;
this.extractService = extractService; this.extractService = extractService;
this.extractIncomeService = extractIncomeService;
this.hospitalService = hospitalService; this.hospitalService = hospitalService;
this.env = env; this.env = env;
this.claim = claim; this.claim = claim;
...@@ -407,5 +410,24 @@ public ApiResponse Schedule([FromBody] log_dbug request) ...@@ -407,5 +410,24 @@ public ApiResponse Schedule([FromBody] log_dbug request)
var ratio = allotService.AllotLog(allot, 3)?.Max(t => ConvertHelper.TryDecimal(t.Message)) ?? 0; var ratio = allotService.AllotLog(allot, 3)?.Max(t => ConvertHelper.TryDecimal(t.Message)) ?? 0;
return new ApiResponse(ResponseType.OK, new { ratio }); return new ApiResponse(ResponseType.OK, new { ratio });
} }
[Route("extract/income/{allotId}")]
[AllowAnonymous]
[HttpGet]
public IActionResult ExtractIncome(int allotId)
{
string filepath = extractIncomeService.Execture(allotId);
var memoryStream = new MemoryStream();
using (var stream = new FileStream(filepath, FileMode.Open))
{
stream.CopyToAsync(memoryStream).Wait();
}
memoryStream.Seek(0, SeekOrigin.Begin);
string fileExt = Path.GetExtension(filepath);
var provider = new FileExtensionContentTypeProvider();
var memi = provider.Mappings[fileExt];
return File(memoryStream, memi, Path.GetFileName(filepath));
}
} }
} }
\ No newline at end of file
using Dapper;
using Microsoft.Extensions.Logging;
using NPOI.HSSF.Util;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using Performance.Repository;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace Performance.Services
{
public class ExtractIncomeService : IAutoInjection
{
private readonly PerforPerallotRepository perallotRepository;
private readonly PerforHospitalconfigRepository hospitalconfigRepository;
private readonly PerforExtypeRepository extypeRepository;
private readonly PerforExscriptRepository exscriptRepository;
private readonly ILogger logger;
public ExtractIncomeService(
PerforPerallotRepository perallotRepository,
PerforHospitalconfigRepository hospitalconfigRepository,
PerforExtypeRepository extypeRepository,
PerforExscriptRepository exscriptRepository,
ILogger<ExtractIncomeService> logger
)
{
this.perallotRepository = perallotRepository;
this.hospitalconfigRepository = hospitalconfigRepository;
this.extypeRepository = extypeRepository;
this.exscriptRepository = exscriptRepository;
this.logger = logger;
}
public string Execture(int allotId)
{
try
{
var allot = perallotRepository.GetEntity(t => t.ID == allotId);
if (allot == null) throw new PerformanceException("选取的绩效无效!");
var pairs = GetIncomeData(allot);
string filepath = CreateExcel(allot.HospitalId, pairs);
if (string.IsNullOrEmpty(filepath) || !FileHelper.IsExistFile(filepath))
throw new PerformanceException("抽取文件错误");
logger.LogInformation("医生收入文件: " + filepath);
return filepath;
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
throw new PerformanceException("抽取数据过程中发生异常!");
}
}
private Dictionary<string, List<IncomeDataDto>> GetIncomeData(per_allot allot)
{
var configs = hospitalconfigRepository.GetEntities(t => t.HospitalId == allot.HospitalId);
if (configs == null || !configs.Any()) return null;
var types = extypeRepository.GetEntities(t => t.Source == 100);
if (types == null || !types.Any()) return null;
Dictionary<string, List<IncomeDataDto>> pairs = new Dictionary<string, List<IncomeDataDto>>();
foreach (var item in types)
{
pairs.Add(item.EName, new List<IncomeDataDto>());
var scripts = exscriptRepository.GetEntities(t => t.TypeId == item.Id);
if (scripts == null || !scripts.Any()) continue;
foreach (var script in scripts)
{
var config = configs.FirstOrDefault(t => t.Id == script.ConfigId);
if (config == null) continue;
var data = QueryData(config, allot, script.ExecScript);
if (data != null && data.Any())
pairs[item.EName].AddRange(data);
}
}
return pairs;
}
private IEnumerable<IncomeDataDto> QueryData(sys_hospitalconfig config, per_allot allot, string execsql)
{
var parameters = GetParameters(allot);
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);
}
var result = connection.Query<IncomeDataDto>(execsql, commandTimeout: 20000);
return result;
}
}
private string CreateExcel(int hospitalId, Dictionary<string, List<IncomeDataDto>> dataDict)
{
if (dataDict == null || !dataDict.Any()) throw new PerformanceException("未查询到数据!");
IWorkbook workbook = new XSSFWorkbook();
ICellStyle cellStyle = getCellStyle.Invoke(workbook);
foreach (var dict in dataDict)
{
ISheet sheet = workbook.CreateSheet(dict.Key);
CreateHeader(sheet, cellStyle);
int rowIndex = sheet.LastRowNum + 1;
foreach (var data in dict.Value)
{
IRow row = sheet.CreateRow(rowIndex);
int index = 0;
foreach (var field in memberDict.Values)
{
ICell cell = row.CreateCell(index);
OutToExcelCell(cell, field?.Invoke(data));
cell.CellStyle = cellStyle;
index++;
}
rowIndex++;
}
}
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", $"{hospitalId}", "income");
if (!FileHelper.IsExistDirectory(path))
FileHelper.CreateDirectory(path);
string filepath = Path.Combine(path, $"医生收入{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx");
using (FileStream fs = new FileStream(filepath, FileMode.Create))
{
workbook.Write(fs);
}
if (workbook != null) workbook.Close();
return filepath;
}
private void CreateHeader(ISheet sheet, ICellStyle cellStyle)
{
IRow row = sheet.CreateRow(0);
if (row == null) return;
int index = 0;
foreach (var col in memberDict.Keys)
{
ICell cell = row.CreateCell(index);
cell.SetCellValue(col);
cell.CellStyle = cellStyle;
index++;
}
sheet.CreateFreezePane(0, 1); //首行冻结
}
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;
}
public void OutToExcelCell(ICell cell, object obj)
{
if (obj == null)
{
cell.SetCellValue("");
return;
}
string value = obj.ToString();
try
{
var type = obj.GetType();
switch (type.ToString())
{
case "System.String"://字符串类型
cell.SetCellValue(value);
break;
case "System.DateTime"://日期类型
DateTime dateV;
DateTime.TryParse(value, out dateV);
cell.SetCellValue(dateV.ToString("yyyy/M/d"));
break;
case "System.Boolean"://布尔型
bool boolV = false;
bool.TryParse(value, out boolV);
cell.SetCellValue(boolV);
break;
case "System.Int16"://整型
case "System.Int32":
case "System.Int64":
case "System.Byte":
int intV = 0;
int.TryParse(value, out intV);
cell.SetCellValue(intV);
break;
case "System.Decimal"://浮点型
case "System.Double":
double doubV = 0;
double.TryParse(value, out doubV);
cell.SetCellValue(doubV);
break;
case "System.DBNull"://空值处理
cell.SetCellValue("");
break;
default:
cell.SetCellValue("");
break;
}
}
catch
{
cell.SetCellValue(value);
}
}
private readonly Dictionary<string, Func<IncomeDataDto, object>> memberDict = new Dictionary<string, Func<IncomeDataDto, object>>
{
{ "医生工号", (t) => t.EmpCode }, { "医生姓名", (t) => t.EmpName }, { "开单科室", (t) => t.DeptName }, {"执行科室", (t) => t.ExecDeptName }, {"费用类型", (t) => t.Category }, {"费用", (t) => t.Fee }
};
private readonly Func<IWorkbook, ICellStyle> getCellStyle = (workbook) =>
{
IFont font = workbook.CreateFont();
font.FontHeightInPoints = 12;
font.FontName = "微软雅黑";
ICellStyle cellStyle = workbook.CreateCellStyle();
cellStyle.Alignment = HorizontalAlignment.Center;//设置水平居中
cellStyle.VerticalAlignment = VerticalAlignment.Center;//设置垂直居中
cellStyle.SetFont(font);
return cellStyle;
};
}
public class IncomeDataDto
{
/// <summary>
/// 医生工号
/// </summary>
public string EmpCode { get; set; }
/// <summary>
/// 医生姓名
/// </summary>
public string EmpName { get; set; }
/// <summary>
/// 开单科室
/// </summary>
public string DeptName { get; set; }
/// <summary>
/// 执行科室
/// </summary>
public string ExecDeptName { get; set; }
/// <summary>
/// 费用类型
/// </summary>
public string Category { get; set; }
/// <summary>
/// 费用
/// </summary>
public decimal Fee { get; set; }
}
}
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