From 1ac10ca9de830164bdbd6bfa0bbac43a9d647180 Mon Sep 17 00:00:00 2001 From: LRan <962019857@qq.com> Date: Wed, 2 Nov 2016 15:35:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=97=A5=E5=BF=97=E5=89=8D?= =?UTF-8?q?=E5=8F=B0=E5=B1=95=E7=A4=BA=EF=BC=8C=E4=BF=AE=E6=94=B9=E4=BA=86?= =?UTF-8?q?=E6=97=A5=E5=BF=97=E8=A1=A8=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Bootstrap.Admin/Bootstrap.Admin.csproj | 4 ++ .../Controllers/AdminController.cs | 8 +++ Bootstrap.Admin/Controllers/LogsController.cs | 31 ++++++++ Bootstrap.Admin/Models/QueryLogOption.cs | 72 +++++++++++++++++++ Bootstrap.Admin/Scripts/Logs.js | 35 +++++++++ Bootstrap.Admin/Views/Admin/Logs.cshtml | 34 +++++++++ Bootstrap.DataAccess/Log.cs | 29 ++------ Bootstrap.DataAccess/LogHelper.cs | 23 +++--- Bootstrap.DataAccessTests/LogHelperTests.cs | 18 ++--- DatabaseScripts/Install.sql | 24 ++++--- 10 files changed, 222 insertions(+), 56 deletions(-) create mode 100644 Bootstrap.Admin/Controllers/LogsController.cs create mode 100644 Bootstrap.Admin/Models/QueryLogOption.cs create mode 100644 Bootstrap.Admin/Scripts/Logs.js create mode 100644 Bootstrap.Admin/Views/Admin/Logs.cshtml diff --git a/Bootstrap.Admin/Bootstrap.Admin.csproj b/Bootstrap.Admin/Bootstrap.Admin.csproj index ccc212e5..71a006b2 100644 --- a/Bootstrap.Admin/Bootstrap.Admin.csproj +++ b/Bootstrap.Admin/Bootstrap.Admin.csproj @@ -158,6 +158,7 @@ + @@ -187,6 +188,7 @@ + @@ -196,6 +198,7 @@ + @@ -233,6 +236,7 @@ + diff --git a/Bootstrap.Admin/Controllers/AdminController.cs b/Bootstrap.Admin/Controllers/AdminController.cs index 02417673..8efb76ac 100644 --- a/Bootstrap.Admin/Controllers/AdminController.cs +++ b/Bootstrap.Admin/Controllers/AdminController.cs @@ -72,6 +72,14 @@ namespace Bootstrap.Admin.Controllers v.HomeUrl = "~/Admin"; return View(v); } + public ActionResult Logs() + { + var v = new NavigatorBarModel(); + v.ShowMenu = "hide"; + v.Menus[6].Active = "active"; + v.HomeUrl = "~/Admin"; + return View(v); + } /// /// /// diff --git a/Bootstrap.Admin/Controllers/LogsController.cs b/Bootstrap.Admin/Controllers/LogsController.cs new file mode 100644 index 00000000..394ad632 --- /dev/null +++ b/Bootstrap.Admin/Controllers/LogsController.cs @@ -0,0 +1,31 @@ +using Bootstrap.Admin.Models; +using Bootstrap.DataAccess; +using System.Linq; +using System.Web.Http; + +namespace Bootstrap.Admin.Controllers +{ + public class LogsController : ApiController + { + /// + /// + /// + /// + /// + [HttpGet] + public QueryData Get([FromUri]QueryLogOption value) + { + return value.RetrieveData(); + } + /// + /// + /// + /// + /// + [HttpGet] + public Log Get(int id) + { + return LogHelper.RetrieveLogs().FirstOrDefault(t => t.ID == id); + } + } +} \ No newline at end of file diff --git a/Bootstrap.Admin/Models/QueryLogOption.cs b/Bootstrap.Admin/Models/QueryLogOption.cs new file mode 100644 index 00000000..e6427680 --- /dev/null +++ b/Bootstrap.Admin/Models/QueryLogOption.cs @@ -0,0 +1,72 @@ +using Bootstrap.DataAccess; +using Longbow.Web.Mvc; +using System; +using System.Globalization; +using System.Linq; + +namespace Bootstrap.Admin.Models +{ + public class QueryLogOption : PaginationOption + { + /// + /// + /// + public string OperateType { get; set; } + /// + /// + /// + public string OperateTimeStart { get; set; } + /// + /// + /// + public string OperateTimeEnd { get; set; } + public QueryData RetrieveData() + { + var data = LogHelper.RetrieveLogs(string.Empty); + if (!string.IsNullOrEmpty(OperateType)) + { + data = data.Where(t => t.OperationType.ToString().Contains(OperateType)); + } + + if (!string.IsNullOrEmpty(OperateTimeStart)) + { + DateTime opTimeStart = StringToDateTime(OperateTimeStart); + if (opTimeStart != null) + data = data.Where(t => IsSmallThen(opTimeStart, t.OperationTime)); + } + if (!string.IsNullOrEmpty(OperateTimeEnd)) + { + DateTime opTimeEnd = StringToDateTime(OperateTimeEnd); + if (opTimeEnd != null) + data = data.Where(t => IsSmallThen(t.OperationTime, opTimeEnd)); + } + + var ret = new QueryData(); + ret.total = data.Count(); + // TODO: 通过option.Sort属性判断对那列进行排序,现在统一对名称列排序 + data = Order == "asc" ? data.OrderBy(t => t.OperationType) : data.OrderByDescending(t => t.OperationType); + ret.rows = data.Skip(Offset).Take(Limit); + return ret; + } + private static DateTime StringToDateTime(string dt_str) + { + DateTime dt ; + DateTimeFormatInfo dtFormat = new DateTimeFormatInfo(); + dtFormat.ShortDatePattern = "yyyy-MM-dd HH:mm:ss"; + dt = Convert.ToDateTime(dt_str, dtFormat); + return dt; + } + /// + /// 比较两个DateTime + /// (去掉了毫秒) + /// + /// + /// + /// + private static bool IsSmallThen(DateTime d1, DateTime d2) + { + return new DateTime(d1.Year, d1.Month, d1.Day, d1.Hour, d1.Minute, d1.Second) <= + new DateTime(d2.Year, d2.Month, d2.Day, d2.Hour, d2.Minute, d2.Second); + } + } +} \ No newline at end of file diff --git a/Bootstrap.Admin/Scripts/Logs.js b/Bootstrap.Admin/Scripts/Logs.js new file mode 100644 index 00000000..4f2f03c7 --- /dev/null +++ b/Bootstrap.Admin/Scripts/Logs.js @@ -0,0 +1,35 @@ +$(function () { + //隐藏掉操作按钮 + $("#toolbar").hide(); + + var bsa = new BootstrapAdmin({ + url: '../api/Logs', + dataEntity: new DataEntity({ + map: { + ID: "logID", + OperationType: "operateType", + UserID: "userId", + OperationTime: "operateTime", + operateIp: "OperationIp" + } + }) + }); + $('table').smartTable({ + url: '../api/Logs', //请求后台的URL(*) + sortName: 'OperationType', + queryParams: function (params) { return $.extend(params, { operateType: $("#txt_operate_type").val(), OperateTimeStart: $("#txt_operate_start").val(), OperateTimeEnd: $("#txt_operate_end").val() }); }, //传递参数(*) + columns: [{ checkbox: true }, + { title: "Id", field: "ID", events: bsa.idEvents(), formatter: BootstrapAdmin.idFormatter, }, + { title: "操作类型", field: "OperationType", sortable: true }, + { title: "用户名称", field: "UserName", sortable: false }, + { + title: "操作时间", field: "OperationTime", sortable: false, + formatter: function (value, row, index) { + return value.substring(0,19).replace("T", " "); + } + }, + { title: "操作IP", field: "OperationIp", sortable: false }, + { title: "备注", field: "Remark", sortable: false } + ] + }); +}); \ No newline at end of file diff --git a/Bootstrap.Admin/Views/Admin/Logs.cshtml b/Bootstrap.Admin/Views/Admin/Logs.cshtml new file mode 100644 index 00000000..6581f163 --- /dev/null +++ b/Bootstrap.Admin/Views/Admin/Logs.cshtml @@ -0,0 +1,34 @@ +@model NavigatorBarModel +@{ + ViewBag.Title = "系统日志"; + Layout = "~/Views/Shared/_Default.cshtml"; +} +@section Javascript { + +} +@section header { + @Html.Partial("Header", Model) +} +@section navigator { + @Html.Partial("Navigator", Model) +} +@section query { +
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+
+} diff --git a/Bootstrap.DataAccess/Log.cs b/Bootstrap.DataAccess/Log.cs index e3c29f88..9dc3c528 100644 --- a/Bootstrap.DataAccess/Log.cs +++ b/Bootstrap.DataAccess/Log.cs @@ -14,38 +14,23 @@ namespace Bootstrap.DataAccess public int OperationType { get; set; } /// - /// 获得/设置 用户ID + /// 获得/设置 用户名称 /// - public int UserID { get; set; } + public string UserName { get; set; } /// /// 获得/设置 操作时间 /// public DateTime OperationTime { get; set; } - /// - /// 获得/设置 操作表表名 - /// - public string TableName { get; set; } - - /// - /// 获得/设置 操作内容 - /// - public string BusinessName { get; set; } - - /// - /// 获得/设置 操作表的主键 - /// - public string PrimaryKey { get; set; } - - /// - /// 获得/设置 sql语句 - /// - public string SqlText { get; set; } - /// /// 获得/设置 操作者Ip /// public string OperationIp { get; set; } + + /// + /// 获取/设置 备注 + /// + public string Remark { get; set; } } } diff --git a/Bootstrap.DataAccess/LogHelper.cs b/Bootstrap.DataAccess/LogHelper.cs index 0226b135..a987b8aa 100644 --- a/Bootstrap.DataAccess/LogHelper.cs +++ b/Bootstrap.DataAccess/LogHelper.cs @@ -1,4 +1,5 @@ -using Longbow.Caching; +using Longbow; +using Longbow.Caching; using Longbow.Caching.Configuration; using Longbow.ExceptionManagement; using System; @@ -35,13 +36,10 @@ namespace Bootstrap.DataAccess { ID = (int)reader[0], OperationType = (int)reader[1], - UserID = (int)reader[2], + UserName = (string)reader[2], OperationTime = (DateTime)reader[3], - TableName = (string)reader[4], - BusinessName = (string)reader[5], - PrimaryKey = (string)reader[6], - SqlText = (string)reader[7], - OperationIp = (string)reader[8], + OperationIp = LgbConvert.ReadValue((string)reader[4],string.Empty), + Remark=LgbConvert.ReadValue((string)reader[5],string.Empty) }); } } @@ -85,19 +83,16 @@ namespace Bootstrap.DataAccess { if (p == null) throw new ArgumentNullException("p"); bool ret = false; - string sql = "Insert Into Logs (OperationType, UserID,OperationTime,TableName,BusinessName,PrimaryKey,SqlText,OperationIp) Values (@OperationType, @UserID,@OperationTime,@TableName,@BusinessName,@PrimaryKey,@SqlText,@OperationIp)"; + string sql = "Insert Into Logs (OperationType, UserName,OperationTime,OperationIp,Remark) Values (@OperationType, @UserName,@OperationTime,@OperationIp,@Remark)"; try { using (DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, sql)) { cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@OperationType", p.OperationType, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@UserID", p.UserID, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@OperationTime", p.OperationTime, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@TableName", p.TableName, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@BusinessName", p.BusinessName, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@PrimaryKey", p.PrimaryKey, ParameterDirection.Input)); - cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@SqlText", p.SqlText, ParameterDirection.Input)); + cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@UserName", p.UserName, ParameterDirection.Input)); + cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@OperationTime", System.DateTime.Now, ParameterDirection.Input)); cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@OperationIp", p.OperationIp, ParameterDirection.Input)); + cmd.Parameters.Add(DBAccessManager.SqlDBAccess.CreateParameter("@Remark", p.Remark, ParameterDirection.Input)); DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd); } ret = true; diff --git a/Bootstrap.DataAccessTests/LogHelperTests.cs b/Bootstrap.DataAccessTests/LogHelperTests.cs index ed60a475..5275b7b1 100644 --- a/Bootstrap.DataAccessTests/LogHelperTests.cs +++ b/Bootstrap.DataAccessTests/LogHelperTests.cs @@ -1,7 +1,7 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; -using System.Data; +using System.Linq; +using Microsoft.VisualStudio.TestTools.UnitTesting; using System.Data.Common; -using System.Linq; +using System.Data; namespace Bootstrap.DataAccess.Tests { @@ -12,12 +12,12 @@ namespace Bootstrap.DataAccess.Tests [TestInitialize] public void Initialized() { - Log = new Log() { OperationType = 1, UserID = 1, OperationTime = System.DateTime.Now, TableName = "_测试日志_", BusinessName = "新增测试日志信息", PrimaryKey = "ID", SqlText = "Insert Into Logs", OperationIp = "0.0.0.0" }; + Log = new Log() { OperationType = 1, UserName = "_测试用户名称_", OperationTime = System.DateTime.Now, OperationIp = "0.0.0.0",Remark="" }; } [TestCleanup] public void CleanUp() { - using (DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, "delete from Logs where OperationIp='0'")) + using (DbCommand cmd = DBAccessManager.SqlDBAccess.CreateCommand(CommandType.Text, "delete from Logs where UserName='_测试用户名称_'")) { DBAccessManager.SqlDBAccess.ExecuteNonQuery(cmd); } @@ -30,17 +30,17 @@ namespace Bootstrap.DataAccess.Tests [TestMethod] public void SaveLogTest() { - Assert.IsTrue(LogHelper.SaveLog(Log), "新增日志信息出错,请检查LogHelper的saveLog 方法"); + Assert.IsTrue(LogHelper.SaveLog(Log), "新增日志信息出错,请检查LogHelper的SaveLog 方法"); var logs = LogHelper.RetrieveLogs(); - Assert.IsTrue(logs.Count() > 0, "新增日志信息出错,请检查LogHelper的saveLog 方法"); + Assert.IsTrue(logs.Count() > 0, "新增日志信息出错,请检查LogHelper的SaveLog 方法"); } [TestMethod] public void DeleteLogTest() { // 先判断数据环境是否可以删除,没有数据先伪造数据 - var log = LogHelper.RetrieveLogs().FirstOrDefault(m => m.OperationType == Log.OperationType); + var log = LogHelper.RetrieveLogs().FirstOrDefault(l => l.UserName == Log.UserName); if (log == null) LogHelper.SaveLog(Log); - log = LogHelper.RetrieveLogs().FirstOrDefault(m => m.OperationType == Log.OperationType); + log = LogHelper.RetrieveLogs().FirstOrDefault(l => l.UserName == Log.UserName); Assert.IsTrue(LogHelper.DeleteLog(log.ID.ToString()), "删除日志信息出错"); } } diff --git a/DatabaseScripts/Install.sql b/DatabaseScripts/Install.sql index 9ceabfe4..6be0c4f6 100644 --- a/DatabaseScripts/Install.sql +++ b/DatabaseScripts/Install.sql @@ -180,27 +180,29 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'字典名称' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'字典代码' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Dicts', @level2type=N'COLUMN',@level2name=N'Code' GO -/****** Object: Table [dbo].[Logs] Script Date: 10/28/2016 16:39:11 ******/ +GO +/****** Object: Table [dbo].[Logs] Script Date: 11/02/2016 15:33:28 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO +SET ANSI_PADDING ON +GO CREATE TABLE [dbo].[Logs]( - [ID] [int] IDENTITY(1,1) NOT NULL, - [OperationType] [int] NULL, - [UserID] [int] NULL, - [OperationTime] [datetime] NULL, - [TableName] [nvarchar](50) NULL, - [BusinessName] [nvarchar](50) NULL, - [PrimaryKey] [nvarchar](50) NULL, - [SqlText] [nvarchar](max) NULL, - [OperationIp] [nvarchar](50) NULL, + [ID] [int] IDENTITY(1,1) NOT NULL, + [OperationType] [int] NOT NULL, + [UserName] [varchar](50) NOT NULL, + [OperationTime] [datetime] NOT NULL, + [OperationIp] [nvarchar](50) NULL, + [Remark] [nvarchar](500) NULL, CONSTRAINT [PK_Logs] PRIMARY KEY CLUSTERED ( - [ID] ASC + [ID] ASC )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] ) ON [PRIMARY] GO +SET ANSI_PADDING OFF +GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Logs', @level2type=N'COLUMN',@level2name=N'ID' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Logs', @level2type=N'COLUMN',@level2name=N'OperationType'