简化程序
This commit is contained in:
		@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 | 
			
		||||
# Visual Studio Version 17
 | 
			
		||||
VisualStudioVersion = 17.0.32014.148
 | 
			
		||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Archiver", "src\Archiver\Archiver.csproj", "{D42E639F-0E4D-4CE3-9793-230D6B07C3FE}"
 | 
			
		||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ArchiverLite", "src\Archiver\ArchiverLite.csproj", "{D42E639F-0E4D-4CE3-9793-230D6B07C3FE}"
 | 
			
		||||
EndProject
 | 
			
		||||
Global
 | 
			
		||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
	<PropertyGroup>
 | 
			
		||||
		<OutputType>Exe</OutputType>
 | 
			
		||||
		<TargetFramework>net6.0</TargetFramework>
 | 
			
		||||
		<ImplicitUsings>enable</ImplicitUsings>
 | 
			
		||||
		<Nullable>enable</Nullable>
 | 
			
		||||
	</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="CliFx" Version="2.2.1" />
 | 
			
		||||
		<PackageReference Include="Dapper" Version="2.0.123" />
 | 
			
		||||
		<PackageReference Include="MySqlConnector" Version="2.1.2" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
</Project>
 | 
			
		||||
							
								
								
									
										20
									
								
								src/Archiver/ArchiverLite.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/Archiver/ArchiverLite.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
			
		||||
<Project Sdk="Microsoft.NET.Sdk">
 | 
			
		||||
 | 
			
		||||
	<PropertyGroup>
 | 
			
		||||
		<OutputType>Exe</OutputType>
 | 
			
		||||
		<TargetFramework>net8.0</TargetFramework>
 | 
			
		||||
		<ImplicitUsings>enable</ImplicitUsings>
 | 
			
		||||
		<Nullable>enable</Nullable>
 | 
			
		||||
		<TrimMode>partial</TrimMode>
 | 
			
		||||
	</PropertyGroup>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	<ItemGroup>
 | 
			
		||||
		<PackageReference Include="CliFx" Version="2.3.5" />
 | 
			
		||||
		<PackageReference Include="Dapper" Version="2.1.28" />
 | 
			
		||||
		<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
 | 
			
		||||
		<PackageReference Include="MySqlConnector" Version="2.3.5" />
 | 
			
		||||
	</ItemGroup>
 | 
			
		||||
	
 | 
			
		||||
	
 | 
			
		||||
</Project>
 | 
			
		||||
@@ -1,159 +0,0 @@
 | 
			
		||||
using Chenfeng.MES.Archiver.Core;
 | 
			
		||||
using Chenfeng.MES.Archiver.Data;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Archiver.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("copy2")]
 | 
			
		||||
    public class CopyTableCommand : ICommand
 | 
			
		||||
    {
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
 | 
			
		||||
        [CommandOption("legacy", Description = "旧版MES")]
 | 
			
		||||
        public bool Legacy { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandParameter(0, Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
 | 
			
		||||
        public MySqlConnection? Db { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
            if (this.Connection.Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
                connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
                connBuilder.CharacterSet = "utf8";
 | 
			
		||||
                //connBuilder.ConnectionTimeout = 5 * 60;
 | 
			
		||||
                Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
 | 
			
		||||
                SqlMapper.Settings.CommandTimeout = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM");
 | 
			
		||||
            if (Legacy)
 | 
			
		||||
            {
 | 
			
		||||
                MesLegacyTables(starMonth);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                MesTables(starMonth);
 | 
			
		||||
            }
 | 
			
		||||
            Print("操作完成");
 | 
			
		||||
 | 
			
		||||
            return ValueTask.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void ExecuteRow(string table, string key, object param, MySqlTransaction? transaction)
 | 
			
		||||
        {
 | 
			
		||||
            Db.Execute($"INSERT INTO `{table}_new` SELECT * FROM `{table}` where {key}=@{key}", param, transaction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IEnumerable<T> GetIdList<T>(string table, string field, string condition, object param)
 | 
			
		||||
        {
 | 
			
		||||
            return Db.Query<T>($"select {field} from `{table}` where {condition}", param);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void MesTables(string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            Print("复制订单");
 | 
			
		||||
            foreach (var orderno in GetIdList<long>("order", "orderno", "LEFT(orderno,6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "order_box_block", "order_data_block", "order_data_goods", "order_data_parts", "order_item", "order_module_extra", "order_module_item", "order_package" })
 | 
			
		||||
                    {
 | 
			
		||||
                        ExecuteRow(childTable, "orderno", new { orderno }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    ExecuteRow("order", "orderno", new { orderno }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("复制工序");
 | 
			
		||||
 | 
			
		||||
            foreach (var id in GetIdList<long>("order_process", "id", "LEFT(orderno,6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "order_process_step_item", "order_process_step" })
 | 
			
		||||
                    {
 | 
			
		||||
                        ExecuteRow(childTable, "OrderProcessID", new { OrderProcessID = id }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    ExecuteRow("order_process", "id", new { id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("复制标准版订单");
 | 
			
		||||
            foreach (var id in GetIdList<long>("simple_plan_order", "PlaceNo", "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                ExecuteRow("simple_plan_order", "PlaceNo", new { PlaceNo = id }, null);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("复制排单");
 | 
			
		||||
            foreach (var id in GetIdList<long>("order_block_plan", "id", "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                //if (Db.State != System.Data.ConnectionState.Open) Db.Open();
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    ExecuteRow("order_block_plan", "ID", new { ID = id }, trans);
 | 
			
		||||
                    ExecuteRow("order_block_plan_result", "ID", new { ID = id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //CopyStep((table, newTable) =>
 | 
			
		||||
            //{
 | 
			
		||||
            //    CopyData(table, newTable, "concat('20',left(id,4)) "+op+" @starMonth ", new { starMonth });
 | 
			
		||||
            //}, "order_scrap_board");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MySqlTransaction GetTransaction()
 | 
			
		||||
        {
 | 
			
		||||
            if (Db.State != System.Data.ConnectionState.Open) Db.Open();
 | 
			
		||||
            return Db.BeginTransaction();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public  void MesLegacyTables( string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            Print("复制旧版订单");
 | 
			
		||||
 | 
			
		||||
            foreach (var orderno in GetIdList<string>("saleorder", "orderno", "LEFT(DATE_FORMAT(SaleDate,'%Y%m'),6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "SaleOrderItem", "saleblock", "saleobject", "saleorderobject", "saleorderoffer", "saleorderpackage", "saleblockobjids", "saleobjectobjids", "saleorder_block_cadmodelinfo", "saleorderblockbaseposition",
 | 
			
		||||
            "saleordergoodsinfo", "saleorder_block_point", "saleorder_block_pointinfo", "orderprocess", "orderprocessstep", "orderprocessstepitem"})
 | 
			
		||||
                    {
 | 
			
		||||
                        ExecuteRow(childTable, "orderno", new { orderno }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    ExecuteRow("saleorder", "orderno", new { orderno }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("复制旧版排单");
 | 
			
		||||
 | 
			
		||||
            foreach (var id in GetIdList<string>("orderblockprocessplan", "id", "LEFT(DATE_FORMAT(createtime,'%Y%m'),6) >= @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    ExecuteRow("orderblockprocessplan", "ID", new { ID = id }, trans);
 | 
			
		||||
                    ExecuteRow("orderblockprocessplanplaceresult", "ID", new { ID = id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,215 +0,0 @@
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Data.Common;
 | 
			
		||||
using Chenfeng.MES.Archiver.Core;
 | 
			
		||||
using Chenfeng.MES.Archiver.Data;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("copy")]
 | 
			
		||||
    public class CopyTableCommand : ICommand, IArchiveReader
 | 
			
		||||
    {
 | 
			
		||||
        [CommandOption("connection", Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
 | 
			
		||||
        public string TableSuffix { get; set; } = "new";
 | 
			
		||||
 | 
			
		||||
        public DbConnection? Db { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
 | 
			
		||||
        [CommandOption("legacy", Description = "旧版MES")]
 | 
			
		||||
        public bool Legacy { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("replace", Description = "替换表")]
 | 
			
		||||
        public bool Replace { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("restore", Description = "回复表")]
 | 
			
		||||
        public bool Restore { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("rm-backup", Description = "删除备份表")]
 | 
			
		||||
        public bool RemoveBackup { get; set; }
 | 
			
		||||
 | 
			
		||||
        [CommandOption("timeout", Description = "sql命令超时时间")]
 | 
			
		||||
        public int Timeout { get; set; } = 3;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("script", Description = "是否生成执行脚本")]
 | 
			
		||||
        public bool Script { get; set; }
 | 
			
		||||
 | 
			
		||||
        [CommandOption("verbose", 'v', Description = "显示sql")]
 | 
			
		||||
        public bool Verbose { get; set; }
 | 
			
		||||
 | 
			
		||||
        [CommandOption("copy-data",Description ="拷贝数据")]
 | 
			
		||||
        public bool CopyData { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
 | 
			
		||||
            var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM");
 | 
			
		||||
 | 
			
		||||
            SqlMapper.Settings.CommandTimeout = 60 * Timeout;
 | 
			
		||||
            console.Output.WriteLine((Legacy ? "旧" : "新") + "版数据库");
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                if (this.Connection.Length > 0)
 | 
			
		||||
                {
 | 
			
		||||
                    var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
                    connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
                    connBuilder.CharacterSet = "utf8";
 | 
			
		||||
                    Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Db?.Open();
 | 
			
		||||
                if (Legacy)
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesLegacyTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (Db!=null && sqlScripts.Length>0)
 | 
			
		||||
                {
 | 
			
		||||
                    var sql = "set foreign_key_checks = 0;" + sqlScripts.ToString() + "set foreign_key_checks = 1;";
 | 
			
		||||
                    if (Verbose)
 | 
			
		||||
                    {
 | 
			
		||||
                        Print(sql);
 | 
			
		||||
                    }
 | 
			
		||||
                    Db.Execute(sql);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (Script)
 | 
			
		||||
                {
 | 
			
		||||
                    if (Directory.Exists("./scripts") == false)
 | 
			
		||||
                    {
 | 
			
		||||
                        Directory.CreateDirectory("./scripts");
 | 
			
		||||
                    }
 | 
			
		||||
                    using (var file = File.OpenWrite($"./scripts/mes{(Legacy ? "-legacy" : "")}-table.sql"))
 | 
			
		||||
                    {
 | 
			
		||||
                        using (var writer = new StreamWriter(file))
 | 
			
		||||
                        {
 | 
			
		||||
                            writer.Write(sqlScripts);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                Print("操作成功");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                console.Output.WriteLine(ex.ToString());
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                Db?.Close();
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return default;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteData(string table, string where, object param)
 | 
			
		||||
        {
 | 
			
		||||
            if (ExecuteBefore(table))
 | 
			
		||||
            {
 | 
			
		||||
                ExecuteSql($"INSERT INTO `{TableDic[table]}` SELECT * FROM `{table}` WHERE {where}", param);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteChildData(string table, string parentTable, string condition)
 | 
			
		||||
        {
 | 
			
		||||
            if (ExecuteBefore(table))
 | 
			
		||||
            {
 | 
			
		||||
                ExecuteSql($"INSERT INTO `{TableDic[table]}`  SELECT child.* FROM `{TableDic[parentTable]}` parent join `{table}` child on {condition} ");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private bool ExecuteBefore(string table)
 | 
			
		||||
        {
 | 
			
		||||
            if (RemoveBackup)
 | 
			
		||||
            {
 | 
			
		||||
                ExecuteSql($"DROP TABLE IF EXISTS `{table}_bak`", Execute: false);
 | 
			
		||||
            }
 | 
			
		||||
            else if (Restore)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                ExecuteSql($"DROP TABLE IF EXISTS `{table}`", Execute: false);
 | 
			
		||||
                ExecuteSql($"RENAME TABLE `{table}_bak` TO `{table}`", Execute: false);
 | 
			
		||||
            }
 | 
			
		||||
            else if (Replace)
 | 
			
		||||
            {
 | 
			
		||||
 | 
			
		||||
                ExecuteSql($"RENAME TABLE `{table}` TO `{table}_bak`", Execute: false);
 | 
			
		||||
                ExecuteSql($"RENAME TABLE `{TableDic[table]}` TO `{table}`", Execute: false);
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                ExecuteSql($"DROP TABLE IF EXISTS `{TableDic[table]}`");
 | 
			
		||||
                ExecuteSql($"CREATE TABLE `{TableDic[table]}` LIKE `{table}`"); // IF NOT EXISTS
 | 
			
		||||
                Print(TableDic[table] + " 创建完成");
 | 
			
		||||
                return CopyData;
 | 
			
		||||
            }
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        private StringBuilder sqlScripts = new StringBuilder();
 | 
			
		||||
        private void ExecuteSql(string sql, object? param = null, bool Execute = true)
 | 
			
		||||
        {
 | 
			
		||||
            if (Execute)
 | 
			
		||||
            {
 | 
			
		||||
                Db?.Execute(sql, param);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (Script || Execute == false)
 | 
			
		||||
            {
 | 
			
		||||
                var fullSql = sql + ";";
 | 
			
		||||
                if (param != null)
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var property in param.GetType().GetProperties())
 | 
			
		||||
                    {
 | 
			
		||||
                        var val = property.GetValue(param)?.ToString();
 | 
			
		||||
                        fullSql = fullSql.Replace("@" + property.Name, val);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                sqlScripts.AppendLine(fullSql);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public Dictionary<string, string> TableDic { get; set; } = new Dictionary<string, string>();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public void Step(Action<string> action, params string[] tables)
 | 
			
		||||
        {
 | 
			
		||||
            var list = tables.Select(table => new
 | 
			
		||||
            {
 | 
			
		||||
                Table = table,
 | 
			
		||||
                NewTable = table + "_" + this.TableSuffix
 | 
			
		||||
            });
 | 
			
		||||
 | 
			
		||||
            foreach (var item in list)
 | 
			
		||||
            {
 | 
			
		||||
                TableDic[item.Table] = item.NewTable;
 | 
			
		||||
                action(item.Table);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,159 +1,44 @@
 | 
			
		||||
using Chenfeng.MES.Archiver.Core;
 | 
			
		||||
using Chenfeng.MES.Archiver.Data;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
using ArchiverLite.Services;
 | 
			
		||||
 | 
			
		||||
namespace Archiver.Commands
 | 
			
		||||
namespace ArchiverLite.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("delete")]
 | 
			
		||||
    public class DeleteTableCommand : ICommand
 | 
			
		||||
    [Command("delete",Description = "清理旧版MES历史数据")]
 | 
			
		||||
    public class DeleteDataCommand : ICommand
 | 
			
		||||
    {
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
 | 
			
		||||
        [CommandOption("legacy", Description = "旧版MES")]
 | 
			
		||||
        public bool Legacy { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandParameter(0, Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
 | 
			
		||||
        public MySqlConnection? Db { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
            var print = (string text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
            if (this.Connection.Length > 0)
 | 
			
		||||
            {
 | 
			
		||||
                var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
                connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
                connBuilder.CharacterSet = "utf8";
 | 
			
		||||
                //connBuilder.ConnectionTimeout = 5 * 60;
 | 
			
		||||
                Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
 | 
			
		||||
                SqlMapper.Settings.CommandTimeout = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM");
 | 
			
		||||
            if (Legacy)
 | 
			
		||||
            var starMonth = DateTime.Now.AddYears(-1).ToString("yyyy") + "01";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            print($"开始清理旧版MES {starMonth}之前数据");
 | 
			
		||||
 | 
			
		||||
            Task.WaitAll(Task.Run(() =>
 | 
			
		||||
            {
 | 
			
		||||
                MesLegacyTables(starMonth);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
                var service = new MesLegacyService(this.Connection);
 | 
			
		||||
                service.ClearOrder(starMonth);
 | 
			
		||||
            }), Task.Run(() =>
 | 
			
		||||
            {
 | 
			
		||||
                MesTables(starMonth);
 | 
			
		||||
            }
 | 
			
		||||
            Print("操作完成");
 | 
			
		||||
                var service = new MesLegacyService(this.Connection);
 | 
			
		||||
                service.ClearOrderBlockPlan(starMonth);
 | 
			
		||||
            }));
 | 
			
		||||
 | 
			
		||||
            print("操作完成");
 | 
			
		||||
 | 
			
		||||
            return ValueTask.CompletedTask;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DeleteRow(string table, string key, object param, MySqlTransaction? transaction)
 | 
			
		||||
        {
 | 
			
		||||
            Db.Execute($"DELETE FROM `{table}` where {key}=@{key}", param, transaction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IEnumerable<T> GetIdList<T>(string table, string field, string condition, object param)
 | 
			
		||||
        {
 | 
			
		||||
            return Db.Query<T>($"select {field} from `{table}` where {condition}", param);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void MesTables(string starMonth, string op = "<")
 | 
			
		||||
        {
 | 
			
		||||
            Print("清理订单");
 | 
			
		||||
            foreach (var orderno in GetIdList<long>("order", "orderno", "LEFT(orderno,6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "order_box_block", "order_data_block", "order_data_goods", "order_data_parts", "order_item", "order_module_extra", "order_module_item", "order_package" })
 | 
			
		||||
                    {
 | 
			
		||||
                        DeleteRow(childTable, "orderno", new { orderno }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    DeleteRow("order", "orderno", new { orderno }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("清理工序");
 | 
			
		||||
 | 
			
		||||
            foreach (var id in GetIdList<long>("order_process", "id", "LEFT(orderno,6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "order_process_step_item", "order_process_step" })
 | 
			
		||||
                    {
 | 
			
		||||
                        DeleteRow(childTable, "OrderProcessID", new { OrderProcessID = id }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    DeleteRow("order_process", "id", new { id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("清理标准版订单");
 | 
			
		||||
            foreach (var id in GetIdList<long>("simple_plan_order", "PlaceNo", "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                DeleteRow("simple_plan_order", "PlaceNo", new { PlaceNo = id }, null);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("清理排单");
 | 
			
		||||
            foreach (var id in GetIdList<long>("order_block_plan", "id", "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                //if (Db.State != System.Data.ConnectionState.Open) Db.Open();
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    DeleteRow("order_block_plan", "ID", new { ID = id }, trans);
 | 
			
		||||
                    DeleteRow("order_block_plan_result", "ID", new { ID = id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //CopyStep((table, newTable) =>
 | 
			
		||||
            //{
 | 
			
		||||
            //    CopyData(table, newTable, "concat('20',left(id,4)) "+op+" @starMonth ", new { starMonth });
 | 
			
		||||
            //}, "order_scrap_board");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public MySqlTransaction GetTransaction()
 | 
			
		||||
        {
 | 
			
		||||
            if (Db.State != System.Data.ConnectionState.Open) Db.Open();
 | 
			
		||||
            return Db.BeginTransaction();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public  void MesLegacyTables( string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            Print("清理旧版订单");
 | 
			
		||||
 | 
			
		||||
            foreach (var orderno in GetIdList<string>("saleorder", "orderno", "LEFT(DATE_FORMAT(SaleDate,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "SaleOrderItem", "saleblock", "saleobject", "saleorderobject", "saleorderoffer", "saleorderpackage", "saleblockobjids", "saleobjectobjids", "saleorder_block_cadmodelinfo", "saleorderblockbaseposition",
 | 
			
		||||
            "saleordergoodsinfo", "saleorder_block_point", "saleorder_block_pointinfo", "orderprocess", "orderprocessstep", "orderprocessstepitem"})
 | 
			
		||||
                    {
 | 
			
		||||
                        DeleteRow(childTable, "orderno", new { orderno }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    DeleteRow("saleorder", "orderno", new { orderno }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Print("清理旧版排单");
 | 
			
		||||
 | 
			
		||||
            foreach (var id in GetIdList<string>("orderblockprocessplan", "id", "LEFT(DATE_FORMAT(createtime,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    DeleteRow("orderblockprocessplan", "ID", new { ID = id }, trans);
 | 
			
		||||
                    DeleteRow("orderblockprocessplanplaceresult", "ID", new { ID = id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,267 +0,0 @@
 | 
			
		||||
using Chenfeng.MES.Archiver.Core;
 | 
			
		||||
using Chenfeng.MES.Archiver.Data;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("export")]
 | 
			
		||||
    public class ExportTableCommand : ICommand, IArchiveReader
 | 
			
		||||
    {
 | 
			
		||||
        [CommandParameter(0, Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
 | 
			
		||||
        public MySqlConnection? Db { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
 | 
			
		||||
        [CommandOption("legacy", Description = "旧版MES")]
 | 
			
		||||
        public bool Legacy { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("timeout", Description = "sql命令超时时间")]
 | 
			
		||||
        public int Timeout { get; set; } = 3;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("compress", Description = "文件压缩,默认gzip")]
 | 
			
		||||
        public string Compress { get; set; } = "gz";
 | 
			
		||||
 | 
			
		||||
        [CommandOption("pagesize", Description = "查询分页")]
 | 
			
		||||
        public int PageSize { get; set; } = 500_000;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("output", Description = "导出路径")]
 | 
			
		||||
        public string Output { get; set; } = "./output";
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var startTime = DateTime.Now;
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
 | 
			
		||||
            var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
            connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
            connBuilder.CharacterSet = "utf8";
 | 
			
		||||
 | 
			
		||||
            var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM");
 | 
			
		||||
 | 
			
		||||
            SqlMapper.Settings.CommandTimeout = 60 * Timeout;
 | 
			
		||||
 | 
			
		||||
            console.Output.WriteLine($"拷贝" + (Legacy ? "旧" : "新") + "版表数据");
 | 
			
		||||
 | 
			
		||||
            if (Directory.Exists(Output) == false)
 | 
			
		||||
            {
 | 
			
		||||
                Directory.CreateDirectory(Output);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
 | 
			
		||||
                Db.Open();
 | 
			
		||||
                if (Legacy)
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesLegacyTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                Print("操作成功");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                console.Output.WriteLine(ex.ToString());
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                Db?.Close();
 | 
			
		||||
            }
 | 
			
		||||
            console.Output.WriteLine("执行耗时:" + (DateTime.Now - startTime).TotalMilliseconds + "ms");
 | 
			
		||||
            return default;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteData(string table, string where, object param)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = $"SELECT * FROM `{table}` WHERE {where} ";
 | 
			
		||||
            if (PageSize > 0)
 | 
			
		||||
            {
 | 
			
		||||
                sql += "limit @pageIndex,@pageSize";
 | 
			
		||||
            }
 | 
			
		||||
            DumpData(table, sql, param);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteChildData(string table, string parentTable, string condition)
 | 
			
		||||
        {
 | 
			
		||||
            var parentSqlInfo = tableSqlDic[parentTable];
 | 
			
		||||
            DumpData(table, $"SELECT child.* FROM ({parentSqlInfo.Item1}) parent join `{table}` child on {condition} ", parentSqlInfo.Item2);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public Dictionary<string, Tuple<string, object?>> tableSqlDic { get; set; } = new();
 | 
			
		||||
 | 
			
		||||
        private void DumpData(string table, string sql, object? param = null)
 | 
			
		||||
        {
 | 
			
		||||
            var watch = new Stopwatch();
 | 
			
		||||
            watch.Start();
 | 
			
		||||
            Print(table);
 | 
			
		||||
            Print("开始导出");
 | 
			
		||||
 | 
			
		||||
            tableSqlDic[table] = new Tuple<string, object?>(sql, param);
 | 
			
		||||
            var cmd = Db.CreateCommand();
 | 
			
		||||
            cmd.CommandTimeout = 60 * Timeout;
 | 
			
		||||
            cmd.CommandText = sql;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            if (param != null)
 | 
			
		||||
            {
 | 
			
		||||
                switch (param)
 | 
			
		||||
                {
 | 
			
		||||
                    case Dictionary<string, object> dic:
 | 
			
		||||
                        foreach (var kv in dic.AsEnumerable())
 | 
			
		||||
                        {
 | 
			
		||||
                            cmd.Parameters.AddWithValue("@" + kv.Key, kv.Value);
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                    default:
 | 
			
		||||
                        foreach (var property in param.GetType().GetProperties())
 | 
			
		||||
                        {
 | 
			
		||||
                            cmd.Parameters.AddWithValue("@" + property.Name, property.GetValue(param));
 | 
			
		||||
                        }
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            var columns = new List<string>();
 | 
			
		||||
            var columnString = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            var pageIndex = 1;
 | 
			
		||||
            cmd.Parameters.AddWithValue("@pageSize", PageSize);
 | 
			
		||||
            cmd.Parameters.AddWithValue("@pageIndex", 0);
 | 
			
		||||
 | 
			
		||||
            while (true)
 | 
			
		||||
            {
 | 
			
		||||
                cmd.Parameters["@pageIndex"].Value = (pageIndex - 1) * PageSize;
 | 
			
		||||
 | 
			
		||||
                var valString = new StringBuilder();
 | 
			
		||||
 | 
			
		||||
                var queryWatch = Stopwatch.StartNew();
 | 
			
		||||
                var reader = cmd.ExecuteReader();
 | 
			
		||||
                queryWatch.Stop();
 | 
			
		||||
                if (queryWatch.ElapsedMilliseconds > 10_000)
 | 
			
		||||
                {
 | 
			
		||||
                    Print("slow sql:" + sql + ",page:" + pageIndex);
 | 
			
		||||
                }
 | 
			
		||||
                using (reader)
 | 
			
		||||
                {
 | 
			
		||||
                    if (columnString.Length == 0)
 | 
			
		||||
                    {
 | 
			
		||||
                        for (int i = 0; i < reader.FieldCount; i++)
 | 
			
		||||
                        {
 | 
			
		||||
                            //columns.Add(reader.GetName(i));
 | 
			
		||||
                            columnString.Append($"`{reader.GetName(i)}`,");
 | 
			
		||||
                        }
 | 
			
		||||
                        columnString.Length--;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    while (reader.Read())
 | 
			
		||||
                    {
 | 
			
		||||
                        //var row = new List<object>();
 | 
			
		||||
                        valString.Append('(');
 | 
			
		||||
                        for (int i = 0; i < reader.FieldCount; i++)
 | 
			
		||||
                        {
 | 
			
		||||
                            var val = reader.GetValue(i);
 | 
			
		||||
                            object newVal;
 | 
			
		||||
                            switch (val)
 | 
			
		||||
                            {
 | 
			
		||||
                                case System.DBNull b:
 | 
			
		||||
                                    newVal = "null";
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case bool b:
 | 
			
		||||
                                    newVal = b ? 1 : 0;
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case string s:
 | 
			
		||||
                                    newVal = $"'{s}'";
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case DateTime dt:
 | 
			
		||||
                                    newVal = '\'' + dt.ToString("yyyy-MM-dd HH:mm:ss") + '\'';
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case byte[] byteList:
 | 
			
		||||
                                    newVal = "0x" + string.Concat(byteList.Select(i => i.ToString("X2")));
 | 
			
		||||
                                    break;
 | 
			
		||||
                                default:
 | 
			
		||||
                                    newVal = val;
 | 
			
		||||
                                    break;
 | 
			
		||||
                            }
 | 
			
		||||
                            valString.Append(newVal);
 | 
			
		||||
                            if (i < reader.FieldCount-1)
 | 
			
		||||
                            {
 | 
			
		||||
                                valString.Append(',');
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        valString.Append(')');
 | 
			
		||||
                        valString.Append(',');
 | 
			
		||||
                        //valString.Append($"({string.Join(",", row)}),");
 | 
			
		||||
                    }
 | 
			
		||||
                    if (valString.Length == 0) break;
 | 
			
		||||
 | 
			
		||||
                    valString.Length--; // 移除最后一个逗号
 | 
			
		||||
 | 
			
		||||
                    var distFile = $"{Output}/{table}-p{pageIndex}.{Compress}.sql";
 | 
			
		||||
 | 
			
		||||
                    using var fileStream = File.OpenWrite(distFile);
 | 
			
		||||
                    Stream compressStream;
 | 
			
		||||
                    switch (Compress)
 | 
			
		||||
                    {
 | 
			
		||||
                        case "gz":
 | 
			
		||||
                        case "gzip":
 | 
			
		||||
                            compressStream = new System.IO.Compression.GZipStream(fileStream, System.IO.Compression.CompressionLevel.Fastest);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "deflate":
 | 
			
		||||
                            compressStream = new System.IO.Compression.DeflateStream(fileStream, System.IO.Compression.CompressionLevel.Fastest);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "br":
 | 
			
		||||
                            compressStream = new System.IO.Compression.BrotliStream(fileStream, System.IO.Compression.CompressionLevel.Fastest);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "none": // 不压缩
 | 
			
		||||
                        default:
 | 
			
		||||
                            compressStream = fileStream;
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                    using (compressStream)
 | 
			
		||||
                    {
 | 
			
		||||
                        using (StreamWriter streamWriter = new StreamWriter(compressStream))
 | 
			
		||||
                        {
 | 
			
		||||
                            streamWriter.Write($"INSERT INTO `{table}` (");
 | 
			
		||||
                            streamWriter.Write(columnString);
 | 
			
		||||
                            streamWriter.Write(") VALUES ");
 | 
			
		||||
                            streamWriter.Write(valString);
 | 
			
		||||
                            //streamWriter.Flush();
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (PageSize <= 0) break; // 不分页直接跳出
 | 
			
		||||
                    pageIndex++;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            watch.Stop();
 | 
			
		||||
            Print("导出完成,耗时" + watch.ElapsedMilliseconds + "ms");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void Step(Action<string> action, params string[] tables)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var item in tables)
 | 
			
		||||
            {
 | 
			
		||||
                action(item);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,116 +0,0 @@
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Text.RegularExpressions;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("import")]
 | 
			
		||||
    public class ImportSqlCommand : ICommand
 | 
			
		||||
    {
 | 
			
		||||
        [CommandParameter(0, Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
        [CommandOption("source", Description = "导入文件路径")]
 | 
			
		||||
        public string Source { get; set; } = "./output";
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
        public MySqlConnection? Db { get; private set; }
 | 
			
		||||
        [CommandOption("clear", Description = "导入前清除表数据")]
 | 
			
		||||
        public bool clear { get; set; } =true;
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
           
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
            Print("开始导入!");
 | 
			
		||||
            var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
            connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
            connBuilder.CharacterSet = "utf8";
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
 | 
			
		||||
                Db.Open();
 | 
			
		||||
                var dir = new System.IO.DirectoryInfo(Source);
 | 
			
		||||
                var files = dir.GetFiles();
 | 
			
		||||
                var result=Db.QueryFirst<(string,string)>("show VARIABLES like  '%FOREIGN_KEY_CHECKS'");
 | 
			
		||||
                if (this.clear&& result.Item2=="ON")
 | 
			
		||||
                {
 | 
			
		||||
                    Db.Execute("SET FOREIGN_KEY_CHECKS=0");
 | 
			
		||||
                }
 | 
			
		||||
                foreach (var file in files)
 | 
			
		||||
                {
 | 
			
		||||
                    Print($"导入文件:{file.Name}!");
 | 
			
		||||
                    var startTime = DateTime.Now;
 | 
			
		||||
                    ImportFile(file);
 | 
			
		||||
                    console.Output.WriteLine("执行耗时:" + (DateTime.Now - startTime).TotalMilliseconds + "ms");
 | 
			
		||||
                }
 | 
			
		||||
                if (this.clear && result.Item2 == "ON")
 | 
			
		||||
                {
 | 
			
		||||
                    Db.Execute("SET FOREIGN_KEY_CHECKS=1");
 | 
			
		||||
                }
 | 
			
		||||
                Print("操作成功");
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                console.Output.WriteLine(ex.ToString());
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                Db?.Close();
 | 
			
		||||
            }
 | 
			
		||||
          
 | 
			
		||||
            return default;
 | 
			
		||||
        }
 | 
			
		||||
        private  void ImportFile(FileInfo fileInfo)
 | 
			
		||||
        {
 | 
			
		||||
            var reg = new Regex("(.+?)\\-p(.+?)\\.(.+?)\\.sql");
 | 
			
		||||
            var matchs=reg.Matches(fileInfo.Name);
 | 
			
		||||
            if (matchs.Count == 0|| matchs[0].Groups.Count != 4)
 | 
			
		||||
            {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            var type = matchs[0].Groups[3].ToString();
 | 
			
		||||
            var table = matchs[0].Groups[1].ToString();
 | 
			
		||||
            if (this.clear)
 | 
			
		||||
            {
 | 
			
		||||
                Db.Execute($"TRUNCATE TABLE `{table}`");
 | 
			
		||||
            }
 | 
			
		||||
            var fileStream =  File.OpenRead(fileInfo.FullName);
 | 
			
		||||
            Stream deCompressStream;
 | 
			
		||||
            switch (type)
 | 
			
		||||
            {
 | 
			
		||||
                case "gz":
 | 
			
		||||
                case "gzip":
 | 
			
		||||
                    deCompressStream = new System.IO.Compression.GZipStream(fileStream,System.IO.Compression.CompressionMode.Decompress);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "deflate":
 | 
			
		||||
                    deCompressStream = new System.IO.Compression.DeflateStream(fileStream, System.IO.Compression.CompressionMode.Decompress);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "br":
 | 
			
		||||
                    deCompressStream = new System.IO.Compression.BrotliStream(fileStream, System.IO.Compression.CompressionMode.Decompress);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "none": // 不压缩
 | 
			
		||||
                default:
 | 
			
		||||
                    deCompressStream = fileStream;
 | 
			
		||||
                    break;
 | 
			
		||||
            }
 | 
			
		||||
            using (deCompressStream)
 | 
			
		||||
            {
 | 
			
		||||
                using (StreamReader streamReader = new StreamReader(deCompressStream))
 | 
			
		||||
                {
 | 
			
		||||
                    var sql=streamReader.ReadToEnd();
 | 
			
		||||
                    this.Db.Execute(sql);
 | 
			
		||||
                   
 | 
			
		||||
                    //streamWriter.Flush();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,99 +0,0 @@
 | 
			
		||||
using Chenfeng.MES.Archiver.Core;
 | 
			
		||||
using Chenfeng.MES.Archiver.Data;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using CliFx.Attributes;
 | 
			
		||||
using CliFx.Infrastructure;
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System.Data;
 | 
			
		||||
using System.Diagnostics;
 | 
			
		||||
using System.Text;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Commands
 | 
			
		||||
{
 | 
			
		||||
    [Command("optimize")]
 | 
			
		||||
    public class OptimizeTableCommand : ICommand, IArchiveReader
 | 
			
		||||
    {
 | 
			
		||||
        [CommandParameter(0, Description = "数据库连接")]
 | 
			
		||||
        public string Connection { get; set; } = "";
 | 
			
		||||
 | 
			
		||||
        public MySqlConnection? Db { get; private set; }
 | 
			
		||||
 | 
			
		||||
        public Action<string> Print { get; set; } = (text) => { };
 | 
			
		||||
 | 
			
		||||
        [CommandOption("legacy", Description = "旧版MES")]
 | 
			
		||||
        public bool Legacy { get; set; } = false;
 | 
			
		||||
 | 
			
		||||
        [CommandOption("timeout", Description = "sql命令超时时间")]
 | 
			
		||||
        public int Timeout { get; set; } = 0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public ValueTask ExecuteAsync(IConsole console)
 | 
			
		||||
        {
 | 
			
		||||
            var startTime = DateTime.Now;
 | 
			
		||||
            Print = (text) => console.Output.WriteLine($"{DateTime.Now.ToLongTimeString()} {text}");
 | 
			
		||||
 | 
			
		||||
            var connBuilder = new MySqlConnectionStringBuilder(this.Connection);
 | 
			
		||||
            connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
            connBuilder.CharacterSet = "utf8";
 | 
			
		||||
 | 
			
		||||
            var starMonth = DateTime.Now.AddMonths(-12).ToString("yyyyMM");
 | 
			
		||||
 | 
			
		||||
            SqlMapper.Settings.CommandTimeout = 60 * Timeout;
 | 
			
		||||
 | 
			
		||||
            console.Output.WriteLine($"优化表数据");
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                Db = new MySqlConnection(connBuilder.ConnectionString);
 | 
			
		||||
 | 
			
		||||
                Db.Open();
 | 
			
		||||
                if (Legacy)
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesLegacyTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    TableQueryHelper.MesTables(this, starMonth);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
                Print("操作成功");
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            catch (Exception ex)
 | 
			
		||||
            {
 | 
			
		||||
                console.Output.WriteLine(ex.ToString());
 | 
			
		||||
            }
 | 
			
		||||
            finally
 | 
			
		||||
            {
 | 
			
		||||
                Db?.Close();
 | 
			
		||||
            }
 | 
			
		||||
            console.Output.WriteLine("执行耗时:" + (DateTime.Now - startTime).TotalMilliseconds + "ms");
 | 
			
		||||
            return default;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteData(string table, string where, object param)
 | 
			
		||||
        {
 | 
			
		||||
            var sql = $"alter table `{table}` engine = innodb ";
 | 
			
		||||
            Print("开始优化:" + table);
 | 
			
		||||
            Db.Execute(sql);
 | 
			
		||||
            Print("结束优化:" + table);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ExecuteChildData(string table, string parentTable, string condition)
 | 
			
		||||
        {
 | 
			
		||||
            ExecuteData(table, "", null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        public void Step(Action<string> action, params string[] tables)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var item in tables)
 | 
			
		||||
            {
 | 
			
		||||
                action(item);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Core
 | 
			
		||||
{
 | 
			
		||||
    public interface IArchiveReader
 | 
			
		||||
    {
 | 
			
		||||
        void ExecuteData(string table, string where, object param);
 | 
			
		||||
 | 
			
		||||
        void ExecuteChildData(string table,string parentTable, string condition);
 | 
			
		||||
 | 
			
		||||
        void Step(Action<string> action, params string[] tables);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,77 +0,0 @@
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace Chenfeng.MES.Archiver.Data
 | 
			
		||||
{
 | 
			
		||||
    public class TableQueryHelper
 | 
			
		||||
    {
 | 
			
		||||
        public static void MesTables(Core.IArchiveReader executor, string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            executor.Step((table) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(table, "LEFT(orderno,6) >= @starMonth", new { starMonth });
 | 
			
		||||
            }, "order", "order_box_block", "order_data_block", "order_data_goods", "order_data_parts", "order_item", "order_module_extra", "order_module_item", "order_package");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            executor.Step((tProcess) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(tProcess, "LEFT(orderno,6) >= @starMonth", new { starMonth });
 | 
			
		||||
                executor.Step((table) =>
 | 
			
		||||
                {
 | 
			
		||||
                    executor.ExecuteChildData(table, tProcess, "parent.ID = child.OrderProcessID");
 | 
			
		||||
                }, "order_process_step_item", "order_process_step");
 | 
			
		||||
            }, "order_process");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            executor.Step((table) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(table, "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) >= @starMonth", new { starMonth });
 | 
			
		||||
            }, "simple_plan_order");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            executor.Step((parent) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(parent, "LEFT(DATE_FORMAT(CreateTime,'%Y%m'),6) >= @starMonth", new { starMonth });
 | 
			
		||||
                executor.Step((child) =>
 | 
			
		||||
                {
 | 
			
		||||
                    executor.ExecuteChildData(child, parent, "parent.ID = child.ID");
 | 
			
		||||
                }, "order_block_plan_result");
 | 
			
		||||
            }, "order_block_plan");
 | 
			
		||||
 | 
			
		||||
            //CopyStep((table, newTable) =>
 | 
			
		||||
            //{
 | 
			
		||||
            //    CopyData(table, newTable, "concat('20',left(id,4)) >= @starMonth ", new { starMonth });
 | 
			
		||||
            //}, "order_scrap_board");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public static void MesLegacyTables(Core.IArchiveReader executor, string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            executor.Step((order) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(order, "LEFT(DATE_FORMAT(SaleDate,'%Y%m'),6) >= @starMonth", new { starMonth });
 | 
			
		||||
 | 
			
		||||
                executor.Step((child) =>
 | 
			
		||||
                {
 | 
			
		||||
                    executor.ExecuteChildData(child, order, "parent.orderno=child.orderno");
 | 
			
		||||
                }, "SaleOrderItem", "saleblock", "saleobject", "saleorderobject", "saleorderoffer", "saleorderpackage", "saleblockobjids", "saleobjectobjids", "saleorder_block_cadmodelinfo", "saleorderblockbaseposition",
 | 
			
		||||
            "saleordergoodsinfo", "saleorder_block_point", "saleorder_block_pointinfo", "orderprocess", "orderprocessstep", "orderprocessstepitem");
 | 
			
		||||
 | 
			
		||||
            }, "saleorder");
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            executor.Step((plan) =>
 | 
			
		||||
            {
 | 
			
		||||
                executor.ExecuteData(plan, "LEFT(DATE_FORMAT(createtime,'%Y%m'),6) >= @starMonth", new { starMonth });
 | 
			
		||||
 | 
			
		||||
                executor.Step((child) =>
 | 
			
		||||
                {
 | 
			
		||||
                    executor.ExecuteChildData(child, plan, "parent.id=child.id");
 | 
			
		||||
                }, "orderblockprocessplanplaceresult");
 | 
			
		||||
            }, "orderblockprocessplan");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +1,27 @@
 | 
			
		||||
// See https://aka.ms/new-console-template for more information
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
using ArchiverLite.Commands;
 | 
			
		||||
using CliFx;
 | 
			
		||||
using Microsoft.Extensions.DependencyInjection;
 | 
			
		||||
 | 
			
		||||
//Console.WriteLine("Hello, World!");
 | 
			
		||||
 | 
			
		||||
await new CliApplicationBuilder()
 | 
			
		||||
            .AddCommandsFromThisAssembly()
 | 
			
		||||
            .Build()
 | 
			
		||||
            .RunAsync(args);
 | 
			
		||||
    .SetVersion("0.1.0")
 | 
			
		||||
    .SetExecutableName("ArchiverLite")
 | 
			
		||||
    .AddCommandsFromThisAssembly()
 | 
			
		||||
    //.UseTypeActivator(commandTypes =>
 | 
			
		||||
    //{
 | 
			
		||||
    //    var services = new ServiceCollection();
 | 
			
		||||
 | 
			
		||||
    //    // Register services
 | 
			
		||||
 | 
			
		||||
    //    // Register commands
 | 
			
		||||
    //    foreach (var commandType in commandTypes)
 | 
			
		||||
    //        services.AddTransient(commandType);
 | 
			
		||||
 | 
			
		||||
    //    return services.BuildServiceProvider();
 | 
			
		||||
    //})
 | 
			
		||||
    .Build()
 | 
			
		||||
    .RunAsync(args);
 | 
			
		||||
							
								
								
									
										70
									
								
								src/Archiver/Services/MesLegacyService.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								src/Archiver/Services/MesLegacyService.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,70 @@
 | 
			
		||||
using Dapper;
 | 
			
		||||
using MySqlConnector;
 | 
			
		||||
using System;
 | 
			
		||||
using System.Collections.Generic;
 | 
			
		||||
using System.Linq;
 | 
			
		||||
using System.Text;
 | 
			
		||||
using System.Threading.Tasks;
 | 
			
		||||
 | 
			
		||||
namespace ArchiverLite.Services
 | 
			
		||||
{
 | 
			
		||||
    public class MesLegacyService
 | 
			
		||||
    {
 | 
			
		||||
        private readonly MySqlConnection _db;
 | 
			
		||||
 | 
			
		||||
        public MesLegacyService(string connectionString)
 | 
			
		||||
        {
 | 
			
		||||
            var connBuilder = new MySqlConnectionStringBuilder(connectionString);
 | 
			
		||||
            connBuilder.SslMode = MySqlSslMode.None;
 | 
			
		||||
            connBuilder.CharacterSet = "utf8";
 | 
			
		||||
            //connBuilder.ConnectionTimeout = 5 * 60;
 | 
			
		||||
            _db = new MySqlConnection(connectionString);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ClearOrder(string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var orderno in GetIdList<string>("saleorder", "orderno", "LEFT(DATE_FORMAT(SaleDate,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    foreach (var childTable in new[] { "SaleOrderItem", "saleblock", "saleobject", "saleorderobject", "saleorderoffer", "saleorderpackage", "saleblockobjids", "saleobjectobjids", "saleorder_block_cadmodelinfo", "saleorderblockbaseposition",
 | 
			
		||||
                                 "saleordergoodsinfo", "saleorder_block_point", "saleorder_block_pointinfo", "orderprocess", "orderprocessstep", "orderprocessstepitem"})
 | 
			
		||||
                    {
 | 
			
		||||
                        DeleteRow(childTable, "orderno", new { orderno }, trans);
 | 
			
		||||
                    }
 | 
			
		||||
                    DeleteRow("saleorder", "orderno", new { orderno }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        public void ClearOrderBlockPlan(string starMonth)
 | 
			
		||||
        {
 | 
			
		||||
            foreach (var id in GetIdList<string>("orderblockprocessplan", "id", "LEFT(DATE_FORMAT(createtime,'%Y%m'),6) < @starMonth", new { starMonth }))
 | 
			
		||||
            {
 | 
			
		||||
                using (var trans = GetTransaction())
 | 
			
		||||
                {
 | 
			
		||||
                    DeleteRow("orderblockprocessplan", "ID", new { ID = id }, trans);
 | 
			
		||||
                    DeleteRow("orderblockprocessplanplaceresult", "ID", new { ID = id }, trans);
 | 
			
		||||
                    trans.Commit();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private void DeleteRow(string table, string key, object param, MySqlTransaction? transaction)
 | 
			
		||||
        {
 | 
			
		||||
            _db.Execute($"DELETE FROM `{table}` where {key}=@{key}", param, transaction);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private IEnumerable<T> GetIdList<T>(string table, string field, string condition, object param)
 | 
			
		||||
        {
 | 
			
		||||
            return _db.Query<T>($"select {field} from `{table}` where {condition}", param);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private MySqlTransaction GetTransaction()
 | 
			
		||||
        {
 | 
			
		||||
            if (_db.State != System.Data.ConnectionState.Open) _db.Open();
 | 
			
		||||
            return _db.BeginTransaction();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user