平安校园
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

338 regels
15 KiB

  1. using NPOI.Util;
  2. using NPOI.XWPF.UserModel;
  3. using SafeCampus.Application.Services.Business.Warn.Dto;
  4. using SafeCampus.Application.Services.Business.Warn.Service;
  5. using System.Diagnostics;
  6. using SafeCampus.Core.Extension;
  7. namespace SafeCampus.Web.Core.Controllers.Application.Violation;
  8. /// <summary>
  9. /// 预警分析控制器
  10. /// </summary>
  11. [ApiDescriptionSettings(ApiGroupConsts.SYSTEM_Business, Tag = "预警分析", Order = 86)]
  12. [Route("violation/analysis")]
  13. [RolePermission]
  14. public class VioAnalysisController
  15. {
  16. private readonly ISimpleCacheService _simpleCacheService;
  17. private readonly IWarnInfoService _warnInfoService;
  18. public VioAnalysisController(ISimpleCacheService simpleCacheService, IWarnInfoService warnInfoService)
  19. {
  20. _simpleCacheService = simpleCacheService;
  21. _warnInfoService = warnInfoService;
  22. }
  23. //场景报告导出
  24. //导出查询条件
  25. //生成word
  26. public async Task<IActionResult> ReportExport(ReportExportInput input)
  27. {
  28. //var categories = new List<string>() { "Category A", "Category B", "Category C", "Category D" };
  29. //var values = new List<int>() { 215, 130, 245, 210 };
  30. //GenBar("XXX场景告警统计", categories, values, Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png"));
  31. //GenPie("XXX场景告警统计", categories, values, Path.Combine(Directory.GetCurrentDirectory(), "Template", $"{Guid.NewGuid():N}.png"));
  32. //switch (input.GroupCode)
  33. //{
  34. // case "MCLZ":
  35. // return await GetMCLZ(input);
  36. // case "ZHKT":
  37. // return await GetZHKT(input);
  38. // case "XSGQ":
  39. // return await GetXSGQ(input);
  40. // case "XYFBL":
  41. // return await GetXYFBL(input);
  42. // case "XYAQ":
  43. // return await GetXYAQ(input);
  44. // case "QYGK":
  45. // return await GetQYGK(input);
  46. // case "ABXL":
  47. // return await GetABXL(input);
  48. // default:
  49. // throw Oops.Oh("请选择正确的场景");
  50. //}
  51. //PythonEngine.BeginAllowThreads();
  52. var result = await GetMCLZ(input);
  53. //PythonEngine.Shutdown();
  54. return result;
  55. }
  56. #region 图表生成
  57. private bool GenCharts(string title, List<string> label, List<int> value, string name,string pyName)
  58. {
  59. try
  60. {
  61. var script = Path.Combine(Directory.GetCurrentDirectory(), "Template", pyName);
  62. string args = $"\"{script}\" \"{name}\" \"{title}\" \"{string.Join(",", label)}\" \"{string.Join(",", value)}\"";
  63. ProcessStartInfo start = new ProcessStartInfo();
  64. start.FileName = App.Configuration["AppInfo:Python"]; // Python 解释器路径
  65. start.Arguments = args; // 参数列表
  66. start.UseShellExecute = false;
  67. start.RedirectStandardOutput = true;
  68. start.RedirectStandardError = true;
  69. // 启动进程
  70. using (Process process = Process.Start(start))
  71. {
  72. using (StreamReader reader = process.StandardOutput)
  73. {
  74. string result = reader.ReadToEnd();
  75. Console.Write(result);
  76. }
  77. using (StreamReader reader = process.StandardError)
  78. {
  79. string error = reader.ReadToEnd();
  80. LogHelper.WriteToLog("python执行错误", error);
  81. }
  82. }
  83. }
  84. catch (global::System.Exception)
  85. {
  86. return false;
  87. }
  88. return true;
  89. }
  90. /// <summary>
  91. /// 生成柱状图
  92. /// </summary>
  93. /// <param name="label"></param>
  94. /// <param name="value"></param>
  95. /// <param name="name"></param>
  96. /// <returns></returns>
  97. private bool GenBar(string title, List<string> label, List<int> value, string name)
  98. {
  99. try
  100. {
  101. //var m_threadState = PythonEngine.BeginAllowThreads();
  102. //using (Py.GIL())
  103. //{
  104. // dynamic plt = Py.Import("matplotlib.pyplot");
  105. // dynamic fm = Py.Import("matplotlib.font_manager");
  106. // dynamic prop = fm.FontProperties(fname: "C:\\Windows\\Fonts\\msyh.ttc");
  107. // plt.rcParams["font.family"] = prop.get_name();
  108. // //var categories = new List<string>() { "Category A", "Category B", "Category C", "Category D" };
  109. // //var values = new List<int>() { 215, 130, 245, 210 };
  110. // var bars = plt.bar(ToPythonList(label), ToPythonList(value));
  111. // foreach (var bar in bars)
  112. // {
  113. // double yval = bar.get_height();
  114. // plt.text(bar.get_x() + bar.get_width() / 2.5, yval, Math.Round(yval, 1), va: "bottom");
  115. // }
  116. // // 设置图表标题并显示图表
  117. // plt.title(title);
  118. // plt.savefig(name);
  119. // //plt.show();
  120. // plt.close();
  121. //}
  122. //PythonEngine.EndAllowThreads(m_threadState);
  123. }
  124. catch (global::System.Exception)
  125. {
  126. return false;
  127. }
  128. return true;
  129. }
  130. /// <summary>
  131. /// 生成饼图
  132. /// </summary>
  133. /// <param name="label"></param>
  134. /// <param name="value"></param>
  135. /// <param name="name"></param>
  136. /// <returns></returns>
  137. private bool GenPie(string title, List<string> label, List<int> value, string name)
  138. {
  139. try
  140. {
  141. //var m_threadState = PythonEngine.BeginAllowThreads();
  142. //using (Py.GIL())
  143. //{
  144. // dynamic plt = Py.Import("matplotlib.pyplot");
  145. // dynamic fm = Py.Import("matplotlib.font_manager");
  146. // dynamic prop = fm.FontProperties(fname: "C:\\Windows\\Fonts\\msyh.ttc");
  147. // plt.rcParams["font.family"] = prop.get_name();
  148. // //var categories = new List<string>() { "Category A", "Category B", "Category C", "Category D" };
  149. // //var values = new List<int>() { 215, 130, 245, 210 };
  150. // var color = new List<string>() { "gold", "yellowgreen", "lightcoral", "lightskyblue" };
  151. // var pie = plt.pie(ToPythonList(value), labels: ToPythonList(label), colors: ToPythonList(color), autopct: "%1.1f%%");
  152. // plt.axis("equal");
  153. // // 设置图表标题并显示图表
  154. // plt.title(title);
  155. // plt.savefig(name);
  156. // //plt.show();
  157. // plt.close();
  158. //}
  159. //PythonEngine.EndAllowThreads(m_threadState);
  160. }
  161. catch (global::System.Exception)
  162. {
  163. return false;
  164. }
  165. return true;
  166. }
  167. #endregion
  168. /// <summary>
  169. /// 获取明厨亮灶报告
  170. /// </summary>
  171. /// <returns></returns>
  172. private async Task<FileContentResult> GetMCLZ(ReportExportInput input)
  173. {
  174. var warnGroup = _simpleCacheService
  175. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  176. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  177. var warnList = await _warnInfoService.GetListNoPage(new WarnInfoSearch
  178. {
  179. StartTick = input.StartTime,
  180. EndTick = input.EndTime,
  181. AlarmTypes = warnGroup.Subset.Select(x => x.Code).ToArray(),
  182. PersonSetIds = input.PersonSetIds
  183. });
  184. var templatePath = Path.Combine(Directory.GetCurrentDirectory(), "Template", $"WordTemplate.docx");
  185. await using var fs = new FileStream(templatePath, FileMode.Open, FileAccess.ReadWrite);
  186. XWPFDocument doc = new XWPFDocument(fs);
  187. var content = warnList.GroupBy(x => x.AlarmTypeDesc).ToList();
  188. Dictionary<string, string> replacements = new Dictionary<string, string>()
  189. {
  190. //图片
  191. { "{{ImagePie}}","" },
  192. { "{{ImageBar}}","" },
  193. //场景名称
  194. { "{{GroupName}}", warnGroup.Name},
  195. //摄 像 头
  196. { "{{CameraName}}",string.Join("、",warnGroup.CameraName)},
  197. //统计时间
  198. { "{{StatitionTime}}", $"{input.StartTime:yyyy-MM-dd} 至 {input.EndTime:yyyy-MM-dd}"},
  199. //累计告警
  200. { "{{Count}}",warnList.Count.ToString()},
  201. //内容详情
  202. { "{{Content}}", $"按类型统计如下:{string.Join("、",content.Select(x=>$"{x.Key}:{x.Count()}条"))}"}
  203. };
  204. // 遍历文档中的所有段落
  205. foreach (XWPFParagraph para in doc.Paragraphs)
  206. {
  207. foreach (var kvp in replacements)
  208. {
  209. if (para.Text.Contains(kvp.Key)) // 检查是否为图片文件名
  210. {
  211. if (kvp.Key == "{{ImageBar}}")
  212. {
  213. var categories = content.Select(x => x.Key).ToList();//new List<string>() { "Category A", "Category B", "Category C", "Category D" });
  214. var values = content.Select(x => x.Count()).ToList();// new List<int>() { 215, 130, 245, 210 };
  215. var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Template",
  216. $"{Guid.NewGuid():N}.png");
  217. GenCharts($"{warnGroup.Name}场景告警统计", categories, values, filePath,"GenBar.py");
  218. await using var file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  219. XWPFRun run = para.CreateRun();
  220. using MemoryStream imgStream = new MemoryStream();
  221. await file.CopyToAsync(imgStream);
  222. imgStream.Seek(0, SeekOrigin.Begin);
  223. run.AddPicture(imgStream,
  224. (int)PictureType.JPEG, "image.jpg", Units.ToEMU(403.2), Units.ToEMU(300.8));
  225. para.RemoveRun(0); // 移除原来的占位符文本
  226. await file.DisposeAsync();
  227. File.Delete(filePath);
  228. }else if (kvp.Key == "{{ImagePie}}")
  229. {
  230. var categories = content.Select(x => x.Key).ToList();//new List<string>() { "Category A", "Category B", "Category C", "Category D" });
  231. var values = content.Select(x => x.Count()).ToList();// new List<int>() { 215, 130, 245, 210 };
  232. var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Template",
  233. $"{Guid.NewGuid():N}.png");
  234. GenCharts($"{warnGroup.Name}场景告警统计", categories, values, filePath,"GenPie.py");
  235. await using var file = new FileStream(filePath, FileMode.Open, FileAccess.Read);
  236. XWPFRun run = para.CreateRun();
  237. using MemoryStream imgStream = new MemoryStream();
  238. await file.CopyToAsync(imgStream);
  239. imgStream.Seek(0, SeekOrigin.Begin);
  240. run.AddPicture(imgStream,
  241. (int)PictureType.JPEG, "image.jpg", Units.ToEMU(403.2), Units.ToEMU(300.8));
  242. para.RemoveRun(0); // 移除原来的占位符文本
  243. await file.DisposeAsync();
  244. File.Delete(filePath);
  245. }
  246. else
  247. {
  248. para.ReplaceText(kvp.Key, kvp.Value);
  249. }
  250. }
  251. }
  252. }
  253. await using MemoryStream wordStream = new MemoryStream();
  254. doc.Write(wordStream);
  255. var bytes = wordStream.ToArray();
  256. doc.Close();
  257. var wordFile = new FileContentResult(bytes, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  258. return await Task.FromResult(wordFile);
  259. }
  260. /// <summary>
  261. /// 获取智慧课堂报告
  262. /// </summary>
  263. /// <returns></returns>
  264. private async Task<FileContentResult> GetZHKT(ReportExportInput input)
  265. {
  266. var warnGroup = _simpleCacheService
  267. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  268. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  269. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  270. return await Task.FromResult(wordFile);
  271. }
  272. /// <summary>
  273. /// 获取学生归寝报告
  274. /// </summary>
  275. /// <returns></returns>
  276. private async Task<FileContentResult> GetXSGQ(ReportExportInput input)
  277. {
  278. var warnGroup = _simpleCacheService
  279. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  280. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  281. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  282. return await Task.FromResult(wordFile);
  283. }
  284. /// <summary>
  285. /// 获取校园防霸凌报告
  286. /// </summary>
  287. /// <returns></returns>
  288. private async Task<FileContentResult> GetXYFBL(ReportExportInput input)
  289. {
  290. var warnGroup = _simpleCacheService
  291. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  292. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  293. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  294. return await Task.FromResult(wordFile);
  295. }
  296. /// <summary>
  297. /// 获取校园安全报告
  298. /// </summary>
  299. /// <returns></returns>
  300. private async Task<FileContentResult> GetXYAQ(ReportExportInput input)
  301. {
  302. var warnGroup = _simpleCacheService
  303. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  304. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  305. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  306. return await Task.FromResult(wordFile);
  307. }
  308. /// <summary>
  309. /// 获取区域管控报告
  310. /// </summary>
  311. /// <returns></returns>
  312. private async Task<FileContentResult> GetQYGK(ReportExportInput input)
  313. {
  314. var warnGroup = _simpleCacheService
  315. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  316. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  317. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  318. return await Task.FromResult(wordFile);
  319. }
  320. /// <summary>
  321. /// 获取安保巡逻报告
  322. /// </summary>
  323. /// <returns></returns>
  324. private async Task<FileContentResult> GetABXL(ReportExportInput input)
  325. {
  326. var warnGroup = _simpleCacheService
  327. .Get<List<WarnGroupInfo>>(SafeCampusConst.WarnGroup)
  328. .Where(x => x.Code == input.GroupCode).FirstOrDefault();
  329. var wordFile = new FileContentResult(new byte[] { }, "application/octet-stream") { FileDownloadName = $"{warnGroup.Name}场景分析报告.docx" };
  330. return await Task.FromResult(wordFile);
  331. }
  332. }