ibms-dome/FrontendWebApi/ApiControllers/OperationLogController.cs

420 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using FrontendWebApi.Models;
using iTextSharp.text;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.Formula.Functions;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using NPOI.Util;
using Org.BouncyCastle.Crypto.Agreement.JPake;
using Repository.BackendRepository.Interface;
using Repository.FrontendRepository.Interface;
using System;
using System.Collections.Generic;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Image = System.Drawing.Image;
using System.IdentityModel.Tokens.Jwt;
using System.Net;
using NPOI.POIFS.Crypt.Dsig;
using System.Text;
namespace FrontendWebApi.ApiControllers
{
//[Route("api/[controller]")]
//[ApiController]
public class OperationLogController : MyBaseApiController<OperationLogController>
{
private readonly IBackendRepository backendRepository;
private readonly IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository;
private string operationFileSaveAsPath = "";
public OperationLogController(IBackendRepository backendRepository, IBackgroundServiceMsSqlRepository backgroundServiceMsSqlRepository)
{
this.backendRepository = backendRepository;
operationFileSaveAsPath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "upload", "operation");
this.backgroundServiceMsSqlRepository = backgroundServiceMsSqlRepository;
}
/// <summary>
/// 巨蛋操作紀錄api 1:系統紀錄;2:登入紀錄;3:燈控排程紀錄
/// </summary>
/// <param name="pageResult"></param>
/// <returns></returns>
[HttpPost]
[Route("api/OperationLog/GetLogList")]
public async Task<ApiResult<PageResult<List<OperationLogOutput>>>> GetLogList([FromBody] PageResult<OperationLogInput> pageResult)
{
ApiResult<PageResult<List<OperationLogOutput>>> apiResult = new ApiResult<PageResult<List<OperationLogOutput>>>();
List<OperationLogOutput> logList = new List<OperationLogOutput>();
int total = 0;
string start_time = DateTime.Parse(pageResult.data?.start_time).ToString("yyyy-MM-dd");
string end_time = DateTime.Parse(pageResult.data?.end_time).ToString("yyyy-MM-dd"); ;
string mark = pageResult.isEnable ? ";" : "\n";
try
{
if (pageResult.data.type == 1 || pageResult.data.type == 2)
{
string building_tag = pageResult.data?.building_tag;
string tableName = (building_tag == "D2" || building_tag == "D3") ? "D2_Pri" : $"{building_tag}";
string sWhere = pageResult.data.type == 1 ? "OPERATION ='Invoked'" : "(OPERATION = 'Login' or OPERATION = 'Logout (Timeout)')";
string sWhere2 = pageResult.data.type == 1 ? ((building_tag == "D2" || building_tag == "D3") ?
"and (TARGET like '/Arena/D2%' or target like '/Arena/D3%')" : $"and TARGET like '/Arena/{building_tag}%'") : "";
string pageQuery = pageResult.isEnable ? "" : @"ORDER BY [TIMESTAMP] DESC -- 必須提供 ORDER BY 子句
OFFSET @skip ROWS
FETCH NEXT @pageSize ROWS ONLY;";
string sql = $@"SELECT DISTINCT
[TIMESTAMP] created_at
,[OPERATION] action_name
,[TARGET] parameter
,[SLOTNAME]
,[OLDVALUE]
,[VALUE]
,[USERNAME] user_name
FROM [taipei_dome].[dbo].[ARENA_{tableName}_AUDITHISTORY]
WHERE {sWhere}
AND TIMESTAMP >= @start_time AND TIMESTAMP < DATEADD(day, 1, @end_time)
{sWhere2}
{pageQuery}";
// 取得資料
logList = await backgroundServiceMsSqlRepository.GetAllAsync<OperationLogOutput>(sql,
new
{
pageSize = pageResult.pageSize,
skip = (pageResult.currentPage - 1) * pageResult.pageSize,
operation_type = pageResult.data?.operation_type,
start_time = start_time,
end_time = end_time,
});
sql = @$"SELECT COUNT(*) AS TotalCount
FROM (
SELECT DISTINCT
[TIMESTAMP] created_at,
[OPERATION] action_name,
[TARGET] parameter,
[SLOTNAME],
[OLDVALUE],
[VALUE],
[USERNAME] user_name
FROM [taipei_dome].[dbo].[ARENA_{tableName}_AUDITHISTORY]
WHERE {sWhere}
AND TIMESTAMP >= @start_time AND TIMESTAMP < DATEADD(day, 1, @end_time)
{sWhere2}
) AS subquery;";
total = await backgroundServiceMsSqlRepository.GetOneAsync<int>(sql,
new
{
start_time = start_time,
end_time = end_time,
});
logList.ForEach(log => log.content = $"Target{log.parameter}{mark}Value{log.value}");
}
else if (pageResult.data.type == 3)
{
string pageQuery = pageResult.isEnable ? "" : "LIMIT @pageSize OFFSET @skip";
var sql = $@"SELECT ui.full_name AS user_name, ol.*
FROM operation_log ol
LEFT JOIN userinfo ui ON ui.userinfo_guid COLLATE utf8mb4_unicode_ci = ol.user_guid
WHERE ol.operation_type = @operation_type
AND ol.building_tag = @building_tag
AND ol.created_at >= @start_time
AND ol.created_at <= @end_time
{pageQuery}";
// 取得資料
logList = await backendRepository.GetAllAsync<OperationLogOutput>(sql,
new
{
pageSize = pageResult.pageSize,
skip = (pageResult.currentPage - 1) * pageResult.pageSize,
operation_type = pageResult.data?.operation_type,
building_tag = pageResult.data?.building_tag,
start_time = start_time,
end_time = end_time,
});
sql = $@"SELECT COUNT(*) AS total_count
FROM (
SELECT ui.full_name AS user_name, ol.*
FROM operation_log ol
LEFT JOIN userinfo ui ON ui.userinfo_guid COLLATE utf8mb4_unicode_ci = ol.user_guid
WHERE ol.operation_type = @operation_type
AND ol.building_tag = @building_tag
AND ol.created_at >= @start_time
AND ol.created_at <= @end_time
) AS subquery;";
total = await backendRepository.GetOneAsync<int>(sql,
new
{
operation_type = pageResult.data?.operation_type,
building_tag = pageResult.data?.building_tag,
start_time = start_time,
end_time = end_time,
});
// 設定呈現紀錄內容
foreach (var log in logList)
{
if (log.parameter == null)
{
continue;
}
switch (log.operation_type)
{
case 1:
var chaName = JsonConvert.DeserializeObject<ChangeName>(log.parameter);
if (chaName == null) continue;
log.content = chaName.TagName + "" + chaName.ChangeN;
break;
case 2:
var schedule = JsonConvert.DeserializeObject<SaveSchedule>(log.parameter);
if (schedule == null) continue;
var contentArr = new List<string>() {
"編號:" + schedule.light_schedule_guid,
"名稱:" + schedule.full_name,
};
if (log.action_name == "修改")
{
contentArr.Add("修改內容:" + string.Join("、", schedule.changeNames));
}
log.content = string.Join(mark, contentArr);
break;
}
}
}
else
{
apiResult.Code = "5000";
apiResult.Msg = "無效參數";
return apiResult;
}
var result = new PageResult<List<OperationLogOutput>>
{
pageSize = pageResult.pageSize,
totalItem = total,
currentPage = pageResult.currentPage,
data = logList.OrderByDescending(log => log.created_at).ToList()
};
apiResult.Code = "0000";
apiResult.Data = result;
}
catch (Exception exception)
{
apiResult.Code = "9999";
apiResult.Msg = "系統內部錯誤,請聯絡管理者。";
Logger.LogError("【" + controllerName + "/" + actionName + "】" + exception.Message);
return apiResult;
}
return apiResult;
}
[HttpPost]
[Route("api/OperationLog/ExportList")]
public async Task<IActionResult> ExportList([FromBody] OperationLogExportInput input)
{
List<OperationLogOutput> result = new List<OperationLogOutput>();
//if (input.isNiagara)
//{
// result = input.exportList;
//}
//else
//{
// PageResult<OperationLogInput> pageResult = input.listInput;
// pageResult.isEnable = false;
// result = ((ApiResult<List<OperationLogOutput>>)((OkObjectResult)(await this.GetList(pageResult)).Result).Value).Data.ToList();
//}
input.listInput.isEnable = true;
result = GetLogList(input.listInput).Result.Data.data;
var FileName = $"{input.exportOpeTypeName}_{DateTime.Now}.csv";
// 生成CSV文件
string Csv;
string formatted_created_at = null;
if (result.Count > 0)
{
StringBuilder csv = new StringBuilder();
// 添加CSV標題行
csv.AppendLine("操作人,動作,內容,紀錄時間");
// 添加數據行
foreach (var item in result)
{
if (item.created_at.HasValue)
{
formatted_created_at = item.created_at.Value.ToString("yyyy/MM/dd HH:mm:ss");
}
csv.AppendLine($"{item.user_name},{item.action_name},{item.content},{formatted_created_at}");
}
Csv = csv.ToString();
using (var fileMemoryStream = new MemoryStream())
{
using (var streamWriter = new StreamWriter(fileMemoryStream, Encoding.UTF8))
{
streamWriter.Write(Csv);
}
return File(fileMemoryStream.ToArray(), "text/csv", FileName);
}
}
else
{
var msg = new { Code = "0003", Msg = "無資料可匯出。" };
return StatusCode(400, msg);
}
#region excel寫法 1,048,576
#region excel設定
//var workbook = new XSSFWorkbook();
//IFont font12 = workbook.CreateFont();
//font12.FontName = "新細明體";
//font12.FontHeightInPoints = 12;
//ICellStyle style12 = workbook.CreateCellStyle();
//style12.SetFont(font12);
//style12.Alignment = HorizontalAlignment.Center;
//style12.VerticalAlignment = VerticalAlignment.Center;
//IFont font12Times = workbook.CreateFont();
//font12Times.FontName = "Times New Roman";
//font12Times.FontHeightInPoints = 12;
//IFont font18 = workbook.CreateFont();
//font18.FontName = "新細明體";
//font18.FontHeightInPoints = 18;
//font18.IsBold = true;
//ICellStyle styleTitle18 = workbook.CreateCellStyle();
//styleTitle18.SetFont(font18);
//styleTitle18.Alignment = HorizontalAlignment.Center;
//styleTitle18.VerticalAlignment = VerticalAlignment.Center;
//ICellStyle styleLeft12 = workbook.CreateCellStyle();
//styleLeft12.SetFont(font12);
//styleLeft12.Alignment = HorizontalAlignment.Left;
//styleLeft12.VerticalAlignment = VerticalAlignment.Center;
//ICellStyle styleLine12 = workbook.CreateCellStyle();
//styleLine12.SetFont(font12);
//styleLine12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
//styleLine12.VerticalAlignment = VerticalAlignment.Center;
//styleLine12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLine12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLine12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
//styleLine12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
//ICellStyle stylein12 = workbook.CreateCellStyle();
//stylein12.SetFont(font12Times);
//stylein12.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Left;
//stylein12.VerticalAlignment = VerticalAlignment.Center;
//stylein12.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
//stylein12.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
//stylein12.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
//stylein12.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
//stylein12.WrapText = true;
#endregion
//var sheet = workbook.CreateSheet(input.exportOpeTypeName);
//int RowPosition = 0;
//if (result.Count > 0)
//{
// #region set cell
// int ri = 0;
// IRow row = sheet.CreateRow(RowPosition);
// //if (!input.isNiagara)
// //{
// // sheet.SetColumnWidth(ri++, 1 * 160 * 12);
// //}
// sheet.SetColumnWidth(ri++, 2 * 160 * 12);
// sheet.SetColumnWidth(ri++, 2 * 160 * 12);
// sheet.SetColumnWidth(ri++, 8 * 160 * 12);
// sheet.SetColumnWidth(ri++, 4 * 160 * 12);
// int i = 0;
// ICell cell = row.CreateCell(i++);
// //if (!input.isNiagara)
// //{
// // cell.SetCellValue("編號");
// // cell.CellStyle = styleLine12;
// // cell = row.CreateCell(i++);
// //}
// cell.SetCellValue("操作人");
// cell.CellStyle = styleLine12;
// cell = row.CreateCell(i++);
// cell.SetCellValue("動作");
// cell.CellStyle = styleLine12;
// cell = row.CreateCell(i++);
// cell.SetCellValue("內容");
// cell.CellStyle = styleLine12;
// cell = row.CreateCell(i++);
// cell.SetCellValue("紀錄時間");
// cell.CellStyle = styleLine12;
// #endregion
// foreach (var r in result)
// {
// RowPosition += 1;
// int k = 3;
// row = sheet.CreateRow(RowPosition);
// for (int j = 0; j <= i; j++)
// {
// int s = 0;
// cell = row.CreateCell(j);
// //if (!input.isNiagara && j == s++)
// //{
// // cell.SetCellValue(r.id);
// //}
// if (j == s++)
// {
// cell.SetCellValue(r.user_name);
// }
// if (j == s++)
// {
// cell.SetCellValue(r.action_name);
// }
// if (j == s++)
// {
// cell.SetCellValue(r.content);
// }
// if (j == s++)
// {
// cell.SetCellValue(r.created_at != null ? ((DateTime)r.created_at).ToString("yyyy-MM-dd HH:mm:ss") : null);
// }
// cell.CellStyle = style12;
// }
// }
//}
//var ms = new NpoiMemoryStream
//{
// AllowClose = false
//};
//workbook.Write(ms);
//ms.Flush();
//ms.Seek(0, SeekOrigin.Begin);
//Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
//return File(ms, "application/vnd.ms-excel", $"操作紀錄_{input.exportOpeTypeName}.xlsx");
#endregion
}
}
}