using NPOI.Util; using NPOI.XWPF.UserModel; using SafeCampus.Application.Services.Business.Warn.Dto; using SafeCampus.Application.Services.Business.Warn.Service; using System.Diagnostics; using MoYu.FriendlyException; using SafeCampus.Core.Extension; namespace SafeCampus.Web.Core.Controllers.Application.Violation; /// /// 预警分析控制器 /// [ApiDescriptionSettings(ApiGroupConsts.SYSTEM_Business, Tag = "预警分析", Order = 86)] [Route("violation/analysis")] [RolePermission] public class VioAnalysisController { private readonly ISimpleCacheService _simpleCacheService; private readonly IWarnInfoService _warnInfoService; public VioAnalysisController(ISimpleCacheService simpleCacheService, IWarnInfoService warnInfoService) { _simpleCacheService = simpleCacheService; _warnInfoService = warnInfoService; } //场景报告导出 //导出查询条件 //生成word public async Task ReportExport(ReportExportInput input) { //var categories = new List() { "Category A", "Category B", "Category C", "Category D" }; //var values = new List() { 215, 130, 245, 210 }; //GenBar("XXX场景告警统计", categories, values, Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png")); //GenPie("XXX场景告警统计", categories, values, Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png")); //switch (input.GroupCode) //{ // case "MCLZ": // return await GetMCLZ(input); // case "ZHKT": // return await GetZHKT(input); // case "XSGQ": // return await GetXSGQ(input); // case "XYFBL": // return await GetXYFBL(input); // case "XYAQ": // return await GetXYAQ(input); // case "QYGK": // return await GetQYGK(input); // case "ABXL": // return await GetABXL(input); // default: // throw Oops.Oh("请选择正确的场景"); //} //PythonEngine.BeginAllowThreads(); var result = await GetMCLZ(input); //PythonEngine.Shutdown(); return result; } #region 图表生成 private bool GenCharts(string title, List label, List value, string name,string pyName) { try { var script = Path.Combine(Directory.GetCurrentDirectory(), "Template", pyName); string args = $"\"{script}\" \"{name}\" \"{title}\" \"{string.Join(",", label)}\" \"{string.Join(",", value)}\""; ProcessStartInfo start = new ProcessStartInfo(); start.FileName = App.Configuration["AppInfo:Python"]; // Python 解释器路径 start.Arguments = args; // 参数列表 start.UseShellExecute = false; start.RedirectStandardOutput = true; start.RedirectStandardError = true; // 启动进程 using (Process process = Process.Start(start)) { using (StreamReader reader = process.StandardOutput) { string result = reader.ReadToEnd(); Console.Write(result); } using (StreamReader reader = process.StandardError) { string error = reader.ReadToEnd(); LogHelper.WriteToLog("python执行错误", error); } } } catch (global::System.Exception) { return false; } return true; } /// /// 生成柱状图 /// /// /// /// /// private bool GenBar(string title, List label, List value, string name) { try { //var m_threadState = PythonEngine.BeginAllowThreads(); //using (Py.GIL()) //{ // dynamic plt = Py.Import("matplotlib.pyplot"); // dynamic fm = Py.Import("matplotlib.font_manager"); // dynamic prop = fm.FontProperties(fname: "C:\\Windows\\Fonts\\msyh.ttc"); // plt.rcParams["font.family"] = prop.get_name(); // //var categories = new List() { "Category A", "Category B", "Category C", "Category D" }; // //var values = new List() { 215, 130, 245, 210 }; // var bars = plt.bar(ToPythonList(label), ToPythonList(value)); // foreach (var bar in bars) // { // double yval = bar.get_height(); // plt.text(bar.get_x() + bar.get_width() / 2.5, yval, Math.Round(yval, 1), va: "bottom"); // } // // 设置图表标题并显示图表 // plt.title(title); // plt.savefig(name); // //plt.show(); // plt.close(); //} //PythonEngine.EndAllowThreads(m_threadState); } catch (global::System.Exception) { return false; } return true; } /// /// 生成饼图 /// /// /// /// /// private bool GenPie(string title, List label, List value, string name) { try { //var m_threadState = PythonEngine.BeginAllowThreads(); //using (Py.GIL()) //{ // dynamic plt = Py.Import("matplotlib.pyplot"); // dynamic fm = Py.Import("matplotlib.font_manager"); // dynamic prop = fm.FontProperties(fname: "C:\\Windows\\Fonts\\msyh.ttc"); // plt.rcParams["font.family"] = prop.get_name(); // //var categories = new List() { "Category A", "Category B", "Category C", "Category D" }; // //var values = new List() { 215, 130, 245, 210 }; // var color = new List() { "gold", "yellowgreen", "lightcoral", "lightskyblue" }; // var pie = plt.pie(ToPythonList(value), labels: ToPythonList(label), colors: ToPythonList(color), autopct: "%1.1f%%"); // plt.axis("equal"); // // 设置图表标题并显示图表 // plt.title(title); // plt.savefig(name); // //plt.show(); // plt.close(); //} //PythonEngine.EndAllowThreads(m_threadState); } catch (global::System.Exception) { return false; } return true; } #endregion /// /// 获取明厨亮灶报告 /// /// private async Task GetMCLZ(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var warnList = await _warnInfoService.GetListNoPage(new WarnInfoSearch { StartTick = input.StartTime, EndTick = input.EndTime.AddDays(1).AddSeconds(-1), AlarmTypes = warnGroup.Subset.Where(x=>x.State).Select(x => x.Code).ToArray(), PersonSetIds = input.PersonSetIds, CameraIds = warnGroup.CameraId }); var templatePath = Path.Combine(Directory.GetCurrentDirectory(), "Template", $"WordTemplate.docx"); await using var fs = new FileStream(templatePath, FileMode.Open, FileAccess.ReadWrite); XWPFDocument doc = new XWPFDocument(fs); var content = warnList.GroupBy(x => x.AlarmTypeDesc).ToList(); if (!content.Any()) { throw Oops.Oh("该时间段无数据,无法生成报告!"); } Dictionary replacements = new Dictionary() { //图片 { "{{ImagePie}}","" }, { "{{ImageBar}}","" }, //场景名称 { "{{GroupName}}", warnGroup.Name}, //摄 像 头 { "{{CameraName}}",string.Join("、",warnGroup.CameraName)}, //统计时间 { "{{StatitionTime}}", $"{input.StartTime:yyyy-MM-dd} 至 {input.EndTime:yyyy-MM-dd}"}, //累计告警 { "{{Count}}",warnList.Count.ToString()}, //内容详情 { "{{Content}}", $"按类型统计如下:{string.Join("、",content.Select(x=>$"{x.Key}:{x.Count()}条"))}"} }; // 遍历文档中的所有段落 foreach (XWPFParagraph para in doc.Paragraphs) { foreach (var kvp in replacements) { if (para.Text.Contains(kvp.Key)) // 检查是否为图片文件名 { if (kvp.Key == "{{ImageBar}}") { var categories = content.Select(x => x.Key).ToList();//new List() { "Category A", "Category B", "Category C", "Category D" }); var values = content.Select(x => x.Count()).ToList();// new List() { 215, 130, 245, 210 }; var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png"); GenCharts($"{warnGroup.Name}场景告警统计", categories, values, filePath,"GenBar.py"); await using var file = new FileStream(filePath, FileMode.Open, FileAccess.Read); XWPFRun run = para.CreateRun(); using MemoryStream imgStream = new MemoryStream(); await file.CopyToAsync(imgStream); imgStream.Seek(0, SeekOrigin.Begin); run.AddPicture(imgStream, (int)PictureType.JPEG, "image.jpg", Units.ToEMU(403.2), Units.ToEMU(300.8)); para.RemoveRun(0); // 移除原来的占位符文本 await file.DisposeAsync(); File.Delete(filePath); }else if (kvp.Key == "{{ImagePie}}") { var categories = content.Select(x => x.Key).ToList();//new List() { "Category A", "Category B", "Category C", "Category D" }); var values = content.Select(x => x.Count()).ToList();// new List() { 215, 130, 245, 210 }; var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png"); GenCharts($"{warnGroup.Name}场景告警统计", categories, values, filePath,"GenPie.py"); await using var file = new FileStream(filePath, FileMode.Open, FileAccess.Read); XWPFRun run = para.CreateRun(); using MemoryStream imgStream = new MemoryStream(); await file.CopyToAsync(imgStream); imgStream.Seek(0, SeekOrigin.Begin); run.AddPicture(imgStream, (int)PictureType.JPEG, "image.jpg", Units.ToEMU(403.2), Units.ToEMU(300.8)); para.RemoveRun(0); // 移除原来的占位符文本 await file.DisposeAsync(); File.Delete(filePath); } else { para.ReplaceText(kvp.Key, kvp.Value); } } } } await using MemoryStream wordStream = new MemoryStream(); doc.Write(wordStream); var bytes = wordStream.ToArray(); doc.Close(); var wordFile = new FileContentResult(bytes, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取智慧课堂报告 /// /// private async Task GetZHKT(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取学生归寝报告 /// /// private async Task GetXSGQ(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取校园防霸凌报告 /// /// private async Task GetXYFBL(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取校园安全报告 /// /// private async Task GetXYAQ(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取区域管控报告 /// /// private async Task GetQYGK(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } /// /// 获取安保巡逻报告 /// /// private async Task GetABXL(ReportExportInput input) { var warnGroup = _simpleCacheService .Get>(SafeCampusConst.WarnGroup) .Where(x => x.Code == input.GroupCode).FirstOrDefault(); var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" }; return await Task.FromResult(wordFile); } }