Commit 08837348 by lcx

抽取时更改,保存医护工作量详情(到医生),根据时间删除抽取数据(保留最近5次抽取记录),获取医护工作量详情

parent 0f429ee0
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Mvc;
using Performance.DtoModels;
using Performance.EntityModels;
......@@ -156,5 +157,17 @@ public ApiResponse DeptDics(int hospitalId, int type)
var result = personService.DeptDics(hospitalId, type);
return new ApiResponse(ResponseType.OK, result);
}
/// <summary>
/// 科室工作量详情
/// </summary>
/// <returns></returns>
[HttpPost]
[Route("dept/workdetail")]
public ApiResponse DeptWorkloadDetail([CustomizeValidator(RuleSet = "Select"), FromBody] WorkDetailRequest request)
{
var data = personService.DeptWorkloadDetail(request);
return new ApiResponse(ResponseType.OK, data);
}
}
}
......@@ -866,6 +866,12 @@
<param name="type">1系统科室 2标准科室 3核算单元</param>
<returns></returns>
</member>
<member name="M:Performance.Api.Controllers.PersonController.DeptWorkloadDetail(Performance.DtoModels.WorkDetailRequest)">
<summary>
科室工作量详情
</summary>
<returns></returns>
</member>
<member name="T:Performance.Api.Controllers.ReportController">
<summary>
报表
......
......@@ -1573,6 +1573,16 @@
科室
</summary>
</member>
<member name="P:Performance.EntityModels.ex_result.DoctorName">
<summary>
医生姓名
</summary>
</member>
<member name="P:Performance.EntityModels.ex_result.PersonnelNumber">
<summary>
人员工号
</summary>
</member>
<member name="P:Performance.EntityModels.ex_result.Category">
<summary>
费用类型
......@@ -1598,6 +1608,11 @@
数据库配置Id
</summary>
</member>
<member name="P:Performance.EntityModels.ex_result.CreateTime">
<summary>
创建时间
</summary>
</member>
<member name="P:Performance.EntityModels.ex_result.IsDelete">
<summary>
1 删除 0 未删除
......@@ -3393,6 +3408,71 @@
数据来源 1 excel 导入 2 计算
</summary>
</member>
<member name="T:Performance.EntityModels.report_original_workload">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Id">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.AllotID">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Year">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Month">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.HospitalID">
<summary>
医院ID
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.SourceType">
<summary>
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.AccountingUnit">
<summary>
科室核算单元
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Department">
<summary>
科室
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.DoctorName">
<summary>
医生姓名
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.PersonnelNumber">
<summary>
人员工号
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Category">
<summary>
费用类型
</summary>
</member>
<member name="P:Performance.EntityModels.report_original_workload.Fee">
<summary>
费用
</summary>
</member>
<member name="T:Performance.EntityModels.rep_group">
<summary>
......
......@@ -6,6 +6,8 @@ namespace Performance.DtoModels
{
public class ExtractDto
{
public string DoctorName { get; set; }
public string PersonnelNumber { get; set; }
public string Department { get; set; }
public string Category { get; set; }
public decimal Value { get; set; }
......
using FluentValidation;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.DtoModels
{
public class WorkDetailRequest
{
public int AllotId { get; set; }
public string AccountingUnit { get; set; }
}
public class WorkDetailRequestValidator : AbstractValidator<WorkDetailRequest>
{
public WorkDetailRequestValidator()
{
RuleSet("Select", () =>
{
RuleFor(x => x.AllotId).NotNull().NotEmpty().GreaterThan(0);
RuleFor(x => x.AccountingUnit).NotNull().NotEmpty();
});
}
}
}
......@@ -32,6 +32,16 @@ public class ex_result
public string Department { get; set; }
/// <summary>
/// 医生姓名
/// </summary>
public string DoctorName { get; set; }
/// <summary>
/// 人员工号
/// </summary>
public string PersonnelNumber { get; set; }
/// <summary>
/// 费用类型
/// </summary>
public string Category { get; set; }
......@@ -55,7 +65,12 @@ public class ex_result
/// 数据库配置Id
/// </summary>
public int ConfigId { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public Nullable<DateTime> CreateTime { get; set; }
/// <summary>
/// 1 删除 0 未删除
/// </summary>
......
//-----------------------------------------------------------------------
// <copyright file=" report_original_workload.cs">
// * FileName: .cs
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Performance.EntityModels
{
/// <summary>
///
/// </summary>
[Table("report_original_workload")]
public class report_original_workload
{
/// <summary>
///
/// </summary>
[Key]
public int Id { get; set; }
/// <summary>
///
/// </summary>
public Nullable<int> AllotID { get; set; }
/// <summary>
/// 年
/// </summary>
public int Year { get; set; }
/// <summary>
/// 月
/// </summary>
public int Month { get; set; }
/// <summary>
/// 医院ID
/// </summary>
public int HospitalID { get; set; }
/// <summary>
///
/// </summary>
public string SourceType { get; set; }
/// <summary>
/// 科室核算单元
/// </summary>
public string AccountingUnit { get; set; }
/// <summary>
/// 科室
/// </summary>
public string Department { get; set; }
/// <summary>
/// 医生姓名
/// </summary>
public string DoctorName { get; set; }
/// <summary>
/// 人员工号
/// </summary>
public string PersonnelNumber { get; set; }
/// <summary>
/// 费用类型
/// </summary>
public string Category { get; set; }
/// <summary>
/// 费用
/// </summary>
public Nullable<decimal> Fee { get; set; }
}
}
......@@ -50,10 +50,10 @@ public class sys_role
/// 父级角色
/// </summary>
public string ParentRoles { get; set; }
/// <summary>
///
/// </summary>
public int Sort { get; set; }
public Nullable<int> Sort { get; set; }
}
}
......@@ -21,12 +21,12 @@ namespace Performance.Extract.Api.Controllers
[Route("api/[controller]")]
public class ExtractController : Controller
{
private readonly DFExtractService1 extractService;
private readonly DFExtractService extractService;
private readonly HospitalService hospitalService;
private readonly WebapiUrl url;
private readonly ILogger<ExtractController> logger;
private readonly IHostingEnvironment evn;
public ExtractController(DFExtractService1 extractService,
public ExtractController(DFExtractService extractService,
HospitalService hospitalService,
IOptions<WebapiUrl> url,
ILogger<ExtractController> logger,
......
//-----------------------------------------------------------------------
//-----------------------------------------------------------------------
// <copyright file=" sys_allot.cs">
// * FileName: sys_allot.cs
// * history : Created by T4 2019-03-06 16:43:31
......@@ -30,7 +30,7 @@ public bool UpdateAllotStates(int allotId, int states, string remark, int genera
}
/// <summary>
/// 只支持EXCEL抽取报表数据
/// 只支持EXCEL抽取报表数据
/// </summary>
/// <param name="import"></param>
/// <param name="pairs"></param>
......@@ -46,7 +46,7 @@ public bool ImportData(rep_importconfig import, Dictionary<string, object> pairs
}
/// <summary>
/// 指定数据源插入MYSQL
/// 指定数据源插入MYSQL
/// </summary>
/// <param name="import"></param>
/// <param name="pairs"></param>
......@@ -97,5 +97,79 @@ public bool UpdateData(rep_importconfig import, Dictionary<string, object> pairs
return flag > 0;
}
}
/// <summary>
/// 清除历史抽取数据
/// </summary>
/// <param name="allotid"></param>
public void ClearResultData(int allotid)
{
using (var connection = context.Database.GetDbConnection())
{
if (connection.State != ConnectionState.Open) connection.Open();
try
{
string clear = "delete from ex_result where allotid = @allotid and isdelete = 1 and createtime < (select min(createtime) from (select distinct createtime from ex_result where allotid = @allotid and isdelete = 1 order by createtime desc limit 4) t);";
connection.Execute(clear, new { allotid }, commandTimeout: 60 * 60);
}
catch (Exception ex)
{
throw ex;
}
}
}
/// <summary>
/// 保存工作量数据
/// </summary>
/// <param name="allot"></param>
/// <param name="parameters"></param>
public void ImportWorkloadData(per_allot allot, object parameters)
{
using (var connection = context.Database.GetDbConnection())
{
if (connection.State != ConnectionState.Open) connection.Open();
using (var transaction = connection.BeginTransaction())
{
try
{
string clear = "delete from report_original_workload where allotid = @allotid and hospitalid = @hospitalid;";
connection.Execute(clear, new { allotid = allot.ID, hospitalid = allot.HospitalId }, commandTimeout: 60 * 60, transaction: transaction);
string insert = "insert into report_original_workload(allotid,year,month,hospitalid,accountingunit,department,doctorname,personnelnumber,category,fee) values(@allotid,@year,@month,@hospitalid,@accountingunit,@department,@doctorname,@personnelnumber,@category,@fee);";
connection.Execute(insert, parameters, commandTimeout: 60 * 60, transaction: transaction);
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
throw ex;
}
}
}
}
/// <summary>
/// 查询工作量数据
/// </summary>
/// <param name="allotid"></param>
public IEnumerable<report_original_workload> QueryWorkloadData(int allotid, string accountingunit)
{
using (var connection = context.Database.GetDbConnection())
{
if (connection.State != ConnectionState.Open) connection.Open();
try
{
string clear = "select * from report_original_workload where allotid = @allotid and accountingunit = @accountingunit order by fee desc,convert(doctorname using gbk);";
return connection.Query<report_original_workload>(clear, new { allotid, accountingunit }, commandTimeout: 60 * 60);
}
catch (Exception ex)
{
throw ex;
}
}
}
}
}
using Dapper;
using Dapper;
using Microsoft.Extensions.Logging;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
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.Linq.Expressions;
using System.Text.RegularExpressions;
namespace Performance.Services
{
public class DFExtractService1 : IAutoInjection
{
#region
private readonly ILogger<DFExtractService1> logger;
private readonly IEmailService emailService;
private readonly PerSheetService perSheetService;
private readonly PerforHospitalRepository perforHospitalRepository;
private readonly PerforHospitalconfigRepository perforHospitalconfigRepository;
private readonly PerforPerallotRepository perforPerallotRepository;
private readonly PerforImspecialunitRepository perforImspecialunitRepository;
private readonly PerforImdataRepository perforImdataRepository;
private readonly PerforRepimportconfigRepository repimportconfigRepository;
private readonly PerforExitemRepository perforExitemRepository;
private readonly PerforExmoduleRepository perforExmoduleRepository;
private readonly PerforExspecialRepository perforExspecialRepository;
private readonly PerforExresultRepository perforExresultRepository;
private readonly PerforExscriptRepository perforExscriptRepository;
private readonly PerforPerdeptdicRepository perforPerdeptdicRepository;
private readonly PerforPeremployeeRepository perforPeremployeeRepository;
private readonly PersonService personService;
private IWorkbook workbook = null;
private ICellStyle style;
private per_allot Allot;
private const string specialname = "4.2 特殊核算单元绩效测算表";
public DFExtractService1(ILogger<DFExtractService1> logger,
IEmailService emailService,
PerSheetService perSheetService,
PerforHospitalRepository perforHospitalRepository,
PerforHospitalconfigRepository perforHospitalconfigRepository,
PerforPerallotRepository perforPerallotRepository,
PerforImspecialunitRepository perforImspecialunitRepository,
PerforImdataRepository perforImdataRepository,
PerforRepimportconfigRepository repimportconfigRepository,
PerforExitemRepository perforExitemRepository,
PerforExmoduleRepository perforExmoduleRepository,
PerforExspecialRepository perforExspecialRepository,
PerforExresultRepository perforExresultRepository,
PerforExscriptRepository perforExscriptRepository,
PerforPerdeptdicRepository perforPerdeptdicRepository,
PerforPeremployeeRepository perforPeremployeeRepository,
PersonService personService)
{
this.logger = logger;
this.emailService = emailService;
this.perSheetService = perSheetService;
this.perforHospitalRepository = perforHospitalRepository;
this.perforHospitalconfigRepository = perforHospitalconfigRepository;
this.perforPerallotRepository = perforPerallotRepository;
this.perforImspecialunitRepository = perforImspecialunitRepository;
this.perforImdataRepository = perforImdataRepository;
this.repimportconfigRepository = repimportconfigRepository;
this.perforExitemRepository = perforExitemRepository;
this.perforExmoduleRepository = perforExmoduleRepository;
this.perforExspecialRepository = perforExspecialRepository;
this.perforExresultRepository = perforExresultRepository;
this.perforExscriptRepository = perforExscriptRepository;
this.perforPerdeptdicRepository = perforPerdeptdicRepository;
this.perforPeremployeeRepository = perforPeremployeeRepository;
this.personService = personService;
}
#endregion
#region 抽取
public string ExtractData(int allotId, string email, int hospitalId, string filePath = null)
{
var hospital = perforHospitalRepository.GetEntity(t => t.ID == hospitalId);
try
{
var allot = perforPerallotRepository.GetEntity(t => t.ID == allotId);
Allot = allot ?? throw new PerformanceException("");
var statesArray = new int[] { (int)AllotStates.GenerateSucceed, (int)AllotStates.Archive };
var allots = perforPerallotRepository.GetEntities(t => t.HospitalId == hospitalId && statesArray.Contains(t.States));
var lastAllot = allots?.OrderByDescending(t => t.Year).ThenByDescending(t => t.Month).First();
var configs = perforHospitalconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
var typeIds = new List<int>();
var modules = perforExmoduleRepository.GetEntities(t => t.HospitalId == hospitalId);
var items = new List<ex_item>();
if (modules != null && modules.Any())
{
typeIds.AddRange(modules.Select(t => t.TypeId ?? 0));
items = perforExitemRepository.GetEntities(t => t.ModuleId.HasValue
&& modules.Select(m => m.Id).Contains(t.ModuleId.Value));
typeIds.AddRange(items?.Select(t => t.TypeId ?? 0) ?? new List<int>());
}
var specials = perforExspecialRepository.GetEntities(t => t.HospitalId == hospitalId);
if (specials != null && specials.Any())
typeIds.AddRange(specials.Select(t => t.TypeId ?? 0));
typeIds = typeIds.Distinct().ToList();
var data = new List<ex_result>();
var scripts = perforExscriptRepository.GetEntities(t => typeIds.Contains(t.TypeId));
ClearHistData(allot);
var otherItems = items.Where(t => modules.Where(m => m.SheetType != (int)SheetType.Income).Select(m => m.Id).Contains(t.ModuleId.Value)).ToList();
if (scripts != null && scripts.Any())
{
data.AddRange(ExtractIncome(modules, scripts, configs, allot));
data.AddRange(ExtractItems(otherItems, scripts, configs, allot, modules));
data.AddRange(ExtractSpcial(specials, scripts, configs, allot));
}
var standData = StandData(data);
return lastAllot == null ? TemplateExecute(email, hospital, configs, modules, items, specials, standData)
: AlllotExecute(email, hospital, configs, modules, items, specials, standData, lastAllot, filePath);
}
catch (Exception ex)
{
logger.LogError($"提取绩效数据异常 数据写入出现异常{ex.ToString()}");
//SendEmail(email, "", $"{hospital.HosName}HIS数据提取失败", $"{hospital.HosName}提取数据过程中出现异常情况,我们将尽快解决问题。给您带来的不便我们深感歉意!");
throw ex;
}
finally
{
Allot.IsExtracting = null;
perforPerallotRepository.Update(Allot);
if (workbook != null)
workbook.Close();
GC.Collect();
}
}
/// <summary>
/// 抽取收入费用
/// </summary>
/// <typeparam name="TEntity">ex_module</typeparam>
/// <param name="entities"></param>
/// <param name="scripts">抽取配置项</param>
/// <param name="configs">数据连接项</param>
/// <param name="allot">绩效</param>
/// <returns></returns>
private List<ex_result> ExtractIncome<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot)
{
var data = new List<ex_result>();
var modules = entities as List<ex_module>;
if (modules == null || !modules.Any(t => t.SheetType == (int)SheetType.Income && t.TypeId > 0))
return data;
foreach (var module in modules.Where(t => t.TypeId > 0))
{
foreach (var config in configs)
{
var item = scripts.FirstOrDefault(t => t.TypeId == module.TypeId && t.DatabaseType == config.DataBaseType);
if (item == null) continue;
var querydata = QueryData(config, allot, item.ExecScript, module.ModuleName);
if (querydata != null && querydata.Any())
{
perforExresultRepository.AddRange(querydata.ToArray());
data.AddRange(querydata);
}
}
}
return data;
}
/// <summary>
/// 抽取支出、工作量等费用
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
/// <param name="scripts"></param>
/// <param name="configs"></param>
/// <param name="allot"></param>
/// <param name="modules"></param>
/// <returns></returns>
private List<ex_result> ExtractItems<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot, List<ex_module> modules)
{
var data = new List<ex_result>();
var items = entities as List<ex_item>;
if (items == null || !items.Any(t => t.TypeId > 0))
return data;
foreach (var exitem in items.Where(t => t.TypeId > 0))
{
var module = modules.FirstOrDefault(t => t.Id == exitem.ModuleId);
foreach (var config in configs)
{
var item = scripts.FirstOrDefault(t => t.TypeId == exitem.TypeId && t.DatabaseType == config.DataBaseType);
if (item == null) continue;
var result = QueryData(config, allot, item.ExecScript, module.ModuleName);
if (result != null && result.Any())
{
result.ForEach(t => t.Category = exitem.ItemName);
perforExresultRepository.AddRange(result.ToArray());
data.AddRange(result);
}
}
}
return data;
}
/// <summary>
/// 抽取特殊科室数据
/// </summary>
/// <typeparam name="TEntity"></typeparam>
/// <param name="entities"></param>
/// <param name="scripts"></param>
/// <param name="configs"></param>
/// <param name="allot"></param>
/// <returns></returns>
private List<ex_result> ExtractSpcial<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot)
{
var data = new List<ex_result>();
var specials = entities as List<ex_special>;
if (specials == null || !specials.Any(t => t.TypeId > 0))
return data;
foreach (var special in specials.Where(t => t.TypeId > 0))
{
foreach (var config in configs)
{
var item = scripts.FirstOrDefault(t => t.TypeId == special.TypeId && t.DatabaseType == config.DataBaseType);
if (item == null) continue;
var result = QueryData(config, allot, item.ExecScript, specialname);
result.ForEach(t =>
{
t.Category = special.Target;
t.Department = special.Department;
});
data.AddRange(result);
}
}
if (data != null && data.Any())
perforExresultRepository.AddRange(data.ToArray());
return data;
}
/// <summary>
/// 清除历史抽取数据
/// </summary>
/// <param name="allot"></param>
private void ClearHistData(per_allot allot)
{
logger.LogInformation($"开始清除历史提取数据");
var data = perforExresultRepository.GetEntities(t => t.AllotId == allot.ID);
if (data == null || !data.Any(t => t.Id > 0))
return;
data.ForEach(t => t.IsDelete = 1);
perforExresultRepository.UpdateRange(data.ToArray());
}
/// <summary>
/// 空白模板
/// </summary>
/// <param name="email"></param>
/// <param name="lastAllot"></param>
/// <param name="hospital"></param>
/// <param name="configs"></param>
/// <param name="modules"></param>
/// <param name="items"></param>
/// <param name="specials"></param>
/// <param name="extracts"></param>
/// <returns></returns>
public string TemplateExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<NewExtractDto> data)
{
string originalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院绩效模板.xlsx");
var (tempPath, newPath) = CopyOriginalFile(hospital.ID, originalPath);
workbook = new XSSFWorkbook(tempPath);
CreateNotExistSheet(modules, workbook);
style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
var sheetType = perSheetService.GetSheetType(sheet.SheetName);
if (sheetType == SheetType.Unidentifiable) continue;
var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
switch (sheetType)
{
case SheetType.Employee:
WriteEmployee(sheet, sheetRead);
break;
case SheetType.ClinicEmployee:
WriteClinicEmployee(sheet, sheetRead);
break;
case SheetType.OtherIncome:
WriteOtherIncome(sheet, sheetRead, modules, items, data);
break;
case SheetType.Income:
WriteIncome(sheet, sheetRead, modules, items, data);
break;
case SheetType.Expend:
WriteExpend(sheet, sheetRead, modules, items, data);
break;
case SheetType.Workload:
WriteWorkload(sheet, sheetRead, modules, items, data);
break;
case SheetType.AccountBasic:
WriteAccountBasic(sheet, sheetRead);
break;
case SheetType.SpecialUnit:
WriteSpecialUnit(sheet, sheetRead, specials, data);
break;
}
}
using (FileStream file = new FileStream(newPath, FileMode.OpenOrCreate))
{
workbook.Write(file);
}
logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
ImportData(Allot, configs);
SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
return newPath;
}
/// <summary>
/// 历史绩效为模板
/// </summary>
/// <param name="email"></param>
/// <param name="lastAllot"></param>
/// <param name="hospital"></param>
/// <param name="configs"></param>
/// <param name="modules"></param>
/// <param name="items"></param>
/// <param name="specials"></param>
/// <param name="extracts"></param>
/// <returns></returns>
public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<NewExtractDto> extracts, per_allot lastAllot, string path)
{
if (string.IsNullOrEmpty(path)) throw new PerformanceException("历史绩效文件不存在!");
var (tempPath, newPath) = CopyOriginalFile(hospital.ID, path);
workbook = new XSSFWorkbook(tempPath);
CreateNotExistSheet(modules, workbook);
style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
var sheetType = perSheetService.GetSheetType(sheet.SheetName);
var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
switch (sheetType)
{
case SheetType.Employee:
WriteEmployee(sheet, sheetRead, false);
break;
case SheetType.ClinicEmployee:
WriteClinicEmployee(sheet, sheetRead, false);
break;
case SheetType.OtherIncome:
ClearData(sheet, 5, 7);
WriteOtherIncome(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Income:
ClearData(sheet, 5, 7, true);
WriteIncome(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Expend:
ClearData(sheet, 5, 7);
WriteExpend(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Workload:
ClearData(sheet, 3, 3);
WriteWorkload(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.AccountBasic:
WriteAccountBasic(sheet, sheetRead, false);
break;
case SheetType.SpecialUnit:
ClearData(sheet, 2, 0);
WriteSpecialUnit(sheet, sheetRead, specials, extracts, lastAllot, false);
break;
}
}
using (FileStream file = new FileStream(newPath, FileMode.OpenOrCreate))
{
workbook.Write(file);
}
logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
ImportData(Allot, configs);
SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
return newPath;
}
#endregion
#region QueryData
/// <summary>
/// 查询数据
/// </summary>
/// <param name="config"></param>
/// <param name="allot"></param>
/// <param name="execsql"></param>
/// <param name="source"></param>
/// <param name="category"></param>
/// <returns></returns>
private List<ex_result> QueryData(sys_hospitalconfig config, per_allot allot, string execsql, string source, string category = "")
{
var data = new List<ex_result>();
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);
}
logger.LogInformation($"提取绩效数据 {category ?? ""}SQL脚本{execsql}");
var result = connection.Query<ExtractDto>(execsql, commandTimeout: 20000);
logger.LogInformation($"提取绩效数据 {category ?? ""} 执行脚本获取数据{result?.Count() ?? 0}条记录");
if (result != null && result.Count() > 0)
{
data = result.Select(t => new ex_result
{
Department = t.Department,
Category = t.Category?.Trim(),
Fee = t.Value,
Source = source,
DatabaseType = config.DataBaseType,
ConfigId = config.Id,
AllotId = allot.ID,
}).ToList();
}
return data;
}
}
/// <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>
/// 从HIS抽取报表数据
/// </summary>
/// <param name="allot"></param>
/// <param name="configs"></param>
private void ImportData(per_allot allot, List<sys_hospitalconfig> configs)
{
Dictionary<string, object> pairs = new Dictionary<string, object>
{
{ "@allotid", allot.ID },
{ "@hospitalid", allot.HospitalId },
{ "@year", allot.Year },
{ "@month", allot.Month },
};
var imports = repimportconfigRepository.GetEntities(w => w.ScriptType == 1);
if (imports == null || !imports.Any()) return;
foreach (var import in imports)
{
var conf = configs.FirstOrDefault(w => w.HospitalId == allot.HospitalId && w.Id == import.ConfigId);
if (conf != null)
{
var timeRanges = import.TimeRange.SplitRemoveEmpty(",");
if (timeRanges == null || !timeRanges.Any()) continue;
foreach (var item in timeRanges)
{
if (item == "1")
{
pairs["@year"] = allot.Year;
pairs["@month"] = allot.Month;
}
else if (item == "2")
{
pairs["@year"] = allot.Year - 1;
pairs["@month"] = allot.Month;
}
else if (item == "3")
{
pairs["@year"] = allot.Year;
pairs["@month"] = allot.Month - 1;
}
try
{
DatabaseType type = (DatabaseType)conf.DataBaseType;
var connection = ConnectionBuilder.Create(type, conf.DbSource, conf.DbName, conf.DbUser, conf.DbPassword);
var data = connection.Query(import.ImportScript, new DynamicParameters(pairs), commandTimeout: 60 * 60);
perforPerallotRepository.ImportData(import, pairs, data);
}
catch (Exception ex)
{
logger.LogError(ex.ToString());
}
}
}
}
}
private List<NewExtractDto> StandData(IEnumerable<ex_result> results)
{
if (results == null || !results.Any()) return new List<NewExtractDto>();
var dict = personService.GetDepartments(Allot.HospitalId)?.ToList();
if (dict == null || !dict.Any())
return results.Select(t => new NewExtractDto
{
SheetName = t.Source,
Department = t.Department,
Category = t.Category,
Value = (t.Fee ?? 0) == 0 ? null : t.Fee
}).ToList();
dict.ForEach(t =>
{
t.HISDeptName = HasValue(t.HISDeptName, t.Department);
});
var data = results.GroupJoin(dict, outer => new { Department = outer.Department }, inner => new { Department = inner.HISDeptName }, (outer, inner) => new { outer, inner })
.Select(t =>
{
var dept = !string.IsNullOrEmpty(t.inner.FirstOrDefault()?.Department) ? t.inner.FirstOrDefault()?.Department : t.outer.Department;
return new NewExtractDto
{
SheetName = t.outer.Source,
Department = dept,
Category = t.outer.Category,
Value = t.outer.Fee ?? 0, //(t.outer.Fee ?? 0) == 0 ? null : t.outer.Fee
OutDoctorAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutDoctorAccounting?.AccountingUnit,
OutNurseAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutNurseAccounting?.AccountingUnit,
OutTechnicAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutTechnicAccounting?.AccountingUnit,
InpatDoctorAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatDoctorAccounting?.AccountingUnit,
InpatNurseAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatNurseAccounting?.AccountingUnit,
InpatTechnicAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatTechnicAccounting?.AccountingUnit,
};
});
data = data.GroupBy(t => new { t.Department, t.Category, t.SheetName }).Select(t => new NewExtractDto
{
SheetName = t.Key.SheetName,
Department = t.Key.Department,
Category = t.Key.Category,
Value = t.Sum(group => group.Value) == 0 ? null : t.Sum(group => group.Value),
OutDoctorAccounting = t.First().OutDoctorAccounting,
OutNurseAccounting = t.First().OutNurseAccounting,
OutTechnicAccounting = t.First().OutTechnicAccounting,
InpatDoctorAccounting = t.First().InpatDoctorAccounting,
InpatNurseAccounting = t.First().InpatNurseAccounting,
InpatTechnicAccounting = t.First().InpatTechnicAccounting,
});
return data.ToList();
}
#endregion
#region Excel
private (string TempPath, string NewPath) CopyOriginalFile(int hospitalId, string originalPath)
{
var dpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", $"{hospitalId}", "autoextract");
FileHelper.CreateDirectory(dpath);
string tempPath = Path.Combine(dpath, $"Template{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx");
FileHelper.Copy(originalPath, tempPath);
string newPath = Path.Combine(dpath, $"绩效提取数据{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx");
return (tempPath, newPath);
}
private static void CreateNotExistSheet(List<ex_module> modulesList, IWorkbook workbook)
{
SortedDictionary<string, int> pairs = new SortedDictionary<string, int>();
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
pairs.Add(workbook.GetSheetAt(i).SheetName, i);
}
int sheetIndex = 0;
foreach (var module in modulesList.Where(t => t.SheetType == (int)SheetType.Income)?.OrderBy(t => t.ModuleName))
{
var sheet = workbook.GetSheet(module.ModuleName);
if (sheet == null)
{
string[] keyArray = new string[] { "开单", "执行" };
if (keyArray.Any(key => module.ModuleName.Contains(key)))
{
var item = pairs.Where(t => t.Key.StartsWith("1.")).OrderByDescending(t => t.Key).First();
if (sheetIndex == 0)
sheetIndex = item.Value + 1;
var copysheet = workbook.GetSheet(item.Key);
var newSheet = copysheet.CopySheet(item.Key, true);
workbook.SetSheetOrder(newSheet.SheetName, sheetIndex);
workbook.SetSheetName(sheetIndex, module.ModuleName);
sheetIndex++;
}
}
}
}
private void ClearData(ISheet sheet, int beginRowNum, int beginCellNum, bool isIncome = false)
{
if (sheet == null)
return;
for (int i = beginRowNum; i < sheet.LastRowNum + 1; i++)
{
var row = sheet.GetRow(i);
if (row != null)
{
//跳过核算单元和科室
for (int j = beginCellNum; j < row.LastCellNum; j++)
{
var cell = row.GetCell(j);
if (cell != null && (cell.CellType != CellType.Formula || isIncome))
{
cell.RemoveCellComment();
row.RemoveCell(cell);
}
}
}
}
sheet.ForceFormulaRecalculation = true;
}
private (Dictionary<string, int> dictClear, Dictionary<string, int> dictVerify) ClearDataDict(ISheet sheet, IPerSheetDataRead sheetRead, List<string> header, int sheetType)
{
Dictionary<int, string[]> verify = new Dictionary<int, string[]>
{
{ (int)SheetType.Employee, new string[]{ "核算单元", "人员工号", "医生姓名" } },
{ (int)SheetType.ClinicEmployee, new string[]{ "核算单元", "人员工号", "医生姓名" } },
{ (int)SheetType.AccountBasic, new string[]{ "核算单元类型", "核算单元", "科室名称" } },
};
Dictionary<string, int> dictClear = new Dictionary<string, int>();
Dictionary<string, int> dictVerify = new Dictionary<string, int>();
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue)) continue;
if (header.Contains(headvalue)) dictClear.Add(headvalue, i);
if (verify[sheetType].Contains(headvalue)) dictVerify.Add(headvalue, i);
}
return (dictClear, dictVerify);
}
private IRow GetOrCreate(ISheet sheet, int index)
{
var row = sheet.GetRow(index);
if (row == null)
row = sheet.CreateRow(index);
return row;
}
private ICell GetOrCreate(IRow row, int index)
{
var cell = row.GetCell(index);
if (cell == null)
cell = row.CreateCell(index);
//cell.CellStyle.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Orange.Index;
return cell;
}
public void GenRowStyle(IRow r, ICellStyle cellStyle)
{
List<ICell> clist = r.Cells;
foreach (var cItem in clist)
{
cItem.CellStyle = cellStyle;
}
r.RowStyle = cellStyle;
}
#endregion
#region SheetData
private void WriteEmployee(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
Dictionary<string, Func<per_employee, object>> dict = new Dictionary<string, Func<per_employee, object>>
{
{ "人员分类", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "人员工号", (t) => t.PersonnelNumber },
{ "医生姓名", (t) => t.DoctorName },
{ "参加工作时间", (t) => t.WorkTime },
{ "出勤率", (t) => t.Attendance },
};
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "出勤率" }, (int)SheetType.Employee);
var delEmployees = new List<per_employee>();
foreach (var item in validData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var personnel = GetOrCreate(row, dictVerify["人员工号"]).ToString();
var doctorname = GetOrCreate(row, dictVerify["医生姓名"]).ToString();
var employee = validData.FirstOrDefault(t => (t.AccountingUnit ?? "") == accountingunit && (t.PersonnelNumber ?? "") == personnel && (t.DoctorName ?? "") == doctorname);
if (employee == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
cell.SetCellValue("");
}
//validData.Remove(employee);
delEmployees.Add(employee);
}
beginRowIndex++;
}
if (delEmployees.Any(t => t.Id > 0))
validData.RemoveAll(t => delEmployees.Select(e => e.Id).Contains(t.Id));
}
//新增数据
foreach (var item in validData)
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteClinicEmployee(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && !accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
Dictionary<string, Func<per_employee, object>> dict = new Dictionary<string, Func<per_employee, object>>
{
{ "核算单元分类", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "人员工号", (t) => t.PersonnelNumber },
{ "医生姓名", (t) => t.DoctorName },
{ "职务分类", (t) => t.JobTitle },
{ "出勤率", (t) => t.Attendance },
};
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "出勤率" }, (int)SheetType.ClinicEmployee);
var delEmployees = new List<per_employee>();
foreach (var item in validData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var personnel = GetOrCreate(row, dictVerify["人员工号"]).ToString();
var doctorname = GetOrCreate(row, dictVerify["医生姓名"]).ToString();
var employee = validData.FirstOrDefault(t => (t.AccountingUnit ?? "") == accountingunit && (t.PersonnelNumber ?? "") == personnel && (t.DoctorName ?? "") == doctorname);
if (employee == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
cell.SetCellValue("");
}
//validData.Remove(employee);
delEmployees.Add(employee);
}
beginRowIndex++;
}
if (delEmployees.Any(t => t.Id > 0))
validData.RemoveAll(t => delEmployees.Select(e => e.Id).Contains(t.Id));
}
//新增数据
foreach (var item in validData)
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteAccountBasic(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && !accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
#region 计算数据
bool duty(per_employee t) => !string.IsNullOrEmpty(t.Duty) && (t.Duty.IndexOf("科主任") > -1 || t.Duty.IndexOf("副主任") > -1
|| t.Duty.IndexOf("护士长") > -1 || t.Duty.IndexOf("副护士长") > -1);
var groupData = validData.GroupBy(t => new { t.Department, t.UnitType }).Select(t => new AccountBasic
{
UnitType = t.Key.UnitType,
Department = t.Key.Department,
AccountingUnit = t.FirstOrDefault(group => group.Department == t.Key.Department)?.AccountingUnit,
EfficiencyNumber = t.Sum(group => group.EfficiencyNumber),
DirectorNumber = t.Count(duty),
PermanentStaff = t.Sum(group => group.PermanentStaff * group.Attendance),
IsDelete = 0,
}).OrderBy(t => t.UnitType).ThenBy(t => t.AccountingUnit).ToList();
Dictionary<string, Func<dynamic, object>> dict = new Dictionary<string, Func<dynamic, object>>
{
{ "核算单元类型", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "科室名称", (t) => t.Department },
{ "效率绩效人数", (t) => t.EfficiencyNumber },
{ "科主任/护士长人数", (t) => t.DirectorNumber },
{ "核算单元人员数量", (t) => t.PermanentStaff },
};
#endregion
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "效率绩效人数", "科主任/护士长人数", "核算单元人员数量" }, (int)SheetType.AccountBasic);
foreach (var item in groupData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var unittype = GetOrCreate(row, dictVerify["核算单元类型"]).ToString();
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var department = GetOrCreate(row, dictVerify["科室名称"]).ToString();
var data = groupData.FirstOrDefault(t => (t.UnitType ?? "") == unittype && (t.AccountingUnit ?? "") == accountingunit && (t.Department ?? "") == department);
if (data == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
var func = dict[pair.Key];
if (func != null)
OutToExcelCell(cell, func.Invoke(data));
}
data.IsDelete = 1;
}
beginRowIndex++;
}
}
//新增数据
foreach (var item in groupData.Where(t => t.IsDelete == 0))
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteOtherIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.OtherIncome);
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id)?.ToList() ?? new List<ex_item>();
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
{
var itemCount = itemList?.Count ?? 0;
logger.LogInformation($"item有{itemCount}个.");
if (itemCount > 0) WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
return;
}
//查询数据
var category = extractdata.Select(t => t.Category?.Trim()).Distinct().ToList();
var existHead = category.Except(itemList.Select(i => i.ItemName?.Trim()));
if (existHead != null && existHead.Any())
itemList.AddRange(existHead.Select(t => new ex_item { ItemName = t, FactorValue1 = 0, FactorValue2 = 0, FactorValue3 = 0 }));
logger.LogInformation($"item有{itemList?.Count ?? 0}个.{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp, true);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteExpend(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.Expend);
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteWorkload(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteWorkHeader(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
var specialHead = new List<string>();
var extractHead = extractdata?.Select(t => t.Category);
if (extractHead != null && extractHead.Any())
specialHead = itemList.Select(t => t.ItemName).Intersect(extractHead.Distinct())?.ToList(); // 有数据的列添加样式
//写入数据
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteWorkData(sheet, sheetRead, extractdata.ToList(), specialHead, isNewTemp);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_special> specials, List<NewExtractDto> data, per_allot lastAllot = null, bool IsWriteHead = true)
{
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var dictionary = new Dictionary<string, Func<ex_special, List<im_specialunit>, object>>
{
{ "科室", (special,lastallot) => special.Department },
{ "人数", (special,lastallot) => lastallot.Where(t=>special.Department == t.Department).Max(t=>t.Number) },
{ "量化指标", (special,lastallot) => special.Target},
{ "量化指标绩效分值",(special,lastallot) => special.TargetFactor },
{ "调节系数", (special,lastallot) => special.AdjustFactor },
};
var speaialList = specials?.OrderBy(t => t.Department).ToList();
logger.LogInformation($"item有{speaialList?.Count ?? 0}个.");
if (speaialList == null || !speaialList.Any()) return;
List<im_specialunit> allotDataList = new List<im_specialunit>();
if (lastAllot != null)
allotDataList = perforImspecialunitRepository.GetEntities(t => t.AllotID == lastAllot.ID);
//取消合并单元格
int mergedCount = sheet.NumMergedRegions;
for (int i = mergedCount - 1; i >= 0; i--)
{
var temp = sheet.GetMergedRegion(i);
if (temp.FirstRow > sheetRead.Point.HeaderFirstRowNum)
sheet.RemoveMergedRegion(i);
}
var modDataGroup = speaialList.GroupBy(t => new { t.Department }).Select(group => new
{
Department = group.Key.Department,
Count = group.Count()
})?.OrderBy(t => t.Department);
int mergedBegin = sheetRead.Point.DataFirstRowNum.Value;
int mergedEnd = sheetRead.Point.DataFirstRowNum.Value;
var extractdata = data.Where(t => t.SheetName == specialname).ToList();
logger.LogInformation($"data有{extractdata?.Count ?? 0}个.");
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
for (int i = 0; i < speaialList.Count; i++)
{
var headIndex = sheetRead.Point.HeaderFirstRowNum;
var cellList = sheet.GetRow(headIndex.Value).Cells;
var rowIndex = sheetRead.Point.DataFirstRowNum.Value + i;
var importRow = sheet.CreateRow(rowIndex);
int cellIndex = 0;
foreach (var cell in cellList)
{
object value = null;
if (dictionary.ContainsKey(cell.StringCellValue))
{
var item = dictionary.First(t => t.Key == cell.StringCellValue);
value = item.Value.Invoke(speaialList[i], allotDataList) ?? "";
if (item.Key == "科室" && rowIndex == mergedBegin)
{
var count = modDataGroup.First(t => t.Department.ToString() == value.ToString()).Count;
mergedEnd = mergedBegin + count - 1;
}
}
if (cell.StringCellValue == "数量" && speaialList[i]?.TypeId > 0)
{
value = extractdata?.FirstOrDefault(t => t.Category == speaialList[i].Target)?.Value;
}
if (!new List<string> { "量化指标", "数量", "量化指标绩效分值" }.Contains(cell.StringCellValue) && rowIndex == mergedBegin)
{
CellRangeAddress region = new CellRangeAddress(mergedBegin, mergedEnd, cellIndex, cellIndex);
sheet.AddMergedRegion(region); //合并单元格
}
var newCell = importRow.CreateCell(cellIndex);
//newCell.SetCellValue(Verify(value));
OutToExcelCell(newCell, value);
if (dictionary.ContainsKey(cell.StringCellValue) || (cell.StringCellValue == "数量" && !string.IsNullOrEmpty(value?.ToString())))
newCell.CellStyle = style;
cellIndex++;
}
mergedBegin = mergedEnd + 1;
}
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
#region 写入数据
/// <summary>
/// 写入列头
/// </summary>
/// <param name="sheet"></param>
/// <param name="sheetRead"></param>
/// <param name="items">列头数据(列名、系数)</param>
/// <param name="isNewTemp">是否为空白模板</param>
private void WriteHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_item> items, bool isNewTemp)
{
var nurseFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "护理组").FactorRow.Value);
var doctorFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医生组").FactorRow.Value);
var technicianFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医技组").FactorRow.Value);
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
logger.LogInformation($"提取绩效数据 提取绩效数据 写入列头信息 -- {sheet.SheetName}");
var cellItems = new List<ex_item>();
cellItems.AddRange(items);
if (!isNewTemp)
{
List<string> original = new List<string>();
#region 过滤历史模板中已有的列头
//写入列头信息
int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 4;
for (int i = cellStartIndex; i < head.LastCellNum; i++)
{
var cellvalue = head.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(cellvalue)) continue;
cellItems.RemoveAll(t => t.ItemName == cellvalue);
}
#endregion
}
if (cellItems == null || !cellItems.Any()) return;
#region 新增模板中不存在的列头
var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 4 : head.LastCellNum;
foreach (var item in cellItems)
{
var headcell = GetOrCreate(head, lastcellIndex);
headcell.SetCellValue(item.ItemName);
headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
var doctorcell = GetOrCreate(doctorFactor, lastcellIndex);
doctorcell.SetCellValue(item.FactorValue1 != null ? (double)item.FactorValue1 : 0);
doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
var nursecell = GetOrCreate(nurseFactor, lastcellIndex);
nursecell.SetCellValue(item.FactorValue2 != null ? (double)item.FactorValue2 : 0);
nursecell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
var techniciancell = GetOrCreate(technicianFactor, lastcellIndex);
techniciancell.SetCellValue(item.FactorValue3 != null ? (double)item.FactorValue3 : 0);
techniciancell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
lastcellIndex++;
}
#endregion
}
/// <summary>
/// 写入数据
/// </summary>
/// <param name="sheet"></param>
/// <param name="sheetRead"></param>
/// <param name="unitList">核算单元</param>
/// <param name="allExtract">抽取的数据(科室、列头、数据)</param>
/// <param name="header">设定抽取的列头</param>
/// <param name="isNewTemp">是否为空白模板</param>
/// <param name="isIncom">是否是开单、执行收入</param>
private void WriteSheetData(ISheet sheet, IPerSheetDataRead sheetRead, List<NewExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp, bool isIncom = false)
{
logger.LogInformation($"提取绩效数据 填充数据 -- {sheet.SheetName}");
//写入数据
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
var rowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
if (!isNewTemp)
{
#region 给历史模板已有科室补充数据
for (int i = rowIndex; i < sheet.LastRowNum + 1; i++)
{
var row = sheet.GetRow(i);
if (row != null)
{
var department = row.GetCell(6)?.ToString(); // 科室名称
if (string.IsNullOrEmpty(department)) continue;
var deptData = allExtract.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
for (int j = 7; j < head.LastCellNum; j++)
{
var headName = head.GetCell(j).StringCellValue;
var newCell = GetOrCreate(row, j);
if (newCell == null) continue;
var value = deptData.FirstOrDefault(t => t.Category == headName)?.Value;
if (isIncom)
{
value = value == 0 ? null : value;
OutToExcelCell(newCell, value);
newCell.CellStyle = style;
}
else if (newCell.CellType != CellType.Formula)
{
value = value == 0 ? null : value;
OutToExcelCell(newCell, value);
if (header != null && header.Contains(headName))
newCell.CellStyle = style;
}
}
allExtract.RemoveAll(t => t.Department == department);
}
}
#endregion
}
if (allExtract == null || !allExtract.Any()) return;
#region 补充新的科室及数据
var lastrowIndex = isNewTemp ? rowIndex : sheet.LastRowNum + 1;
foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
{
var row = sheet.CreateRow(lastrowIndex);
for (int i = head.FirstCellNum + 3; i < head.LastCellNum; i++)
{
var headName = head.GetCell(i).StringCellValue;
var newCell = row.CreateCell(i);
var celldata = allExtract.FirstOrDefault(t => t.Department == department);
if (headName == "科室名称")
{
newCell.SetCellValue(department ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (celldata != null)
{
if (headName.Replace("\n", "") == "核算单元(医生组)")
{
var accounting = HasValue(celldata.OutDoctorAccounting, celldata.InpatDoctorAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatDoctorAccounting, celldata.OutDoctorAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName.Replace("\n", "") == "核算单元(护理组)")
{
var accounting = HasValue(celldata.OutNurseAccounting, celldata.InpatNurseAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatNurseAccounting, celldata.OutNurseAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName.Replace("\n", "") == "核算单元(医技组)")
{
var accounting = HasValue(celldata.OutTechnicAccounting, celldata.InpatTechnicAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatTechnicAccounting, celldata.OutTechnicAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
{
celldata = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
if (isIncom)
{
OutToExcelCell(newCell, celldata?.Value);
newCell.CellStyle = style;
}
else if (header != null && header.Contains(headName))
{
OutToExcelCell(newCell, celldata?.Value);
newCell.CellStyle = style;
}
}
}
}
lastrowIndex++;
}
#endregion
}
/// <summary>
/// 写入工作量列头
/// </summary>
/// <param name="sheet"></param>
/// <param name="sheetRead"></param>
/// <param name="items"></param>
/// <param name="isNewTemp"></param>
private void WriteWorkHeader(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_item> items, bool isNewTemp)
{
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var factor = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 1);
var cellItems = new List<ex_item>();
cellItems.AddRange(items);
if (!isNewTemp)
{
#region 过滤历史模板中已有的列头
//写入列头信息
int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 2;
for (int i = cellStartIndex; i < head.LastCellNum; i++)
{
var cellvalue = head.GetCell(i)?.ToString();
if (string.IsNullOrEmpty(cellvalue)) continue;
cellItems.RemoveAll(t => t.ItemName == cellvalue);
}
#endregion
}
if (cellItems == null || !cellItems.Any()) return;
#region 新增模板中不存在的列头
var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 2 : head.LastCellNum;
foreach (var item in cellItems)
{
var headcell = GetOrCreate(head, lastcellIndex);
headcell.SetCellValue(item.ItemName);
headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
var doctorcell = GetOrCreate(factor, lastcellIndex);
doctorcell.SetCellValue(item.FactorValue1 != null ? (double)item.FactorValue1 : 0);
doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头, CellFormat.数字2);
lastcellIndex++;
}
#endregion
}
/// <summary>
/// 写入工作量数据
/// </summary>
/// <param name="sheet"></param>
/// <param name="sheetRead"></param>
/// <param name="unitList"></param>
/// <param name="allExtract"></param>
/// <param name="header"></param>
/// <param name="isNewTemp"></param>
private void WriteWorkData(ISheet sheet, IPerSheetDataRead sheetRead, List<NewExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp)
{
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var rowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 2;
if (!isNewTemp)
{
#region 给历史模板已有科室补充数据
for (int i = rowIndex; i < sheet.LastRowNum + 1; i++)
{
var row = sheet.GetRow(i);
if (row != null)
{
var department = row.GetCell(2)?.ToString(); // 科室名称
if (string.IsNullOrEmpty(department)) continue;
var deptData = allExtract.Where(t => t.Department == department);
if (deptData == null || !deptData.Any()) continue;
for (int j = 3; j < head.LastCellNum; j++)
{
var headName = head.GetCell(j).StringCellValue;
var newCell = GetOrCreate(row, j);
if (newCell == null) continue;
if (newCell.CellType != CellType.Formula)
{
var extract = deptData.FirstOrDefault(t => t.Category == headName);
var value = extract?.Value == 0 ? null : extract?.Value;
OutToExcelCell(newCell, value);
if (header != null && header.Contains(headName))
newCell.CellStyle = style;
}
}
allExtract.RemoveAll(t => t.Department == department);
}
}
#endregion
}
if (allExtract == null || !allExtract.Any()) return;
//var unit = sheet.SheetName.IndexOf("医生") > -1 ? new int[] { (int)UnitType.医生组, (int)UnitType.医技组 } : new int[] { (int)UnitType.护理组 };
#region 补充新的科室及数据
var lastrowIndex = isNewTemp ? rowIndex : sheet.LastRowNum + 1;
foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
{
var row = sheet.CreateRow(lastrowIndex);
for (int i = head.FirstCellNum + 1; i < head.LastCellNum; i++)
{
var headName = head.GetCell(i).StringCellValue;
var newCell = row.CreateCell(i);
var celldata = allExtract.FirstOrDefault(t => t.Department == department);
if (headName == "科室名称")
{
newCell.SetCellValue(department);
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (celldata != null)
{
if (headName == "核算单元")
{
var accounting = sheet.SheetName.IndexOf("医生") > -1
? HasValue(celldata.OutDoctorAccounting, celldata.InpatDoctorAccounting, celldata.OutTechnicAccounting, celldata.InpatTechnicAccounting)
: (celldata.OutNurseAccounting ?? celldata.InpatNurseAccounting);
newCell.SetCellValue(accounting);
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
{
var extract = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
OutToExcelCell(newCell, extract?.Value);
if (header != null && header.Contains(headName))
newCell.CellStyle = style;
}
}
}
lastrowIndex++;
}
#endregion
}
private string HasValue(params string[] list)
{
if (list == null || !list.Any()) return null;
return list.FirstOrDefault(t => !string.IsNullOrEmpty(t));
}
#endregion
#endregion
#region Common
/// <summary>
/// 发送邮件
/// </summary>
/// <param name="path"></param>
/// <param name="subject"></param>
/// <param name="body"></param>
private void SendEmail(string mail, string path, string subject, string body)
{
if (string.IsNullOrEmpty(mail)) return;
var message = new EmailMessage
{
To = new List<string> { mail },
DisplayName = "溯直健康",
Subject = subject,
Body = body
};
if (!string.IsNullOrEmpty(path))
message.Attachments = new List<string> { path };
emailService.Send(message);
}
/// <summary>
/// 校验数据格式,并转换
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public void OutToExcelCell(ICell cell, object obj)
{
string value = obj?.ToString() ?? "";
try
{
var type = obj?.GetType() ?? typeof(string);
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);
}
}
#endregion
#region 配置校验
/// <summary>
/// 配置校验
/// </summary>
/// <param name="allotId"></param>
/// <param name="hospitalId"></param>
/// <param name="useTemplate"></param>
public string Judge(int allotId, int hospitalId, int useTemplate, out string filePath)
{
string result = null;
filePath = "";
try
{
// 获取绩效信息
var allot = perforPerallotRepository.GetEntity(t => t.ID == allotId);
if (allot == null)
throw new PerformanceException("AllotID错误");
// 获取医院信息
var hospital = perforHospitalRepository.GetEntity(t => t.ID == hospitalId);
if (hospital == null)
throw new PerformanceException("医院ID错误");
// 获取医院配置信息
var hospitalConfigList = perforHospitalconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
if (hospitalConfigList == null || hospitalConfigList.Count == 0)
throw new PerformanceException("当前医院暂不支持HIS数据抽取");
// 获取最近一次绩效
var statesArray = new int[] { (int)AllotStates.GenerateSucceed, (int)AllotStates.Archive };
var allotList = perforPerallotRepository.GetEntities(t => t.HospitalId == hospitalId && statesArray.Contains(t.States));
var allotLast = allotList?.OrderByDescending(t => t.Year).ThenByDescending(t => t.Month).First();
if (allotLast != null)
filePath = allotLast.Path;
// 获取当前医院模版信息
var modulesList = perforExmoduleRepository.GetEntities(t => t.HospitalId == hospitalId);
if (modulesList == null || modulesList.Count == 0)
throw new PerformanceException("当前医院还未配置模版");
// 获取模板项
var moduleIdList = modulesList.Select(t => t.Id).ToList();
var itemsList = perforExitemRepository.GetEntities(t => t.ModuleId.HasValue && moduleIdList.Contains(t.ModuleId.Value));
if (itemsList == null || itemsList.Count == 0)
throw new PerformanceException("当前医院还未配置模版项");
// 获取当前模板所有相关抽取SQL语句
var extypeIds = itemsList.Select(t => t.TypeId).Union(modulesList.Select(t => t.TypeId)).Distinct().ToList();
var extractList = perforExscriptRepository.GetEntities(t => extypeIds.Contains(t.TypeId));
if (extractList == null || extractList.Count == 0)
throw new PerformanceException("当前医院配置模板无需抽取");
}
catch (PerformanceException ex)
{
logger.LogError($"提取绩效数据异常 {ex.ToString()}");
result = ex.Message;
}
catch (Exception ex)
{
logger.LogError($"提取绩效数据异常 {ex.ToString()}");
throw new Exception(ex.Message);
}
return result;
}
#endregion
}
public class AccountBasic
{
public string UnitType { get; set; }
public string Department { get; set; }
public string AccountingUnit { get; set; }
public decimal? EfficiencyNumber { get; set; }
public decimal? DirectorNumber { get; set; }
public decimal? PermanentStaff { get; set; }
public int IsDelete { get; set; }
}
public class NewExtractDto : ExtractDto
{
public string SheetName { get; set; }
public string OutDoctorAccounting { get; set; }
public string OutNurseAccounting { get; set; }
public string OutTechnicAccounting { get; set; }
public string InpatDoctorAccounting { get; set; }
public string InpatNurseAccounting { get; set; }
public string InpatTechnicAccounting { get; set; }
public new decimal? Value { get; set; }
}
}
......@@ -11,7 +11,10 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
namespace Performance.Services
{
......@@ -27,7 +30,6 @@ public class DFExtractService : IAutoInjection
private readonly PerforImspecialunitRepository perforImspecialunitRepository;
private readonly PerforImdataRepository perforImdataRepository;
private readonly PerforRepimportconfigRepository repimportconfigRepository;
private readonly LogManageService logManageService;
private readonly PerforExitemRepository perforExitemRepository;
private readonly PerforExmoduleRepository perforExmoduleRepository;
......@@ -35,9 +37,15 @@ public class DFExtractService : IAutoInjection
private readonly PerforExresultRepository perforExresultRepository;
private readonly PerforExscriptRepository perforExscriptRepository;
private readonly PerforPerdeptdicRepository perforPerdeptdicRepository;
private readonly PerforPeremployeeRepository perforPeremployeeRepository;
private readonly PersonService personService;
private IWorkbook workbook = null;
private ICellStyle style;
private per_allot Allot;
private const string specialname = "4.2 特殊核算单元绩效测算表";
private DateTime? CreateTime = null;
public DFExtractService(ILogger<DFExtractService> logger,
IEmailService emailService,
......@@ -48,13 +56,16 @@ public class DFExtractService : IAutoInjection
PerforImspecialunitRepository perforImspecialunitRepository,
PerforImdataRepository perforImdataRepository,
PerforRepimportconfigRepository repimportconfigRepository,
LogManageService logManageService,
PerforExitemRepository perforExitemRepository,
PerforExmoduleRepository perforExmoduleRepository,
PerforExspecialRepository perforExspecialRepository,
PerforExresultRepository perforExresultRepository,
PerforExscriptRepository perforExscriptRepository)
PerforExscriptRepository perforExscriptRepository,
PerforPerdeptdicRepository perforPerdeptdicRepository,
PerforPeremployeeRepository perforPeremployeeRepository,
PersonService personService)
{
this.logger = logger;
this.emailService = emailService;
......@@ -65,13 +76,16 @@ public class DFExtractService : IAutoInjection
this.perforImspecialunitRepository = perforImspecialunitRepository;
this.perforImdataRepository = perforImdataRepository;
this.repimportconfigRepository = repimportconfigRepository;
this.logManageService = logManageService;
this.perforExitemRepository = perforExitemRepository;
this.perforExmoduleRepository = perforExmoduleRepository;
this.perforExspecialRepository = perforExspecialRepository;
this.perforExresultRepository = perforExresultRepository;
this.perforExscriptRepository = perforExscriptRepository;
this.perforPerdeptdicRepository = perforPerdeptdicRepository;
this.perforPeremployeeRepository = perforPeremployeeRepository;
this.personService = personService;
}
#endregion
......@@ -103,6 +117,7 @@ public string ExtractData(int allotId, string email, int hospitalId, string file
typeIds.AddRange(items?.Select(t => t.TypeId ?? 0) ?? new List<int>());
}
var specials = perforExspecialRepository.GetEntities(t => t.HospitalId == hospitalId);
if (specials != null && specials.Any())
typeIds.AddRange(specials.Select(t => t.TypeId ?? 0));
......@@ -110,6 +125,7 @@ public string ExtractData(int allotId, string email, int hospitalId, string file
var data = new List<ex_result>();
var scripts = perforExscriptRepository.GetEntities(t => typeIds.Contains(t.TypeId));
ClearHistData(allot);
CreateTime = DateTime.Now;
var otherItems = items.Where(t => modules.Where(m => m.SheetType != (int)SheetType.Income).Select(m => m.Id).Contains(t.ModuleId.Value)).ToList();
if (scripts != null && scripts.Any())
{
......@@ -118,12 +134,12 @@ public string ExtractData(int allotId, string email, int hospitalId, string file
data.AddRange(ExtractSpcial(specials, scripts, configs, allot));
}
return lastAllot == null ? TemplateExecute(email, hospital, configs, modules, items, specials, data)
: AlllotExecute(email, hospital, configs, modules, items, specials, data, lastAllot, filePath);
var standData = StandData(data);
return lastAllot == null ? TemplateExecute(email, hospital, configs, modules, items, specials, standData)
: AlllotExecute(email, hospital, configs, modules, items, specials, standData, lastAllot, filePath);
}
catch (Exception ex)
{
logManageService.WriteMsg("提取数据异常", $"数据写入出现异常", 4, Allot.ID, "ReceiveMessage");
logger.LogError($"提取绩效数据异常 数据写入出现异常{ex.ToString()}");
//SendEmail(email, "", $"{hospital.HosName}HIS数据提取失败", $"{hospital.HosName}提取数据过程中出现异常情况,我们将尽快解决问题。给您带来的不便我们深感歉意!");
throw ex;
......@@ -138,6 +154,9 @@ public string ExtractData(int allotId, string email, int hospitalId, string file
}
}
/// <summary>
/// 抽取收入费用
/// </summary>
......@@ -160,11 +179,14 @@ private List<ex_result> ExtractIncome<TEntity>(List<TEntity> entities, List<ex_s
{
var item = scripts.FirstOrDefault(t => t.TypeId == module.TypeId && t.DatabaseType == config.DataBaseType);
if (item == null) continue;
data.AddRange(QueryData(config, allot, item.ExecScript, module.ModuleName));
var querydata = QueryData(config, allot, item.ExecScript, module.ModuleName);
if (querydata != null && querydata.Any())
{
perforExresultRepository.AddRange(querydata.ToArray());
data.AddRange(querydata);
}
}
}
if (data != null && data.Any())
perforExresultRepository.AddRange(data.ToArray());
return data;
}
......@@ -195,12 +217,18 @@ private List<ex_result> ExtractItems<TEntity>(List<TEntity> entities, List<ex_sc
if (item == null) continue;
var result = QueryData(config, allot, item.ExecScript, module.ModuleName);
result.ForEach(t => t.Category = exitem.ItemName);
data.AddRange(result);
if (result != null && result.Any())
{
result.ForEach(t =>
{
t.Category = exitem.ItemName;
});
perforExresultRepository.AddRange(result.ToArray());
data.AddRange(result);
}
}
}
if (data != null && data.Any())
perforExresultRepository.AddRange(data.ToArray());
return data;
}
......@@ -228,7 +256,7 @@ private List<ex_result> ExtractSpcial<TEntity>(List<TEntity> entities, List<ex_s
var item = scripts.FirstOrDefault(t => t.TypeId == special.TypeId && t.DatabaseType == config.DataBaseType);
if (item == null) continue;
var result = QueryData(config, allot, item.ExecScript, "4.2 特殊核算单元绩效测算表");
var result = QueryData(config, allot, item.ExecScript, specialname);
result.ForEach(t =>
{
t.Category = special.Target;
......@@ -250,11 +278,14 @@ private List<ex_result> ExtractSpcial<TEntity>(List<TEntity> entities, List<ex_s
private void ClearHistData(per_allot allot)
{
logger.LogInformation($"开始清除历史提取数据");
var data = perforExresultRepository.GetEntities(t => t.AllotId == allot.ID);
if (data == null || !data.Any(t => t.Id > 0))
return;
var data = perforExresultRepository.GetEntities(t => t.AllotId == allot.ID && t.IsDelete == 0);
if (data != null && data.Any(t => t.Id > 0))
{
data.ForEach(t => t.IsDelete = 1);
perforExresultRepository.UpdateRange(data.ToArray());
perforExresultRepository.RemoveRange(data.ToArray());
perforPerallotRepository.ClearResultData(allot.ID);
}
}
/// <summary>
......@@ -269,7 +300,7 @@ private void ClearHistData(per_allot allot)
/// <param name="specials"></param>
/// <param name="extracts"></param>
/// <returns></returns>
public string TemplateExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<ex_result> data)
public string TemplateExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<NewExtractDto> data)
{
string originalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院绩效模板.xlsx");
var (tempPath, newPath) = CopyOriginalFile(hospital.ID, originalPath);
......@@ -279,8 +310,6 @@ public string TemplateExecute(string email, sys_hospital hospital, List<sys_hosp
style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
List<AccountUnitEntity> unitList = new List<AccountUnitEntity>();
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
......@@ -290,20 +319,29 @@ public string TemplateExecute(string email, sys_hospital hospital, List<sys_hosp
var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
switch (sheetType)
{
case SheetType.Employee:
WriteEmployee(sheet, sheetRead);
break;
case SheetType.ClinicEmployee:
WriteClinicEmployee(sheet, sheetRead);
break;
case SheetType.OtherIncome:
WriteOtherIncome(sheet, sheetRead, unitList, configs, modules, items, data);
WriteOtherIncome(sheet, sheetRead, modules, items, data);
break;
case SheetType.Income:
WriteIncome(sheet, sheetRead, unitList, configs, modules, items, data);
WriteIncome(sheet, sheetRead, modules, items, data);
break;
case SheetType.Expend:
WriteExpend(sheet, sheetRead, unitList, configs, modules, items, data);
WriteExpend(sheet, sheetRead, modules, items, data);
break;
case SheetType.Workload:
WriteWorkload(sheet, sheetRead, unitList, configs, modules, items, data);
WriteWorkload(sheet, sheetRead, modules, items, data);
break;
case SheetType.AccountBasic:
WriteAccountBasic(sheet, sheetRead);
break;
case SheetType.SpecialUnit:
WriteSpecialUnit(sheet, sheetRead, configs, specials, data);
WriteSpecialUnit(sheet, sheetRead, specials, data);
break;
}
}
......@@ -311,7 +349,6 @@ public string TemplateExecute(string email, sys_hospital hospital, List<sys_hosp
{
workbook.Write(file);
}
logManageService.WriteMsg("提取绩效数据", $"{hospital.HosName}HIS数据提取成功,文件路径:{newPath}。", 5, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
ImportData(Allot, configs);
SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
......@@ -330,7 +367,7 @@ public string TemplateExecute(string email, sys_hospital hospital, List<sys_hosp
/// <param name="specials"></param>
/// <param name="extracts"></param>
/// <returns></returns>
public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<ex_result> extracts, per_allot lastAllot, string path)
public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<NewExtractDto> extracts, per_allot lastAllot, string path)
{
if (string.IsNullOrEmpty(path)) throw new PerformanceException("历史绩效文件不存在!");
......@@ -341,13 +378,6 @@ public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospit
style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
List<AccountUnitEntity> unitList = new List<AccountUnitEntity>();
if (lastAllot != null)
{
unitList = perforImdataRepository.GetAccountUnit(lastAllot.ID).ToList();
logger.LogInformation($"lastAllot.ID: {lastAllot.ID}, lastAllot date: {lastAllot.Year}-{lastAllot.Month}, unitList count: {unitList?.Count ?? 0}");
}
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
......@@ -356,25 +386,34 @@ public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospit
var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
switch (sheetType)
{
case SheetType.Employee:
WriteEmployee(sheet, sheetRead, false);
break;
case SheetType.ClinicEmployee:
WriteClinicEmployee(sheet, sheetRead, false);
break;
case SheetType.OtherIncome:
ClearData(sheet, 5, 7);
WriteOtherIncome(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
WriteOtherIncome(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Income:
ClearData(sheet, 5, 7, true);
WriteIncome(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
WriteIncome(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Expend:
ClearData(sheet, 5, 7);
WriteExpend(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
WriteExpend(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.Workload:
ClearData(sheet, 3, 3);
WriteWorkload(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
WriteWorkload(sheet, sheetRead, modules, items, extracts, false);
break;
case SheetType.AccountBasic:
WriteAccountBasic(sheet, sheetRead, false);
break;
case SheetType.SpecialUnit:
ClearData(sheet, 2, 0);
WriteSpecialUnit(sheet, sheetRead, configs, specials, extracts, false, lastAllot);
WriteSpecialUnit(sheet, sheetRead, specials, extracts, lastAllot, false);
break;
}
}
......@@ -382,7 +421,6 @@ public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospit
{
workbook.Write(file);
}
logManageService.WriteMsg("提取绩效数据", $"{hospital.HosName}HIS数据提取成功,文件路径:{newPath}。", 5, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
ImportData(Allot, configs);
SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
......@@ -422,10 +460,13 @@ private List<ex_result> QueryData(sys_hospitalconfig config, per_allot allot, st
Department = t.Department,
Category = t.Category?.Trim(),
Fee = t.Value,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Source = source,
DatabaseType = config.DataBaseType,
ConfigId = config.Id,
AllotId = allot.ID,
CreateTime = CreateTime,
}).ToList();
}
return data;
......@@ -454,7 +495,7 @@ private List<ex_result> QueryData(sys_hospitalconfig config, per_allot allot, st
/// </summary>
/// <param name="allot"></param>
/// <param name="configs"></param>
public void ImportData(per_allot allot, List<sys_hospitalconfig> configs)
private void ImportData(per_allot allot, List<sys_hospitalconfig> configs)
{
Dictionary<string, object> pairs = new Dictionary<string, object>
{
......@@ -507,6 +548,94 @@ public void ImportData(per_allot allot, List<sys_hospitalconfig> configs)
}
}
private List<NewExtractDto> StandData(IEnumerable<ex_result> results)
{
if (results == null || !results.Any()) return new List<NewExtractDto>();
var dict = personService.GetDepartments(Allot.HospitalId)?.ToList();
if (dict == null || !dict.Any())
return results.Select(t => new NewExtractDto
{
SheetName = t.Source,
DoctorName = t.DoctorName,
PersonnelNumber = t.PersonnelNumber,
Department = t.Department,
Category = t.Category,
Value = (t.Fee ?? 0) == 0 ? null : t.Fee
}).ToList();
dict.ForEach(t =>
{
t.HISDeptName = HasValue(t.HISDeptName, t.Department);
});
var data = results.GroupJoin(dict, outer => new { Department = outer.Department }, inner => new { Department = inner.HISDeptName }, (outer, inner) => new { outer, inner })
.Select(t =>
{
var dept = !string.IsNullOrEmpty(t.inner.FirstOrDefault()?.Department) ? t.inner.FirstOrDefault()?.Department : t.outer.Department;
return new NewExtractDto
{
SheetName = t.outer.Source,
Department = dept,
Category = t.outer.Category,
DoctorName = t.outer.DoctorName,
PersonnelNumber = t.outer.PersonnelNumber,
Value = t.outer.Fee ?? 0, //(t.outer.Fee ?? 0) == 0 ? null : t.outer.Fee
OutDoctorAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutDoctorAccounting?.AccountingUnit,
OutNurseAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutNurseAccounting?.AccountingUnit,
OutTechnicAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.OutTechnicAccounting?.AccountingUnit,
InpatDoctorAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatDoctorAccounting?.AccountingUnit,
InpatNurseAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatNurseAccounting?.AccountingUnit,
InpatTechnicAccounting = t.inner.FirstOrDefault(l => l.Department == dept)?.InpatTechnicAccounting?.AccountingUnit,
};
});
new Task(() => SaveWorkload(data.Where(t => t.SheetName.Contains("3.")))).Start();
var groupdata = data.GroupBy(t => new { t.Department, t.Category, t.SheetName }).Select(t => new NewExtractDto
{
SheetName = t.Key.SheetName,
Department = t.Key.Department,
Category = t.Key.Category,
Value = t.Sum(group => group.Value) == 0 ? null : t.Sum(group => group.Value),
OutDoctorAccounting = t.First().OutDoctorAccounting,
OutNurseAccounting = t.First().OutNurseAccounting,
OutTechnicAccounting = t.First().OutTechnicAccounting,
InpatDoctorAccounting = t.First().InpatDoctorAccounting,
InpatNurseAccounting = t.First().InpatNurseAccounting,
InpatTechnicAccounting = t.First().InpatTechnicAccounting,
});
return groupdata.ToList();
}
private void SaveWorkload(IEnumerable<NewExtractDto> dtos)
{
try
{
if (dtos == null || !dtos.Any()) return;
var parameters = dtos.Select(t => new
{
allotid = Allot.ID,
year = Allot.Year,
month = Allot.Month,
hospitalid = Allot.HospitalId,
accountingunit = HasValue(t.InpatTechnicAccounting, t.OutTechnicAccounting, t.InpatDoctorAccounting, t.InpatNurseAccounting, t.OutDoctorAccounting, t.OutNurseAccounting),
department = t.Department,
doctorname = t.DoctorName,
personnelnumber = t.PersonnelNumber,
category = t.Category,
fee = t.Value
});
if (parameters != null && parameters.Any())
perforPerallotRepository.ImportWorkloadData(Allot, parameters);
}
catch (Exception ex)
{
logger.LogError($"allotid: {Allot.ID},保存医护工作量报表数据时异常: " + ex.ToString());
}
}
#endregion
#region Excel
......@@ -578,6 +707,31 @@ private void ClearData(ISheet sheet, int beginRowNum, int beginCellNum, bool isI
sheet.ForceFormulaRecalculation = true;
}
private (Dictionary<string, int> dictClear, Dictionary<string, int> dictVerify) ClearDataDict(ISheet sheet, IPerSheetDataRead sheetRead, List<string> header, int sheetType)
{
Dictionary<int, string[]> verify = new Dictionary<int, string[]>
{
{ (int)SheetType.Employee, new string[]{ "核算单元", "人员工号", "医生姓名" } },
{ (int)SheetType.ClinicEmployee, new string[]{ "核算单元", "人员工号", "医生姓名" } },
{ (int)SheetType.AccountBasic, new string[]{ "核算单元类型", "核算单元", "科室名称" } },
};
Dictionary<string, int> dictClear = new Dictionary<string, int>();
Dictionary<string, int> dictVerify = new Dictionary<string, int>();
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue)) continue;
if (header.Contains(headvalue)) dictClear.Add(headvalue, i);
if (verify[sheetType].Contains(headvalue)) dictVerify.Add(headvalue, i);
}
return (dictClear, dictVerify);
}
private IRow GetOrCreate(ISheet sheet, int index)
{
var row = sheet.GetRow(index);
......@@ -597,196 +751,393 @@ private ICell GetOrCreate(IRow row, int index)
return cell;
}
public void GenRowStyle(IRow r, ICellStyle cellStyle)
{
List<ICell> clist = r.Cells;
foreach (var cItem in clist)
{
cItem.CellStyle = cellStyle;
}
r.RowStyle = cellStyle;
}
#endregion
#region SheetData
private void WriteOtherIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
private void WriteEmployee(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
Dictionary<string, Func<per_employee, object>> dict = new Dictionary<string, Func<per_employee, object>>
{
{ "人员分类", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "人员工号", (t) => t.PersonnelNumber },
{ "医生姓名", (t) => t.DoctorName },
{ "参加工作时间", (t) => t.WorkTime },
{ "出勤率", (t) => t.Attendance },
};
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "出勤率" }, (int)SheetType.Employee);
var delEmployees = new List<per_employee>();
foreach (var item in validData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var personnel = GetOrCreate(row, dictVerify["人员工号"]).ToString();
var doctorname = GetOrCreate(row, dictVerify["医生姓名"]).ToString();
var employee = validData.FirstOrDefault(t => (t.AccountingUnit ?? "") == accountingunit && (t.PersonnelNumber ?? "") == personnel && (t.DoctorName ?? "") == doctorname);
if (employee == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
cell.SetCellValue("");
}
//validData.Remove(employee);
delEmployees.Add(employee);
}
beginRowIndex++;
}
if (delEmployees.Any(t => t.Id > 0))
validData.RemoveAll(t => delEmployees.Select(e => e.Id).Contains(t.Id));
}
//新增数据
foreach (var item in validData)
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteClinicEmployee(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && !accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
Dictionary<string, Func<per_employee, object>> dict = new Dictionary<string, Func<per_employee, object>>
{
{ "核算单元分类", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "人员工号", (t) => t.PersonnelNumber },
{ "医生姓名", (t) => t.DoctorName },
{ "职务分类", (t) => t.JobTitle },
{ "出勤率", (t) => t.Attendance },
};
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "出勤率" }, (int)SheetType.ClinicEmployee);
var delEmployees = new List<per_employee>();
foreach (var item in validData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var personnel = GetOrCreate(row, dictVerify["人员工号"]).ToString();
var doctorname = GetOrCreate(row, dictVerify["医生姓名"]).ToString();
var employee = validData.FirstOrDefault(t => (t.AccountingUnit ?? "") == accountingunit && (t.PersonnelNumber ?? "") == personnel && (t.DoctorName ?? "") == doctorname);
if (employee == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
cell.SetCellValue("");
}
//validData.Remove(employee);
delEmployees.Add(employee);
}
beginRowIndex++;
}
if (delEmployees.Any(t => t.Id > 0))
validData.RemoveAll(t => delEmployees.Select(e => e.Id).Contains(t.Id));
}
//新增数据
foreach (var item in validData)
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteAccountBasic(ISheet sheet, IPerSheetDataRead sheetRead, bool isNewTemp = true)
{
var accountingunits = new string[] { AccountUnitType.行政高层.ToString(), AccountUnitType.行政中层.ToString(), AccountUnitType.行政工勤.ToString() };
var validData = perforPeremployeeRepository.GetEntities(t => t.AllotId == Allot.ID && !accountingunits.Contains(t.UnitType))?.ToList();
if (validData == null || !validData.Any()) return;
#region 计算数据
bool duty(per_employee t) => !string.IsNullOrEmpty(t.Duty) && (t.Duty.IndexOf("科主任") > -1 || t.Duty.IndexOf("副主任") > -1
|| t.Duty.IndexOf("护士长") > -1 || t.Duty.IndexOf("副护士长") > -1);
var groupData = validData.GroupBy(t => new { t.Department, t.UnitType }).Select(t => new AccountBasic
{
UnitType = t.Key.UnitType,
Department = t.Key.Department,
AccountingUnit = t.FirstOrDefault(group => group.Department == t.Key.Department)?.AccountingUnit,
EfficiencyNumber = t.Sum(group => group.EfficiencyNumber),
DirectorNumber = t.Count(duty),
PermanentStaff = t.Sum(group => group.PermanentStaff * group.Attendance),
IsDelete = 0,
}).OrderBy(t => t.UnitType).ThenBy(t => t.AccountingUnit).ToList();
Dictionary<string, Func<dynamic, object>> dict = new Dictionary<string, Func<dynamic, object>>
{
{ "核算单元类型", (t) => t.UnitType },
{ "核算单元", (t) => t.AccountingUnit },
{ "科室名称", (t) => t.Department },
{ "效率绩效人数", (t) => t.EfficiencyNumber },
{ "科主任/护士长人数", (t) => t.DirectorNumber },
{ "核算单元人员数量", (t) => t.PermanentStaff },
};
#endregion
var lastnum = sheet.LastRowNum + 1;
var headRow = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var beginRowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// 清楚历史数据
if (!isNewTemp)
{
var (dictClear, dictVerify) = ClearDataDict(sheet, sheetRead, new List<string> { "效率绩效人数", "科主任/护士长人数", "核算单元人员数量" }, (int)SheetType.AccountBasic);
foreach (var item in groupData)
{
if (beginRowIndex > lastnum) break;
var row = GetOrCreate(sheet, beginRowIndex);
var unittype = GetOrCreate(row, dictVerify["核算单元类型"]).ToString();
var accountingunit = GetOrCreate(row, dictVerify["核算单元"]).ToString();
var department = GetOrCreate(row, dictVerify["科室名称"]).ToString();
var data = groupData.FirstOrDefault(t => (t.UnitType ?? "") == unittype && (t.AccountingUnit ?? "") == accountingunit && (t.Department ?? "") == department);
if (data == null)
{
//sheet.RemoveRow(row);
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.Remove));
beginRowIndex++;
continue;
}
else
{
foreach (var pair in dictClear)
{
if (pair.Value == -1) continue;
var cell = GetOrCreate(row, pair.Value);
var func = dict[pair.Key];
if (func != null)
OutToExcelCell(cell, func.Invoke(data));
}
data.IsDelete = 1;
}
beginRowIndex++;
}
}
//新增数据
foreach (var item in groupData.Where(t => t.IsDelete == 0))
{
var row = GetOrCreate(sheet, beginRowIndex);
for (int i = 0; i < headRow.LastCellNum; i++)
{
var headvalue = headRow.GetCell(i)?.ToString()?.Trim();
if (string.IsNullOrEmpty(headvalue) || !dict.ContainsKey(headvalue)) continue;
var func = dict[headvalue];
if (func != null)
{
var cell = GetOrCreate(row, i);
OutToExcelCell(cell, func.Invoke(item));
}
}
GenRowStyle(row, CellStyle.CreateCellStyle(workbook, StyleType.数据));
beginRowIndex++;
}
}
private void WriteOtherIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始提取.");
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.OtherIncome);
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
//查询数据
List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
{
Department = t.Department,
Category = t.Category,
Value = t.Fee ?? 0
}).ToList();
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp);
WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp);
logger.LogInformation($"{sheet.SheetName}提取结束.");
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
private void WriteIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始提取.");
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
//if (itemList == null || !itemList.Any()) return;
var itemList = items.Where(t => t.ModuleId == module.Id)?.ToList() ?? new List<ex_item>();
var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
{
var itemCount = itemList?.Count ?? 0;
logger.LogInformation($"item有{itemCount}个.");
if (itemCount > 0) WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
return;
}
//查询数据
List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
{
Department = t.Department,
Category = t.Category,
Value = t.Fee ?? 0
}).ToList();
//logger.LogInformation($"{sheet.SheetName}合计值为: " + allExtract.Sum(t => t.Value));
var category = allExtract.Select(t => t.Category?.Trim()).Distinct().ToList();
var category = extractdata.Select(t => t.Category?.Trim()).Distinct().ToList();
var existHead = category.Except(itemList.Select(i => i.ItemName?.Trim()));
if (existHead != null && existHead.Any())
itemList.AddRange(existHead.Select(t => new ex_item
{
ItemName = t,
}));
itemList.AddRange(existHead.Select(t => new ex_item { ItemName = t, FactorValue1 = 0, FactorValue2 = 0, FactorValue3 = 0 }));
logger.LogInformation($"item有{itemList?.Count ?? 0}个.{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
//WriteIncomeHeaderAndFactor(sheet, sheetRead, category, isNewTemp);
WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp, true);
logger.LogInformation($"{sheet.SheetName}提取结束.");
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp, true);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteExpend(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
private void WriteExpend(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始提取.");
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.Expend);
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteHeaderAndFactor(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
//查询数据
List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
{
Department = t.Department,
Category = t.Category,
Value = t.Fee ?? 0
}).ToList();
WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp);
logger.LogInformation($"{sheet.SheetName}提取结束.");
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteSheetData(sheet, sheetRead, extractdata.ToList(), itemList.Select(t => t.ItemName), isNewTemp);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
private void WriteWorkload(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
private void WriteWorkload(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_module> modules, List<ex_item> items, List<NewExtractDto> data, bool isNewTemp = true)
{
logger.LogInformation($"{sheet.SheetName}开始提取.");
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
if (module == null) return;
var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
var itemList = items.Where(t => t.ModuleId == module.Id);
logger.LogInformation($"item有{itemList?.Count() ?? 0}个.");
if (itemList == null || !itemList.Any()) return;
WriteWorkHeader(sheet, sheetRead, itemList, isNewTemp);
logger.LogInformation($"{sheet.SheetName}开始写入列头系数.");
WriteWorkHeader(sheet, sheetRead, itemList.ToList(), isNewTemp);
var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
var extractdata = data.Where(t => t.SheetName == module.ModuleName);
logger.LogInformation($"data有{extractdata?.Count() ?? 0}个.");
if (extractdata == null || !extractdata.Any())
return;
//查询数据
List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
{
Department = t.Department,
Category = t.Category,
Value = t.Fee ?? 0
}).ToList();
var specialHead = new List<string>();
var extractHead = allExtract?.Select(t => t.Category);
var extractHead = extractdata?.Select(t => t.Category);
if (extractHead != null && extractHead.Any())
{
specialHead = itemList.Select(t => t.ItemName).Intersect(extractHead.Distinct())?.ToList();
}
specialHead = itemList.Select(t => t.ItemName).Intersect(extractHead.Distinct())?.ToList(); // 有数据的列添加样式
logManageService.WriteMsg("提取绩效数据", $"填充数据 -- {module.ModuleName}", 1, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 填充数据 -- {module.ModuleName}");
//写入数据
WriteWorkData(sheet, sheetRead, unitList, allExtract, specialHead, isNewTemp);
logger.LogInformation($"{sheet.SheetName}提取结束.");
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
WriteWorkData(sheet, sheetRead, extractdata.ToList(), specialHead, isNewTemp);
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
#region WriteAccountBasic
//private void WriteAccountBasic(ISheet sheet, IPerSheetDataRead sheetRead, int allotLastId)
//{
// var dictionary = new Dictionary<string, Func<im_accountbasic, object>>
// {
// { "核算单元类型", (t) => t.UnitType },
// { "核算单元", (t) => t.DoctorAccountingUnit },
// { "科室名称", (t) => t.Department },
// { "科主任/护士长人数", (t) => t.DoctorDirectorNumber },
// { "核算单元人员数量", (t) => t.DoctorNumber },
// { "预算比例", (t) => t.DoctorBasicFactor },
// { "倾斜系数", (t) => t.DoctorSlopeFactor },
// { "工作量倾斜系数", (t) => t.WorkSlopeFactor },
// { "保底绩效参考标准", (t) => t.MinimumReference },
// { "保底绩效系数", (t) => t.MinimumFactor },
// { "其他绩效1", (t) => t.DoctorOtherPerfor1 },
// { "考核得分率", (t) => t.DoctorScoringAverage },
// { "医院奖罚", (t) => t.DoctorExtra },
// { "其他绩效2", (t) => t.DoctorOtherPerfor2 },
// { "调节系数", (t) => t.DoctorAdjustFactor },
// };
// logManageService.WriteMsg("提取绩效数据", $"填充数据 -- 临床科室医护绩效测算表", 1, Allot.ID, "ReceiveMessage");
// logger.Information($"填充数据 -- 临床科室医护绩效测算表", "提取绩效数据");
// var dataList = perforImaccountbasicRepository.GetEntities(t => t.AllotID == allotLastId)?.OrderBy(t => t.UnitType).ThenBy(t => t.DoctorAccountingUnit).ToList();
// for (int i = 0; i < dataList.Count; i++)
// {
// var headIndex = sheetRead.Point.HeaderFirstRowNum;
// var cellList = sheet.GetRow(headIndex.Value).Cells;
// var rowIndex = sheetRead.Point.DataFirstRowNum.Value + i;
// var importRow = sheet.CreateRow(rowIndex);
// foreach (var cell in cellList)
// {
// var item = dictionary.FirstOrDefault(t => t.Key == cell.StringCellValue);
// var value = item.Value.Invoke(dataList[i]) ?? "";
// if (cell.StringCellValue == "核算单元类型")
// {
// value = value.ToString() == "1" ? "医生组" : value.ToString() == "2" ? "护理组" : "医技组";
// }
// var newCell = importRow.CreateCell(cell.ColumnIndex);
// OutToExcelCell(newCell, value);
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// }
//}
#endregion
private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<sys_hospitalconfig> configs, List<ex_special> specials, List<ex_result> data, bool IsWriteHead = true, per_allot lastAllot = null)
private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_special> specials, List<NewExtractDto> data, per_allot lastAllot = null, bool IsWriteHead = true)
{
logger.LogInformation($"{sheet.SheetName}开始提取.");
logger.LogInformation($"{sheet.SheetName}开始执行写入.");
var dictionary = new Dictionary<string, Func<ex_special, List<im_specialunit>, object>>
{
{ "科室", (special,lastallot) => special.Department },
......@@ -822,10 +1173,10 @@ private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<sy
int mergedBegin = sheetRead.Point.DataFirstRowNum.Value;
int mergedEnd = sheetRead.Point.DataFirstRowNum.Value;
var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == "4.2 特殊核算单元绩效测算表");
var extractdata = data.Where(t => t.SheetName == specialname).ToList();
logger.LogInformation($"data有{extractdata?.Count ?? 0}个.");
logManageService.WriteMsg("提取绩效数据", $"填充数据 -- 特殊核算单元绩效测算表", 1, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 填充数据 -- 特殊核算单元绩效测算表");
logger.LogInformation($"{sheet.SheetName}开始写入数据.");
for (int i = 0; i < speaialList.Count; i++)
{
var headIndex = sheetRead.Point.HeaderFirstRowNum;
......@@ -852,7 +1203,7 @@ private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<sy
}
if (cell.StringCellValue == "数量" && speaialList[i]?.TypeId > 0)
{
value = extractdata?.FirstOrDefault(t => t.Category == speaialList[i].Target)?.Fee;
value = extractdata?.FirstOrDefault(t => t.Category == speaialList[i].Target)?.Value;
}
if (!new List<string> { "量化指标", "数量", "量化指标绩效分值" }.Contains(cell.StringCellValue) && rowIndex == mergedBegin)
......@@ -871,7 +1222,7 @@ private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<sy
}
mergedBegin = mergedEnd + 1;
}
logger.LogInformation($"{sheet.SheetName}提取结束.");
logger.LogInformation($"{sheet.SheetName}写入结束.");
}
#region 写入数据
......@@ -889,7 +1240,6 @@ private void WriteHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, Lis
var technicianFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医技组").FactorRow.Value);
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
logManageService.WriteMsg("提取绩效数据", $"写入列头信息 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 提取绩效数据 写入列头信息 -- {sheet.SheetName}");
var cellItems = new List<ex_item>();
......@@ -935,69 +1285,6 @@ private void WriteHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, Lis
#endregion
}
/// <summary>
/// 写入列头
/// </summary>
/// <param name="sheet"></param>
/// <param name="sheetRead"></param>
/// <param name="items">列头数据(列名、系数)</param>
/// <param name="isNewTemp">是否为空白模板</param>
private void WriteIncomeHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, List<string> items, bool isNewTemp)
{
var nurseFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "护理组").FactorRow.Value);
var doctorFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医生组").FactorRow.Value);
var technicianFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医技组").FactorRow.Value);
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
logManageService.WriteMsg("提取绩效数据", $"写入列头信息 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 提取绩效数据 写入列头信息 -- {sheet.SheetName}");
logger.LogInformation($"{sheet.SheetName}查询出的列头有:" + string.Join(", ", items));
if (!isNewTemp)
{
List<string> original = new List<string>();
#region 过滤历史模板中已有的列头
//写入列头信息
int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 4;
for (int i = cellStartIndex; i < head.LastCellNum; i++)
{
var cellvalue = head.GetCell(i)?.ToString();
if (string.IsNullOrEmpty(cellvalue)) continue;
items.Remove(cellvalue);
}
#endregion
}
if (items == null || !items.Any()) return;
logger.LogInformation($"{sheet.SheetName}需要新增的列头有:" + string.Join(", ", items));
#region 新增模板中不存在的列头
var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 4 : head.LastCellNum;
foreach (var item in items)
{
var headcell = GetOrCreate(head, lastcellIndex);
headcell.SetCellValue(item);
headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
var doctorcell = GetOrCreate(doctorFactor, lastcellIndex);
doctorcell.SetCellValue(0);
doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
var nursecell = GetOrCreate(nurseFactor, lastcellIndex);
nursecell.SetCellValue(0);
nursecell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
var techniciancell = GetOrCreate(technicianFactor, lastcellIndex);
techniciancell.SetCellValue(0);
techniciancell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
lastcellIndex++;
}
#endregion
}
/// <summary>
/// 写入数据
/// </summary>
......@@ -1008,9 +1295,8 @@ private void WriteIncomeHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRea
/// <param name="header">设定抽取的列头</param>
/// <param name="isNewTemp">是否为空白模板</param>
/// <param name="isIncom">是否是开单、执行收入</param>
private void WriteSheetData(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<ExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp, bool isIncom = false)
private void WriteSheetData(ISheet sheet, IPerSheetDataRead sheetRead, List<NewExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp, bool isIncom = false)
{
logManageService.WriteMsg("提取绩效数据", $"填充数据 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
logger.LogInformation($"提取绩效数据 填充数据 -- {sheet.SheetName}");
//写入数据
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
......@@ -1064,47 +1350,56 @@ private void WriteSheetData(ISheet sheet, IPerSheetDataRead sheetRead, List<Acco
foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
{
var row = sheet.CreateRow(lastrowIndex);
for (int i = head.FirstCellNum; i < head.LastCellNum; i++)
for (int i = head.FirstCellNum + 3; i < head.LastCellNum; i++)
{
var headName = head.GetCell(i).StringCellValue;
var newCell = row.CreateCell(i);
if (headName.Replace("\n", "") == "核算单元(医生组)")
{
var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 1)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 1)?.AccountingUnit;
newCell.SetCellValue(dept ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName.Replace("\n", "") == "核算单元(护理组)")
{
var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 2)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 2)?.AccountingUnit;
newCell.SetCellValue(dept ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName.Replace("\n", "") == "核算单元(医技组)")
{
var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 3)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 3)?.AccountingUnit;
newCell.SetCellValue(dept ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName == "科室名称")
var celldata = allExtract.FirstOrDefault(t => t.Department == department);
if (headName == "科室名称")
{
newCell.SetCellValue(department ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
else if (celldata != null)
{
var value = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName)?.Value;
if (isIncom)
if (headName.Replace("\n", "") == "核算单元(医生组)")
{
var accounting = HasValue(celldata.OutDoctorAccounting, celldata.InpatDoctorAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatDoctorAccounting, celldata.OutDoctorAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName.Replace("\n", "") == "核算单元(护理组)")
{
value = value == 0 ? null : value;
OutToExcelCell(newCell, value);
newCell.CellStyle = style;
var accounting = HasValue(celldata.OutNurseAccounting, celldata.InpatNurseAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatNurseAccounting, celldata.OutNurseAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (header != null && header.Contains(headName))
else if (headName.Replace("\n", "") == "核算单元(医技组)")
{
value = value == 0 ? null : value;
OutToExcelCell(newCell, value);
newCell.CellStyle = style;
var accounting = HasValue(celldata.OutTechnicAccounting, celldata.InpatTechnicAccounting);
if (sheet.SheetName.IndexOf("住院") > -1)
accounting = HasValue(celldata.InpatTechnicAccounting, celldata.OutTechnicAccounting);
newCell.SetCellValue(accounting ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
{
celldata = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
if (isIncom)
{
OutToExcelCell(newCell, celldata?.Value);
newCell.CellStyle = style;
}
else if (header != null && header.Contains(headName))
{
OutToExcelCell(newCell, celldata?.Value);
newCell.CellStyle = style;
}
}
}
}
......@@ -1169,7 +1464,7 @@ private void WriteWorkHeader(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_
/// <param name="allExtract"></param>
/// <param name="header"></param>
/// <param name="isNewTemp"></param>
private void WriteWorkData(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<ExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp)
private void WriteWorkData(ISheet sheet, IPerSheetDataRead sheetRead, List<NewExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp)
{
var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
var rowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 2;
......@@ -1210,39 +1505,53 @@ private void WriteWorkData(ISheet sheet, IPerSheetDataRead sheetRead, List<Accou
if (allExtract == null || !allExtract.Any()) return;
//var unit = sheet.SheetName.IndexOf("医生") > -1 ? new int[] { (int)UnitType.医生组, (int)UnitType.医技组 } : new int[] { (int)UnitType.护理组 };
#region 补充新的科室及数据
var lastrowIndex = isNewTemp ? rowIndex : sheet.LastRowNum + 1;
foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
{
var row = sheet.CreateRow(lastrowIndex);
for (int i = head.FirstCellNum; i < head.LastCellNum; i++)
for (int i = head.FirstCellNum + 1; i < head.LastCellNum; i++)
{
var headName = head.GetCell(i).StringCellValue;
var newCell = row.CreateCell(i);
if (headName == "核算单元")
var celldata = allExtract.FirstOrDefault(t => t.Department == department);
if (headName == "科室名称")
{
var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department)?.AccountingUnit;
newCell.SetCellValue(dept ?? "");
newCell.SetCellValue(department);
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else if (headName == "科室名称")
else if (celldata != null)
{
newCell.SetCellValue(department ?? "");
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
{
var extract = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
var value = extract?.Value == 0 ? null : extract?.Value;
OutToExcelCell(newCell, value);
if (header != null && header.Contains(headName))
newCell.CellStyle = style;
if (headName == "核算单元")
{
var accounting = sheet.SheetName.IndexOf("医生") > -1
? HasValue(celldata.OutDoctorAccounting, celldata.InpatDoctorAccounting, celldata.OutTechnicAccounting, celldata.InpatTechnicAccounting)
: (celldata.OutNurseAccounting ?? celldata.InpatNurseAccounting);
newCell.SetCellValue(accounting);
newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
}
else
{
var extract = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
OutToExcelCell(newCell, extract?.Value);
if (header != null && header.Contains(headName))
newCell.CellStyle = style;
}
}
}
lastrowIndex++;
}
#endregion
}
private string HasValue(params string[] list)
{
if (list == null || !list.Any()) return null;
return list.FirstOrDefault(t => !string.IsNullOrEmpty(t));
}
#endregion
#endregion
......@@ -1388,4 +1697,27 @@ public string Judge(int allotId, int hospitalId, int useTemplate, out string fil
}
#endregion
}
public class AccountBasic
{
public string UnitType { get; set; }
public string Department { get; set; }
public string AccountingUnit { get; set; }
public decimal? EfficiencyNumber { get; set; }
public decimal? DirectorNumber { get; set; }
public decimal? PermanentStaff { get; set; }
public int IsDelete { get; set; }
}
public class NewExtractDto : ExtractDto
{
public string SheetName { get; set; }
public string OutDoctorAccounting { get; set; }
public string OutNurseAccounting { get; set; }
public string OutTechnicAccounting { get; set; }
public string InpatDoctorAccounting { get; set; }
public string InpatNurseAccounting { get; set; }
public string InpatTechnicAccounting { get; set; }
public new decimal? Value { get; set; }
}
}
//using Dapper;
//using Microsoft.Extensions.Logging;
//using NPOI.SS.UserModel;
//using NPOI.SS.Util;
//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.RegularExpressions;
//namespace Performance.Services
//{
// public class DFExtractService : IAutoInjection
// {
// #region
// private readonly ILogger<DFExtractService> logger;
// private readonly IEmailService emailService;
// private readonly PerSheetService perSheetService;
// private readonly PerforHospitalRepository perforHospitalRepository;
// private readonly PerforHospitalconfigRepository perforHospitalconfigRepository;
// private readonly PerforPerallotRepository perforPerallotRepository;
// private readonly PerforImspecialunitRepository perforImspecialunitRepository;
// private readonly PerforImdataRepository perforImdataRepository;
// private readonly PerforRepimportconfigRepository repimportconfigRepository;
// private readonly LogManageService logManageService;
// private readonly PerforExitemRepository perforExitemRepository;
// private readonly PerforExmoduleRepository perforExmoduleRepository;
// private readonly PerforExspecialRepository perforExspecialRepository;
// private readonly PerforExresultRepository perforExresultRepository;
// private readonly PerforExscriptRepository perforExscriptRepository;
// private IWorkbook workbook = null;
// private ICellStyle style;
// private per_allot Allot;
// public DFExtractService(ILogger<DFExtractService> logger,
// IEmailService emailService,
// PerSheetService perSheetService,
// PerforHospitalRepository perforHospitalRepository,
// PerforHospitalconfigRepository perforHospitalconfigRepository,
// PerforPerallotRepository perforPerallotRepository,
// PerforImspecialunitRepository perforImspecialunitRepository,
// PerforImdataRepository perforImdataRepository,
// PerforRepimportconfigRepository repimportconfigRepository,
// LogManageService logManageService,
// PerforExitemRepository perforExitemRepository,
// PerforExmoduleRepository perforExmoduleRepository,
// PerforExspecialRepository perforExspecialRepository,
// PerforExresultRepository perforExresultRepository,
// PerforExscriptRepository perforExscriptRepository)
// {
// this.logger = logger;
// this.emailService = emailService;
// this.perSheetService = perSheetService;
// this.perforHospitalRepository = perforHospitalRepository;
// this.perforHospitalconfigRepository = perforHospitalconfigRepository;
// this.perforPerallotRepository = perforPerallotRepository;
// this.perforImspecialunitRepository = perforImspecialunitRepository;
// this.perforImdataRepository = perforImdataRepository;
// this.repimportconfigRepository = repimportconfigRepository;
// this.logManageService = logManageService;
// this.perforExitemRepository = perforExitemRepository;
// this.perforExmoduleRepository = perforExmoduleRepository;
// this.perforExspecialRepository = perforExspecialRepository;
// this.perforExresultRepository = perforExresultRepository;
// this.perforExscriptRepository = perforExscriptRepository;
// }
// #endregion
// #region 抽取
// public string ExtractData(int allotId, string email, int hospitalId, string filePath = null)
// {
// var hospital = perforHospitalRepository.GetEntity(t => t.ID == hospitalId);
// try
// {
// var allot = perforPerallotRepository.GetEntity(t => t.ID == allotId);
// Allot = allot ?? throw new PerformanceException("");
// var statesArray = new int[] { (int)AllotStates.GenerateSucceed, (int)AllotStates.Archive };
// var allots = perforPerallotRepository.GetEntities(t => t.HospitalId == hospitalId && statesArray.Contains(t.States));
// var lastAllot = allots?.OrderByDescending(t => t.Year).ThenByDescending(t => t.Month).First();
// var configs = perforHospitalconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
// var typeIds = new List<int>();
// var modules = perforExmoduleRepository.GetEntities(t => t.HospitalId == hospitalId);
// var items = new List<ex_item>();
// if (modules != null && modules.Any())
// {
// typeIds.AddRange(modules.Select(t => t.TypeId ?? 0));
// items = perforExitemRepository.GetEntities(t => t.ModuleId.HasValue
// && modules.Select(m => m.Id).Contains(t.ModuleId.Value));
// typeIds.AddRange(items?.Select(t => t.TypeId ?? 0) ?? new List<int>());
// }
// var specials = perforExspecialRepository.GetEntities(t => t.HospitalId == hospitalId);
// if (specials != null && specials.Any())
// typeIds.AddRange(specials.Select(t => t.TypeId ?? 0));
// typeIds = typeIds.Distinct().ToList();
// var data = new List<ex_result>();
// var scripts = perforExscriptRepository.GetEntities(t => typeIds.Contains(t.TypeId));
// ClearHistData(allot);
// var otherItems = items.Where(t => modules.Where(m => m.SheetType != (int)SheetType.Income).Select(m => m.Id).Contains(t.ModuleId.Value)).ToList();
// if (scripts != null && scripts.Any())
// {
// data.AddRange(ExtractIncome(modules, scripts, configs, allot));
// data.AddRange(ExtractItems(otherItems, scripts, configs, allot, modules));
// data.AddRange(ExtractSpcial(specials, scripts, configs, allot));
// }
// return lastAllot == null ? TemplateExecute(email, hospital, configs, modules, items, specials, data)
// : AlllotExecute(email, hospital, configs, modules, items, specials, data, lastAllot, filePath);
// }
// catch (Exception ex)
// {
// logManageService.WriteMsg("提取数据异常", $"数据写入出现异常", 4, Allot.ID, "ReceiveMessage");
// logger.LogError($"提取绩效数据异常 数据写入出现异常{ex.ToString()}");
// //SendEmail(email, "", $"{hospital.HosName}HIS数据提取失败", $"{hospital.HosName}提取数据过程中出现异常情况,我们将尽快解决问题。给您带来的不便我们深感歉意!");
// throw ex;
// }
// finally
// {
// Allot.IsExtracting = null;
// perforPerallotRepository.Update(Allot);
// if (workbook != null)
// workbook.Close();
// GC.Collect();
// }
// }
// /// <summary>
// /// 抽取收入费用
// /// </summary>
// /// <typeparam name="TEntity">ex_module</typeparam>
// /// <param name="entities"></param>
// /// <param name="scripts">抽取配置项</param>
// /// <param name="configs">数据连接项</param>
// /// <param name="allot">绩效</param>
// /// <returns></returns>
// private List<ex_result> ExtractIncome<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot)
// {
// var data = new List<ex_result>();
// var modules = entities as List<ex_module>;
// if (modules == null || !modules.Any(t => t.SheetType == (int)SheetType.Income && t.TypeId > 0))
// return data;
// foreach (var module in modules.Where(t => t.TypeId > 0))
// {
// foreach (var config in configs)
// {
// var item = scripts.FirstOrDefault(t => t.TypeId == module.TypeId && t.DatabaseType == config.DataBaseType);
// if (item == null) continue;
// data.AddRange(QueryData(config, allot, item.ExecScript, module.ModuleName));
// }
// }
// if (data != null && data.Any())
// perforExresultRepository.AddRange(data.ToArray());
// return data;
// }
// /// <summary>
// /// 抽取支出、工作量等费用
// /// </summary>
// /// <typeparam name="TEntity"></typeparam>
// /// <param name="entities"></param>
// /// <param name="scripts"></param>
// /// <param name="configs"></param>
// /// <param name="allot"></param>
// /// <param name="modules"></param>
// /// <returns></returns>
// private List<ex_result> ExtractItems<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot, List<ex_module> modules)
// {
// var data = new List<ex_result>();
// var items = entities as List<ex_item>;
// if (items == null || !items.Any(t => t.TypeId > 0))
// return data;
// foreach (var exitem in items.Where(t => t.TypeId > 0))
// {
// var module = modules.FirstOrDefault(t => t.Id == exitem.ModuleId);
// foreach (var config in configs)
// {
// var item = scripts.FirstOrDefault(t => t.TypeId == exitem.TypeId && t.DatabaseType == config.DataBaseType);
// if (item == null) continue;
// var result = QueryData(config, allot, item.ExecScript, module.ModuleName);
// result.ForEach(t => t.Category = exitem.ItemName);
// data.AddRange(result);
// }
// }
// if (data != null && data.Any())
// perforExresultRepository.AddRange(data.ToArray());
// return data;
// }
// /// <summary>
// /// 抽取特殊科室数据
// /// </summary>
// /// <typeparam name="TEntity"></typeparam>
// /// <param name="entities"></param>
// /// <param name="scripts"></param>
// /// <param name="configs"></param>
// /// <param name="allot"></param>
// /// <returns></returns>
// private List<ex_result> ExtractSpcial<TEntity>(List<TEntity> entities, List<ex_script> scripts, List<sys_hospitalconfig> configs, per_allot allot)
// {
// var data = new List<ex_result>();
// var specials = entities as List<ex_special>;
// if (specials == null || !specials.Any(t => t.TypeId > 0))
// return data;
// foreach (var special in specials.Where(t => t.TypeId > 0))
// {
// foreach (var config in configs)
// {
// var item = scripts.FirstOrDefault(t => t.TypeId == special.TypeId && t.DatabaseType == config.DataBaseType);
// if (item == null) continue;
// var result = QueryData(config, allot, item.ExecScript, "4.2 特殊核算单元绩效测算表");
// result.ForEach(t =>
// {
// t.Category = special.Target;
// t.Department = special.Department;
// });
// data.AddRange(result);
// }
// }
// if (data != null && data.Any())
// perforExresultRepository.AddRange(data.ToArray());
// return data;
// }
// /// <summary>
// /// 清除历史抽取数据
// /// </summary>
// /// <param name="allot"></param>
// private void ClearHistData(per_allot allot)
// {
// logger.LogInformation($"开始清除历史提取数据");
// var data = perforExresultRepository.GetEntities(t => t.AllotId == allot.ID);
// if (data == null || !data.Any(t => t.Id > 0))
// return;
// perforExresultRepository.RemoveRange(data.ToArray());
// }
// /// <summary>
// /// 空白模板
// /// </summary>
// /// <param name="email"></param>
// /// <param name="lastAllot"></param>
// /// <param name="hospital"></param>
// /// <param name="configs"></param>
// /// <param name="modules"></param>
// /// <param name="items"></param>
// /// <param name="specials"></param>
// /// <param name="extracts"></param>
// /// <returns></returns>
// public string TemplateExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<ex_result> data)
// {
// string originalPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Template", "医院绩效模板.xlsx");
// var (tempPath, newPath) = CopyOriginalFile(hospital.ID, originalPath);
// workbook = new XSSFWorkbook(tempPath);
// CreateNotExistSheet(modules, workbook);
// style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
// List<AccountUnitEntity> unitList = new List<AccountUnitEntity>();
// for (int i = 0; i < workbook.NumberOfSheets; i++)
// {
// var sheet = workbook.GetSheetAt(i);
// var sheetType = perSheetService.GetSheetType(sheet.SheetName);
// if (sheetType == SheetType.Unidentifiable) continue;
// var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
// switch (sheetType)
// {
// case SheetType.OtherIncome:
// WriteOtherIncome(sheet, sheetRead, unitList, configs, modules, items, data);
// break;
// case SheetType.Income:
// WriteIncome(sheet, sheetRead, unitList, configs, modules, items, data);
// break;
// case SheetType.Expend:
// WriteExpend(sheet, sheetRead, unitList, configs, modules, items, data);
// break;
// case SheetType.Workload:
// WriteWorkload(sheet, sheetRead, unitList, configs, modules, items, data);
// break;
// case SheetType.SpecialUnit:
// WriteSpecialUnit(sheet, sheetRead, configs, specials, data);
// break;
// }
// }
// using (FileStream file = new FileStream(newPath, FileMode.OpenOrCreate))
// {
// workbook.Write(file);
// }
// logManageService.WriteMsg("提取绩效数据", $"{hospital.HosName}HIS数据提取成功,文件路径:{newPath}。", 5, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
// ImportData(Allot, configs);
// SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}在{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
// return newPath;
// }
// /// <summary>
// /// 历史绩效为模板
// /// </summary>
// /// <param name="email"></param>
// /// <param name="lastAllot"></param>
// /// <param name="hospital"></param>
// /// <param name="configs"></param>
// /// <param name="modules"></param>
// /// <param name="items"></param>
// /// <param name="specials"></param>
// /// <param name="extracts"></param>
// /// <returns></returns>
// public string AlllotExecute(string email, sys_hospital hospital, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_special> specials, List<ex_result> extracts, per_allot lastAllot, string path)
// {
// if (string.IsNullOrEmpty(path)) throw new PerformanceException("历史绩效文件不存在!");
// var (tempPath, newPath) = CopyOriginalFile(hospital.ID, path);
// workbook = new XSSFWorkbook(tempPath);
// CreateNotExistSheet(modules, workbook);
// style = CellStyle.CreateCellStyle(workbook, StyleType.数据);
// List<AccountUnitEntity> unitList = new List<AccountUnitEntity>();
// if (lastAllot != null)
// {
// unitList = perforImdataRepository.GetAccountUnit(lastAllot.ID).ToList();
// logger.LogInformation($"lastAllot.ID: {lastAllot.ID}, lastAllot date: {lastAllot.Year}-{lastAllot.Month}, unitList count: {unitList?.Count ?? 0}");
// }
// for (int i = 0; i < workbook.NumberOfSheets; i++)
// {
// var sheet = workbook.GetSheetAt(i);
// var sheetType = perSheetService.GetSheetType(sheet.SheetName);
// var sheetRead = PerSheetDataFactory.GetDataRead(sheetType);
// switch (sheetType)
// {
// case SheetType.OtherIncome:
// ClearData(sheet, 5, 7);
// WriteOtherIncome(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
// break;
// case SheetType.Income:
// ClearData(sheet, 5, 7, true);
// WriteIncome(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
// break;
// case SheetType.Expend:
// ClearData(sheet, 5, 7);
// WriteExpend(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
// break;
// case SheetType.Workload:
// ClearData(sheet, 3, 3);
// WriteWorkload(sheet, sheetRead, unitList, configs, modules, items, extracts, false);
// break;
// case SheetType.SpecialUnit:
// ClearData(sheet, 2, 0);
// WriteSpecialUnit(sheet, sheetRead, configs, specials, extracts, false, lastAllot);
// break;
// }
// }
// using (FileStream file = new FileStream(newPath, FileMode.OpenOrCreate))
// {
// workbook.Write(file);
// }
// logManageService.WriteMsg("提取绩效数据", $"{hospital.HosName}HIS数据提取成功,文件路径:{newPath}。", 5, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 {hospital.HosName}HIS数据提取成功,文件路径:{newPath}。");
// ImportData(Allot, configs);
// SendEmail(email, newPath, $"{hospital.HosName}HIS数据提取成功", $"{hospital.HosName}在{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}成功提取。");
// return newPath;
// }
// #endregion
// #region QueryData
// /// <summary>
// /// 查询数据
// /// </summary>
// /// <param name="config"></param>
// /// <param name="allot"></param>
// /// <param name="execsql"></param>
// /// <param name="source"></param>
// /// <param name="category"></param>
// /// <returns></returns>
// private List<ex_result> QueryData(sys_hospitalconfig config, per_allot allot, string execsql, string source, string category = "")
// {
// var data = new List<ex_result>();
// 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);
// }
// logger.LogInformation($"提取绩效数据 {category ?? ""}SQL脚本{execsql}");
// var result = connection.Query<ExtractDto>(execsql, commandTimeout: 20000);
// logger.LogInformation($"提取绩效数据 {category ?? ""} 执行脚本获取数据{result?.Count() ?? 0}条记录");
// if (result != null && result.Count() > 0)
// {
// data = result.Select(t => new ex_result
// {
// Department = t.Department,
// Category = t.Category?.Trim(),
// Fee = t.Value,
// Source = source,
// DatabaseType = config.DataBaseType,
// ConfigId = config.Id,
// AllotId = allot.ID,
// }).ToList();
// }
// return data;
// }
// }
// /// <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>
// /// 从HIS抽取报表数据
// /// </summary>
// /// <param name="allot"></param>
// /// <param name="configs"></param>
// public void ImportData(per_allot allot, List<sys_hospitalconfig> configs)
// {
// Dictionary<string, object> pairs = new Dictionary<string, object>
// {
// { "@allotid", allot.ID },
// { "@hospitalid", allot.HospitalId },
// { "@year", allot.Year },
// { "@month", allot.Month },
// };
// var imports = repimportconfigRepository.GetEntities(w => w.ScriptType == 1);
// if (imports == null || !imports.Any()) return;
// foreach (var import in imports)
// {
// var conf = configs.FirstOrDefault(w => w.HospitalId == allot.HospitalId && w.Id == import.ConfigId);
// if (conf != null)
// {
// var timeRanges = import.TimeRange.SplitRemoveEmpty(",");
// if (timeRanges == null || !timeRanges.Any()) continue;
// foreach (var item in timeRanges)
// {
// if (item == "1")
// {
// pairs["@year"] = allot.Year;
// pairs["@month"] = allot.Month;
// }
// else if (item == "2")
// {
// pairs["@year"] = allot.Year - 1;
// pairs["@month"] = allot.Month;
// }
// else if (item == "3")
// {
// pairs["@year"] = allot.Year;
// pairs["@month"] = allot.Month - 1;
// }
// try
// {
// DatabaseType type = (DatabaseType)conf.DataBaseType;
// var connection = ConnectionBuilder.Create(type, conf.DbSource, conf.DbName, conf.DbUser, conf.DbPassword);
// var data = connection.Query(import.ImportScript, new DynamicParameters(pairs), commandTimeout: 60 * 60);
// perforPerallotRepository.ImportData(import, pairs, data);
// }
// catch (Exception ex)
// {
// logger.LogError(ex.ToString());
// }
// }
// }
// }
// }
// #endregion
// #region Excel
// private (string TempPath, string NewPath) CopyOriginalFile(int hospitalId, string originalPath)
// {
// var dpath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files", $"{hospitalId}", "autoextract");
// FileHelper.CreateDirectory(dpath);
// string tempPath = Path.Combine(dpath, $"Template{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx");
// FileHelper.Copy(originalPath, tempPath);
// string newPath = Path.Combine(dpath, $"绩效提取数据{DateTime.Now.ToString("yyyyMMddHHmmssfff")}.xlsx");
// return (tempPath, newPath);
// }
// private static void CreateNotExistSheet(List<ex_module> modulesList, IWorkbook workbook)
// {
// SortedDictionary<string, int> pairs = new SortedDictionary<string, int>();
// for (int i = 0; i < workbook.NumberOfSheets; i++)
// {
// pairs.Add(workbook.GetSheetAt(i).SheetName, i);
// }
// int sheetIndex = 0;
// foreach (var module in modulesList.Where(t => t.SheetType == (int)SheetType.Income)?.OrderBy(t => t.ModuleName))
// {
// var sheet = workbook.GetSheet(module.ModuleName);
// if (sheet == null)
// {
// string[] keyArray = new string[] { "开单", "执行" };
// if (keyArray.Any(key => module.ModuleName.Contains(key)))
// {
// var item = pairs.Where(t => t.Key.StartsWith("1.")).OrderByDescending(t => t.Key).First();
// if (sheetIndex == 0)
// sheetIndex = item.Value + 1;
// var copysheet = workbook.GetSheet(item.Key);
// var newSheet = copysheet.CopySheet(item.Key, true);
// workbook.SetSheetOrder(newSheet.SheetName, sheetIndex);
// workbook.SetSheetName(sheetIndex, module.ModuleName);
// sheetIndex++;
// }
// }
// }
// }
// private void ClearData(ISheet sheet, int beginRowNum, int beginCellNum, bool isIncome = false)
// {
// if (sheet == null)
// return;
// for (int i = beginRowNum; i < sheet.LastRowNum + 1; i++)
// {
// var row = sheet.GetRow(i);
// if (row != null)
// {
// //跳过核算单元和科室
// for (int j = beginCellNum; j < row.LastCellNum; j++)
// {
// var cell = row.GetCell(j);
// if (cell != null && (cell.CellType != CellType.Formula || isIncome))
// {
// cell.RemoveCellComment();
// row.RemoveCell(cell);
// }
// }
// }
// }
// sheet.ForceFormulaRecalculation = true;
// }
// private IRow GetOrCreate(ISheet sheet, int index)
// {
// var row = sheet.GetRow(index);
// if (row == null)
// row = sheet.CreateRow(index);
// return row;
// }
// private ICell GetOrCreate(IRow row, int index)
// {
// var cell = row.GetCell(index);
// if (cell == null)
// cell = row.CreateCell(index);
// //cell.CellStyle.FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Orange.Index;
// return cell;
// }
// #endregion
// #region SheetData
// private void WriteOtherIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
// {
// logger.LogInformation($"{sheet.SheetName}开始提取.");
// var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.OtherIncome);
// if (module == null) return;
// var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
// logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
// if (itemList == null || !itemList.Any()) return;
// WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
// var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
// if (extractdata == null || !extractdata.Any())
// return;
// //查询数据
// List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
// {
// Department = t.Department,
// Category = t.Category,
// Value = t.Fee ?? 0
// }).ToList();
// WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp);
// logger.LogInformation($"{sheet.SheetName}提取结束.");
// }
// private void WriteIncome(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
// {
// logger.LogInformation($"{sheet.SheetName}开始提取.");
// var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
// if (module == null) return;
// var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
// logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
// //if (itemList == null || !itemList.Any()) return;
// var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
// if (extractdata == null || !extractdata.Any())
// return;
// //查询数据
// List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
// {
// Department = t.Department,
// Category = t.Category,
// Value = t.Fee ?? 0
// }).ToList();
// //logger.LogInformation($"{sheet.SheetName}合计值为: " + allExtract.Sum(t => t.Value));
// var category = allExtract.Select(t => t.Category?.Trim()).Distinct().ToList();
// var existHead = category.Except(itemList.Select(i => i.ItemName?.Trim()));
// if (existHead != null && existHead.Any())
// itemList.AddRange(existHead.Select(t => new ex_item
// {
// ItemName = t,
// }));
// WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
// //WriteIncomeHeaderAndFactor(sheet, sheetRead, category, isNewTemp);
// WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp, true);
// logger.LogInformation($"{sheet.SheetName}提取结束.");
// }
// private void WriteExpend(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
// {
// logger.LogInformation($"{sheet.SheetName}开始提取.");
// var module = modules.FirstOrDefault(t => t.SheetType == (int)SheetType.Expend);
// if (module == null) return;
// var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
// logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
// if (itemList == null || !itemList.Any()) return;
// WriteHeaderAndFactor(sheet, sheetRead, itemList, isNewTemp);
// var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
// if (extractdata == null || !extractdata.Any())
// return;
// //查询数据
// List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
// {
// Department = t.Department,
// Category = t.Category,
// Value = t.Fee ?? 0
// }).ToList();
// WriteSheetData(sheet, sheetRead, unitList, allExtract, itemList.Select(t => t.ItemName), isNewTemp);
// logger.LogInformation($"{sheet.SheetName}提取结束.");
// }
// private void WriteWorkload(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<sys_hospitalconfig> configs, List<ex_module> modules, List<ex_item> items, List<ex_result> data, bool isNewTemp = true)
// {
// logger.LogInformation($"{sheet.SheetName}开始提取.");
// var module = modules.FirstOrDefault(t => t.ModuleName.Replace(" ", "") == sheet.SheetName.Replace(" ", ""));
// if (module == null) return;
// var itemList = items.Where(t => t.ModuleId == module.Id).ToList();
// logger.LogInformation($"item有{itemList?.Count ?? 0}个.");
// if (itemList == null || !itemList.Any()) return;
// WriteWorkHeader(sheet, sheetRead, itemList, isNewTemp);
// var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == module.ModuleName);
// if (extractdata == null || !extractdata.Any())
// return;
// //查询数据
// List<ExtractDto> allExtract = extractdata.Select(t => new ExtractDto
// {
// Department = t.Department,
// Category = t.Category,
// Value = t.Fee ?? 0
// }).ToList();
// var specialHead = new List<string>();
// var extractHead = allExtract?.Select(t => t.Category);
// if (extractHead != null && extractHead.Any())
// {
// specialHead = itemList.Select(t => t.ItemName).Intersect(extractHead.Distinct())?.ToList();
// }
// logManageService.WriteMsg("提取绩效数据", $"填充数据 -- {module.ModuleName}", 1, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 填充数据 -- {module.ModuleName}");
// //写入数据
// WriteWorkData(sheet, sheetRead, unitList, allExtract, specialHead, isNewTemp);
// logger.LogInformation($"{sheet.SheetName}提取结束.");
// }
// #region WriteAccountBasic
// //private void WriteAccountBasic(ISheet sheet, IPerSheetDataRead sheetRead, int allotLastId)
// //{
// // var dictionary = new Dictionary<string, Func<im_accountbasic, object>>
// // {
// // { "核算单元类型", (t) => t.UnitType },
// // { "核算单元", (t) => t.DoctorAccountingUnit },
// // { "科室名称", (t) => t.Department },
// // { "科主任/护士长人数", (t) => t.DoctorDirectorNumber },
// // { "核算单元人员数量", (t) => t.DoctorNumber },
// // { "预算比例", (t) => t.DoctorBasicFactor },
// // { "倾斜系数", (t) => t.DoctorSlopeFactor },
// // { "工作量倾斜系数", (t) => t.WorkSlopeFactor },
// // { "保底绩效参考标准", (t) => t.MinimumReference },
// // { "保底绩效系数", (t) => t.MinimumFactor },
// // { "其他绩效1", (t) => t.DoctorOtherPerfor1 },
// // { "考核得分率", (t) => t.DoctorScoringAverage },
// // { "医院奖罚", (t) => t.DoctorExtra },
// // { "其他绩效2", (t) => t.DoctorOtherPerfor2 },
// // { "调节系数", (t) => t.DoctorAdjustFactor },
// // };
// // logManageService.WriteMsg("提取绩效数据", $"填充数据 -- 临床科室医护绩效测算表", 1, Allot.ID, "ReceiveMessage");
// // logger.Information($"填充数据 -- 临床科室医护绩效测算表", "提取绩效数据");
// // var dataList = perforImaccountbasicRepository.GetEntities(t => t.AllotID == allotLastId)?.OrderBy(t => t.UnitType).ThenBy(t => t.DoctorAccountingUnit).ToList();
// // for (int i = 0; i < dataList.Count; i++)
// // {
// // var headIndex = sheetRead.Point.HeaderFirstRowNum;
// // var cellList = sheet.GetRow(headIndex.Value).Cells;
// // var rowIndex = sheetRead.Point.DataFirstRowNum.Value + i;
// // var importRow = sheet.CreateRow(rowIndex);
// // foreach (var cell in cellList)
// // {
// // var item = dictionary.FirstOrDefault(t => t.Key == cell.StringCellValue);
// // var value = item.Value.Invoke(dataList[i]) ?? "";
// // if (cell.StringCellValue == "核算单元类型")
// // {
// // value = value.ToString() == "1" ? "医生组" : value.ToString() == "2" ? "护理组" : "医技组";
// // }
// // var newCell = importRow.CreateCell(cell.ColumnIndex);
// // OutToExcelCell(newCell, value);
// // newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// // }
// // }
// //}
// #endregion
// private void WriteSpecialUnit(ISheet sheet, IPerSheetDataRead sheetRead, List<sys_hospitalconfig> configs, List<ex_special> specials, List<ex_result> data, bool IsWriteHead = true, per_allot lastAllot = null)
// {
// logger.LogInformation($"{sheet.SheetName}开始提取.");
// var dictionary = new Dictionary<string, Func<ex_special, List<im_specialunit>, object>>
// {
// { "科室", (special,lastallot) => special.Department },
// { "人数", (special,lastallot) => lastallot.Where(t=>special.Department == t.Department).Max(t=>t.Number) },
// { "量化指标", (special,lastallot) => special.Target},
// { "量化指标绩效分值",(special,lastallot) => special.TargetFactor },
// { "调节系数", (special,lastallot) => special.AdjustFactor },
// };
// var speaialList = specials?.OrderBy(t => t.Department).ToList();
// logger.LogInformation($"item有{speaialList?.Count ?? 0}个.");
// if (speaialList == null || !speaialList.Any()) return;
// List<im_specialunit> allotDataList = new List<im_specialunit>();
// if (lastAllot != null)
// allotDataList = perforImspecialunitRepository.GetEntities(t => t.AllotID == lastAllot.ID);
// //取消合并单元格
// int mergedCount = sheet.NumMergedRegions;
// for (int i = mergedCount - 1; i >= 0; i--)
// {
// var temp = sheet.GetMergedRegion(i);
// if (temp.FirstRow > sheetRead.Point.HeaderFirstRowNum)
// sheet.RemoveMergedRegion(i);
// }
// var modDataGroup = speaialList.GroupBy(t => new { t.Department }).Select(group => new
// {
// Department = group.Key.Department,
// Count = group.Count()
// })?.OrderBy(t => t.Department);
// int mergedBegin = sheetRead.Point.DataFirstRowNum.Value;
// int mergedEnd = sheetRead.Point.DataFirstRowNum.Value;
// var extractdata = data.Where(t => t.AllotId == Allot.ID && t.Source == "4.2 特殊核算单元绩效测算表");
// logManageService.WriteMsg("提取绩效数据", $"填充数据 -- 特殊核算单元绩效测算表", 1, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 填充数据 -- 特殊核算单元绩效测算表");
// for (int i = 0; i < speaialList.Count; i++)
// {
// var headIndex = sheetRead.Point.HeaderFirstRowNum;
// var cellList = sheet.GetRow(headIndex.Value).Cells;
// var rowIndex = sheetRead.Point.DataFirstRowNum.Value + i;
// var importRow = sheet.CreateRow(rowIndex);
// int cellIndex = 0;
// foreach (var cell in cellList)
// {
// object value = null;
// if (dictionary.ContainsKey(cell.StringCellValue))
// {
// var item = dictionary.First(t => t.Key == cell.StringCellValue);
// value = item.Value.Invoke(speaialList[i], allotDataList) ?? "";
// if (item.Key == "科室" && rowIndex == mergedBegin)
// {
// var count = modDataGroup.First(t => t.Department.ToString() == value.ToString()).Count;
// mergedEnd = mergedBegin + count - 1;
// }
// }
// if (cell.StringCellValue == "数量" && speaialList[i]?.TypeId > 0)
// {
// value = extractdata?.FirstOrDefault(t => t.Category == speaialList[i].Target)?.Fee;
// }
// if (!new List<string> { "量化指标", "数量", "量化指标绩效分值" }.Contains(cell.StringCellValue) && rowIndex == mergedBegin)
// {
// CellRangeAddress region = new CellRangeAddress(mergedBegin, mergedEnd, cellIndex, cellIndex);
// sheet.AddMergedRegion(region); //合并单元格
// }
// var newCell = importRow.CreateCell(cellIndex);
// //newCell.SetCellValue(Verify(value));
// OutToExcelCell(newCell, value);
// if (dictionary.ContainsKey(cell.StringCellValue) || (cell.StringCellValue == "数量" && !string.IsNullOrEmpty(value?.ToString())))
// newCell.CellStyle = style;
// cellIndex++;
// }
// mergedBegin = mergedEnd + 1;
// }
// logger.LogInformation($"{sheet.SheetName}提取结束.");
// }
// #region 写入数据
// /// <summary>
// /// 写入列头
// /// </summary>
// /// <param name="sheet"></param>
// /// <param name="sheetRead"></param>
// /// <param name="items">列头数据(列名、系数)</param>
// /// <param name="isNewTemp">是否为空白模板</param>
// private void WriteHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_item> items, bool isNewTemp)
// {
// var nurseFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "护理组").FactorRow.Value);
// var doctorFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医生组").FactorRow.Value);
// var technicianFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医技组").FactorRow.Value);
// var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
// logManageService.WriteMsg("提取绩效数据", $"写入列头信息 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 提取绩效数据 写入列头信息 -- {sheet.SheetName}");
// var cellItems = new List<ex_item>();
// cellItems.AddRange(items);
// if (!isNewTemp)
// {
// List<string> original = new List<string>();
// #region 过滤历史模板中已有的列头
// //写入列头信息
// int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 4;
// for (int i = cellStartIndex; i < head.LastCellNum; i++)
// {
// var cellvalue = head.GetCell(i)?.ToString()?.Trim();
// if (string.IsNullOrEmpty(cellvalue)) continue;
// cellItems.RemoveAll(t => t.ItemName == cellvalue);
// }
// #endregion
// }
// if (cellItems == null || !cellItems.Any()) return;
// #region 新增模板中不存在的列头
// var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 4 : head.LastCellNum;
// foreach (var item in cellItems)
// {
// var headcell = GetOrCreate(head, lastcellIndex);
// headcell.SetCellValue(item.ItemName);
// headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
// var doctorcell = GetOrCreate(doctorFactor, lastcellIndex);
// doctorcell.SetCellValue(item.FactorValue1 != null ? (double)item.FactorValue1 : 0);
// doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// var nursecell = GetOrCreate(nurseFactor, lastcellIndex);
// nursecell.SetCellValue(item.FactorValue2 != null ? (double)item.FactorValue2 : 0);
// nursecell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// var techniciancell = GetOrCreate(technicianFactor, lastcellIndex);
// techniciancell.SetCellValue(item.FactorValue3 != null ? (double)item.FactorValue3 : 0);
// techniciancell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// lastcellIndex++;
// }
// #endregion
// }
// /// <summary>
// /// 写入列头
// /// </summary>
// /// <param name="sheet"></param>
// /// <param name="sheetRead"></param>
// /// <param name="items">列头数据(列名、系数)</param>
// /// <param name="isNewTemp">是否为空白模板</param>
// private void WriteIncomeHeaderAndFactor(ISheet sheet, IPerSheetDataRead sheetRead, List<string> items, bool isNewTemp)
// {
// var nurseFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "护理组").FactorRow.Value);
// var doctorFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医生组").FactorRow.Value);
// var technicianFactor = sheet.GetRow(sheetRead.Point.AccountingUnit.First(t => t.UnitType == "医技组").FactorRow.Value);
// var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
// logManageService.WriteMsg("提取绩效数据", $"写入列头信息 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 提取绩效数据 写入列头信息 -- {sheet.SheetName}");
// logger.LogInformation($"{sheet.SheetName}查询出的列头有:" + string.Join(", ", items));
// if (!isNewTemp)
// {
// List<string> original = new List<string>();
// #region 过滤历史模板中已有的列头
// //写入列头信息
// int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 4;
// for (int i = cellStartIndex; i < head.LastCellNum; i++)
// {
// var cellvalue = head.GetCell(i)?.ToString();
// if (string.IsNullOrEmpty(cellvalue)) continue;
// items.Remove(cellvalue);
// }
// #endregion
// }
// if (items == null || !items.Any()) return;
// logger.LogInformation($"{sheet.SheetName}需要新增的列头有:" + string.Join(", ", items));
// #region 新增模板中不存在的列头
// var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 4 : head.LastCellNum;
// foreach (var item in items)
// {
// var headcell = GetOrCreate(head, lastcellIndex);
// headcell.SetCellValue(item);
// headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
// var doctorcell = GetOrCreate(doctorFactor, lastcellIndex);
// doctorcell.SetCellValue(0);
// doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// var nursecell = GetOrCreate(nurseFactor, lastcellIndex);
// nursecell.SetCellValue(0);
// nursecell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// var techniciancell = GetOrCreate(technicianFactor, lastcellIndex);
// techniciancell.SetCellValue(0);
// techniciancell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.系数, CellFormat.百分比);
// lastcellIndex++;
// }
// #endregion
// }
// /// <summary>
// /// 写入数据
// /// </summary>
// /// <param name="sheet"></param>
// /// <param name="sheetRead"></param>
// /// <param name="unitList">核算单元</param>
// /// <param name="allExtract">抽取的数据(科室、列头、数据)</param>
// /// <param name="header">设定抽取的列头</param>
// /// <param name="isNewTemp">是否为空白模板</param>
// /// <param name="isIncom">是否是开单、执行收入</param>
// private void WriteSheetData(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<ExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp, bool isIncom = false)
// {
// logManageService.WriteMsg("提取绩效数据", $"填充数据 -- {sheet.SheetName}", 1, Allot.ID, "ReceiveMessage");
// logger.LogInformation($"提取绩效数据 填充数据 -- {sheet.SheetName}");
// //写入数据
// var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value);
// var rowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 1;
// if (!isNewTemp)
// {
// #region 给历史模板已有科室补充数据
// for (int i = rowIndex; i < sheet.LastRowNum + 1; i++)
// {
// var row = sheet.GetRow(i);
// if (row != null)
// {
// var department = row.GetCell(6)?.ToString(); // 科室名称
// if (string.IsNullOrEmpty(department)) continue;
// var deptData = allExtract.Where(t => t.Department == department);
// if (deptData == null || !deptData.Any()) continue;
// for (int j = 7; j < head.LastCellNum; j++)
// {
// var headName = head.GetCell(j).StringCellValue;
// var newCell = GetOrCreate(row, j);
// if (newCell == null) continue;
// var value = deptData.FirstOrDefault(t => t.Category == headName)?.Value;
// if (isIncom)
// {
// value = value == 0 ? null : value;
// OutToExcelCell(newCell, value);
// newCell.CellStyle = style;
// }
// else if (newCell.CellType != CellType.Formula)
// {
// value = value == 0 ? null : value;
// OutToExcelCell(newCell, value);
// if (header != null && header.Contains(headName))
// newCell.CellStyle = style;
// }
// }
// allExtract.RemoveAll(t => t.Department == department);
// }
// }
// #endregion
// }
// if (allExtract == null || !allExtract.Any()) return;
// #region 补充新的科室及数据
// var lastrowIndex = isNewTemp ? rowIndex : sheet.LastRowNum + 1;
// foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
// {
// var row = sheet.CreateRow(lastrowIndex);
// for (int i = head.FirstCellNum; i < head.LastCellNum; i++)
// {
// var headName = head.GetCell(i).StringCellValue;
// var newCell = row.CreateCell(i);
// if (headName.Replace("\n", "") == "核算单元(医生组)")
// {
// var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 1)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 1)?.AccountingUnit;
// newCell.SetCellValue(dept ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else if (headName.Replace("\n", "") == "核算单元(护理组)")
// {
// var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 2)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 2)?.AccountingUnit;
// newCell.SetCellValue(dept ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else if (headName.Replace("\n", "") == "核算单元(医技组)")
// {
// var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department && t.UnitType == 3)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department && t.UnitType == 3)?.AccountingUnit;
// newCell.SetCellValue(dept ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else if (headName == "科室名称")
// {
// newCell.SetCellValue(department ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else
// {
// var value = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName)?.Value;
// if (isIncom)
// {
// value = value == 0 ? null : value;
// OutToExcelCell(newCell, value);
// newCell.CellStyle = style;
// }
// else if (header != null && header.Contains(headName))
// {
// value = value == 0 ? null : value;
// OutToExcelCell(newCell, value);
// newCell.CellStyle = style;
// }
// }
// }
// lastrowIndex++;
// }
// #endregion
// }
// /// <summary>
// /// 写入工作量列头
// /// </summary>
// /// <param name="sheet"></param>
// /// <param name="sheetRead"></param>
// /// <param name="items"></param>
// /// <param name="isNewTemp"></param>
// private void WriteWorkHeader(ISheet sheet, IPerSheetDataRead sheetRead, List<ex_item> items, bool isNewTemp)
// {
// var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
// var factor = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 1);
// var cellItems = new List<ex_item>();
// cellItems.AddRange(items);
// if (!isNewTemp)
// {
// #region 过滤历史模板中已有的列头
// //写入列头信息
// int cellStartIndex = sheetRead.Point.HeaderFirstCellNum.Value + 2;
// for (int i = cellStartIndex; i < head.LastCellNum; i++)
// {
// var cellvalue = head.GetCell(i)?.ToString();
// if (string.IsNullOrEmpty(cellvalue)) continue;
// cellItems.RemoveAll(t => t.ItemName == cellvalue);
// }
// #endregion
// }
// if (cellItems == null || !cellItems.Any()) return;
// #region 新增模板中不存在的列头
// var lastcellIndex = isNewTemp ? sheetRead.Point.HeaderFirstCellNum.Value + 2 : head.LastCellNum;
// foreach (var item in cellItems)
// {
// var headcell = GetOrCreate(head, lastcellIndex);
// headcell.SetCellValue(item.ItemName);
// headcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头);
// var doctorcell = GetOrCreate(factor, lastcellIndex);
// doctorcell.SetCellValue(item.FactorValue1 != null ? (double)item.FactorValue1 : 0);
// doctorcell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.列头, CellFormat.数字2);
// lastcellIndex++;
// }
// #endregion
// }
// /// <summary>
// /// 写入工作量数据
// /// </summary>
// /// <param name="sheet"></param>
// /// <param name="sheetRead"></param>
// /// <param name="unitList"></param>
// /// <param name="allExtract"></param>
// /// <param name="header"></param>
// /// <param name="isNewTemp"></param>
// private void WriteWorkData(ISheet sheet, IPerSheetDataRead sheetRead, List<AccountUnitEntity> unitList, List<ExtractDto> allExtract, IEnumerable<string> header, bool isNewTemp)
// {
// var head = GetOrCreate(sheet, sheetRead.Point.HeaderFirstRowNum.Value + 0);
// var rowIndex = sheetRead.Point.HeaderFirstRowNum.Value + 2;
// if (!isNewTemp)
// {
// #region 给历史模板已有科室补充数据
// for (int i = rowIndex; i < sheet.LastRowNum + 1; i++)
// {
// var row = sheet.GetRow(i);
// if (row != null)
// {
// var department = row.GetCell(2)?.ToString(); // 科室名称
// if (string.IsNullOrEmpty(department)) continue;
// var deptData = allExtract.Where(t => t.Department == department);
// if (deptData == null || !deptData.Any()) continue;
// for (int j = 3; j < head.LastCellNum; j++)
// {
// var headName = head.GetCell(j).StringCellValue;
// var newCell = GetOrCreate(row, j);
// if (newCell == null) continue;
// if (newCell.CellType != CellType.Formula)
// {
// var extract = deptData.FirstOrDefault(t => t.Category == headName);
// var value = extract?.Value == 0 ? null : extract?.Value;
// OutToExcelCell(newCell, value);
// if (header != null && header.Contains(headName))
// newCell.CellStyle = style;
// }
// }
// allExtract.RemoveAll(t => t.Department == department);
// }
// }
// #endregion
// }
// if (allExtract == null || !allExtract.Any()) return;
// #region 补充新的科室及数据
// var lastrowIndex = isNewTemp ? rowIndex : sheet.LastRowNum + 1;
// foreach (var department in allExtract.Select(t => t.Department).Where(t => !string.IsNullOrEmpty(t)).Distinct())
// {
// var row = sheet.CreateRow(lastrowIndex);
// for (int i = head.FirstCellNum; i < head.LastCellNum; i++)
// {
// var headName = head.GetCell(i).StringCellValue;
// var newCell = row.CreateCell(i);
// if (headName == "核算单元")
// {
// var dept = unitList.FirstOrDefault(t => t.SheetName == sheet.SheetName && t.Department == department)?.AccountingUnit ?? unitList.FirstOrDefault(t => t.SheetName != sheet.SheetName && t.Department == department)?.AccountingUnit;
// newCell.SetCellValue(dept ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else if (headName == "科室名称")
// {
// newCell.SetCellValue(department ?? "");
// newCell.CellStyle = CellStyle.CreateCellStyle(workbook, StyleType.默认);
// }
// else
// {
// var extract = allExtract.FirstOrDefault(t => t.Department == department && t.Category == headName);
// var value = extract?.Value == 0 ? null : extract?.Value;
// OutToExcelCell(newCell, value);
// if (header != null && header.Contains(headName))
// newCell.CellStyle = style;
// }
// }
// lastrowIndex++;
// }
// #endregion
// }
// #endregion
// #endregion
// #region Common
// /// <summary>
// /// 发送邮件
// /// </summary>
// /// <param name="path"></param>
// /// <param name="subject"></param>
// /// <param name="body"></param>
// private void SendEmail(string mail, string path, string subject, string body)
// {
// if (string.IsNullOrEmpty(mail)) return;
// var message = new EmailMessage
// {
// To = new List<string> { mail },
// DisplayName = "溯直健康",
// Subject = subject,
// Body = body
// };
// if (!string.IsNullOrEmpty(path))
// message.Attachments = new List<string> { path };
// emailService.Send(message);
// }
// /// <summary>
// /// 校验数据格式,并转换
// /// </summary>
// /// <param name="obj"></param>
// /// <returns></returns>
// public void OutToExcelCell(ICell cell, object obj)
// {
// string value = obj?.ToString() ?? "";
// try
// {
// var type = obj?.GetType() ?? typeof(string);
// 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);
// }
// }
// #endregion
// #region 配置校验
// /// <summary>
// /// 配置校验
// /// </summary>
// /// <param name="allotId"></param>
// /// <param name="hospitalId"></param>
// /// <param name="useTemplate"></param>
// public string Judge(int allotId, int hospitalId, int useTemplate, out string filePath)
// {
// string result = null;
// filePath = "";
// try
// {
// // 获取绩效信息
// var allot = perforPerallotRepository.GetEntity(t => t.ID == allotId);
// if (allot == null)
// throw new PerformanceException("AllotID错误");
// // 获取医院信息
// var hospital = perforHospitalRepository.GetEntity(t => t.ID == hospitalId);
// if (hospital == null)
// throw new PerformanceException("医院ID错误");
// // 获取医院配置信息
// var hospitalConfigList = perforHospitalconfigRepository.GetEntities(t => t.HospitalId == hospitalId);
// if (hospitalConfigList == null || hospitalConfigList.Count == 0)
// throw new PerformanceException("当前医院暂不支持HIS数据抽取");
// // 获取最近一次绩效
// var statesArray = new int[] { (int)AllotStates.GenerateSucceed, (int)AllotStates.Archive };
// var allotList = perforPerallotRepository.GetEntities(t => t.HospitalId == hospitalId && statesArray.Contains(t.States));
// var allotLast = allotList?.OrderByDescending(t => t.Year).ThenByDescending(t => t.Month).First();
// if (allotLast != null)
// filePath = allotLast.Path;
// // 获取当前医院模版信息
// var modulesList = perforExmoduleRepository.GetEntities(t => t.HospitalId == hospitalId);
// if (modulesList == null || modulesList.Count == 0)
// throw new PerformanceException("当前医院还未配置模版");
// // 获取模板项
// var moduleIdList = modulesList.Select(t => t.Id).ToList();
// var itemsList = perforExitemRepository.GetEntities(t => t.ModuleId.HasValue && moduleIdList.Contains(t.ModuleId.Value));
// if (itemsList == null || itemsList.Count == 0)
// throw new PerformanceException("当前医院还未配置模版项");
// // 获取当前模板所有相关抽取SQL语句
// var extypeIds = itemsList.Select(t => t.TypeId).Union(modulesList.Select(t => t.TypeId)).Distinct().ToList();
// var extractList = perforExscriptRepository.GetEntities(t => extypeIds.Contains(t.TypeId));
// if (extractList == null || extractList.Count == 0)
// throw new PerformanceException("当前医院配置模板无需抽取");
// }
// catch (PerformanceException ex)
// {
// logger.LogError($"提取绩效数据异常 {ex.ToString()}");
// result = ex.Message;
// }
// catch (Exception ex)
// {
// logger.LogError($"提取绩效数据异常 {ex.ToString()}");
// throw new Exception(ex.Message);
// }
// return result;
// }
// #endregion
// }
//}
......@@ -458,5 +458,25 @@ public List<TitleValue> DeptDics(int hospitalId, int type)
}
return result.Select(t => new TitleValue { Title = t, Value = t }).ToList();
}
/// <summary>
/// 科室工作量数据详情
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public object DeptWorkloadDetail(WorkDetailRequest request)
{
var data = perallotRepository.QueryWorkloadData(request.AllotId, request.AccountingUnit);
if (data != null && data.Any())
return data.Select(t => new
{
t.Department,
t.DoctorName,
t.PersonnelNumber,
t.Category,
t.Fee
});
return new string[] { };
}
}
}
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