简单说明
框架:.NET 6.0 MVC 数据库:sqlLite3(当然这是为考虑本地数据简单,可以考虑使用大型数据库)
一、界面效果展示
1、启动主页面
2、记录摘要界面
3、对应版本详细
二、实现代码逻辑
1、启动主页面
//关联日志文件写
builder.Logging.AddProvider(new CustomFileLoogerProvider(new CustomFileLoggerConfiguration()
{
MinLevel = (LogLevel)Enum.Parse(typeof(LogLevel), builder.Configuration["FileLogPath:MinLogLevel"]),
InLogLevel = LogLevel.Information,
LogPath = builder.Environment.ContentRootPath + builder.Configuration["FileLogPath:LogPath"]
}));
// Add services to the container.
builder.Services.AddControllersWithViews();
//配置DBServer
builder.Services.AddSingleton<IDBServer, DBServer>();
2、数据库相关
2.1 服务接口
public interface IDBServer
{
HomeViewData HomeViewData { get; }
string RecordViewData { get; }
List<RecordData> SNInfoLists { get; }
void UpDataHomeViewData();
void UpDataHistoricalSummaryViewData(string? sn);
void UpData();
/// <summary>
/// 更新历史版本信息
/// </summary>
/// <param name="sn">版本号</param>
/// <param name="dataTime">发行日期</param>
/// <param name="InfoStr">详细信息</param>
/// <returns></returns>
bool UpDataDetailedInformation(string sn, string dataTime, string InfoStr);
}
2.2 服务实现
public class SqlHelp
{
private string connectionString = @"Data Source=MyDatabase.db;";
private SQLiteConnection connection;
public ILogger<DBServer> Logger { get; }
public SqlHelp(ILogger<Server.DBServer> logger)
{
connection = new SQLiteConnection(connectionString);
Logger = logger;
}
//仅获取简要信息 包含日期和版本号
internal void GetReleaseBriefInfo(ref List<RecordData> list)
{
string sql = "SELECT * FROM ReRecord;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
connection.Open();
SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
DataTable dt = new DataTable();
adaptr.Fill(dt);
adaptr.Dispose();
command.Dispose();
list = new List<RecordData>(dt.Rows.Count);
for (int i = 0; i < dt.Rows.Count; i++)
{
list.Add(new RecordData(dt.Rows[i][2].ToString(), dt.Rows[i][1].ToString()));
}
connection.Close();
}
//根据sn查找完整信息
internal void GetReleaseInfo(string sn, ref List<RecordDataInfo> list)
{
string sql = "SELECT * FROM ReRecordDescribe where Sn=@sn;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
//SQLiteParameter[] para = new SQLiteParameter[]
//{
// new SQLiteParameter("@sn",sn)
//};
SQLiteParameter snPara = new SQLiteParameter("@sn", sn);
command.Parameters.Add(snPara);
connection.Open();
SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
DataTable dt = new DataTable();
adaptr.Fill(dt);
adaptr.Dispose();
command.Dispose();
list = new List<RecordDataInfo>(dt.Rows.Count);
for (int i = 0; i < dt.Rows.Count; i++)
{
list.Add(new RecordDataInfo(Convert.ToInt32(dt.Rows[i][2].ToString()), dt.Rows[i][3].ToString()));
}
connection.Close();
}
private bool FindSNInfo(string sn, string dateInfo)
{
string sql = "SELECT * FROM ReRecord where DateInfo=@DateInfo and Sn=@sn;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteParameter[] para = new SQLiteParameter[]
{
new SQLiteParameter("@sn",sn),
new SQLiteParameter("@DateInfo",dateInfo)
};
command.Parameters.AddRange(para);
connection.Open();
try
{
SQLiteDataAdapter adaptr = new SQLiteDataAdapter(command);
DataTable dt = new DataTable();
adaptr.Fill(dt);
adaptr.Dispose();
command.Dispose();
connection.Close();
if (dt.Rows.Count == 0)//没有进行增加
{
return false;
}
return true;
}
catch (Exception ex)
{
throw ex;
}
finally
{
connection.Close();
command.Dispose();
}
}
private void AddSnInfo(string sn, string dateInfo)
{
string sql = "INSERT INTO ReRecord(DateInfo,Sn) VALUES(@DateInfo,@sn);";
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteParameter[] para = new SQLiteParameter[]
{
new SQLiteParameter("@sn",sn),
new SQLiteParameter("@DateInfo",dateInfo)
};
command.Parameters.AddRange(para);
connection.Open();
try
{
int a = command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
connection.Close();
}
private void DelOrgDescribeInfo(string sn)
{
string sql = "DELETE FROM ReRecordDescribe WHERE Sn=@sn;";
SQLiteCommand command = new SQLiteCommand(sql, connection);
SQLiteParameter snPara = new SQLiteParameter("@sn", sn);
command.Parameters.Add(snPara);
connection.Open();
try
{
int a = command.ExecuteNonQuery();
}
catch (Exception ex)
{
throw ex;
}
connection.Close();
}
private bool AddDescribeInfo(string sn, List<RecordDataInfo> list)
{
string sql = "INSERT INTO ReRecordDescribe(Sn,Num,Describe) VALUES(@sn,@Num,@Describe);";
connection.Open();
SQLiteTransaction tx = connection.BeginTransaction();
SQLiteCommand command = new SQLiteCommand(sql, connection);
command.Transaction = tx;
try
{
for (int i = 0; i < list.Count; i++)
{
SQLiteParameter[] para = new SQLiteParameter[]
{
new SQLiteParameter("@sn",sn),
new SQLiteParameter("@Num",list[i].Num),
new SQLiteParameter("@Describe",list[i].Describe)
};
command.Parameters.AddRange(para);
int a = command.ExecuteNonQuery();
}
tx.Commit();
command.Dispose();
}
catch (Exception ex)
{
Logger.LogWarning("AddDescribeInfo:" + ex.Message);
tx.Rollback();
}
connection.Close();
return true;
}
//根据sn查找完整信息
internal void UpdateInfo(string sn, string dateInfo, List<RecordDataInfo> list)
{
if (!FindSNInfo(sn, dateInfo))
{
AddSnInfo(sn, dateInfo);
}
DelOrgDescribeInfo(sn);
AddDescribeInfo(sn, list);
}
}
3、日志文件写实现
3.1 ILogger实现
public class CustomFileLogger : ILogger
{
private readonly string _name;
private readonly CustomFileLoggerConfiguration _config;
private LogLevel _logLevel;
public CustomFileLogger(string name, CustomFileLoggerConfiguration config)
{
_name = name;
_config = config;
if (config != null)
{
if (!Directory.Exists(config.LogPath))
{
Directory.CreateDirectory(config.LogPath);
}
}
}
public IDisposable BeginScope<TState>(TState state)
{
return null;
}
public bool IsEnabled(LogLevel logLevel)
{
return logLevel == _config.InLogLevel;
}
public void Log<TState>(LogLevel logLevel, EventId eventId, TState state, Exception? exception, Func<TState, Exception?, string> formatter)
{
if (!IsEnabled(logLevel))
{
return;
}
_logLevel = logLevel;
FileLog($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:fff")} - {logLevel.ToString()} - {_name} - {formatter(state, exception)} \n");
}
private void FileLog(string strLog)
{
string fileName = DateTime.Now.ToString("yyyy-MM-dd") + "_" + _logLevel.ToString() + ".txt";
string filePath = _config.LogPath + "\\" + fileName;
File.AppendAllText(filePath, strLog);
// File.AppendAllTextAsync(filePath, strLog);
}
}
3.2 ILoggerProvider实现
public class CustomFileLoogerProvider:ILoggerProvider
{
private readonly CustomFileLoggerConfiguration _config;
public CustomFileLoogerProvider(CustomFileLoggerConfiguration config)
{
_config = config;
}
public ILogger CreateLogger(string categoryName)
{
return new CustomFileLogger(categoryName,_config);
}
public void Dispose()
{
}
}
4、业务调用
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IDBServer dBServer;
public HomeController(ILogger<HomeController> logger, IDBServer dBServer)
{
_logger = logger;
this.dBServer = dBServer;
}
public IActionResult Index()
{
dBServer.UpDataHomeViewData();
return View("Index", dBServer.HomeViewData);
}
public IActionResult HistoricalSummary(string? SN)
{
dBServer.UpDataHistoricalSummaryViewData(SN);
return View("HistoricalSummary", dBServer.HomeViewData);
}
public IActionResult RecordInfo()
{
dBServer.UpData();
this.ViewData["info"] = DateTime.Now.ToString() + dBServer.RecordViewData;
return View("RecordInfo", dBServer.SNInfoLists);
}
[HttpPost]
public string PostInfo(string SN, string DateTime, string Info)
{
if (dBServer.UpDataDetailedInformation(SN, DateTime, Info))
{
return "更新成功!";
}
return "更新失败!";
}
public IActionResult About()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
} public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly IDBServer dBServer;
public HomeController(ILogger<HomeController> logger, IDBServer dBServer)
{
_logger = logger;
this.dBServer = dBServer;
}
public IActionResult Index()
{
dBServer.UpDataHomeViewData();
return View("Index", dBServer.HomeViewData);
}
public IActionResult HistoricalSummary(string? SN)
{
dBServer.UpDataHistoricalSummaryViewData(SN);
return View("HistoricalSummary", dBServer.HomeViewData);
}
public IActionResult RecordInfo()
{
dBServer.UpData();
this.ViewData["info"] = DateTime.Now.ToString() + dBServer.RecordViewData;
return View("RecordInfo", dBServer.SNInfoLists);
}
[HttpPost]
public string PostInfo(string SN, string DateTime, string Info)
{
if (dBServer.UpDataDetailedInformation(SN, DateTime, Info))
{
return "更新成功!";
}
return "更新失败!";
}
public IActionResult About()
{
return View();
}
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
}
}