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.
 
 
 

2723 lines
125 KiB

using System.ComponentModel;
using System.Data;
using System.Text;
using MySql.Data.MySqlClient;
namespace Tiobon.PublishHelper
{
public partial class Form_Main : Form
{
#region 初始化
public Form_Main()
{
InitializeComponent();
}
private void Form_Main_Load(object sender, EventArgs e)
{
Utility.Init();
Init();
}
Thread t_RefreshServer;
/// <summary>
/// 重要:规约要求开发环境必装dev目录下,运维测试必装root目录下
/// </summary>
private string SelectEnv = string.Empty;
/// <summary>
/// 冗余多开发环境docker地址后缀
/// </summary>
private string SelectCmdSuffix = string.Empty;
private void Init()
{
lb_Logger.ItemHeight = 16;
treeView_Main.ItemHeight = 20;
Utility.SendLogHandle += SendLog;
Utility.SetStatus += SetStatus;
Utility.SetProgressBarValue += SetProgressBar;
Utility.SetProgressBarVisible += SetProgressBarVisible;
tssl_ServerStatus.Visible = false;
tssl_Split3.Visible = false;
RefreshTree();
cb_webapi.Checked = Utility.m_OprateLog.Webapi;
cb_hfs.Checked = Utility.m_OprateLog.Hfs;
cb_job.Checked = Utility.m_OprateLog.Job;
cb_rtm.Checked = Utility.m_OprateLog.Rtm;
cb_remove.Checked = Utility.m_OprateLog.Remove;
cb_build.Checked = Utility.m_OprateLog.Build;
cb_web.Checked = Utility.m_OprateLog.Web;
cb_pad.Checked = Utility.m_OprateLog.Pad;
timer_Main.Start();
if (!string.IsNullOrEmpty(Utility.m_OprateLog.ServerName) && !string.IsNullOrEmpty(Utility.m_OprateLog.HospitalName))
{
foreach (TreeNode node in treeView_Main.Nodes)
{
if (node.Name == Utility.m_OprateLog.ServerName)
{
foreach (TreeNode nodeItem in node.Nodes)
{
if (nodeItem.Name == Utility.m_OprateLog.HospitalName)
{
treeView_Main.SelectedNode = nodeItem;
break;
}
}
break;
}
}
}
t_RefreshServer = new Thread(new ThreadStart(delegate
{
RefreshServer();
}));
t_RefreshServer.Start();
//SetFont(this);
}
Font defaultFont = new Font("宋体", 11, FontStyle.Regular);
void SetFont(Control control)
{
control.Font = defaultFont;
if (control.HasChildren)
{
foreach (Control item in control.Controls)
{
if (item is GroupBox)
continue;
SetFont(item);
}
}
}
//private double m_CpuMax = 0;
private double m_MemMax = 0;
private double m_DiskMax = 0;
private void RefreshServer()
{
while (!b_Closed)
{
if (DateTime.Now.Second % 5 == 0)
{
try
{
BeginInvoke(new EventHandler(delegate
{
(bool Success, double Cpu, double MemTotal, double MemUsed, double Disk) res = (false, 0.0, 0.0, 0.0, 0.0);
DevServer server = null;
var node = treeView_Main.SelectedNode;
if (node != null)
{
if (node.Tag.ToString() != "hospital")
{
server = Utility.m_DevServers.Where(o => o.Name == node.Name).FirstOrDefault();
}
else
{
server = Utility.m_DevServers.Where(o => o.Name == node.Parent.Name).FirstOrDefault();
}
if (server != null)
{
res = Utility.GetServerStatus(server);
}
}
Color color = System.Drawing.SystemColors.ControlText;
if (server != null && res.Success)
{
var mused = Math.Round(100.0 * res.MemUsed / res.MemTotal, 2);
tssl_ServerStatus.Visible = true;
tssl_Split3.Visible = true;
tssl_ServerStatus.Text = $"{server.Ip}(已用): Cpu {res.Cpu}% Mem {mused}% Disk {res.Disk}%";
//if (res.Cpu > 90 && res.Cpu < 100 && m_CpuMax != res.Cpu)
//{
// m_CpuMax = res.Cpu;
// Utility.SendLog($"{server.Ip} Cpu使用率过高 {res.Cpu}%");
//}
if (mused > 90 && m_MemMax != mused)
{
m_MemMax = mused;
//Utility.SendLog($"{server.Ip} 物理内存使用率过高 {mused}%");
color = Color.Red;
}
if (res.Disk > 90 && m_DiskMax != res.Disk)
{
m_DiskMax = res.Disk;
//Utility.SendLog($"{server.Ip} 磁盘使用率过高 {res.Disk}%");
color = Color.Red;
}
tssl_ServerStatus.ForeColor = color;
}
else
{
tssl_ServerStatus.ForeColor = color;
tssl_ServerStatus.Visible = false;
tssl_Split3.Visible = false;
}
}));
}
catch { }
}
System.Threading.Thread.Sleep(1000);
}
}
bool b_Closed = false;
private void Form_Main_FormClosing(object sender, FormClosingEventArgs e)
{
if (b_Closed)
return;
if (e.CloseReason == CloseReason.UserClosing || e.CloseReason == CloseReason.None)
{
if (MessageBox.Show("确定关闭发布工具?", "提示", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
{
b_Closed = true;
ExitSystem();
}
else
{
e.Cancel = true;
}
}
else
{
b_Closed = true;
ExitSystem();
}
}
private void ExitSystem()
{
try
{
var node = treeView_Main.SelectedNode;
if (node != null)
{
if (node.Tag.ToString() == "hospital")
{
Utility.m_OprateLog.ServerName = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault()?.Name;
Utility.m_OprateLog.HospitalName = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault()?.Hospitals?.Where(o => o.Name == node.Name).FirstOrDefault()?.Name;
}
}
timer_Main.Stop();
t_RefreshServer.Abort();
Utility.m_OprateLog.Webapi = cb_webapi.Checked;
Utility.m_OprateLog.Hfs = cb_hfs.Checked;
Utility.m_OprateLog.Job = cb_job.Checked;
Utility.m_OprateLog.Rtm = cb_rtm.Checked;
Utility.m_OprateLog.Remove = cb_remove.Checked;
Utility.m_OprateLog.Build = cb_build.Checked;
Utility.m_OprateLog.Web = cb_web.Checked;
Utility.m_OprateLog.Pad = cb_pad.Checked;
Utility.SaveOprateLog();
//Environment.Exit(0);
}
catch { }
}
private void RefreshTree()
{
tssl_Dev.Text = $"Dev:Server - {Utility.m_DevServers.Count} Hospital - {Utility.m_DevServers.Sum(o => o.Hospitals.Count)}";
tssl_Publish.Text = $"Pulish:Server - {Utility.m_PublishServers.Count} File - {Utility.m_PublishServers.Sum(o => o.Folders.Sum(f => f.Files.Count))}";
treeView_Main.Nodes.Clear();
Utility.m_DevServers.ForEach(server =>
{
TreeNode tnServer = new TreeNode()
{
Tag = "server",
Name = server.Name,
Text = $"{server.Name}"
};
server?.Hospitals?.ForEach(hospital =>
{
tnServer.Nodes.Add(new TreeNode()
{
Tag = "hospital",
Name = hospital.Name,
Text = $"{hospital.Name}({hospital.DefaultFort})"
});
});
treeView_Main.Nodes.Add(tnServer);
});
treeView_Main.ExpandAll();
}
#endregion
#region Tree操作
private bool HasSelectdServer(out DevServer server)
{
server = null;
var node = treeView_Main.SelectedNode;
if (node is null || node.Tag.ToString() != "server")
return false;
server = Utility.m_DevServers.Where(o => o.Name == node.Name).FirstOrDefault();
if (server is null)
return false;
return true;
}
private bool HasSelectdHospital(out DevServer server, out Hospital hospital)
{
server = null;
hospital = null;
var node = treeView_Main.SelectedNode;
if (node is null || node.Tag.ToString() != "hospital")
return false;
server = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault();
if (server is null)
return false;
hospital = server?.Hospitals?.Where(o => o.Name == node.Name).FirstOrDefault();
if (hospital is null)
return false;
return true;
}
private void contextMenuStrip_Tree_Opening(object sender, CancelEventArgs e)
{
if (treeView_Main.SelectedNode == null)
return;
//选中服务器
if (treeView_Main.SelectedNode.Tag.ToString() == "server")
{
var server = Utility.m_DevServers.Where(o => o.Name == treeView_Main.SelectedNode.Name).FirstOrDefault();
if (server?.Ip == Utility.m_TestServerIp)
{
foreach (ToolStripItem item in contextMenuStrip_Tree.Items)
{
item.Visible = false;
}
}
else
{
foreach (ToolStripItem item in contextMenuStrip_Tree.Items)
{
if (item.Name == "tsmi_RemoveLocker" || item.Name == "tsmi_HospitalCreate")
{
item.Visible = true;
}
else
{
item.Visible = false;
}
}
}
}
else
{
//选中医院
var server = Utility.m_DevServers.Where(o => o.Name == treeView_Main.SelectedNode.Parent.Name).FirstOrDefault();
if (server?.Ip == Utility.m_TestServerIp)
{
foreach (ToolStripItem item in contextMenuStrip_Tree.Items)
{
item.Visible = false;
}
}
else
{
foreach (ToolStripItem item in contextMenuStrip_Tree.Items)
{
if (item.Name == "tsmi_RemoveLocker")
{
item.Visible = false;
}
else
{
item.Visible = true;
}
}
}
}
}
private void treeView_Main_AfterSelect(object sender, TreeViewEventArgs e)
{
Thread t = new Thread(new ThreadStart(delegate
{
RefreshDocker();
}));
t.Start();
}
private void RefreshDocker(TreeNode node = null)
{
try
{
BeginInvoke(new EventHandler(delegate
{
if (node == null)
node = treeView_Main.SelectedNode;
if (node?.Tag.ToString() != "hospital")
{
return;
}
var server = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault();
var hospital = server?.Hospitals?.Where(o => o.Name == node.Name).FirstOrDefault();
if (server is null || hospital is null)
return;
//获取docker信息
var flag = $"{server.Name} - {hospital.Name} - {hospital.DefaultFort}";
this.gb_Docker.Text = flag;
var (Success, Result) = SshHelper.ExcuteCmd(server, DockerCommand.GetDockerStatus(hospital.FileName));
listView_App.Items.Clear();
if (Success)
{
if (!string.IsNullOrEmpty(Result))
{
string[] empties = Result.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < empties.Length; ++i)
{
string[] items = empties[i].Split(new string[] { "||" }, StringSplitOptions.None);
ListViewItem item = new ListViewItem();
item.SubItems[0].Text = items[0];
for (int j = 1; j < items.Length; ++j)
item.SubItems.Add(items[j]);
listView_App.Items.Add(item);
}
Utility.SendLog(flag, $"刷新成功");
SelectEnv = hospital.DefaultFort == "600" ? "dev" : "root";
SelectCmdSuffix = SelectEnv == "dev" ? "/compose" : string.Empty;
}
}
else
{
if (SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/compose/{hospital.FileName}"))
{
if (string.IsNullOrEmpty(Result))
{
Utility.SendLog(flag, "项目已经停止运行");
}
else
{
Utility.SendLog(flag, Result);
}
}
else
{
Utility.SendLog(flag, $"医院不存在");
}
}
}));
}
catch { }
}
private void tsmi_HospitalCreate_Click(object sender, EventArgs e)
{
var node = treeView_Main.SelectedNode;
if (node is null)
return;
DevServer server = null;
Hospital hospital = null;
//服务器操作
if (node.Tag.ToString() == "server")
{
server = Utility.m_DevServers.Where(o => o.Name == node.Name).FirstOrDefault();
using (Form_Hospital_Item f = new Form_Hospital_Item(server.Name, "新增"))
{
f.ShowDialog();
hospital = f.m_Hoipital;
}
if (!(hospital is null))
{
Utility.SaveDevServer();
RefreshTree();
}
}
else
{
//医院操作
server = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault();
hospital = server?.Hospitals?.Where(o => o.Name == node.Name).FirstOrDefault();
if (server is null || hospital is null)
return;
if (SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/compose/{hospital.FileName}"))
{
MessageBox.Show("医院已经存在,不允许重复创建", "提示");
return;
}
if (SshHelper.InRtmNow())
{
MessageBox.Show("正在执行其他命令,请等待!", "提示");
return;
}
Thread t = new Thread(new ThreadStart(delegate
{
SshHelper.ExcuteCmdRtm(server, $"cd /home/{server.UserName}/ihdis;sudo bash create-hospital.sh {hospital.FileName} {hospital.DefaultFort} {GetMask(server)};");
RefreshDocker();
}));
t.Start();
}
}
private string GetMask(DevServer server)
{
var res = SshHelper.ExcuteCmd(server, "sudo ip route");
if (res.Success)
{
List<int> lst = new List<int>();
res.Result
.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries).Where(o => o.StartsWith("172."))
.ToList()
.ForEach(s =>
{
lst.Add(Convert.ToInt32(s.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries)[2]));
});
while (true)
{
var r = new Random().Next(1, 255);
if (!lst.Contains(r))
{
return r.ToString();
}
System.Threading.Thread.Sleep(1);
}
}
else
{
return new Random().Next(1, 255).ToString();
}
}
private void tsmi_HospitalRemove_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
if (!SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/compose/{hospital.FileName}"))
{
MessageBox.Show("医院不存在", "提示");
return;
}
if (MessageBox.Show("是否确定删除医院?", "提示", MessageBoxButtons.YesNo) == DialogResult.No)
{
return;
}
if (SshHelper.InRtmNow())
{
MessageBox.Show("正在执行其他命令,请等待!", "提示");
return;
}
Thread t = new Thread(new ThreadStart(delegate
{
SshHelper.ExcuteCmdRtm(server, $"cd /home/{server.UserName}/ihdis;sudo bash remove-hospital.sh {hospital.FileName};");
RefreshDocker();
}));
t.Start();
}
private void tsmi_RemoveLocker_Click(object sender, EventArgs e)
{
if (!HasSelectdServer(out DevServer server))
return;
Utility.RemoveDevFiles(server);
}
private void tsmi_Stop_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
SetStatus("停止docker-compose...");
SshHelper.ExcuteCmd(server, DockerCommand.DockerComposeDown(server.UserName, hospital.FileName, SelectCmdSuffix));
RefreshDocker(treeView_Main.SelectedNode);
SetStatus("执行完毕...");
}
private void tsmi_Start_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
SetStatus("启动docker-compose...");
SshHelper.ExcuteCmd(server, DockerCommand.DockerComposeUp(server.UserName, hospital.FileName, SelectCmdSuffix));
RefreshDocker(treeView_Main.SelectedNode);
SetStatus("执行完毕...");
}
private void treeView_Main_DrawNode(object sender, DrawTreeNodeEventArgs e)
{
if (e.State == TreeNodeStates.Selected)//状态判定
{
// 背景色(原本的背景色,蓝色)
Color bgColor = Color.FromArgb(0, 120, 215);
Brush brush = new SolidBrush(bgColor);
e.Graphics.FillRectangle(brush, new Rectangle(e.Node.Bounds.Left, e.Node.Bounds.Top, e.Node.Bounds.Width, e.Node.Bounds.Height));//背景色为蓝色
// 绘制文本为蓝底白字
TextRenderer.DrawText(e.Graphics,
e.Node.Text,
e.Node.TreeView.Font,
new Rectangle(e.Node.Bounds.Left + 1, e.Node.Bounds.Top, e.Node.Bounds.Width, e.Node.Bounds.Height),
Color.White);
}
else
{
e.DrawDefault = true;
}
}
#endregion
#region 开发服务器配置
private void tsmi_DevServer_Click(object sender, EventArgs e)
{
using (Form_DevServer f = new Form_DevServer())
{
f.ShowDialog();
}
RefreshTree();
}
#endregion
#region 发布服务器配置
private void tsmi_PulishServer_Click(object sender, EventArgs e)
{
using (Form_PublishServer f = new Form_PublishServer())
{
f.ShowDialog();
}
RefreshTree();
}
#endregion
#region ListView操作
private void tsmi_OpenCode_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
if (string.IsNullOrEmpty(hospital.SCPath))
return;
try
{
System.Diagnostics.Process.Start("explorer.exe", "/select," + hospital.SCPath);
}
catch { }
}
private void tsmi_HospitalRestart_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
SetStatus("重启docker-compose...");
SshHelper.ExcuteCmd(server, DockerCommand.DockerComposeRestart(server.UserName, hospital.FileName, SelectCmdSuffix));
RefreshDocker(treeView_Main.SelectedNode);
SetStatus("执行完毕...");
}
private void tsmi_HospitalTester_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
System.Diagnostics.Process.Start($"http://{server.Ip}:{hospital.DefaultFort}00");
}
private void tsmi_Import_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
if (server.Ip == Utility.m_TestServerIp)
{
return;
}
if (!SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/compose/{hospital.FileName}"))
{
MessageBox.Show("医院不存在", "提示");
return;
}
if (MessageBox.Show($"是否确定导入数据至[{server.Ip}]-[{hospital.FileName}],该操作将清空现有的IHDIS数据库?", "提示", MessageBoxButtons.YesNo) != DialogResult.Yes)
{
return;
}
string fname = string.Empty;
using (Form_ImportDb f = new Form_ImportDb())
{
f.ShowDialog();
fname = f.m_FileName;
if (f.m_DialogResult != DialogResult.OK)
return;
}
Thread t = new Thread(new ThreadStart(delegate
{
ImportSql(server, hospital, fname);
}));
t.Start();
}
object m_InImportSql = new object();
bool b_InImportSql = false;
private void ImportSql(DevServer server, Hospital hospital, string fname)
{
lock (m_InImportSql)
{
if (b_InImportSql)
{
return;
}
b_InImportSql = true;
}
string remoteFile = $"/tmp/{Guid.NewGuid():N}.sql";
try
{
SetProgressBarVisible(true);
//step 1 上传文件
Utility.SendLog("开始上传文件");
SftpHelper.UploadFile(server, fname, remoteFile, SetProgressBar);
//step 2 解析文件
string db = "ihdis";
int tables = 0;
bool b_use = false;
using (StreamReader sr = new StreamReader(fname))
{
var line = sr.ReadLine();
while (line != null)
{
if (!b_use && line.Contains("USE `ihdis`;"))
{
b_use = true;
db = "mysql";
}
if (line.Trim().StartsWith("CREATE TABLE"))
{
tables++;
}
line = sr.ReadLine();
}
}
//step 3 执行导入
Utility.SendLog($"开始导入sql文件,共有表 {tables}");
SshHelper.ExcuteCmd(server, $"cd /home/{server.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -pjlmed#123 -e \"DROP DATABASE IF EXISTS ihdis;\";", true);
SshHelper.ExcuteCmd(server, $"cd /home/{server.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -pjlmed#123 -e \"CREATE DATABASE IF NOT EXISTS ihdis;\";", true);
Thread t = new Thread(new ThreadStart(delegate
{
QueryTables(server, hospital, tables);
}));
t.Start();
SshHelper.ExcuteCmd(server, $"cd /home/{server.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -pjlmed#123 {db} < {remoteFile}", true);
Utility.SendLog("导入sql文件完毕");
SshHelper.ExcuteCmd(server, DockerCommand.DockerComposeContainerRestart(server.UserName, hospital.FileName, "webapi", SelectCmdSuffix));
}
catch (Exception ex)
{
Utility.SendLog($"导入sql失败:{ex}");
}
finally
{
SetProgressBarVisible(false);
Utility.SendLog($"删除垃圾文件 {remoteFile}");
SftpHelper.Delete(server, remoteFile);
lock (m_InImportSql)
{
b_InImportSql = false;
}
}
}
private void QueryTables(DevServer server, Hospital hospital, int sum)
{
string last = string.Empty;
string sql = $"SELECT TABLE_NAME,TABLE_ROWS FROM information_schema.TABLES WHERE TABLE_SCHEMA='ihdis' order by CREATE_TIME DESC,TABLE_NAME DESC;";
string connStr = $"server = {server.Ip}; port = {hospital.DefaultFort}90; userid = root; password = jlmed#123;database=ihdis;";
while (true)
{
lock (m_InImportSql)
{
if (!b_InImportSql)
{
break;
}
}
try
{
//查询数据库表
DataTable dt = MySqlHelper.ExecuteDataset(connStr, sql).Tables[0];
SetProgressBar(sum, dt.Rows.Count);
string cur = $"{dt.Rows[0]["TABLE_NAME"]} {dt.Rows[0]["TABLE_ROWS"]} ...";
if (last != cur)
{
Utility.SendLog($"[{dt.Rows.Count}/{sum}] {cur}");
last = cur;
}
}
catch { }
System.Threading.Thread.Sleep(2000);
}
}
private void listView_App_MouseDoubleClick(object sender, MouseEventArgs e)
{
QueryLog();
}
private void QueryLog()
{
try
{
if (listView_App.SelectedItems.Count <= 0)
return;
var items = listView_App.SelectedItems[0].SubItems[1].Text.Split('_');
if (items.Length < 2)
return;
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
using (Form_Logger f = new Form_Logger(server, hospital, items[1]))
{
f.ShowDialog();
}
}
catch { }
}
private void tsmi_Log_Click(object sender, EventArgs e)
{
QueryLog();
}
private void tsmi_Restart_Click(object sender, EventArgs e)
{
if (listView_App.SelectedItems.Count <= 0)
return;
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
SetStatus("重启容器中...");
SshHelper.ExcuteCmd(server, DockerCommand.DockeContainerRestart(listView_App.SelectedItems[0].Text));
RefreshDocker(treeView_Main.SelectedNode);
SetStatus("执行完毕...");
}
#endregion
#region 日志操作
private static List<string> m_LogsTemp = new List<string>();
private void timer_Main_Tick(object sender, EventArgs e)
{
try
{
lock (m_Logs)
{
m_LogsTemp.Clear();
m_Logs.ForEach(log => m_LogsTemp.Add(log));
m_Logs.Clear();
}
if (m_LogsTemp.Count > 0)
{
if (lb_Logger.Items.Count > 2000)
lb_Logger.Items.Clear();
m_LogsTemp.ForEach(log => lb_Logger.Items.Add(log));
lb_Logger.TopIndex = lb_Logger.Items.Count - 1;
}
}
catch { }
}
private static List<string> m_Logs = new List<string>();
private void SendLog(string oprator, string msg)
{
lock (m_Logs)
{
if (string.IsNullOrEmpty(oprator))
m_Logs.Add($"{DateTime.Now:HH:mm:ss} {msg}");
else
m_Logs.Add($"{DateTime.Now:HH:mm:ss} [{oprator}] {msg}");
}
}
private void tsmi_Copy_Click(object sender, EventArgs e)
{
if (lb_Logger.SelectedIndex <= 0)
return;
try
{
Clipboard.SetDataObject(lb_Logger.Items[lb_Logger.SelectedIndex].ToString(), true);
//MessageBox.Show("已经拷贝至系统剪贴板,请执行CTRL+V粘贴!", "提示");
}
catch
{
//MessageBox.Show(ex.Message);
}
}
private void tsmi_Clear_Click(object sender, EventArgs e)
{
lb_Logger.Items.Clear();
}
private void tsmi_ClearCache_Click(object sender, EventArgs e)
{
try
{
Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory)
.ToList()
.ForEach(f =>
{
if (f.EndsWith(".dat"))
File.Delete(f);
});
}
catch { }
}
private void tsmi_OpenFile_Click(object sender, EventArgs e)
{
try
{
string fname = AppDomain.CurrentDomain.BaseDirectory + "Log\\" + DateTime.Now.ToString("yyyy_MM_dd") + ".txt";
System.Diagnostics.Process.Start("explorer.exe", "/select," + fname);
}
catch { }
}
private void lb_Logger_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();//绘制背景
Brush myBrush = Brushes.White;
if (e.Index >= 0)
{
var item = lb_Logger.Items[e.Index].ToString();
if (item.Contains("失败") || item.Contains("异常") || item.Contains("错误") || item.Contains("ERR!") || item.Contains("ERROR") || item.Contains("error") || item.Contains("fatal") || item.Contains("failed"))
{
if (!item.Contains(" 0 个错误"))
myBrush = Brushes.Red;
}
else if (item.Contains("完成") || item.Contains("success") || item.Contains("complete") || item.Contains("Already up"))
{
myBrush = Brushes.Green;
}
e.Graphics.FillRectangle(myBrush, e.Bounds);
e.DrawFocusRectangle();//焦点框
//文本
e.Graphics.DrawString(lb_Logger.Items[e.Index].ToString(), e.Font, Brushes.Black, e.Bounds, StringFormat.GenericDefault);
}
}
#endregion
#region 状态变更
private void SetStatus(string str)
{
try
{
BeginInvoke(new EventHandler(delegate
{
tssl_Oprate.Text = str;
}));
}
catch { }
}
#endregion
#region 项目发布
bool m_InPublish = false;
object m_LockPublish = new object();
bool m_RemoveFile = false;
bool m_BuildFisrt = false;
DevServer m_SelectServer = null;
Hospital m_SelectHospital = null;
List<string> m_SelectProjects = new List<string>();
private void btn_Publish_Click(object sender, EventArgs e)
{
lock (m_LockPublish)
{
if (m_InPublish)
return;
}
#region 初始化选择
var node = treeView_Main.SelectedNode;
if (node is null || node.Tag.ToString() != "hospital")
{
MessageBox.Show("请选择医院!", "提示");
return;
}
m_SelectServer = Utility.m_DevServers.Where(o => o.Name == node.Parent?.Name).FirstOrDefault();
m_SelectHospital = m_SelectServer?.Hospitals?.Where(o => o.Name == node.Name).FirstOrDefault();
if (m_SelectServer is null || m_SelectHospital is null)
return;
if (string.IsNullOrEmpty(m_SelectHospital.SCPath) || string.IsNullOrEmpty(m_SelectHospital.WWWPath))
{
var h = Utility.m_DevServers.Where(o => o.Ip == "192.168.8.72").FirstOrDefault()?.Hospitals?.Where(o => o.FileName == "develop")?.FirstOrDefault();
if (h != null)
{
m_SelectHospital.SCPath = h?.SCPath;
m_SelectHospital.WWWPath = h?.WWWPath;
Utility.SendLog("检测到未配置代码路径,默认使用72开发环境配置");
}
else
{
MessageBox.Show("请先完善医院信息:前后端目录!", "提示");
return;
}
}
m_SelectProjects.Clear();
bool b_back = false;
m_RemoveFile = cb_remove.Checked;
m_BuildFisrt = cb_build.Checked;
if (cb_hfs.Checked)
{
b_back = true;
m_SelectProjects.Add("hfs");
}
if (cb_job.Checked)
{
b_back = true;
m_SelectProjects.Add("job");
}
if (cb_iot.Checked)
{
b_back = true;
m_SelectProjects.Add("iot");
}
if (cb_ts.Checked)
{
b_back = true;
m_SelectProjects.Add("ts");
}
if (cb_rtm.Checked)
{
b_back = true;
m_SelectProjects.Add("rtm");
}
if (cb_web.Checked)
{
m_SelectProjects.Add("web");
}
if (cb_pad.Checked)
{
m_SelectProjects.Add("pad");
}
if (cb_webapi.Checked)
{
b_back = true;
m_SelectProjects.Add("webapi");
}
if (m_SelectHospital.FileName == "produse" && b_back)
{
MessageBox.Show("后端代码不允许发布至生产服务器!", "提示");
return;
}
if (m_SelectProjects.Count <= 0)
{
return;
}
else
{
if (MessageBox.Show($"确定发布以下项目?\r\n{string.Join("\r\n", m_SelectProjects)}\r\n至\r\n{m_SelectServer.Ip}\r\n{m_SelectHospital.FileName}({m_SelectHospital.DefaultFort})", "提示", MessageBoxButtons.YesNo) == DialogResult.No)
{
return;
}
}
#endregion
#region 执行发布
new Thread(new ThreadStart(() =>
{
if (m_SelectHospital.FileName != "produse" && Utility.LockDevFiles(m_SelectServer, $"发布[{m_SelectHospital.FileName}]"))
{
return;
}
Publish();
RefreshDocker(node);
if (m_SelectHospital.FileName != "produse")
{
Utility.RemoveDevFiles(m_SelectServer);
}
})).Start();
#endregion
}
private bool Publish()
{
Utility.m_StopPublish = false;
lock (m_LockPublish)
{
if (m_InPublish)
return false;
else
m_InPublish = true;
}
Utility.SendLog("开始执行发布", true);
if (m_BuildFisrt && Utility.m_OprateLog.PackGit)
{
Utility.SendLog("开始拉取最新代码");
if (m_SelectProjects.Any(p => p == "webapi")
|| m_SelectProjects.Any(p => p == "hfs")
|| m_SelectProjects.Any(p => p == "rtm")
|| m_SelectProjects.Any(p => p == "job")
|| m_SelectProjects.Any(p => p == "iot")
|| m_SelectProjects.Any(p => p == "ts"))
{
CmdHelper.ExecCmd($"cd {m_SelectHospital.SCPath}\r\n"
+ $"{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\n"
+ $"git pull\r\n"
+ $"exit\r\n");
}
else
{
CmdHelper.ExecCmd($"cd {m_SelectHospital.WWWPath}\r\n"
+ $"{m_SelectHospital.WWWPath.Split(':')[0].Trim()}:\r\n"
+ $"git pull\r\n"
+ $"exit\r\n");
}
Utility.SendLog("拉取最新代码完成");
}
bool b_suc = true;
try
{
Utility.SetProgressBarVisible(true);
int index = 0;
Utility.SetProgressBarValue(m_SelectProjects.Count, (ulong)index);
m_SelectProjects.ForEach(project =>
{
if (Utility.m_StopPublish)
return;
if (!b_suc)
{
return;
}
try
{
Utility.SendLog($"{project}", $"开始发布");
++index;
#region 是否执行编译
b_suc = ProjectBuild(project);
if (!b_suc)
{
return;
}
else
{
if (project == "web")
{
//文件不存在,并且目录也不存在,标识未编译
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\dist"))
{
Directory.CreateDirectory($"{m_SelectHospital.WWWPath}\\dist");
Utility.SendLog($"{project}", "检测到文件目录dist不存在,已自动创建,继续执行");
}
}
else if (project == "pad")
{
//文件不存在,并且目录也不存在,标识未编译
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\pad-h5\\dist"))
{
Directory.CreateDirectory($"{m_SelectHospital.WWWPath}\\dist");
Utility.SendLog($"{project}", "检测到文件目录dist不存在,已自动创建,继续执行");
}
}
}
#endregion
#region 是否删除远程文件
ProjectRemove(project);
#endregion
#region 上传文件
b_suc = ProjectUpload(project);
if (!b_suc)
{
return;
}
#endregion
#region 执行pulish行指令
ProjectPublish(project);
#endregion
Utility.SetProgressBarValue(m_SelectProjects.Count, (ulong)index);
Utility.SendLog($"{project}", $"发布 {project} 完毕");
}
catch (Exception ex)
{
Utility.SendLog($"{project}", $"执行发布失败:{ex}");
}
});
if (b_suc)
{
//重启容器(只发布web、pad不需要重启)
if (m_SelectProjects.Any(p => p == "webapi")
|| m_SelectProjects.Any(p => p == "hfs")
|| m_SelectProjects.Any(p => p == "rtm")
|| m_SelectProjects.Any(p => p == "job")
|| m_SelectProjects.Any(p => p == "iot")
|| m_SelectProjects.Any(p => p == "ts"))
{
m_SelectProjects.Where(p => p != "web" && p != "pad").ToList().ForEach(p =>
{
Utility.SendLog($"正在重新启动容器 {p}", true);
SshHelper.ExcuteCmd(m_SelectServer, DockerCommand.DockerComposeRemove(SelectEnv == "dev"
? m_SelectServer.UserName : SelectEnv, m_SelectHospital.FileName, p, SelectCmdSuffix));
//SshHelper.ExcuteCmd(m_SelectServer, DockerCommand.DockerComposeRemove(m_SelectServer.UserName, m_SelectHospital.FileName, p));
});
SshHelper.ExcuteCmd(m_SelectServer, DockerCommand.DockerComposeUp(SelectEnv == "dev"
? m_SelectServer.UserName : SelectEnv, m_SelectHospital.FileName, SelectCmdSuffix));
//SshHelper.ExcuteCmd(m_SelectServer, DockerCommand.DockerComposeUp(m_SelectServer.UserName, m_SelectHospital.FileName));
}
}
else
{
Utility.SendLog($"发布", $"发生错误,执行发布失败,停止发布...");
}
}
catch (Exception ex)
{
Utility.SendLog($"执行发布失败:{ex}");
b_suc = false;
}
finally
{
Utility.SetProgressBarVisible(false);
lock (m_LockPublish)
{
m_InPublish = false;
}
}
Utility.SendLog("执行发布完毕", true);
return b_suc;
}
/// <summary>
/// 编译
/// </summary>
/// <param name="project"></param>
private bool ProjectBuild(string project)
{
if (Utility.m_StopPublish)
return false;
if (!m_BuildFisrt)
return true;
Utility.SendLog("编译生成", $"[{project}]开始编译生成");
string cmd;
switch (project)
{
case "webapi":
{
cmd = $"cd {m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\\r\n{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -c Release -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "hfs":
{
cmd = $"cd {m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\\r\n{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "rtm":
{
cmd = $"cd {m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\\r\n{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "job":
{
cmd = $"cd {m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\\r\n{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "iot":
{
cmd = $"cd {m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\\r\n{m_SelectHospital.SCPath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "ts":
{
var tspath = $"{m_SelectHospital.SCPath.Substring(0, m_SelectHospital.SCPath.LastIndexOf('\\'))}\\adapter\\JianLian.Adapter.Center\\Host\\JianLian.Adapter.Hosting";
cmd = $"cd {tspath}\\\r\n{tspath.Split(':')[0].Trim()}:\r\ndotnet build\r\ndotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\nexit\r\n";
break;
}
case "pad":
{
cmd = $"cd {m_SelectHospital.WWWPath}\\pad-h5\\\r\n{m_SelectHospital.WWWPath.Split(':')[0].Trim()}:\r\nnpm install\r\nnpm run build\r\nexit\r\n";
break;
}
case "web":
{
var path = $"cd {m_SelectHospital.WWWPath}\\\r\n{m_SelectHospital.WWWPath.Split(':')[0].Trim()}:\r\n";
cmd = $"{path}npm install -g cnpm --registry=https://registry.npm.taobao.org \r\n cnpm i \r\n npm run build\r\nexit\r\n";
break;
}
default:
return false;
}
var cmdResult = CmdHelper.ExecCmd(cmd);
if (cmdResult.Item1)
{
Utility.SendLog("编译生成", $"[{project}]编译生成发生错误,终止执行");
Utility.SendLog("编译生成", $"[{project}] {cmdResult.Item2}");
return false;
}
else
{
Utility.SendLog("编译生成", $"[{project}]编译生成完毕");
//等待IO操作
System.Threading.Thread.Sleep(2000);
return true;
}
}
/// <summary>
/// 删除远程文件
/// </summary>
/// <param name="project"></param>
private void ProjectRemove(string project)
{
if (Utility.m_StopPublish)
return;
if (!m_RemoveFile)
return;
if (project != "web" && project != "pad")
{
//SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{m_SelectServer.UserName}/ihdis/dev/app/server/{project}/*", true);
if (SelectEnv == "dev")
{
SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{m_SelectServer.UserName}/ihdis/dev/app/server/{project}/*", true);
}
else
{
SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{SelectEnv}/ihdis/{project}/code/*", true);
}
}
else
{
if (SelectEnv == "dev")
{
SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{m_SelectServer.UserName}/ihdis/{(m_SelectHospital.FileName == "produse" ? "produse" : $"compose/{m_SelectHospital.FileName}")}/app/www/{project}/*", true);
}
else
{
SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/app/www/{project}/*", true);
}
}
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="project"></param>
private bool ProjectUpload(string project)
{
if (Utility.m_StopPublish)
return false;
bool b_suc = true;
SetProgressBarVisible(true);
try
{
Utility.SendLog("文件上传", $"[{project}]开始上传文件");
List<string> files = new List<string>();
var toRemotePath = SelectEnv == "dev"
? $"/home/{m_SelectServer.UserName}/ihdis/dev/app/server/{project}"
: $"/home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/code/{project}";
switch (project)
{
case "webapi":
{
//更新日志
string llogpath = $"{m_SelectHospital.SCPath}\\src\\Document\\Upgrade.md";
//string rlogpath = $"/home/{m_SelectServer.UserName}/ihdis/compose/{m_SelectHospital.FileName}/data/hfs/wwwroot/files/upgradelogs.md";
var rlogpath = string.Empty;
rlogpath = SelectEnv == "dev"
? $"/home/{m_SelectServer.UserName}/ihdis/compose/{m_SelectHospital.FileName}/data/hfs/wwwroot/files/upgradelogs.md"
: $"/home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/data/hfs/wwwroot/files/upgradelogs.md";
if (File.Exists(llogpath))
{
SftpHelper.UploadFile(m_SelectServer, llogpath, rlogpath);
}
//xml文件
string[] fs = Directory.GetFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\bin\\Release\\net5.0\\publish", $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HttpApi.Hosting\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "hfs":
{
//xml文件
string[] fs = Directory.GetFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\bin\\Release\\net5.0\\publish", $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.HFS\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "rtm":
{
//xml文件
string[] fs = Directory.GetFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\bin\\Release\\net5.0\\publish", $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.SignalR\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "job":
{
//xml文件
string[] fs = Directory.GetFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\bin\\Release\\net5.0\\publish", $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.BackgroundJobs\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "iot":
{
//xml文件
string[] fs = Directory.GetFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\bin\\Release\\net5.0\\publish", $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{m_SelectHospital.SCPath}\\src\\Host\\JianLian.HDIS.IoT\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "ts":
{
var tspath = $"{m_SelectHospital.SCPath.Substring(0, m_SelectHospital.SCPath.LastIndexOf('\\'))}\\adapter\\JianLian.Adapter.Center\\Host\\JianLian.Adapter.Hosting";
//xml文件
string[] fs = Directory.GetFiles($"{tspath}\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{tspath}\\bin\\Debug\\net5.0", toRemotePath, files, SetProgressBar);
//发布文件
files.Clear();
GetUploadFiles($"{tspath}\\bin\\Release\\net5.0\\publish", $"{tspath}\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{tspath}\\bin\\Release\\net5.0\\publish", toRemotePath, files, SetProgressBar);
break;
}
case "pad":
{
var fname = $"{AppDomain.CurrentDomain.BaseDirectory}\\dist.zip";
//var rname = $"/home/{m_SelectServer.UserName}/ihdis/{(m_SelectHospital.FileName == "produse" ? "produse" : $"compose/{m_SelectHospital.FileName}")}/app/www/{project}/dist.zip";
var rname = SelectEnv == "dev"
? $"/home/{m_SelectServer.UserName}/ihdis/{(m_SelectHospital.FileName == "produse" ? "produse" : $"compose/{m_SelectHospital.FileName}")}/app/www/{project}/dist.zip"
: $"/home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/app/www/{project}/dist.zip";
//文件不存在,并且目录也不存在,标识未编译
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\pad-h5\\dist"))
{
Utility.SendLog($"{project}", "项目未编译,发布失败");
return false;
}
//执行压缩
Utility.SendLog($"{project}", "正在执行压缩");
ZipHelper.ZipFiles(fname, $"{m_SelectHospital.WWWPath}\\pad-h5\\dist");
files.Add(fname);
SftpHelper.UploadFile(m_SelectServer, fname, rname, SetProgressBar);
break;
}
case "web":
{
var fname = $"{AppDomain.CurrentDomain.BaseDirectory}\\dist.zip";
//var rname = $"/home/{m_SelectServer.UserName}/ihdis/{(m_SelectHospital.FileName == "produse" ? "produse" : $"compose/{m_SelectHospital.FileName}")}/app/www/{project}/dist.zip";
var rname = SelectEnv == "dev"
? $"/home/{m_SelectServer.UserName}/ihdis/{(m_SelectHospital.FileName == "produse" ? "produse" : $"compose/{m_SelectHospital.FileName}")}/app/www/{project}/dist.zip"
: $"/home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/app/www/{project}/dist.zip";
//文件不存在,并且目录也不存在,标识未编译
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\dist"))
{
Utility.SendLog($"{project}", "项目未编译,发布失败");
return false;
}
//执行压缩
Utility.SendLog($"{project}", "正在执行压缩");
ZipHelper.ZipFiles(fname, $"{m_SelectHospital.WWWPath}\\dist");
files.Add(fname);
SftpHelper.UploadFile(m_SelectServer, fname, rname, SetProgressBar);
break;
}
default:
return false;
}
}
catch (Exception ex)
{
b_suc = false;
throw new Exception(ex.Message);
}
finally
{
SetProgressBarVisible(false);
}
Utility.SendLog("文件上传", $"[{project}]上传文件完毕");
return b_suc;
}
private void SetProgressBarVisible(bool visible)
{
try
{
BeginInvoke(new EventHandler(delegate
{
tssl_Split2.Visible = visible;
tspb_Upload.Visible = visible;
tssl_Upload.Visible = visible;
}));
}
catch { }
}
private void SetProgressBar(long max, ulong value)
{
SetProgressBar((int)max, (int)value);
}
private void SetProgressBar(int max, int value)
{
try
{
BeginInvoke(new EventHandler(delegate
{
tspb_Upload.Minimum = 0;
tspb_Upload.Maximum = max;
tspb_Upload.Value = value;
tssl_Upload.Text = $"{value}/{max}";
}));
}
catch { }
}
private void GetUploadFiles(string basePath, string path, List<string> files)
{
string[] fs = Directory.GetFiles(path);
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(fname.Replace(basePath + "\\", ""));
});
string[] ds = Directory.GetDirectories(path);
ds.ToList().ForEach(spath =>
{
if (!spath.EndsWith("Logs"))
GetUploadFiles(basePath, spath, files);
});
}
/// <summary>
/// 执行指令
/// </summary>
/// <param name="project"></param>
private void ProjectPublish(string project)
{
if (Utility.m_StopPublish)
return;
if (project != "web" && project != "pad")
{
//SshHelper.ExcuteCmd(m_SelectServer, $"sudo rm -rf /home/{m_SelectServer.UserName}/ihdis/compose/{m_SelectHospital.FileName}/data/{project}/*;sudo cp -r /home/{m_SelectServer.UserName}/ihdis/dev/app/server/{project}/* /home/{m_SelectServer.UserName}/ihdis/compose/{m_SelectHospital.FileName}/code/{project}");
//SshHelper.ExcuteCmdRtm(m_SelectServer, $"cd /home/{m_SelectServer.UserName}/ihdis/dev;sudo bash publish-{project}.sh {m_SelectHospital.FileName};");
//SshHelper.ExcuteCmdRtm(m_SelectServer, $"cd /home/{m_SelectServer.UserName}/ihdis/dev;sudo bash publish-copycode.sh {m_SelectHospital.FileName} {project};");
if (SelectEnv == "dev")
{
SshHelper.ExcuteCmdRtm(m_SelectServer, $"cd /home/{m_SelectServer.UserName}/ihdis/dev;sudo bash publish-copycode.sh {m_SelectHospital.FileName} {project};");
}
else
{
//发布测试环境代码直接发到指定目录了,不需要copy
}
}
else
{
if (SelectEnv == "dev")
{
if (m_SelectHospital.FileName == "produse")
{
SshHelper.ExcuteCmdRtm(m_SelectServer, $"unzip -o -d /home/{m_SelectServer.UserName}/ihdis/produse/app/www/{project} /home/{m_SelectServer.UserName}/ihdis/produse/app/www/{project}/dist.zip");
}
else
{
SshHelper.ExcuteCmdRtm(m_SelectServer, $"cd /home/{m_SelectServer.UserName}/ihdis;sudo bash unzip-www.sh {m_SelectHospital.FileName} {project};");
}
}
else
{
SshHelper.ExcuteCmdRtm(m_SelectServer, $"unzip -o -d /home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/app/www/{project} /home/{SelectEnv}/ihdis/{m_SelectHospital.FileName}/app/www/{project}/dist.zip");
}
}
}
private void btn_Stop_Click(object sender, EventArgs e)
{
Utility.m_StopPublish = true;
}
#endregion
#region 项目打包
bool b_InPublishNew = false;
private void tsmi_Pack_Click(object sender, EventArgs e)
{
var node = treeView_Main.SelectedNode;
var server = Utility.m_DevServers.Where(o => o.Name == node?.Parent?.Name).FirstOrDefault();
var hospital = server?.Hospitals?.Where(o => o.Name == node?.Name).FirstOrDefault();
if (b_InPublishNew)
{
return;
}
b_InPublishNew = true;
try
{
#region 初始化
using (Form_Publish f = new Form_Publish(server, hospital))
{
f.ShowDialog();
if (f.m_DialogResult != DialogResult.Yes)
{
return;
}
}
string version = Utility.m_OprateLog.PackVersion;
DevServer devServer = Utility.m_DevServers.Where(o => o.Ip == Utility.m_OprateLog.PackDevIp).FirstOrDefault();
hospital = devServer?.Hospitals.Where(o => o.FileName == Utility.m_OprateLog.PackHospital).FirstOrDefault();
PublishServer publishServer = Utility.m_PublishServers.Where(o => o.Ip == Utility.m_OprateLog.PackPublishIp).FirstOrDefault();
if (devServer is null)
{
Utility.SendLog("打包", $"开发服务器不存在 {devServer.Ip}");
return;
}
if (hospital is null)
{
Utility.SendLog("打包", $"医院不存在 {hospital.FileName}");
return;
}
if (publishServer is null)
{
Utility.SendLog("打包", $"发布服务器不存在 {publishServer.Ip}");
return;
}
if (string.IsNullOrEmpty(hospital.SCPath) || string.IsNullOrEmpty(hospital.WWWPath))
{
var h = Utility.m_DevServers.Where(o => o.Ip == "192.168.8.72").FirstOrDefault()?.Hospitals?.Where(o => o.FileName == "develop")?.FirstOrDefault();
if (h != null)
{
hospital.SCPath = h?.SCPath;
hospital.WWWPath = h?.WWWPath;
Utility.SendLog("检测到未配置代码路径,默认使用72开发环境配置");
}
else
{
MessageBox.Show("请先完善医院信息:前后端目录!", "提示");
return;
}
}
server = devServer;
#endregion
#region 是否先执行发布、或者是升级包
m_SelectServer = devServer;
m_SelectHospital = hospital;
if (m_SelectServer is null || m_SelectHospital is null)
return;
m_SelectProjects.Clear();
m_RemoveFile = cb_remove.Checked;
m_BuildFisrt = cb_build.Checked;
if (cb_hfs.Checked)
{
m_SelectProjects.Add("hfs");
}
if (cb_job.Checked)
{
m_SelectProjects.Add("job");
}
if (cb_rtm.Checked)
{
m_SelectProjects.Add("rtm");
}
if (cb_iot.Checked)
{
m_SelectProjects.Add("iot");
}
if (cb_ts.Checked)
{
m_SelectProjects.Add("ts");
}
if (cb_web.Checked)
{
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\node_modules"))
{
MessageBox.Show("Web项目未执行npm install,直接发布将会报错!");
return;
}
m_SelectProjects.Add("web");
}
if (cb_pad.Checked)
{
if (!Directory.Exists($"{m_SelectHospital.WWWPath}\\pad-h5\\node_modules"))
{
MessageBox.Show("Pad项目未执行npm install,直接发布将会报错!");
return;
}
m_SelectProjects.Add("pad");
}
if (cb_webapi.Checked)
{
m_SelectProjects.Add("webapi");
}
if (Utility.m_OprateLog.PackUpgrade)
{
if (!m_SelectProjects.Any() && !cb_andriod.Checked)
{
MessageBox.Show("升级包未选择任何模块,不再执行!");
return;
}
}
#endregion
#region 指令生成
List<string> cmdlist = new List<string>();
//生成基础包文件
cmdlist.Add($"sudo rm -rf /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}");
cmdlist.Add($"sudo mkdir -p /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}");
cmdlist.Add($"sudo cp -r /home/{publishServer.UserName}/ihdis/packages/sample/* /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}");
#region 安装包需要打包镜像
if (!Utility.m_OprateLog.PackUpgrade)
{
//镜像版本文件的环境变量
string env = $"\"IHDIS_PORT=600\n" +
$"mask=60\n" +
$"redis_TAG=5.0.5\n" +
$"mysql_TAG=8.0\n" +
$"nginx_TAG=1.17\n" +
$"rabbitmq_TAG=3.7.17-management\n" +
$"adminer_TAG=4.7.1\n" +
$"phpredisadmin_TAG=v1.11.4\n" +
$"portainer_TAG=1.22.0\n" +
$"webapi_TAG={version}\n" +
$"hfs_TAG={version}\n" +
$"rtm_TAG={version}\n" +
$"iot_TAG={version}\n" +
$"ts_TAG={version}\n" +
$"job_TAG={version}\"";
cmdlist.Add($"sudo echo -e {env} > /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/.env");
//APP镜像生成
SetAppCmd(hospital, devServer, version, cmdlist, cb_webapi);
SetAppCmd(hospital, devServer, version, cmdlist, cb_hfs);
SetAppCmd(hospital, devServer, version, cmdlist, cb_rtm);
SetAppCmd(hospital, devServer, version, cmdlist, cb_job);
SetAppCmd(hospital, devServer, version, cmdlist, cb_iot);
SetAppCmd(hospital, devServer, version, cmdlist, cb_ts);
}
#endregion
bool b_ts = Utility.m_OprateLog.PackUpgrade && Utility.m_OprateLog.PackUpgradeTS;
#region TS插件包
if (b_ts)
{
//ts升级包,只拷贝ts文件
cmdlist.Add($"sudo cp -r /home/{devServer.UserName}/ihdis/dev/app/server/ts /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/code");
}
#endregion
#region 安装包/升级包
else
{
//后端代码映射
cmdlist.Add($"sudo cp -r /home/{devServer.UserName}/ihdis/dev/app/server/* /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/code");
//升级包移除ts文件
if (Utility.m_OprateLog.PackUpgrade)
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/code/ts/*");
//版本升级日志
cmdlist.Add($"sudo cp /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/data/hfs/wwwroot/files/upgradelogs.md /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/hfs/wwwroot/files/upgradelogs.md");
cmdlist.Add($"sudo echo {version} > /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/Version");
//PC代码
var cname = cb_web.Text;
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/www/{cname}/*");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/app/www/{cname}/dist.zip");
cmdlist.Add($"sudo cp -r /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/app/www/{cname} /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/www/");
//PAD-H5代码:只有是升级包并且未勾选,才会不打包该模块
cname = cb_pad.Text;
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/www/{cname}/*");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/app/www/{cname}/dist.zip");
cmdlist.Add($"sudo cp -r /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/app/www/{cname} /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/www/");
//PAD-Andriod文件
var cmdStr = CopyPadCmd(devServer, hospital, publishServer, version, $"hdis");
if (!string.IsNullOrWhiteSpace(cmdStr))
cmdlist.Add(cmdStr);
//基础数据库文件(包含TS):安装包、升级包必有
cmdlist.Add($"sudo cp /home/{devServer.UserName}/ihdis/packages/tempdb/{hospital.FileName}/{version}/hdis_table.sql /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/conf/mysql/");
cmdlist.Add($"sudo echo {version} > /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/Version");
}
if (Utility.m_OprateLog.PackUpgrade)
{
//升级包删除多余的文件
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/conf/*");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/iot");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/mysql");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/oracle");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/portainer");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/rabbitmq");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/redis");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/ts");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/webapi");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/install/*");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/log/*");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/load_images.cmd");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/load_images.sh");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/docker-compose.yml");
}
#endregion
//包注释文件
cmdlist.Add($"sudo cp /tmp/v{version}_log.dat /home/{devServer.UserName}/ihdis/packages/versions/{hospital.FileName}/v{version}_log.dat");
//压缩文件
cmdlist.Add($"sudo mkdir /home/{devServer.UserName}/ihdis/packages/versions/{hospital.FileName}/");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/versions/{hospital.FileName}/{version}.zip");
cmdlist.Add($"cd /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/ && sudo zip /home/{devServer.UserName}/ihdis/packages/versions/{hospital.FileName}/{version}.zip -r ./");
cmdlist.Add($"sudo chmod 777 /home/{devServer.UserName}/ihdis/packages/versions/version_list");
cmdlist.Add($"sudo echo {version} >> /home/{devServer.UserName}/ihdis/packages/versions/version_list");
//清理缓存文件
cmdlist.Add($"sudo rm -rf /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/packages/tempdb/{hospital.FileName}/*");
#endregion
#region 开始执行脚本
Thread t = new Thread(new ThreadStart(delegate
{
var flag = Utility.m_OprateLog.PackUpgrade ? (Utility.m_OprateLog.PackUpgradeTS ? "[TS插件包]" : "[升级包]") : "[基础包]";
if (Utility.LockDevFiles(server, $"{flag}打包[{hospital.FileName}]"))
{
return;
}
try
{
Utility.SetStatus($"{flag}开始打包");
#region TS打包
if (Utility.m_OprateLog.PackUpgrade && Utility.m_OprateLog.PackUpgradeTS)
{
//ts升级包,单独处理
var tspath = AppDomain.CurrentDomain.BaseDirectory.Replace(@"assistant\JianLian.Assistant\JianLian.HDIS.PublishHelper\bin\Debug\", "") + @"adapter\JianLian.Adapter.Center";
Utility.SendLog(flag, $"编译项目");
CmdHelper.ExecCmd($"cd {tspath}\\Host\\JianLian.Adapter.Hosting\r\n"
+ $"{tspath.Split(':')[0].Trim()}:\r\n"
+ $"dotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\n"
+ $"exit\r\n");
//编译TS组件
Utility.SendLog(flag, $"编译组件 {hospital}");
CmdHelper.ExecCmd($"cd {tspath}\\Custom\\JianLian.Adapter.{Utility.m_OprateLog.PackUpgradeTSCustom}\r\n"
+ $"{tspath.Split(':')[0].Trim()}:\r\n"
+ $"dotnet build\r\n"
+ $"exit\r\n");
//清除文件
SshHelper.ExcuteCmd(devServer, $"rm -rf /home/{m_SelectServer.UserName}/ihdis/dev/app/server/ts/*", true);
//上传文件
List<string> files = new List<string>();
string[] fs = Directory.GetFiles($"{tspath}\\Host\\JianLian.Adapter.Hosting\\bin\\Debug\\net5.0", "*.xml");
fs.ToList().ForEach(fname =>
{
FileInfo file = new FileInfo(fname);
files.Add(file.Name);
});
SftpHelper.UploadFile(m_SelectServer, $"{tspath}\\Host\\JianLian.Adapter.Hosting\\bin\\Debug\\net5.0", $"/home/{m_SelectServer.UserName}/ihdis/dev/app/server/ts", files, SetProgressBar);
files.Clear();
GetUploadFiles($"{tspath}\\Host\\JianLian.Adapter.Hosting\\bin\\Release\\net5.0\\publish", $"{tspath}\\Host\\JianLian.Adapter.Hosting\\bin\\Release\\net5.0\\publish", files);
SftpHelper.UploadFile(m_SelectServer, $"{tspath}\\Host\\JianLian.Adapter.Hosting\\bin\\Release\\net5.0\\publish", $"/home/{m_SelectServer.UserName}/ihdis/dev/app/server/ts", files, SetProgressBar);
files.Clear();
GetUploadFiles($"{tspath}\\Custom\\JianLian.Adapter.{Utility.m_OprateLog.PackUpgradeTSCustom}\\bin\\Debug\\net5.0", $"{tspath}\\Custom\\JianLian.Adapter.{Utility.m_OprateLog.PackUpgradeTSCustom}\\bin\\Debug\\net5.0", files);
SftpHelper.UploadFile(m_SelectServer, $"{tspath}\\Custom\\JianLian.Adapter.{Utility.m_OprateLog.PackUpgradeTSCustom}\\bin\\Debug\\net5.0", $"/home/{m_SelectServer.UserName}/ihdis/dev/app/server/ts", files, SetProgressBar);
}
#endregion
#region 安装包/升级包
else
{
#region 发布
bool b_suc = true;
if (Utility.m_OprateLog.PackPublish)
{
if (m_SelectProjects.Count > 0)
{
b_suc = Publish();
}
}
else
{
Utility.SendLog($"{flag}不需要执行发布流程,默认使用服务端文件");
}
if (!b_suc)
{
Utility.SendLog($"{flag}由于发布失败,打包不继续执行");
return;
}
#endregion
#region 生成数据库脚本文件
var newdb = $"hdis_{version.Replace(".", "_")}";
if (Utility.m_OprateLog.PackDbFile)
{
Utility.SendLog($"{flag}等待程序初始化 10 秒");
System.Threading.Thread.Sleep(10000);
//需要先设置数据库密码为空,再设置回来
//生成最新版本数据库文件
SshHelper.ExcuteCmd(devServer, $"cd /home/{devServer.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -e \"ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY ''; flush privileges; \"", true);
SshHelper.ExcuteCmd(devServer, $"cd /home/{devServer.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -e \"CREATE DATABASE IF NOT EXISTS {newdb};\";", true);
SshHelper.ExcuteCmd(devServer, $"cd /home/{devServer.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql /bin/bash -c \"mysqldump hdis -uroot | mysql {newdb} -uroot\"", true);
//上传reset.sql并执行
string resetsql = File.ReadAllText($"{hospital.SCPath}/src/Document/build/reset.sql", Encoding.UTF8).Replace("use hdis_compare;", $"use {newdb};");
var rsfname = Utility.GetTempFileName("reset.sql");
File.WriteAllText(rsfname, resetsql, Encoding.UTF8);
SftpHelper.UploadFile(devServer, rsfname, "/tmp/reset.sql");
SshHelper.ExcuteCmd(devServer, $"cd /home/{devServer.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost {newdb} < /tmp/reset.sql");
SshHelper.ExcuteCmd(devServer, $"cd /home/{devServer.UserName}/ihdis/compose/{hospital.FileName};sudo docker-compose exec -T mysql mysql -uroot -hlocalhost -e \"ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'jlmed#123'; flush privileges; \"", true);
//下载数据库
DownLoadDb(devServer, hospital, newdb);
string allPath = $"{hospital.SCPath}\\src\\Document\\script\\hdis.sql";
// 转换编码
string allText = File.ReadAllText(allPath);
File.WriteAllText(allPath, allText);
}
else
{
Utility.SendLog($"{flag}不需要打包最新数据库,使用本地文件 {hospital.SCPath}\\src\\Document\\script\\hdis.sql");
Utility.SendLog($"{flag}{hospital.SCPath}\\src\\Document\\script\\hdis.sql");
Utility.SendLog($"{flag}{hospital.SCPath}\\src\\Document\\script\\hdis_ts.sql");
}
//合并ts数据库
string ihdis_sql = File.ReadAllText($"{hospital.SCPath}\\src\\Document\\script\\hdis.sql");
string ihdis_ts_sql = File.ReadAllText($"{hospital.SCPath}\\src\\Document\\script\\hdis_ts.sql");
string sql = $" use `hdis`; \n {ihdis_sql} \n use `hdis_ts`; \n {ihdis_ts_sql}";
var sql_fname = Utility.GetTempFileName("hdis_table.sql");
File.WriteAllText(sql_fname, $"{sql}");
//上传数据库文件
SftpHelper.CreateDirectory(publishServer, $"/home/{publishServer.UserName}/ihdis/packages/tempdb/{hospital.FileName}/");
SftpHelper.CreateDirectory(publishServer, $"/home/{publishServer.UserName}/ihdis/packages/tempdb/{hospital.FileName}/{version}/");
System.Threading.Thread.Sleep(1000);
SftpHelper.UploadFile(publishServer, sql_fname, $"/home/{publishServer.UserName}/ihdis/packages/tempdb/{hospital.FileName}/{version}/hdis_table.sql", null, true);
//开始生成数据库脚本
var localFile = Utility.GetTempFileName($"v{Utility.m_OprateLog.PackVersion}_sql.zip");
SftpHelper.CreateDirectory(publishServer, $"/home/{publishServer.UserName}/ihdis/packages/versions/{hospital.FileName}/");
var remoteFile = $"/home/{publishServer.UserName}/ihdis/packages/versions/{hospital.FileName}/v{Utility.m_OprateLog.PackVersion}_sql.zip";
CreateDbFile(localFile, hospital);
System.Threading.Thread.Sleep(1000);
SftpHelper.UploadFile(publishServer, localFile, remoteFile);
#endregion
}
#endregion
#region 包注释文件
StringBuilder sb_comment = new StringBuilder();
sb_comment.AppendLine(Utility.m_OprateLog.PackUpgrade ? "Upgrade Package" : "Installation Package");
sb_comment.AppendLine($"Version: {version}");
sb_comment.AppendLine($"PackageTime: {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
sb_comment.AppendLine($"PackageEnvironment: {devServer.Ip} {hospital.FileName}");
sb_comment.AppendLine($"Operator: {Environment.MachineName}");
sb_comment.AppendLine($"Moudule: {((Utility.m_OprateLog.PackUpgrade && Utility.m_OprateLog.PackUpgradeTS) ? "ts" : string.Join($"; ", this.gb_Oprate.Controls.Cast<Control>().Where(o => o is CheckBox c && (Utility.m_OprateLog.PackUpgrade ? c.Name != "cb_ts" : true) && c.Name != "cb_remove" && c.Name != "cb_build").Select(o => o.Text).OrderBy(o => o)))}");
string lfname = Utility.GetTempFileName($"v{version}_log.dat");
string rfname = $"/tmp/v{version}_log.dat";
File.WriteAllText(lfname, sb_comment.ToString(), Encoding.UTF8);
SftpHelper.UploadFile(server, lfname, rfname);
#endregion
#region 执行指令
SshHelper.ExcuteCmds(devServer, cmdlist, $"{flag}版本打包");
#endregion
if (Utility.m_OprateLog.PackDownload)
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory);
Utility.SendLog("下载", "开始执行下载", true);
Utility.SetProgressBarVisible(true);
SftpHelper.DownloadFile(server, $"/home/{server.UserName}/ihdis/packages/versions/{hospital.FileName}/{version}.zip", $"{path}\\{version}.zip", true, progress: Utility.SetProgressBarValue);
SftpHelper.DownloadFile(server, $"/home/{server.UserName}/ihdis/packages/versions/{hospital.FileName}/v{version}_log.dat", $"{path}\\v{version}_log.dat", true, progress: Utility.SetProgressBarValue);
SftpHelper.DownloadFile(server, $"/home/{server.UserName}/ihdis/packages/versions/{hospital.FileName}/v{version}_sql.zip", $"{path}\\v{version}_sql.zip", true, progress: Utility.SetProgressBarValue, completedAction: () =>
{
Utility.SendLog("下载", "文件全部下载完毕", true);
var cfile = $"{path}\\v{version}_log.dat";
if (File.Exists(cfile))
{
Utility.SendLog("下载", "开始添加压缩包版本注释", true);
var comment = File.ReadAllText(cfile, Encoding.UTF8);
if (!b_ts)
{
ZipHelper.SetComment($"{path}\\v{version}_sql.zip", comment);
}
ZipHelper.SetComment($"{path}\\{version}.zip", comment);
try
{
Directory.GetFiles(path, "*zip.*.tmp").ToList().ForEach(f =>
{
File.Delete(f);
});
File.Delete(cfile);
}
catch { }
Utility.SendLog("下载", "完成", true);
}
});
Utility.SetProgressBarVisible(false);
}
else
{
Utility.SetStatus($"{flag}打包完毕,请使用本工具下载安装包,否则会现场安装时导致安装包校验不通过。");
}
}
catch (Exception ex)
{
Utility.SendLog($"{flag}打包异常:{ex.Message}");
}
finally
{
Utility.RemoveDevFiles(server);
}
}));
t.Start();
#endregion
}
finally
{
b_InPublishNew = false;
}
}
private string CopyPadCmd(DevServer devServer, Hospital hospital, PublishServer publishServer, string version, string db)
{
string sql = $"SELECT Version FROM SystemPadVersion ORDER BY ABS(NOW() - CreationTime) ASC LIMIT 0, 1;";
string connStr = $"server = {devServer.Ip}; port = {hospital.DefaultFort}90; userid = root; password = jlmed#123;database={db};";
DataTable dt = MySqlHelper.ExecuteDataset(connStr, sql).Tables[0];
if (dt.Rows.Count > 0)
{
return $"sudo cp /home/{devServer.UserName}/ihdis/compose/{hospital.FileName}/data/hfs/wwwroot/files/pad/{dt.Rows[0][0].ToString()}.apk /home/{publishServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data/hfs/wwwroot/files/pad/{dt.Rows[0][0].ToString()}.apk";
}
else
{
return string.Empty;
}
}
private void DownLoadDb(DevServer devServer, Hospital hospital, string db)
{
Utility.SetProgressBarVisible(true);
//查询数据库表
string sql = $"SELECT * FROM INFORMATION_SCHEMA.`COLUMNS` C WHERE C.TABLE_SCHEMA = '{db}';";
string connStr = $"server = {devServer.Ip}; port = {hospital.DefaultFort}90; userid = root; password = jlmed#123;database={db};";
DataTable dt = MySqlHelper.ExecuteDataset(connStr, sql).Tables[0];
Dictionary<string, List<string>> tables = new Dictionary<string, List<string>>();
foreach (DataRow dr in dt.Rows)
{
if (!tables.ContainsKey(dr["TABLE_NAME"].ToString()))
{
tables.Add(dr["TABLE_NAME"].ToString(), new List<string>
{
dr["COLUMN_NAME"].ToString()
});
}
else
{
tables[dr["TABLE_NAME"].ToString()].Add(dr["COLUMN_NAME"].ToString());
}
}
//导出数据
try
{
Utility.SendLog("导出数据库", "共有表 " + tables.Count);
string fname = $"{hospital.SCPath}\\src\\Document\\script\\hdis.sql";
if (File.Exists(fname))
{
File.Delete(fname);
}
int tcount = 0;
StringBuilder sb = new StringBuilder();
sb.AppendLine("SET FOREIGN_KEY_CHECKS = 0;");
tables.Keys.ToList().ForEach(tabelname =>
{
Utility.SetProgressBarValue(tables.Keys.Count, (ulong)++tcount);
sb.AppendLine($"-- 正在导出 表 {db}.{tabelname} 结构");
//Utility.SendLog("导出数据库", $"-- 正在导出 表 ihdis.{tabelname} 结构");
//删除原表
//sb.AppendLine($"DROP TABLE IF EXISTS `{tabelname}`;");
//导出表结构
sb.AppendLine($"{MySqlHelper.ExecuteDataset(connStr, $"SHOW CREATE TABLE `{db}`.`{tabelname}`;").Tables[0].Rows[0]["Create Table"]};");
sb.AppendLine();
//导出数据
sb.AppendLine($"-- 正在导出 表 {db}.{tabelname} 数据");
int rows = int.Parse(MySqlHelper.ExecuteScalar(connStr, $"SELECT COUNT(0) FROM `{db}`.`{tabelname}`;").ToString());
//Utility.SendLog("导出数据库", $"-- 正在导出 表 ihdis.{tabelname} 数据,共有数据 {rows}");
int sum = 0;
using (MySqlDataReader reader = MySqlHelper.ExecuteReader(connStr, $"SELECT * FROM `{db}`.`{tabelname}`;"))
{
if (reader.HasRows)
{
//字段类型
Dictionary<int, string> dic = new Dictionary<int, string>();
//添加字段
//sb.AppendLine($"DELETE FROM `{tabelname}`;");
StringBuilder sb_insert = new StringBuilder();
sb_insert.Append($"INSERT INTO `{tabelname}` (");
for (int i = 0; i < reader.FieldCount; ++i)
{
sb_insert.Append($"`{reader.GetName(i)}`");
if (i != reader.FieldCount - 1)
sb_insert.Append(", ");
dic.Add(i, reader.GetDataTypeName(i));
}
sb_insert.Append(") VALUES");
sb_insert.AppendLine();
//表开始
WriteToFile(fname, $"{sb}");
sb.Clear();
int index = 0;
//添加数据
while (reader.Read())
{
sum++;
sb.Append("\t(");
for (int i = 0; i < reader.FieldCount; ++i)
{
sb.Append($"{ConvertData(reader[i], dic[i])}");
if (i != reader.FieldCount - 1)
sb.Append(", ");
}
sb.Append(")");
//500行数据入库一次
if (index++ >= 500)
{
sb.Append(";");
sb.AppendLine();
sb.AppendLine();
WriteToFile(fname, $"{sb_insert}{sb}");
sb.Clear();
index = 0;
continue;
}
//1024KB为一组插入语句
if (sb.Length >= 100 * 1024)
{
sb.Append(";");
sb.AppendLine();
sb.AppendLine();
WriteToFile(fname, $"{sb_insert}{sb}");
sb.Clear();
index = 0;
continue;
}
if (sum != rows)
sb.Append(",");
else
sb.Append(";");
sb.AppendLine();
}
//表结束
if (sb.Length > 0)
{
sb.AppendLine();
WriteToFile(fname, $"{sb_insert}{sb}");
sb.Clear();
index = 0;
}
}
}
sb.AppendLine();
});
sb.AppendLine("SET FOREIGN_KEY_CHECKS = 1;");
if (sb.Length > 0)
WriteToFile(fname, sb.ToString());
Utility.SendLog("导出数据库", $"导出数据完毕");
}
catch (Exception ex)
{
Utility.SendLog("导出数据库", "导出数据异常" + ex.ToString());
}
Utility.SetProgressBarVisible(false);
}
private string ConvertData(object data, string type)
{
if (data.GetType().FullName == "System.DBNull")
return "NULL";
string value;
if (type.Contains("CHAR")) //varchar ,char
{
value = data.ToString();
if (value.IndexOf("\r") > 0)
value = value.Replace("\r", "\\r");
if (value.IndexOf("\n") > 0)
value = value.Replace("\n", "\\n");
if (value.IndexOf("'") > 0)
value = value.Replace("'", "''");
if (value.IndexOf("\\") > 0)
value = value.Replace("\\", "\\\\");
value = $"'{value}'";
}
else if (type.Contains("JSON"))
{
value = data.ToString().Trim() == "" ? "NULL" : $"'{data}'";
}
else if (type.Contains("TIMESTAMP") || type.Contains("DATETIME"))
{
value = data.ToString().Trim() == "" ? "NULL" : $"'{Convert.ToDateTime(data.ToString()):yyyy-MM-dd HH:mm:ss}'";
}
else if (type.Contains("DATE"))
{
value = data.ToString().Trim() == "" ? "NULL" : $"'{Convert.ToDateTime(data.ToString()):yyyy-MM-dd}'";
}
else
{
value = data.ToString().Trim() == "" ? "NULL" : data.ToString();
}
return value;
}
private void WriteToFile(string fname, string content)
{
if (!File.Exists(fname))
{
using (StreamWriter sw = File.CreateText(fname))
{
sw.Write(content);
}
}
else
{
using (StreamWriter sw = File.AppendText(fname))
{
sw.Write(content);
}
}
}
/// <summary>
/// 创建并复镜像文件
/// </summary>
/// <param name="hospital"></param>
/// <param name="devServer"></param>
/// <param name="version"></param>
/// <param name="cmdlist"></param>
/// <param name="cb"></param>
private void SetAppCmd(Hospital hospital, DevServer devServer, string version, List<string> cmdlist, CheckBox cb)
{
var cname = cb.Text;
cmdlist.Add($"rm -rf /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/images/{cname}.*");
cmdlist.Add($"sh /home/{devServer.UserName}/ihdis/dev/build-one.sh {version} {cname} {devServer.UserName} {hospital.FileName}");
cmdlist.Add($"cp /home/{devServer.UserName}/ihdis/dev/app/images/{cname}.{version}.tar.gz /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/app/images/");
//cmdlist.Add($"ssh {publishServer.Ip} sh /home/{publishServer.UserName}/ihdis/script/publish.sh {version} {cname}");
//cmdlist.Add($"sudo sed -i \"s/${version}_TAG.*/${version}_TAG=${cname}/\" /home/{devServer.UserName}/ihdis/packages/{version}/.env");
cmdlist.Add($"sudo sed -i \"s/images\\/{cname}\\..*.tar.gz/images\\/{cname}.{version}.tar.gz/\" /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/load_images.cmd");
cmdlist.Add($"sudo sed -i \"s/images\\/{cname}\\..*.tar.gz/images\\/{cname}.{version}.tar.gz/\" /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/load_images.sh");
cmdlist.Add($"sudo rm -rf /home/{devServer.UserName}/ihdis/dev/app/images/{cname}.{version}*");
cmdlist.Add($"sudo cp -r /home/{devServer.UserName}/ihdis/dev/app/server/ts /home/{devServer.UserName}/ihdis/packages/{hospital.FileName}/{version}/data");
}
private bool CreateDbFile(string fname, Hospital hospital)
{
bool b_suc = false;
//创建文件夹
string path = fname.Substring(0, fname.LastIndexOf("."));
DirectoryInfo dir;
FileSystemInfo[] fileinfo;
if (Directory.Exists(path))
{
dir = new DirectoryInfo(path);
fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
subdir.Delete(true); //删除子目录和文件
}
else
{
File.Delete(i.FullName); //删除指定文件
}
}
Directory.Delete(path);
}
Directory.CreateDirectory(path);
Utility.SendLog("版本打包", $"创建临时目录 {path}");
//比对脚本 \tools\HH.iHDIS.OPS.Tool\HH.iHDIS.OPS.Tool\Config\CompareConfig.json
string toolsPath = AppDomain.CurrentDomain.BaseDirectory.Replace("\\JianLian.HDIS.PublishHelper\\bin\\Debug\\", "");
if (File.Exists($"{toolsPath}\\JianLian.HDIS.OPS.Tool\\Config\\CompareConfig.json"))
{
if (File.Exists($"{path}\\CompareConfig.json"))
{
File.Delete($"{path}\\CompareConfig.json");
}
File.Copy($"{toolsPath}\\JianLian.HDIS.OPS.Tool\\Config\\CompareConfig.json", $"{path}\\CompareConfig.json");
Utility.SendLog("版本打包", $"复制文件 {$"{toolsPath}\\JL.HDIS.OPS.Tool\\Config\\CompareConfig.json"} =>> {path}\\CompareConfig.json");
}
else
{
Utility.SendLog("版本打包", $"未能找到比对脚本:{toolsPath}\\JL.HDIS.OPS.Tool\\Config\\CompareConfig.json");
return b_suc;
}
//数据库脚本 \sc\script\ihdis.sql
if (File.Exists($"{hospital.SCPath}\\src\\Document\\script\\hdis.sql"))
{
if (File.Exists($"{path}\\hdis.sql"))
{
File.Delete($"{path}\\hdis.sql");
}
File.Copy($"{hospital.SCPath}\\src\\Document\\script\\hdis.sql", $"{path}\\hdis.sql");
Utility.SendLog("版本打包", $"复制文件 {hospital.SCPath}\\src\\Document\\script\\hdis.sql =>> {path}\\hdis.sql");
}
else
{
Utility.SendLog("版本打包", $"未能找到数据库脚本:{$"{hospital.SCPath}\\src\\Document\\script\\hdis.sql"}");
return b_suc;
}
//压缩文件
Utility.SendLog("版本打包", $"压缩文件");
ZipHelper.ZipFiles(fname, $"{path}");
//清空缓存文件
Utility.SendLog("版本打包", $"清空缓存文件与文件夹");
dir = new DirectoryInfo(path);
fileinfo = dir.GetFileSystemInfos(); //返回目录中所有文件和子目录
foreach (FileSystemInfo i in fileinfo)
{
if (i is DirectoryInfo) //判断是否文件夹
{
DirectoryInfo subdir = new DirectoryInfo(i.FullName);
subdir.Delete(true); //删除子目录和文件
}
else
{
File.Delete(i.FullName); //删除指定文件
}
}
Directory.Delete(path);
b_suc = true;
Utility.SendLog("版本打包", $"生成数据库脚本完毕 {fname}");
return b_suc;
}
#endregion
#region 采集插件打包
object m_InPulishTS = new object();
bool b_InPulishTS = false;
private void tsmi_TSRelease_Click(object sender, EventArgs e)
{
lock (m_InPulishTS)
{
if (b_InPulishTS)
{
return;
}
}
string flag = "采集插件";
bool b_build = false;
string path = string.Empty;
string tspath = string.Empty;
string version = string.Empty;
bool custom = false;
string customHospitals = string.Empty;
//选择路径和版本
using (Form_Plugin f = new Form_Plugin())
{
f.ShowDialog();
if (f.m_DialogResult != DialogResult.Yes)
{
return;
}
b_build = f.m_Build;
path = f.m_Path;
version = f.m_Version;
custom = f.m_Custom;
customHospitals = f.m_CustomHospitals;
tspath = f.m_TSPath;
Utility.SendLog(flag, $"项目路径 {tspath}");
Utility.SendLog(flag, $"选择的路径 {path}");
Utility.SendLog(flag, $"输入的版本 {version}");
Utility.SendLog(flag, $"是否编译项目 {b_build}");
Utility.SendLog(flag, $"是否自定义医院 {custom} {(custom ? customHospitals : "")}");
}
Utility.SendLog("开始生成采集插件", true);
Thread t = new Thread(new ThreadStart(delegate
{
CreateTSPlugin(flag, b_build, path, tspath, version, custom, customHospitals);
}));
t.Start();
}
void CreateTSPlugin(string flag, bool b_build, string path, string tspath, string version, bool custom, string customHospitals)
{
lock (m_InPulishTS)
{
b_InPulishTS = true;
}
try
{
//采集插件基础文件路径
string tsBasePath = $"{AppDomain.CurrentDomain.BaseDirectory.Replace("\\bin\\Debug\\", "")}\\ts";
//编译项目
if (b_build)
{
Utility.SendLog(flag, $"编译项目");
CmdHelper.ExecCmd($"cd {tspath}\\JianLian.Adapter.Center\\Host\\JianLian.Adapter.Hosting\r\n"
+ $"{tspath.Split(':')[0].Trim()}:\r\n"
+ $"dotnet publish -r linux-x64 --self-contained false -o .\\bin\\Release\\net5.0\\publish\r\n"
+ $"exit\r\n");
}
List<string> customs = custom ? customHospitals.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).ToList() : new List<string>();
//根据Custom\JianLian.Adapter.Hospital,创建医院文件夹
string customHospitalPath = $"{tspath}\\JianLian.Adapter.Center\\Custom";
System.IO.Directory.GetDirectories(customHospitalPath)
.ToList()
.ForEach(o =>
{
//医院名称
var hospital = o.Substring(o.LastIndexOf('.') + 1);
if (custom)
{
if (!customs.Contains(hospital))
{
Utility.SendLog(flag, $"自定义生成,医院 {hospital} 丢弃");
return;
}
}
var hospitalPath = $"{path}\\{hospital}\\{version}";
if (!System.IO.Directory.Exists(hospitalPath))
{
System.IO.Directory.CreateDirectory(hospitalPath);
}
else
{
DeleteFilesItem(hospitalPath, new List<string> { });
}
//编译
if (b_build)
{
Utility.SendLog(flag, $"编译项目 {hospital}");
CmdHelper.ExecCmd($"cd {o}\r\n"
+ $"{tspath.Split(':')[0].Trim()}:\r\n"
+ $"dotnet build\r\n"
+ $"exit\r\n");
}
Utility.SendLog(flag, $"正在生成医院 {hospital}");
if (!File.Exists($"{o}\\bin\\Debug\\net5.0\\Adapter.json"))
{
SendLog(flag, $"医院[{hospital}]配置文件 Adapter.json 不存在,不继续打包该医院");
return;
}
if (!File.Exists($"{o}\\bin\\Debug\\net5.0\\OtherDb.json"))
{
SendLog(flag, $"医院[{hospital}]配置文件 OtherDb.json 不存在,不继续打包该医院");
return;
}
if (!File.Exists($"{o}\\bin\\Debug\\net5.0\\appsettings.json"))
{
SendLog(flag, $"医院[{hospital}]配置文件 appsettings.json 不存在,不继续打包该医院");
return;
}
//拷贝插件基础文件
CopyDirectory(tsBasePath, hospitalPath, true);
////拷贝发布的文件到Code文件夹
//CopyDirectory($"{tspath}\\JianLian.Adapter.Center\\Host\\JianLian.Adapter.Hosting\\bin\\Release\\net5.0\\publish", $"{hospitalPath}\\code", true);
//System.Threading.Thread.Sleep(1000);
//拷贝本医院最新的dll文件和配置文件到Code文件夹
CopyDirectory($"{o}\\bin\\Debug\\net5.0", $"{hospitalPath}", true);
System.Threading.Thread.Sleep(1000);
//修改Adapter.json
//var adaptercontent = File.ReadAllText($"{hospitalPath}\\code\\Adapter.json", Encoding.UTF8);
//adaptercontent = adaptercontent.Replace($"JianLian.Adapter.Sample", $"JianLian.Adapter.{hospital}");
//File.WriteAllText($"{hospitalPath}\\code\\Adapter.json", adaptercontent, Encoding.UTF8);
////修改版本号 .env init.sh README.ihdis
//var envcontent = File.ReadAllText($"{hospitalPath}\\.env", Encoding.UTF8);
//envcontent = envcontent.Replace($"ts_TAG=base", $"ts_TAG={version}");
//File.WriteAllText($"{hospitalPath}\\.env", envcontent, Encoding.UTF8);
//StringBuilder sb_init = new StringBuilder();
//File.ReadAllText($"{hospitalPath}\\init.sh", Encoding.UTF8)
//.Replace("sudo docker tag hh/ts:base hh/ts:{$version}", $"sudo docker tag hh/ts:base hh/ts:{version}")
//.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries)
//.ToList()
//.ForEach(str =>
//{
// sb_init.Append($"{str}\n");
//});
//File.WriteAllText($"{hospitalPath}\\init.sh", sb_init.ToString(), Encoding.ASCII);
var readmecontent = File.ReadAllText($"{hospitalPath}\\README.ihdis", Encoding.UTF8);
readmecontent = readmecontent.Replace($"\"version\": \"base\",", $"\"version\": \"{version}\",");
File.WriteAllText($"{hospitalPath}\\README.ihdis", readmecontent, Encoding.UTF8);
//打包压缩文件
Utility.SendLog(flag, $"医院 {hospital} 开始压缩文件");
var zippath = hospitalPath.Substring(0, hospitalPath.LastIndexOf('\\'));
ZipHelper.ZipFiles($"{zippath}\\ts.zip", hospitalPath);
File.Copy($"{zippath}\\ts.zip", $"{hospitalPath}\\ts.zip");
File.Delete($"{zippath}\\ts.zip");
Utility.SendLog(flag, $"医院 {hospital} 开始清理缓存文件");
DeleteFilesItem(hospitalPath, new List<string> { $"{hospitalPath}\\ts.zip" });
Utility.SendLog(flag, $"医院 {hospital} 生成完毕");
});
Utility.SendLog(flag, $"生成完毕", true);
}
catch (Exception ex)
{
MessageBox.Show($"生成失败:{ex}");
}
finally
{
lock (m_InPulishTS)
b_InPulishTS = false;
}
}
/// <summary>
/// 删除全部文件
/// </summary>
/// <param name="path"></param>
/// <param name="pathExceptions">例外的目录</param>
/// <param name="fileExceptions">例外的文件</param>
private void DeleteFilesItem(string path, List<string> fileExceptions)
{
var fs = Directory.GetFiles(path);
fs.ToList().ForEach(filename =>
{
if (fileExceptions.Contains(filename))
return;
File.Delete(filename);
});
var ds = Directory.GetDirectories(path);
ds.ToList().ForEach(o =>
{
DeleteFilesItem(o, fileExceptions);
});
//清除空目录
fs = Directory.GetFiles(path);
if (fs.Length == 0)
{
Directory.Delete(path);
}
}
private static bool CopyDirectory(string sourcePath, string destinationPath, bool overwriteexisting)
{
bool ret = false;
try
{
sourcePath = sourcePath.EndsWith(@"\") ? sourcePath : sourcePath + @"\";
destinationPath = destinationPath.EndsWith(@"\") ? destinationPath : destinationPath + @"\";
if (Directory.Exists(sourcePath))
{
if (Directory.Exists(destinationPath) == false)
Directory.CreateDirectory(destinationPath);
foreach (string fls in Directory.GetFiles(sourcePath))
{
FileInfo flinfo = new FileInfo(fls);
flinfo.CopyTo(destinationPath + flinfo.Name, overwriteexisting);
}
foreach (string drs in Directory.GetDirectories(sourcePath))
{
DirectoryInfo drinfo = new DirectoryInfo(drs);
if (CopyDirectory(drs, destinationPath + drinfo.Name, overwriteexisting) == false)
ret = false;
}
}
ret = true;
}
catch
{
ret = false;
}
return ret;
}
#endregion
#region 升级日志
private void tsmi_UpgradeLog_Click(object sender, EventArgs e)
{
using (Form_UpgradeLog f = new Form_UpgradeLog())
{
f.ShowDialog();
}
}
#endregion
#region 数据库管理
private void tsmi_HeidiSQL_Click(object sender, EventArgs e)
{
if (!HasSelectdHospital(out DevServer server, out Hospital hospital))
{
return;
}
if (!SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/compose/{hospital.FileName}") && !SftpHelper.Exists(server, $"/home/{server.UserName}/ihdis/{hospital.FileName}"))
{
MessageBox.Show("医院不存在", "提示");
return;
}
string heidisql = @"C:\Program Files\HeidiSQL\heidisql.exe";
if (!File.Exists(heidisql))
{
MessageBox.Show($"未能检测到 [HeidiSQL],请先安装!\r\n默认检测路径为:{heidisql}", "提示");
}
else
{
if (hospital.FileName == "produse")
{
System.Diagnostics.Process.Start(heidisql, $" -d {server.Ip}({hospital.FileName}) -n {0} -h {server.Ip} -u root -p jlmed#123 -P {hospital.DefaultFort}90");
}
else
{
System.Diagnostics.Process.Start(heidisql, $" -d {server.Ip}({hospital.FileName}) -n {0} -h {server.Ip} -u root -p jlmed#123 -P {hospital.DefaultFort}90");
}
}
}
#endregion
#region 关于
private void tsmi_About_Click(object sender, EventArgs e)
{
using (Form_About f = new Form_About())
{
f.ShowDialog();
}
}
#endregion
#region 前端代码生成
private void tsmi_CodeGeneRATOR_Click(object sender, EventArgs e)
{
using (Form_CodeGenerator f = new Form_CodeGenerator())
{
f.ShowDialog();
}
}
#endregion
}
}