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.
454 lines
14 KiB
454 lines
14 KiB
using System.Collections.ObjectModel; |
|
using System.Data; |
|
using System.IO; |
|
using System.Text; |
|
using System.Windows.Input; |
|
using HandyControl.Controls; |
|
using log4net; |
|
using Microsoft.Data.Sqlite; |
|
using Newtonsoft.Json; |
|
using Newtonsoft.Json.Linq; |
|
using SparkClient.Model.Entity; |
|
using SparkClient.Model.Helper; |
|
using SparkClient.ViewModel.Configuration.SettingsPages; |
|
using MessageBox = SparkClient.Views.Dialog.MessageBox; |
|
using SparkClient.Model.Attributes; |
|
using SparkClient.Model.Extension; |
|
|
|
namespace SparkClient.ViewModel.Configuration; |
|
|
|
public class AlgorithmConfigVM : BaseViewModel |
|
{ |
|
private static readonly ILog Logger = LogManager.GetLogger(typeof(AlgorithmConfigVM)); |
|
public ICommand SaveAlgorithmDataCommand { get; } |
|
public ICommand BeautifyJsonCommand { get; } |
|
public ICommand UglifyJsonCommand { get; } |
|
|
|
private ObservableCollection<AgileJsonConfigEntity> _agileJsonConfigEntities; |
|
public ObservableCollection<AgileJsonConfigEntity> AgileJsonConfigEntities |
|
{ |
|
get => _agileJsonConfigEntities; |
|
set |
|
{ |
|
_agileJsonConfigEntities = value; |
|
OnPropertyChanged(nameof(AgileJsonConfigEntities)); |
|
} |
|
} |
|
|
|
private ObservableCollection<Param> _modeList; |
|
public ObservableCollection<Param> ModeList |
|
{ |
|
get => _modeList; |
|
set |
|
{ |
|
_modeList = value; |
|
OnPropertyChanged(nameof(ModeList)); |
|
} |
|
} |
|
|
|
private ObservableCollection<Param> _specList; |
|
public ObservableCollection<Param> SpecList |
|
{ |
|
get => _specList; |
|
set { |
|
_specList = value; |
|
OnPropertyChanged(nameof(ModeList)); |
|
} |
|
} |
|
|
|
private List<string> _jsonKeysBak; |
|
public List<string> JsonKeysBak |
|
{ |
|
get => _jsonKeysBak; |
|
} |
|
private bool _isEnabled; |
|
public bool IsEnabled { get { return _isEnabled; } set { _isEnabled = value; OnPropertyChanged(nameof(IsEnabled)); } } |
|
|
|
private string _AlgorithmConfigJson; |
|
public string AlgorithmConfigJson { get { return _AlgorithmConfigJson; } set { _AlgorithmConfigJson = value; OnPropertyChanged("AlgorithmConfigJson"); } } |
|
public AlgorithmConfigVM() |
|
{ |
|
SaveAlgorithmDataCommand = new RelayCommand(SaveAlgorithmData); |
|
BeautifyJsonCommand = new RelayCommand(BeautifyJson); |
|
UglifyJsonCommand = new RelayCommand(UglifyJson); |
|
ModeList = GetRunModelList(); |
|
SpecList = GetRunSpecList(); |
|
InitAlgorithmData(null); |
|
IsEnabledByRole(); |
|
_jsonKeysBak = GetNestedKeys(JObject.Parse(AlgorithmConfigJson)); |
|
InitAgileJsonConfig(); |
|
|
|
} |
|
[Log] |
|
private void InitAgileJsonConfig() |
|
{ |
|
AgileJsonConfigEntities = new ObservableCollection<AgileJsonConfigEntity>(); |
|
string sql = @"SELECT Mode, Shape, Spec, JsonKey, Value FROM AGILE_ALGORITHM_CONFIG"; |
|
DataTable dataTable = DataBaseHelper.ExecuteQuery(sql); |
|
var baseData = new AgileJsonConfigEntity(this); |
|
if (dataTable != null && dataTable.Rows.Count >= 0) |
|
{ |
|
foreach (DataRow row in dataTable.Rows) |
|
{ |
|
try |
|
{ |
|
AgileJsonConfigEntities.Add(new AgileJsonConfigEntity(this) |
|
{ |
|
ModeValue = row["Mode"].ToSafeString(), |
|
SpecValue = row["Spec"].ToSafeString(), |
|
Shape = row["Shape"].ToSafeString(), |
|
JsonKey = row["JsonKey"].ToSafeString(), |
|
Value = row["Value"].ToSafeString() |
|
}); |
|
} |
|
catch (Exception ex) |
|
{ |
|
Logger.Error(ex.Message); |
|
} |
|
} |
|
} |
|
|
|
} |
|
[Log] |
|
private bool CheckAndSaveAgileJson() |
|
{ |
|
var finalSaveData = new ObservableCollection<AgileJsonConfigEntity>(); |
|
var insertSql = new List<string>(); |
|
foreach (var row in AgileJsonConfigEntities) |
|
{ |
|
if (string.IsNullOrWhiteSpace(row.JsonKey) || string.IsNullOrWhiteSpace(row.Value) || |
|
string.IsNullOrWhiteSpace(row.Shape)) |
|
continue; |
|
if (row.ModeValue.IsNullOrEmpty()|| row.SpecValue.IsNullOrEmpty()) |
|
continue; |
|
insertSql.Add($"INSERT INTO AGILE_ALGORITHM_CONFIG (GUID, Mode, Spec, Shape, JsonKey, Value)" + |
|
$@"VALUES ('{row.GenerateSign()}',{row.ModeValue},'{row.SpecValue}','{row.Shape}','{row.JsonKey}','{row.Value}');"); |
|
finalSaveData.Add(row); |
|
} |
|
|
|
AgileJsonConfigEntities = finalSaveData; |
|
|
|
var deleteSql = $"DELETE FROM AGILE_ALGORITHM_CONFIG;"; |
|
|
|
try |
|
{ |
|
DataBaseHelper.BeginTransaction(); |
|
DataBaseHelper.ExecuteNonQuery(deleteSql); |
|
insertSql.ForEach(e => DataBaseHelper.ExecuteNonQuery(e)); |
|
DataBaseHelper.commit(); |
|
} |
|
catch (Exception e) |
|
{ |
|
Logger.Error($"灵活配置存储异常:{e.Message}\r\n {e.StackTrace}"); |
|
new MessageBox().Show($"灵活配置存储异常:{e.Message}"); |
|
DataBaseHelper.rollback(); |
|
return false; |
|
} |
|
|
|
return true; |
|
} |
|
|
|
[Log] |
|
public string GetAlgorithmConfig(string param) |
|
{ |
|
string sql = @"SELECT Mode, Shape, Spec, JsonKey, Value FROM AGILE_ALGORITHM_CONFIG"; |
|
DataTable dataTable = DataBaseHelper.ExecuteQuery(sql); |
|
if (dataTable != null && dataTable.Rows.Count >= 0) |
|
{ |
|
JToken jsonAlgorithm = JToken.Parse(_AlgorithmConfigJson); |
|
foreach (DataRow row in dataTable.Rows) |
|
{ |
|
//只对当前运行环境有效 |
|
if (Common.RunMode == int.Parse(row["Mode"].ToSafeString())) |
|
{ |
|
string spec = row["Spec"].ToSafeString(); |
|
string[] parameters = param.Split(" "); |
|
//匹配形状忽略,只有原型 |
|
//匹配规格 |
|
if (parameters.Last().Equals(spec.Split("-").Last())) |
|
{ |
|
string jsonKey = row["JsonKey"].ToSafeString(); |
|
string value = row["Value"].ToSafeString(); |
|
if (jsonKey.Contains(".")) |
|
{ |
|
var keys = jsonKey.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); |
|
JToken currentNode = jsonAlgorithm; |
|
for (int i = 0; i < keys.Length - 1; i++) |
|
{ |
|
var currentKey = keys[i]; |
|
// 如果当前节点不存在或不是对象类型,则创建新对象 |
|
if (currentNode[currentKey] == null || currentNode[currentKey]?.Type != JTokenType.Object) |
|
{ |
|
currentNode[currentKey] = new JObject(); |
|
} |
|
currentNode = currentNode[currentKey]; |
|
} |
|
var finalKey = keys[keys.Length - 1]; |
|
currentNode[finalKey] = value.ConvertJTokenValue(); |
|
} |
|
else |
|
{ |
|
jsonAlgorithm[jsonKey] = value.ConvertJTokenValue(); |
|
} |
|
} |
|
} |
|
} |
|
return jsonAlgorithm.ToString(); |
|
} |
|
|
|
return _AlgorithmConfigJson; |
|
} |
|
|
|
/// <summary> |
|
/// 初始化算法数据 |
|
/// </summary> |
|
/// <param name="param"></param> |
|
[Log] |
|
public void InitAlgorithmData(object param) |
|
{ |
|
try |
|
{ |
|
AlgorithmConfigJson = "{}"; |
|
string sql = @"SELECT JSON as json FROM ALGORITHM_CONFIG ORDER BY JSON_ORDER"; |
|
DataTable dataTable = DataBaseHelper.ExecuteQuery(sql); |
|
StringBuilder sb = new StringBuilder(); |
|
if (dataTable != null) |
|
{ |
|
foreach (DataRow row in dataTable.Rows) |
|
{ |
|
sb.Append(row["json"].ToString()); |
|
} |
|
} |
|
if (sb.Length > 0) |
|
{ |
|
AlgorithmConfigJson = JToken.Parse(sb.ToString()).ToString(); |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
new MessageBox().Show($"{MultilingualHelper.getString("ApplicationError")}{ex.Message}"); |
|
Logger.Error($"全局异常捕获:{ex.Message}", ex); |
|
} |
|
} |
|
|
|
// 命令实现 |
|
public ICommand AddCommand => new RelayCommand((param) => |
|
{ |
|
string data = GetAlgorithmConfig("P8 P8"); |
|
AgileJsonConfigEntities.Add(new AgileJsonConfigEntity(this)); |
|
}); |
|
|
|
[Log] |
|
private List<string> GetNestedKeys(JToken token, string prefix = "") |
|
{ |
|
var keys = new List<string>(); |
|
if (token is JObject obj) |
|
{ |
|
foreach (var property in obj.Properties()) |
|
{ |
|
var currentKey = string.IsNullOrEmpty(prefix) |
|
? property.Name |
|
: $"{prefix}.{property.Name}"; |
|
keys.Add(currentKey); |
|
keys.AddRange(GetNestedKeys(property.Value, currentKey)); |
|
} |
|
} |
|
return keys; |
|
} |
|
/// <summary> |
|
/// 保存数据 |
|
/// </summary> |
|
/// <param name="param"></param> |
|
[Log] |
|
public void SaveAlgorithmData(object param) |
|
{ |
|
try |
|
{ |
|
_jsonKeysBak = GetNestedKeys(JObject.Parse(AlgorithmConfigJson)); |
|
if (!CheckAndSaveAgileJson()) |
|
{ |
|
return; |
|
} |
|
|
|
DataBaseHelper.BeginTransaction(); |
|
string temp = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(AlgorithmConfigJson)); |
|
string deleteSql = @"DELETE FROM ALGORITHM_CONFIG"; |
|
DataBaseHelper.ExecuteNonQuery(deleteSql); |
|
int order = 0; |
|
int insertCount = 0; |
|
while (temp.Length > 2000) |
|
{ |
|
AlgorithmConfigEntity entity = new AlgorithmConfigEntity() |
|
{ |
|
GUID = Guid.NewGuid(), |
|
JsonOrder = order++, |
|
Json = temp.Substring(0, 2000), |
|
}; |
|
temp = temp.Substring(2000); |
|
string sql = entity.GenerateInsertSQL(); |
|
SqliteParameter[] sqliteParameters = { |
|
new SqliteParameter("@Json", entity.Json), |
|
new SqliteParameter("@JsonOrder", entity.JsonOrder), |
|
new SqliteParameter("@GUID", entity.GUID), |
|
}; |
|
insertCount += DataBaseHelper.ExecuteNonQuery(sql, sqliteParameters); |
|
} |
|
if (temp.Length > 0) |
|
{ |
|
AlgorithmConfigEntity entity = new AlgorithmConfigEntity() |
|
{ |
|
GUID = Guid.NewGuid(), |
|
JsonOrder = order++, |
|
Json = temp |
|
}; |
|
string sql = entity.GenerateInsertSQL(); |
|
SqliteParameter[] sqliteParameters = { |
|
new SqliteParameter("@Json", entity.Json), |
|
new SqliteParameter("@JsonOrder", entity.JsonOrder), |
|
new SqliteParameter("@GUID", entity.GUID.ToString()), |
|
}; |
|
insertCount += DataBaseHelper.ExecuteNonQuery(sql, sqliteParameters); |
|
} |
|
if (insertCount >= 0) |
|
{ |
|
Growl.Info(MultilingualHelper.getString("SaveSuccess")); |
|
DataBaseHelper.commit(); |
|
} |
|
else |
|
{ |
|
Growl.Error(MultilingualHelper.getString("SaveFail")); |
|
DataBaseHelper.rollback(); |
|
} |
|
} |
|
catch (Exception ex) |
|
{ |
|
Growl.Error(MultilingualHelper.getString("SaveFail")); |
|
Logger.Error($"全局异常捕获:{ex.Message}",ex); |
|
} |
|
} |
|
[Log] |
|
private void IsEnabledByRole (){ |
|
string PERMISSIONS = Settings.SelectValueById("PERMISSIONS"); |
|
if ("admin".Equals(PERMISSIONS)) |
|
{ |
|
IsEnabled = true; |
|
} |
|
else |
|
{ |
|
IsEnabled = false; |
|
} |
|
} |
|
/// <summary> |
|
/// 美化JSON |
|
/// </summary> |
|
/// <param name="param"></param> |
|
[Log] |
|
public void BeautifyJson(object param) |
|
{ |
|
try |
|
{ |
|
AlgorithmConfigJson = JToken.Parse(AlgorithmConfigJson).ToString(); |
|
} |
|
catch (Exception ex) |
|
{ |
|
Growl.ErrorGlobal(ex.Message); |
|
} |
|
} |
|
|
|
/// <summary> |
|
/// 压缩JSON |
|
/// </summary> |
|
/// <param name="param"></param> |
|
[Log] |
|
public void UglifyJson(object param) |
|
{ |
|
AlgorithmConfigJson = JsonConvert.SerializeObject(JsonConvert.DeserializeObject(AlgorithmConfigJson)); |
|
} |
|
|
|
|
|
// 公共方法来获取 AlgorithmConfigJson |
|
[Log] |
|
public string GetAlgorithmConfigJson() |
|
{ |
|
return AlgorithmConfigJson; |
|
} |
|
|
|
public ObservableCollection<Param> GetRunModelList() |
|
{ |
|
return new ObservableCollection<Param> |
|
{ |
|
new Param() |
|
{ |
|
Value = "0", |
|
Name = "实验室模式" |
|
}, |
|
new Param() |
|
{ |
|
Value = "1", |
|
Name = "工厂模式" |
|
} |
|
}; |
|
} |
|
|
|
public ObservableCollection<Param> GetRunSpecList() |
|
{ |
|
return new ObservableCollection<Param> |
|
{ |
|
new Param() |
|
{ |
|
Value = "P8-P8", |
|
Name = "P8-P8" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S1", |
|
Name = "P8-P8-S1" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S2", |
|
Name = "P8-P8-S2" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S3", |
|
Name = "P8-P8-S3" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S4", |
|
Name = "P8-P8-S4" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S5", |
|
Name = "P8-P8-S5" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S6", |
|
Name = "P8-P8-S6" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S7", |
|
Name = "P8-P8-S7" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S8", |
|
Name = "P8-P8-S8" |
|
}, |
|
new Param() |
|
{ |
|
Value = "P8-P8-S9", |
|
Name = "P8-P8-S9" |
|
} |
|
}; |
|
} |
|
} |
|
public class Param |
|
{ |
|
public string Value { get; set; } |
|
public string Name { get; set; } |
|
}
|
|
|