Commit a3a8c203 authored by 段廷瑞's avatar 段廷瑞

【编号:25241】工具平台:减少数据库依赖

parent 9d6c2bdf
......@@ -29,6 +29,11 @@ namespace Tools.MyCommon
/// </summary>
/// <param name="action"></param>
public static void Write(string action)
{
Task.Run(() => WriteCore(action));
}
private static void WriteCore(string action)
{
lock (_locker)
{
......@@ -39,6 +44,11 @@ namespace Tools.MyCommon
VALUES ( '{LoginInfo.UserName}', '{action}', GETDATE(), '{APP.TOKEN}')";
_db?.ExecNonSql(sql);
}
catch (Exception ex)
{
// 日志是尽力而为能力,数据库故障不得影响业务窗口。
System.Diagnostics.Debug.WriteLine("写入工具日志失败:" + ex.Message);
}
finally
{
Monitor.Pulse(_locker); //释放锁
......
......@@ -23,7 +23,7 @@ namespace Tools.MyCommon
/// 数据访问对象
/// <para>通过InitDBHelper()方法初始化</para>
/// </summary>
public DBHelper _db { get; private set; }
public DBHelper _db { get; protected set; }
/// <summary>
/// 全局数据集
/// </summary>
......@@ -52,12 +52,6 @@ namespace Tools.MyCommon
throw new Exception("数据库链接为空,请检查!");
}
this._db = new DBHelper(link);
if (!this._db.ConnectionTest())
{
this._db = null;
// throw new Exception($"数据库链接无效!\r\n链接:{link}"); // 给提示即可,否则无法操作下去,即使想改链接。
MessageBox.Show($"数据库链接无效!\r\n链接:{link}");
}
}
/// <summary>
/// 初始化数据库访问对象
......
......@@ -31,7 +31,7 @@ namespace Tools.MyData
/// <param name="link">链接</param>
public DBHelper(string link)
{
this._link = link;
this._link = Utils.NormalizeDbLinkString(link);
}
/// <summary>
/// 构造函数:数据访问帮助类
......@@ -39,7 +39,7 @@ namespace Tools.MyData
/// <param name="m"></param>
public DBHelper(DbItemModel m)
{
this._link = m.LinkString;
this._link = Utils.NormalizeDbLinkString(m.LinkString);
}
/// <summary>
......
......@@ -604,6 +604,21 @@ namespace Tools.MyUtils
#region 数据库链接处理
/// <summary>
/// 为历史配置和用户输入的连接字符串补充短连接超时。
/// </summary>
public static string NormalizeDbLinkString(string link)
{
if (string.IsNullOrWhiteSpace(link))
return link;
var parts = link.Split(';');
if (parts.Any(p => p.TrimStart().StartsWith("Connect Timeout=", StringComparison.OrdinalIgnoreCase)))
return link;
return link.TrimEnd().TrimEnd(';') + ";Connect Timeout=5";
}
/// <summary>
/// 获取204的数据库链接
/// </summary>
......@@ -611,7 +626,7 @@ namespace Tools.MyUtils
/// <returns></returns>
public static string GetDbLinkString204(string dbName)
{
return $"Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog={dbName};Data Source=jhdsoft.gicp.net,3204";
return $"Password=sa;Persist Security Info=True;User ID=sa;Initial Catalog={dbName};Data Source=jhdsoft.gicp.net,3204;Connect Timeout=5";
}
/// <summary>
/// 生成数据库链接字符串
......@@ -623,7 +638,7 @@ namespace Tools.MyUtils
/// <returns></returns>
public static string GetDbLinkString(string link, string userId, string pwd, string dbName)
{
return $"Password={pwd};Persist Security Info=True;User ID={userId};Initial Catalog={dbName};Data Source={link}";
return $"Password={pwd};Persist Security Info=True;User ID={userId};Initial Catalog={dbName};Data Source={link};Connect Timeout=5";
}
/// <summary>
/// 生成数据库链接字符串
......
......@@ -46,12 +46,27 @@ namespace Tools.UI.sys
{
//初始化模块表
this.ModuleTableList = new List<TQuery> { new TQuery("FTT_UserDemand", "SELECT * FROM FTT_UserDemand ") };
//初始化数据访问对象
this.InitDBHelper(Utils.GetDbLinkString204("FTT_Work"));
//初始化界面
this.InitUI();
//异步装载数据
Task.Run(() => this.InitData());
Task.Run(() => this.LoadDataAsync());
}
private void LoadDataAsync()
{
try
{
var helper = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
var data = helper.GetData(this.ModuleTableList, true);
this.AsyncUI(() =>
{
this._db = helper;
this._ds = data;
this._dt = this._ds.Tables[0];
});
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("需求反馈数据暂时无法加载。\r\n" + ex.Message));
}
}
public override void InitData()
......@@ -86,6 +101,11 @@ namespace Tools.UI.sys
private void BtnSubmit_Click(object sender, EventArgs e)
{
if (this._dt == null)
{
Utils.Tip("数据正在加载,请稍后重试!");
return;
}
var text = this.tbDemand.Text;
if (string.IsNullOrEmpty(text))
{
......@@ -198,6 +218,11 @@ namespace Tools.UI.sys
/// <param name="status"></param>
private void SetStatus(int status)
{
if (this._dt == null)
{
Utils.Tip("数据正在加载,请稍后重试!");
return;
}
if (this.dgvHistory.SelectedRows.Count == 0)
{
MessageBox.Show("请先选择一行信息!", "提示");
......
......@@ -10,6 +10,7 @@ using System.Threading.Tasks;
using System.Windows.Forms;
//
using Tools.MyCommon;
using Tools.MyData;
using Tools.MyUtils;
using Tools.UI.Models;
using Tools.UI.Popups;
......@@ -29,21 +30,45 @@ namespace Tools.UI
}
private void wAppModel_Load(object sender, EventArgs e)
{
var link = Utils.GetDbLinkString204("FTT");
this.tstbLinkString.Text = Utils.GetDbItemModel(link).ToString();
this.InitDBHelper(link);
this.InitData();
this.tstbLinkString.Text = "FTT(jhdsoft.gicp.net,3204)";
Task.Run(() => this.LoadDataAsync());
}
public override void InitData()
private void LoadDataAsync()
{
try
{
var link = Utils.GetDbLinkString204("FTT");
var helper = new DBHelper(link);
var data = LoadAppModels(helper);
this.AsyncUI(() =>
{
this._db = helper;
this.tstbLinkString.Text = Utils.GetDbItemModel(link).ToString();
this.dgvAppModel.DataSource = data;
});
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("应用模块数据暂时无法加载。\r\n" + ex.Message));
}
}
private DataTable LoadAppModels(DBHelper helper)
{
string sql = $@"
SELECT a.ID,a.Code,a.Name,a.PrevID,b.Name AS PrevName,a.ModuleName
FROM dbo.App_SysBusinessModel a
INNER JOIN dbo.App_SysBusinessModel b ON a.PrevID=b.ID
WHERE {strWhere} ORDER BY A.ID DESC";
return helper.GetDataTable(sql, "结果列表");
}
dgvAppModel.DataSource = this._db.GetDataTable(sql, "结果列表");
public override void InitData()
{
if (this._db == null)
return;
this.dgvAppModel.DataSource = LoadAppModels(this._db);
}
private void tsbDB_Click(object sender, EventArgs e)
......
......@@ -47,8 +47,18 @@ namespace Tools.UI
private void wAuditDemo_Load(object sender, EventArgs e)
{
this.InitData();
this.InitUI();
Task.Run(() =>
{
try
{
this.InitData();
this.AsyncUI(() => this.InitUI());
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("审批示例数据暂时无法加载。\r\n" + ex.Message));
}
});
}
public override void InitData()
......@@ -56,7 +66,7 @@ namespace Tools.UI
#region 初始化数据库对象
string link = Utils.GetDbLinkString204("FTT_PDM");
this.InitDBHelper(link);
this._db = new DBHelper(link);
#endregion
#region 初始化模块信息
......
......@@ -24,19 +24,35 @@ namespace Tools.UI
}
private void wEvaluationOfEmployee_Load(object sender, EventArgs e)
{
//初始化保存结构
this.ModuleTableList = new List<MyData.TQuery> {
new TQuery("FTT_DbLinkManager"),
};
//初始化数据库链接
var link = Utils.GetDbLinkString204("FTT_Work");
this.InitDBHelper(link);
//初始化
this.InitData();
this.InitUI();
Task.Run(() => this.LoadDataAsync());
}
private void LoadDataAsync()
{
try
{
var tableList = new List<MyData.TQuery> { new TQuery("FTT_DbLinkManager") };
var helper = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
var data = helper.GetData(tableList, true);
this.AsyncUI(() =>
{
this._db = helper;
this.ModuleTableList = tableList;
this._ds = data;
this.dgvDetail.DataSource = this._ds.Tables[0].DefaultView;
});
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("数据库连接记录暂时无法加载。\r\n" + ex.Message));
}
}
public override void InitData()
{
if (this._db == null)
return;
this._ds = this._db.GetData(this.ModuleTableList, true);
}
public override void InitUI()
......@@ -47,6 +63,11 @@ namespace Tools.UI
}
public override bool SaveCheck()
{
if (this._ds == null || this._db == null)
{
Utils.Tip("数据库尚未连接,请稍后重试!");
return false;
}
if (this.tbNote.Text == string.Empty)
{
Utils.Tip("描述必须输入!");
......
......@@ -43,19 +43,38 @@ namespace Tools.UI
}
private void wEvaluationOfEmployee_Load(object sender, EventArgs e)
{
//初始化保存结构
this.ModuleTableList = new List<MyData.TQuery> {
new TQuery("FTT_EvaluationOfEmployee"),
};
//初始化数据库链接
var link = Utils.GetDbLinkString204("FTT_Work");
this.InitDBHelper(link);
//初始化
this.InitData();
this.InitUI();
//窗口先显示,数据库加载在后台执行。
Task.Run(() => this.LoadDataAsync());
}
IsShown = true;
this.tscbMonth.SelectedIndex = 0;
private void LoadDataAsync()
{
try
{
var tableList = new List<MyData.TQuery> { new TQuery("FTT_EvaluationOfEmployee") };
var helper = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
var oldDb = this._db;
var oldTables = this.ModuleTableList;
this._db = helper;
this.ModuleTableList = tableList;
this.InitData();
var data = this._ds;
this._db = oldDb;
this.ModuleTableList = oldTables;
this.AsyncUI(() =>
{
this._db = helper;
this.ModuleTableList = tableList;
this._ds = data;
this.InitUI();
this.IsShown = true;
this.tscbMonth.SelectedIndex = 0;
});
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("员工考核数据暂时无法加载。\r\n" + ex.Message));
}
}
public override void InitData()
{
......@@ -102,9 +121,19 @@ namespace Tools.UI
return true;
}
private bool EnsureDataLoaded()
{
if (this._db != null && this._ds != null && this._ds.Tables.Count > 0)
return true;
Utils.Tip("数据正在加载,请稍后重试!");
return false;
}
//事件:新增记录
private void tsbAdd_Click(object sender, EventArgs e)
{
if (!this.EnsureDataLoaded())
return;
if (!CheckBeforeEdit())
return;
IsAdd = true;
......@@ -120,6 +149,8 @@ namespace Tools.UI
//事件:更新记录
private void tsbUpdate_Click(object sender, EventArgs e)
{
if (!this.EnsureDataLoaded())
return;
if (!CheckBeforeEdit())
return;
if (CurrentEditRow == null)
......@@ -142,6 +173,8 @@ namespace Tools.UI
//事件:生成报告
private void tsbGenReport_Click(object sender, EventArgs e)
{
if (!this.EnsureDataLoaded())
return;
if (this.tscbMonth.Text.Trim() == "")
{
Utils.Tip("请先选择月份!");
......
......@@ -46,8 +46,10 @@ namespace Tools.UI
}
public override void InitData()
{
this.AsyncUI(() => {
this._ds = this._db.GetData(this.ModuleTableList, true);
var dataSet = this._db.GetData(this.ModuleTableList, true);
this.AsyncUI(() =>
{
this._ds = dataSet;
this.dgvDetail.DataSource = this._ds.Tables[0].DefaultView;
//为优化取数速度虚构dData列,虚构列默认为只读,这里改为可编辑,方便更新操作
this._ds.Tables[0].Columns["dData"].ReadOnly = false;
......
......@@ -37,27 +37,68 @@ namespace Tools.UI
private void wTaskBoard_Load(object sender, EventArgs e)
{
//初始化数据访问对象
var link = Utils.GetDbLinkString204("FTT_Work");
this._db = new DBHelper(link);
//初始化界面
//窗口先显示,报表数据在后台加载。
this.dataGridView1.AllowUserToAddRows = false;
this.dataGridView1.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
//初始化数据
this.Initialize();
Task.Run(() => this.LoadDataAsync());
}
private void wTaskBoard_Shown(object sender, EventArgs e)
private void LoadDataAsync()
{
try
{
var helper = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
var data = LoadTaskData(helper);
this.AsyncUI(() =>
{
this._db = helper;
this._dt = data;
this.BindTaskData();
});
}
catch (Exception ex)
{
this.AsyncUI(() => Utils.Tip("任务看板数据暂时无法加载。\r\n" + ex.Message));
}
}
private DataTable LoadTaskData(DBHelper helper)
{
var sql = $@"EXEC dbo.SP_RPT_KFDJDB_20191031 @PageSize = 1000,@PageIndex = 1, @Flag = 1, @WorkTeamID = 1";
var data = helper.GetDataTable(sql, "TaskDetail", false);
foreach (DataColumn dc in data.Columns)
{
if (dc.ColumnName.Contains("Color"))
{
this.ColorColumn = dc.ColumnName;
continue;
}
dc.ColumnName = dc.ColumnName.Split('_')[0];
}
return data;
}
private void BindTaskData()
{
//初始化单元格背景
this.SetComboItems(this.cbProjectName, "项目名称");
this.SetComboItems(this.cbInChargeUser, "负责人");
this.SetComboItems(this.cbTaskState, "状态");
this._dt.DefaultView.Sort = "[项目交期] DESC";
this.dataGridView1.DataSource = this._dt.DefaultView;
this.SetGridForeColor();
}
private void wTaskBoard_Shown(object sender, EventArgs e)
{
//双击查看任务明细初始化
this._html = File.ReadAllText($@"{Utils.TestPath}\TaskDetail.html");
this._html = File.Exists($@"{Utils.TestPath}\TaskDetail.html")
? File.ReadAllText($@"{Utils.TestPath}\TaskDetail.html") : "<p>[describle]</p>";
this.frmView = new wBasic() { BackColor = Color.White, Size = new Size(700, 500) };
this._browser = new WebBrowser() { Parent = this.frmView, Dock = DockStyle.Fill };
this.frmView.FormClosing += FrmView_FormClosing;
//表格事件
this.dataGridView1.Sorted += DataGridView1_Sorted;
this.dataGridView1.DoubleClick += DataGridView1_DoubleClick;
if (this._dt != null)
this.SetGridForeColor();
}
/// <summary>
......
......@@ -54,14 +54,25 @@ namespace Tools.UI
public override void InitData()
{
this.AsyncUI(() => {
var link = Utils.GetDbLinkString204("FTT_Work");
this.InitDBHelper(link);
this.ModuleTableList = new List<TQuery> { new TQuery("AC_User", "SELECT * FROM dbo.AC_User") };
this._ds = this._db.GetData(this.ModuleTableList, true);
//图片分离兼容处理
var link = Utils.GetDbLinkString204("FTT_Work");
var helper = new DBHelper(link);
var tableList = new List<TQuery> { new TQuery("AC_User", "SELECT * FROM dbo.AC_User") };
var dataSet = helper.GetData(tableList, true);
try
{
// 文件服务配置和图片下载也属于网络操作,不能放到 UI 线程。
SegPictureConfig.Init(link);
Utils.FetchImage(this._ds);
Utils.FetchImage(dataSet);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine("文件服务不可用:" + ex.Message);
}
this.AsyncUI(() =>
{
this._db = helper;
this.ModuleTableList = tableList;
this._ds = dataSet;
//绑定数据源
this.dgvDetail.DataSource = this._ds.Tables[0].DefaultView;
});
......
......@@ -55,11 +55,14 @@ namespace Tools
{
//生成标识
APP.TOKEN = Guid.NewGuid().ToString();
//初始化数据库链接
var link = Utils.GetDbLinkString204("FTT_Work");
this._db = new DBHelper(link);
//初始化登录信息
this.InitLoginInfo();
// 主界面和静态菜单不依赖远程数据库;登录/在线功能按需创建访问对象。
this._db = null;
//后台恢复登录信息;查询失败时保持访客状态。
Task.Run(() =>
{
try { this.InitLoginInfo(); }
catch (Exception ex) { Debug.WriteLine("恢复登录信息失败:" + ex.Message); }
});
//渲染菜单
this.RenderMenu();
}
......@@ -102,17 +105,29 @@ namespace Tools
this.btnMaximized.MouseLeave += BtnWinCtrl_MouseLeave;
this.btnClosed.MouseEnter += BtnClosed_MouseEnter;
this.btnClosed.MouseLeave += BtnClosed_MouseLeave;
//版本号处理
Task.Run(() => this.AsyncUI(() => {
var dt = this._db.GetDataTable($@"
//版本号处理:数据库访问必须在后台完成,失败不影响主界面。
Task.Run(() =>
{
try
{
using (var db = new DBHelper(Utils.GetDbLinkString204("FTT_Work")))
{
var dt = db.GetDataTable($@"
SELECT TOP 1 CAST(DATENAME(YEAR, UDate) AS VARCHAR(10)) + '.' + CAST(DATENAME(MONTH, UDate) AS VARCHAR(10)) + '.' + CAST(COUNT(*) AS VARCHAR(10)) AS SysVersion
FROM dbo.FTT_AutoUpdate
GROUP BY DATENAME(YEAR, UDate), DATENAME(MONTH, UDate)
ORDER BY DATENAME(YEAR, UDate) DESC, DATENAME(MONTH, UDate) DESC", "version", false);
this.lbSysVersion.Text = dt.DefaultView.Count == 0 ? $"2021.0.1" : $"{dt.DefaultView[0][0]}";
}));
//日志记录
UserLog.Write("打开系统");
var version = dt.DefaultView.Count == 0 ? "2021.0.1" : $"{dt.DefaultView[0][0]}";
this.AsyncUI(() => this.lbSysVersion.Text = version);
}
}
catch (Exception ex)
{
Debug.WriteLine("读取远程版本失败:" + ex.Message);
}
});
//数据库不可用时,日志不能影响窗口生命周期。
try { UserLog.Write("打开系统"); } catch { }
}
private void WMain_FormClosing(object sender, FormClosingEventArgs e)
......@@ -388,7 +403,12 @@ namespace Tools
var m = Utils.GetJsonConfig<LoginMemory>();
//检查更新
var updateTime = m.UpdateTime;
var dt =this._db.GetDataTable($"SELECT TOP 1 UDate, URemark FROM dbo.FTT_AutoUpdate WHERE UDate > '{updateTime}' ORDER BY UDate DESC", "FTT_AutoUpdate");
var db = this._db;
if (db == null)
db = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
try
{
var dt = db.GetDataTable($"SELECT TOP 1 UDate, URemark FROM dbo.FTT_AutoUpdate WHERE UDate > '{updateTime}' ORDER BY UDate DESC", "FTT_AutoUpdate");
if (dt.DefaultView.Count > 0)
{
var drv = dt.DefaultView[0];
......@@ -407,22 +427,40 @@ namespace Tools
//退出运行环境
Application.Exit();
}
else if(!IsSilentWhenNotFound)
else if (!IsSilentWhenNotFound)
{
Utils.Tip("当前已是最新版本!");
}
}
}
catch (Exception ex)
{
if (!IsSilentWhenNotFound)
Utils.Tip("暂时无法连接更新服务,请稍后重试。\r\n" + ex.Message);
}
}
/// <summary>
/// 查看更新记录
/// </summary>
private void ViewUpdateLog()
{
StringBuilder sb = new StringBuilder("*注:仅展示最近20条更新记录\r\n");
var dt = this._db.GetDataTable("SELECT TOP 20 ROW_NUMBER() OVER(ORDER BY ID) AS SN, UDate, URemark FROM dbo.FTT_AutoUpdate ORDER BY ID DESC", "Log", false);
foreach (DataRowView r in dt.DefaultView)
var db = this._db;
if (db == null)
db = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
try
{
var date = (r["UDate"] as DateTime?)?.ToString("yyyy/MM/dd HH:mm:ss.fff");
sb.Append($"{new string('-', 100)}\r\n版本序号:{r["SN"]}\r\n更新时间:{date}\r\n{r["URemark"].ToString().Trim()}\r\n");
var dt = db.GetDataTable("SELECT TOP 20 ROW_NUMBER() OVER(ORDER BY ID) AS SN, UDate, URemark FROM dbo.FTT_AutoUpdate ORDER BY ID DESC", "Log", false);
foreach (DataRowView r in dt.DefaultView)
{
var date = (r["UDate"] as DateTime?)?.ToString("yyyy/MM/dd HH:mm:ss.fff");
sb.Append($"{new string('-', 100)}\r\n版本序号:{r["SN"]}\r\n更新时间:{date}\r\n{r["URemark"].ToString().Trim()}\r\n");
}
}
catch (Exception ex)
{
Utils.Tip("暂时无法读取更新记录。\r\n" + ex.Message);
return;
}
//
Utils.Tip(sb.ToString(), 600, 400);
......@@ -439,8 +477,7 @@ namespace Tools
if (result == DialogResult.No)
return;
}
//日志记录
UserLog.Write("退出系统");
try { UserLog.Write("退出系统"); } catch { }
//关闭窗体
this.Close();
}
......@@ -530,8 +567,7 @@ namespace Tools
frm.Dock = DockStyle.Fill;
frm.Show();
}
//日志记录
UserLog.Write($"打开模块:{page.Text}");
try { UserLog.Write($"打开模块:{page.Text}"); } catch { }
//选中标签页
this.tabControl1.SelectedTab = page;
page.Refresh();
......@@ -544,7 +580,7 @@ namespace Tools
{
if (page.Name != nameof(HomePage))
{
UserLog.Write($"关闭模块:{page.Text}"); //日志记录
try { UserLog.Write($"关闭模块:{page.Text}"); } catch { } //日志记录
this.OpenedList.Remove(page.Text); //移除列表
this.tabControl1.TabPages.Remove(page); //移除页面
......@@ -655,6 +691,9 @@ namespace Tools
private void InitLoginInfo()
{
var m = Utils.GetJsonConfig<LoginMemory>();
var db = this._db;
if (db == null)
db = new DBHelper(Utils.GetDbLinkString204("FTT_Work"));
//获取登录信息
var loginInfo = m.LoginInfo;
if (!string.IsNullOrEmpty(loginInfo))
......@@ -666,7 +705,7 @@ namespace Tools
CAST(CASE WHEN UserType = 5311 THEN 1 ELSE 0 END AS BIT) AS IsStaff
FROM dbo.AC_User
WHERE ISNULL(IsStop, 0) = 0 and ID = {Utils.Decryptor(loginInfo)}";
var dt = this._db.GetDataTable(sql, "user", false);
var dt = db.GetDataTable(sql, "user", false);
if (dt.DefaultView.Count > 0)
{
var userName = dt.DefaultView[0]["UserName"].ToString();
......@@ -694,7 +733,11 @@ namespace Tools
}
}
//设置登录用户名
this.SetLoginUserName();
this.AsyncUI(() =>
{
this.SetLoginUserName();
this.RenderMenu();
});
}
/// <summary>
/// 显示登录窗口
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment