Commit a6917ff7 by zry

hangfire

parent 02c96536
......@@ -39,3 +39,4 @@ build/
/artifacts
.svn
logs/
/files
\ No newline at end of file
using FluentValidation.AspNetCore;
using Hangfire;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
......@@ -22,20 +23,28 @@ public class AllotController : Controller
{
private AllotService _allotService;
private HospitalService _hospitalService;
//private PerExcelService _perExcelService;
private IHostingEnvironment _evn;
private ILogger<AllotController> _logger;
public AllotController(AllotService allotService,
HospitalService hospitalService,
//PerExcelService perExcelService,
ILogger<AllotController> logger,
IHostingEnvironment evn)
{
_allotService = allotService;
_hospitalService = hospitalService;
//_perExcelService = perExcelService;
_logger = logger;
_evn = evn;
}
/// <summary>
/// 绩效列表
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("list")]
[HttpPost]
public ApiResponse List([FromBody]AllotRequest request)
......@@ -44,6 +53,11 @@ public ApiResponse List([FromBody]AllotRequest request)
return new ApiResponse(ResponseType.OK, allots);
}
/// <summary>
/// 新增绩效
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("insert")]
[HttpPost]
public ApiResponse<AllotResponse> Insert([CustomizeValidator(RuleSet = "Insert"), FromBody]AllotRequest request)
......@@ -52,6 +66,11 @@ public ApiResponse<AllotResponse> Insert([CustomizeValidator(RuleSet = "Insert")
return new ApiResponse<AllotResponse>(ResponseType.OK, result);
}
/// <summary>
/// 修改绩效
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("update")]
[HttpPost]
public ApiResponse<AllotResponse> Update([CustomizeValidator(RuleSet = "Update"), FromBody]AllotRequest request)
......@@ -60,6 +79,11 @@ public ApiResponse<AllotResponse> Update([CustomizeValidator(RuleSet = "Update")
return new ApiResponse<AllotResponse>(ResponseType.OK, result);
}
/// <summary>
/// 删除绩效
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
[Route("delete")]
[HttpPost]
public ApiResponse Delete([CustomizeValidator(RuleSet = "Delete"), FromBody]AllotRequest request)
......@@ -68,6 +92,11 @@ public ApiResponse Delete([CustomizeValidator(RuleSet = "Delete"), FromBody]Allo
return new ApiResponse(ResponseType.OK);
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="form"></param>
/// <returns></returns>
[Route("import")]
[HttpPost]
public ApiResponse Import([FromForm] IFormCollection form)
......@@ -106,5 +135,14 @@ public ApiResponse Import([FromForm] IFormCollection form)
return new ApiResponse(ResponseType.OK);
}
[Route("generate")]
[HttpPost]
public ApiResponse Generate([CustomizeValidator(RuleSet = "Delete"), FromBody]AllotRequest request)
{
var allot = _allotService.GetAllot(request.ID);
BackgroundJob.Enqueue<PerExcelService>(p => p.Analyze(allot.Path));
return new ApiResponse(ResponseType.OK);
}
}
}
......@@ -16,6 +16,8 @@
<PackageReference Include="AutoMapper" Version="8.0.0" />
<PackageReference Include="AutoMapper.Extensions.Microsoft.DependencyInjection" Version="6.0.0" />
<PackageReference Include="FluentValidation.AspNetCore" Version="8.1.3" />
<PackageReference Include="Hangfire" Version="1.6.22" />
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.8.0" />
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
......
using AutoMapper;
using FluentValidation;
using FluentValidation.AspNetCore;
using Hangfire;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
......@@ -107,6 +108,12 @@ public void ConfigureServices(IServiceCollection services)
//ef配置
var connection = services.BuildServiceProvider().GetService<IOptions<AppConnection>>();
//后台任务调度
services.AddHangfire(config =>
{
config.UseRedisStorage(connection.Value.RedisConnectionString);
});
services.AddDbContext<PerformanceDbContext>(options =>
{
options.UseMySQL(connection.Value.PerformanceConnectionString);
......@@ -136,6 +143,8 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerF
c.RoutePrefix = string.Empty;
});
app.UseHangfireServer();
app.UseHangfireDashboard();
loggerFactory.CreateLogger<Startup>().LogDebug(env.EnvironmentName);
app.UseMvc();
......
......@@ -7,7 +7,8 @@
}
},
"AppConnection": {
"PerformanceConnectionString": "server=192.168.18.166;database=db_performance;uid=root;pwd=1234qwer;pooling=true;charset=utf8;convert zero datetime=true;port=3306;connection timeout=120;max pool size=512;allow user variables=true;"
"PerformanceConnectionString": "server=192.168.18.166;database=db_performance;uid=root;pwd=1234qwer;pooling=true;charset=utf8;convert zero datetime=true;port=3306;connection timeout=120;max pool size=512;allow user variables=true;",
"RedisConnectionString": "116.62.245.55:6379,defaultDatabase=1"
},
"Application": {
//登录过期时间
......
......@@ -6,7 +6,8 @@
},
//连接字符串
"AppConnection": {
"PerformanceConnectionString": "server=116.62.245.55;database=db_performance;uid=suvalue;pwd=suvalue2017;pooling=true;charset=utf8;convert zero datetime=true;port=3306;connection timeout=120;max pool size=512;allow user variables=true;"
"PerformanceConnectionString": "server=116.62.245.55;database=db_performance;uid=suvalue;pwd=suvalue2017;pooling=true;charset=utf8;convert zero datetime=true;port=3306;connection timeout=120;max pool size=512;allow user variables=true;",
"RedisConnectionString": "116.62.245.55:6379,defaultDatabase=1"
},
//互亿
"HuyiSmsConfig": {
......
......@@ -10,5 +10,6 @@ namespace Performance.DtoModels.AppSettings
public class AppConnection
{
public string PerformanceConnectionString { get; set; }
public string RedisConnectionString { get; set; }
}
}
......@@ -15,7 +15,7 @@ public enum SheetType
{
[Description("无法识别")]
Unidentifiable = 1,
[Description("医院人员")]
[Description("医院人员名单")]
Employee = 2,
[Description("收入")]
Income = 3,
......
......@@ -6,10 +6,28 @@ namespace Performance.DtoModels
{
public class PerData
{
public string StandardName { get; set; }
/// <summary>
/// 核算单元名称
/// </summary>
public string AccountingUnit { get; set; }
/// <summary>
/// 科室名称
/// </summary>
public string Department { get; set; }
/// <summary>
/// 列头类型名称
/// </summary>
public string TypeName { get; set; }
public decimal CellValue { get; set; }
/// <summary>
/// 单元格备注
/// </summary>
public string Annotation { get; set; }
}
public class PerData<TKey> : PerData
{
/// <summary>
/// 单元格value
/// </summary>
public TKey CellValue { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.DtoModels
{
public class PerDataEmployee : PerData<string>
{
}
}
......@@ -4,7 +4,7 @@
namespace Performance.DtoModels
{
public class PerDataExpend : PerData
public class PerDataExpend : PerData<decimal>
{
public string ParentType { get; set; }
}
......
......@@ -4,7 +4,7 @@
namespace Performance.DtoModels
{
public class PerDataWorkload : PerData
public class PerDataWorkload : PerData<decimal>
{
public string ParentType { get; set; }
}
......
......@@ -33,6 +33,9 @@ public class PerSheetPoint
/// 核算单元列
/// </summary>
public int? StandardCellNum { get; set; }
/// <summary>
/// 科室名称
/// </summary>
public int? DeptCellNum { get; set; }
}
}
//-----------------------------------------------------------------------
// <copyright file=" im_employee.cs">
// * FileName: im_employee.cs
// * history : 2019-03-08 16:39:35
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel.DataAnnotations;
namespace Performance.EntityModels
{
/// <summary>
/// im_employee Entity Model
/// </summary>
public class im_employee
{
/// <summary>
///
/// </summary>
[Key]
public int ID { get; set; }
/// <summary>
/// sheet页id
/// </summary>
public Nullable<int> SheetID { get; set; }
/// <summary>
/// 核算单元
/// </summary>
public string AccountingUnit { get; set; }
/// <summary>
/// 科室名称
/// </summary>
public string Department { get; set; }
/// <summary>
/// 绩效基数核算参考对象
/// </summary>
public Nullable<decimal> FitPeople { get; set; }
/// <summary>
/// 医生姓名
/// </summary>
public string DoctorName { get; set; }
/// <summary>
/// 职称
/// </summary>
public string JobTitle { get; set; }
/// <summary>
/// 岗位系数
/// </summary>
public Nullable<decimal> PostCoefficient { get; set; }
/// <summary>
/// 参加工作时间
/// </summary>
public Nullable<DateTime> WorkTime { get; set; }
/// <summary>
/// 考核得分率
/// </summary>
public Nullable<decimal> ScoreAverageRate { get; set; }
/// <summary>
/// 出勤率
/// </summary>
public Nullable<decimal> Attendance { get; set; }
/// <summary>
/// 核算单元医生数
/// </summary>
public Nullable<int> PeopleNumber { get; set; }
/// <summary>
/// 工作量绩效
/// </summary>
public Nullable<decimal> Workload { get; set; }
/// <summary>
/// 其他绩效
/// </summary>
public Nullable<decimal> OthePerfor { get; set; }
/// <summary>
/// 医院奖罚
/// </summary>
public Nullable<decimal> Punishment { get; set; }
/// <summary>
/// 调节系数
/// </summary>
public Nullable<decimal> Adjust { get; set; }
/// <summary>
/// 发放系数
/// </summary>
public Nullable<decimal> Grant { get; set; }
}
}
//-----------------------------------------------------------------------
// <copyright file=" im_sheetdata.cs">
// * FileName: im_sheetdata.cs
// * history : 2019-03-08 14:31:00
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.ComponentModel.DataAnnotations;
namespace Performance.EntityModels
{
/// <summary>
/// im_sheetdata Entity Model
/// </summary>
public class im_sheetdata
{
/// <summary>
/// ID
/// </summary>
[Key]
public int ID { get; set; }
/// <summary>
///
/// </summary>
public Nullable<int> AllotID { get; set; }
/// <summary>
///
/// </summary>
public string SheetName { get; set; }
/// <summary>
///
/// </summary>
public Nullable<int> SheetType { get; set; }
}
}
//-----------------------------------------------------------------------
// <copyright file=" im_employee.cs">
// * FileName: im_employee.cs
// * history : Created by T4 2019-03-08 15:45:50
// </copyright>
//-----------------------------------------------------------------------
using System;
using Performance.EntityModels;
namespace Performance.Repository
{
/// <summary>
/// im_employee Repository
/// </summary>
public class PerforImemployeeRepository : PerforRepository<im_employee>
{
public PerforImemployeeRepository(PerformanceDbContext context) : base(context)
{
}
}
}
//-----------------------------------------------------------------------
// <copyright file=" im_sheetdata.cs">
// * FileName: im_sheetdata.cs
// * history : Created by T4 2019-03-08 14:31:25
// </copyright>
//-----------------------------------------------------------------------
using System;
using Performance.EntityModels;
namespace Performance.Repository
{
/// <summary>
/// im_sheetdata Repository
/// </summary>
public class PerforImSheetDataRepository : PerforRepository<im_sheetdata>
{
public PerforImSheetDataRepository(PerformanceDbContext context) : base(context)
{
}
}
}
using AutoMapper;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Logging;
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;
......@@ -12,9 +16,16 @@ namespace Performance.Services
public class AllotService : IAutoInjection
{
private PerforAllotRepository _allotRepository;
public AllotService(PerforAllotRepository allotRepository)
private IHostingEnvironment _evn;
private ILogger<AllotService> _logger;
public AllotService(PerforAllotRepository allotRepository,
IHostingEnvironment evn,
ILogger<AllotService> logger)
{
_allotRepository = allotRepository;
_logger = logger;
_evn = evn;
}
/// <summary>
......@@ -86,7 +97,30 @@ public bool DeleteAllot(int iD)
var allot = _allotRepository.GetEntity(t => t.ID == iD);
if (allot == null)
throw new PerformanceException("当前绩效记录不存在");
return _allotRepository.Remove(allot);
var result = _allotRepository.Remove(allot);
if (!string.IsNullOrEmpty(allot.Path))
{
var dpath = Path.Combine(_evn.ContentRootPath, "Files", $"{allot.HospitalId}", $"{allot.Year}{allot.Month.ToString().PadLeft(2, '0')}");
var name = FileHelper.GetFileName(allot.Path);
var path = Path.Combine(dpath, name);
if (allot.Path != path)
{
try
{
FileHelper.Move(allot.Path, path);
allot.Path = path;
_allotRepository.Remove(allot);
}
catch (Exception ex)
{
_logger.LogError("移动文件失败;{0}", ex);
}
}
FileHelper.CreateDirectory(dpath);
}
return result;
}
/// <summary>
......
......@@ -2,19 +2,21 @@
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Performance.DtoModels;
using Performance.EntityModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace Performance.Services
{
public class PerExcelService : IAutoInjection
{
private PerSheetService _service;
public PerExcelService(PerSheetService service)
private PerSheetService _perSheetService;
public PerExcelService(PerSheetService perSheetService)
{
_service = service;
_perSheetService = perSheetService;
}
public PerExcel Analyze(string path)
{
......@@ -33,11 +35,55 @@ public PerExcel Analyze(string path)
for (int i = 0; i < workbook.NumberOfSheets; i++)
{
var sheet = workbook.GetSheetAt(i);
var st = _service.Sheet(sheet);
if (SheetType.Unidentifiable != _perSheetService.GetSheetType(sheet.SheetName))
{
var st = _perSheetService.Sheet(sheet);
excel.PerSheet.Add(st);
}
}
Save(excel);
return excel;
}
}
private bool Save(PerExcel excel)
{
foreach (var item in excel.PerSheet.Where(t => t.SheetType == SheetType.Employee))
{
var result = C(item.PerData);
}
return true;
}
private List<im_employee> C(List<PerData> dataList)
{
List<im_employee> result = new List<im_employee>();
var empList = dataList.GroupBy(t => new { t.AccountingUnit, t.Department })
.Select(t => new { t.Key, Employee = t.Select(p => (PerDataEmployee)p) });
foreach (var gkey in empList)
{
im_employee employee = new im_employee
{
AccountingUnit = gkey.Key.AccountingUnit,
Department = gkey.Key.Department,
DoctorName = gkey.Employee.FirstOrDefault(t => t.TypeName == "医生姓名").CellValue,
FitPeople = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "绩效基数核算参考对象")?.CellValue),
JobTitle = gkey.Employee.FirstOrDefault(t => t.TypeName == "职称")?.CellValue,
PostCoefficient = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "岗位系数")?.CellValue),
WorkTime = ConvertHelper.To<DateTime?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "考核得分率")?.CellValue),
ScoreAverageRate = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "医生姓名")?.CellValue),
Attendance = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "出勤率")?.CellValue),
PeopleNumber = ConvertHelper.To<int?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "核算单元医生数")?.CellValue),
Workload = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "工作量绩效")?.CellValue),
OthePerfor = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "其他绩效")?.CellValue),
Punishment = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "医院奖罚")?.CellValue),
Adjust = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "调节系数")?.CellValue),
Grant = ConvertHelper.To<decimal?>(gkey.Employee.FirstOrDefault(t => t.TypeName == "发放系数")?.CellValue)
};
result.Add(employee);
}
return result;
}
}
}
......@@ -17,22 +17,23 @@ public PerSheet Sheet(ISheet sheet)
perSheet.SheetType = GetSheetType(sheet.SheetName);
perSheet.ModuleName = EnumHelper.GetDescription(perSheet.SheetType);
if (perSheet.SheetType == SheetType.Unidentifiable)
return null;
IPerSheetDataRead sheetRead = PerSheetDataFactory.GetAnalyze(perSheet.SheetType);
perSheet.PerData = AnalyzeData(sheet , sheetRead);
perSheet.PerData = AnalyzeData(sheet, sheetRead);
return perSheet;
}
public SheetType GetSheetType(string sheetName)
{
if (sheetName.StartsWith("工作量"))
{
if (sheetName.StartsWith("医院人员名单"))
return SheetType.Employee;
else if (sheetName.StartsWith("工作量"))
return SheetType.Expend;
}
else if (sheetName.StartsWith("生成成本"))
{
return SheetType.Workload;
}
return SheetType.Unidentifiable;
}
......
......@@ -13,6 +13,7 @@ public static IPerSheetDataRead GetAnalyze(SheetType sheetType)
switch (sheetType)
{
case SheetType.Employee:
analyze = new PerSheetDataReadEmployee();
break;
case SheetType.Income:
break;
......
using NPOI.SS.UserModel;
using Performance.DtoModels;
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Services
{
public class PerSheetDataReadEmployee : IPerSheetDataRead
{
public PerSheetPoint Point => new PerSheetPoint
{
HeaderFirstRowNum = 0,
HeaderLastRowNum = 0,
HeaderFirstCellNum = 0,
DataFirstRowNum = 1,
StandardCellNum = 0,
DeptCellNum = 1
};
public PerData GetPerData(IRow row, PerHeader perHeader)
{
return new PerDataEmployee
{
AccountingUnit = row.GetCell(Point.StandardCellNum.Value)?.ToString(),
Department = row.GetCell(Point.DeptCellNum.Value)?.ToString(),
TypeName = perHeader?.CellName,
CellValue = row.GetCell(perHeader.PointCell)?.ToString(),
Annotation = row.GetCell(perHeader.PointCell)?.CellComment?.String?.String,
};
}
}
}
......@@ -24,7 +24,7 @@ public PerData GetPerData(IRow row, PerHeader perHeader)
{
return new PerDataExpend
{
StandardName = row.GetCell(Point.StandardCellNum.Value).ToString(),
AccountingUnit = row.GetCell(Point.StandardCellNum.Value).ToString(),
Department = row.GetCell(Point.DeptCellNum.Value).ToString(),
ParentType = perHeader.Parent?.CellName,
TypeName = perHeader.CellName,
......
......@@ -23,7 +23,7 @@ public PerData GetPerData(IRow row, PerHeader perHeader)
{
return new PerDataWorkload
{
StandardName = row.GetCell(Point.StandardCellNum.Value).ToString(),
AccountingUnit = row.GetCell(Point.StandardCellNum.Value).ToString(),
Department = row.GetCell(Point.DeptCellNum.Value).ToString(),
ParentType = perHeader.Parent?.CellName,
TypeName = perHeader.CellName,
......
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