2025迁移版本,多项规则修改

This commit is contained in:
2024-12-10 14:03:09 +08:00
parent dc239c776e
commit 0e28d639c1
34 changed files with 1075 additions and 564 deletions

View File

@@ -0,0 +1,42 @@
// ReSharper disable InconsistentNaming
namespace MesETL.App.Services.Seq;
public class SeqConfig(string Name, bool Recycle = true, int Step = 1, long Max = 999_999_999)
{
public string Name { get; init; } = Name;
public bool Recycle { get; init; } = Recycle;
public int Step { get; init; } = Step;
public long Max { get; init; } = Max;
public static readonly SeqConfig ItemNo = new("seq_ItemNo", true, 1, 999_999_999);
public static readonly SeqConfig OrderModuleID = new("seq_order_module_id", false);
public static readonly SeqConfig OrderDataID = new("seq_order_data_id", false);
public static readonly SeqConfig OrderItemID = new("seq_order_item", false);
public static readonly SeqConfig ProcessStepID = new("seq_step_id", false);
public static readonly SeqConfig PackageNo = new("seq_pack_no", true, 1, 9_999_999);
public static readonly SeqConfig PlanNo = new("seq_plan_order", true, 1, 999_999);
public static readonly SeqConfig SimplePlanNo = new("seq_simple_plan_order", true, 1, 999_999);
// 下面这些类型的流水号在BaseService添加实体时进行生成
public static readonly SeqConfig MachineID = new("seq_machine_id", false);
public static readonly SeqConfig OrderBlockPlanID = new("seq_order_block_plan_id", false);
public static readonly SeqConfig OrderDataGoodsID = new("seq_order_data_goods_id", false);
public static readonly SeqConfig OrderPackageID = new("seq_order_pack_id", false);
public static readonly SeqConfig OrderProcessID = new("seq_order_process_id", false);
public static readonly SeqConfig OrderProcessStepItemID = new("seq_order_process_step_item_id", false);
public static readonly SeqConfig ProcessGroupID = new("seq_process_group_id", false);
public static readonly SeqConfig ProcessInfoID = new("seq_process_info_id", false);
public static readonly SeqConfig ProcessItemExpID = new("seq_process_item_exp_id", false);
public static readonly SeqConfig ProcessScheduleCapacityID = new("seq_process_schedule_capacity_id", false);
public static readonly SeqConfig ProcessStepEfficiencyID = new("seq_process_step_efficiency_id", false);
public static readonly SeqConfig ReportTemplateID = new("seq_report_template_id", false);
public static readonly SeqConfig SysConfigKey = new("seq_sys_config_key", false);
public static readonly SeqConfig WorkCalendarID = new("seq_work_calendar_id", false);
public static readonly SeqConfig WorkShiftID = new("seq_work_shift_id", false);
public static readonly SeqConfig WorkTimeID = new("seq_work_time_id", false);
public static readonly SeqConfig OrderPatchDetailID = new("seq_order_patch_detail_id", false);
public static readonly SeqConfig OrderModuleExtraID = new("seq_order_module_extra_id", false);
public static readonly SeqConfig SimplePackageID = new("seq_simple_pack_id", false);
public static readonly SeqConfig OrderModuleItemID = new("seq_order_module_item_id", false);
public static readonly SeqConfig OrderWaveGroupID = new("seq_order_wave_group_id", false);
}

View File

@@ -0,0 +1,134 @@
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Text;
using MesETL.App.Options;
using MesETL.Shared.Helper;
using Microsoft.Extensions.Options;
using MySqlConnector;
namespace MesETL.App.Services.Seq;
public class SeqService
{
private readonly string _connectionString;
private readonly Dictionary<SeqConfig, long> _cachedSequence;
public IReadOnlyDictionary<SeqConfig, long> CachedSequence => _cachedSequence;
public SeqService(IOptions<DatabaseOutputOptions> options)
{
var connStr = options.Value.ConnectionString ?? throw new ApplicationException("未配置输出数据库连接字符串");
var builder = new MySqlConnectionStringBuilder(connStr)
{
Database = "mes_global"
};
_connectionString = builder.ConnectionString;
_cachedSequence = new Dictionary<SeqConfig, long>();
}
private async Task<long> UpdateSequenceID(string name,int step,long max,bool recycle, int add)
{
var sql = new StringBuilder(
$"""
INSERT INTO seq (SeqName,CurrentVal,Increment,MinVal,MaxVal,UpdateTime)
VALUES ({name},{add},{step},1,{max},NOW())
ON DUPLICATE KEY UPDATE UpdateTime = NOW(),
""");
if (recycle)
{
sql.Append($"CurrentVal = (@updatedVal := IF(CurrentVal + {add} >= MaxVal, {add}, CurrentVal + {add}));");
}
else
{
sql.Append($"CurrentVal = (@updatedVal := CurrentVal + {add});");
}
sql.Append("SELECT @updatedVal;");
var result = await DatabaseHelper.QueryScalarAsync(_connectionString, sql.ToString());
return Convert.ToInt64(result);
}
public async Task<long> PeekKey(SeqConfig config)
{
var sql = $"SELECT CurrentVal FROM seq WHERE SeqName = '{config.Name}' LIMIT 1;";
return Convert.ToInt64(await DatabaseHelper.QueryScalarAsync(_connectionString, sql));
}
public async Task<long[]> GetKeys(SeqConfig config, int count)
{
if (count < 1) return [];
var list = new long[count];
var add = config.Step * count;
var lastId = await UpdateSequenceID(config.Name, config.Step, config.Max, config.Recycle, add);
var step = Convert.ToInt64(config.Step);
for (var i = count - 1; i > -1; i--)
{
list[i] = lastId;
lastId -= step;
}
return list;
}
/// <summary>
/// 添加并取得一个缓存的流水号
/// </summary>
/// <param name="config"></param>
/// <returns></returns>
public long AddCachedSeq(SeqConfig config)
{
if (!_cachedSequence.TryGetValue(config, out var val))
{
var seq = PeekKey(config).GetAwaiter().GetResult();
val = seq;
_cachedSequence[config] = val;
}
var step = config.Step;
if (config.Recycle)
{
val = val + step >= config.Max ? val : val + step;
}
else val += step;
_cachedSequence[config] = val;
return val;
}
/// <summary>
/// 移除一个缓存的流水号
/// </summary>
/// <param name="config"></param>
public void RemoveCachedSeq(SeqConfig config)
{
_cachedSequence.Remove(config);
}
/// <summary>
/// 清空所有缓存的流水号
/// </summary>
public void ClearCache()
{
_cachedSequence.Clear();
}
/// <summary>
/// 将缓存的流水号应用至数据库
/// </summary>
public async Task ApplyToDatabaseAsync()
{
var sql = GenerateCachedSeqSql();
await DatabaseHelper.NonQueryAsync(_connectionString, sql);
}
private string GenerateCachedSeqSql()
{
var sb = new StringBuilder();
foreach (var kv in _cachedSequence)
{
sb.AppendLine($"UPDATE seq SET CurrentVal = {kv.Value} WHERE SeqName = '{kv.Key.Name}';");
}
return sb.ToString();
}
}