添加项目文件。

This commit is contained in:
2023-03-13 15:00:34 +08:00
parent 42bf06ca3e
commit 1d73df3235
1205 changed files with 185078 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
using JNPF.DependencyInjection;
using SqlSugar;
namespace JNPF.Common.Security;
/// <summary>
/// 代码生成数据权限帮助类.
/// </summary>
[SuppressSniffer]
public static class CodeGenAuthorizeHelper
{
/// <summary>
/// 逆转数据转换别名.
/// </summary>
public static string ReverseDataConversion(List<IConditionalModel> conditionalModels, string tableName, string tableNumber)
{
var pvalue = conditionalModels.ToJsonString();
return pvalue.Replace(tableName, tableNumber);
}
}

View File

@@ -0,0 +1,305 @@
using System.Text.RegularExpressions;
using JNPF.Common.Configuration;
using JNPF.Common.Extension;
using JNPF.Common.Models.NPOI;
using JNPF.DataEncryption;
using JNPF.DependencyInjection;
namespace JNPF.Common.Security;
/// <summary>
/// 代码生成导出数据帮助类.
/// </summary>
[SuppressSniffer]
public static class CodeGenExportDataHelper
{
/// <summary>
/// 组装导出带子表的数据,返回 第一个合并行标头,第二个导出数据.
/// </summary>
/// <param name="selectKey">导出选择列.</param>
/// <param name="realList">原数据集合.</param>
/// <param name="paramsModels">模板信息.</param>
/// <returns>第一行标头 , 导出数据.</returns>
public static object[] GetCreateFirstColumnsHeader(List<string> selectKey, List<Dictionary<string, object>> realList, List<ParamsModel> paramsModels)
{
//selectKey.ForEach(item =>
//{
// if (realList.Any(it => it.Keys.Contains(item)))
// {
// realList.FirstOrDefault()[item] = string.Empty;
// }
//});
selectKey.ForEach(item =>
{
realList.ForEach(it =>
{
if (!it.ContainsKey(item)) it.Add(item, string.Empty);
});
});
var newRealList = realList.Copy();
realList.ForEach(items =>
{
var rowChildDatas = new Dictionary<string, List<Dictionary<string, object>>>();
foreach (var item in items)
{
if (item.Value != null && item.Key.ToLower().Contains("tablefield") && (item.Value is List<Dictionary<string, object>> || item.Value.GetType().Name.Equals("JArray")))
{
var ctList = item.Value.ToObject<List<Dictionary<string, object>>>();
rowChildDatas.Add(item.Key, ctList);
}
}
var len = rowChildDatas.Select(x => x.Value.Count()).OrderByDescending(x => x).FirstOrDefault();
if (len != null && len > 0)
{
for (int i = 0; i < len; i++)
{
if (i == 0)
{
var newRealItem = newRealList.Find(x => x["id"].Equals(items["id"]));
foreach (var cData in rowChildDatas)
{
var itemData = cData.Value.FirstOrDefault();
if (itemData != null)
{
foreach (var key in itemData)
if (newRealItem.ContainsKey(cData.Key + "-" + key.Key)) newRealItem[cData.Key + "-" + key.Key] = key.Value;
}
}
}
else
{
var newRealItem = new Dictionary<string, object>();
foreach (var it in items)
{
if (it.Key.Equals("id")) newRealItem.Add(it.Key, it.Value);
else newRealItem.Add(it.Key, string.Empty);
}
foreach (var cData in rowChildDatas)
{
if (cData.Value.Count > i)
{
foreach (var it in cData.Value[i])
if (newRealItem.ContainsKey(cData.Key + "-" + it.Key)) newRealItem[cData.Key + "-" + it.Key] = it.Value;
}
}
newRealList.Add(newRealItem);
}
}
}
});
var resultList = new List<Dictionary<string, object>>();
newRealList.ForEach(newRealItem =>
{
if (!resultList.Any(x => x["id"].Equals(newRealItem["id"]))) resultList.AddRange(newRealList.Where(x => x["id"].Equals(newRealItem["id"])).ToList());
});
var firstColumns = new Dictionary<string, int>();
if (selectKey.Any(x => x.Contains("-") && x.Contains("tableField")))
{
var empty = string.Empty;
var keyList = selectKey.Select(x => x.Split("-").First()).Distinct().ToList();
var mainFieldIndex = 1;
keyList.ForEach(item =>
{
if (item.Contains("tableField"))
{
var title = paramsModels.FirstOrDefault(x => x.field.Contains(item))?.value.Split("-")[0];
firstColumns.Add(title + empty, selectKey.Count(x => x.Contains(item)));
empty += " ";
mainFieldIndex = 1;
}
else
{
if (mainFieldIndex == 1) empty += " ";
if (!firstColumns.ContainsKey(empty)) firstColumns.Add(empty, mainFieldIndex);
else firstColumns[empty] = mainFieldIndex;
mainFieldIndex++;
}
});
}
return new object[] { firstColumns, resultList };
}
/// <summary>
/// 数据导出通用.
/// </summary>
/// <param name="fileName">导出文件名.</param>
/// <param name="selectKey">selectKey.</param>
/// <param name="userId">用户ID.</param>
/// <param name="realList">数据集合.</param>
/// <param name="paramList">参数.</param>
/// <param name="isGroupTable">是否分组表格.</param>
/// <param name="isInlineEditor">是否行内编辑.</param>
/// <returns></returns>
public static dynamic GetDataExport(string fileName, string selectKey, string userId, List<Dictionary<string, object>> realList, List<ParamsModel> paramList, bool isGroupTable = false, bool isInlineEditor = false)
{
switch (isInlineEditor)
{
case true:
paramList.ForEach(item =>
{
item.field = string.Format("{0}_name", item.field);
});
break;
}
// 如果是 分组表格 类型
if (isGroupTable)
{
List<Dictionary<string, object>>? newValueList = new List<Dictionary<string, object>>();
realList.ForEach(item =>
{
List<Dictionary<string, object>>? tt = item["children"].ToJsonString().ToObject<List<Dictionary<string, object>>>();
newValueList.AddRange(tt);
});
realList = newValueList;
var selectKeyList = new List<string>();
selectKey.Split(',').ToList().ForEach(item => { if (realList.Any(x => x.ContainsKey(item)) || item.ToLower().Contains("tablefield")) selectKeyList.Add(item); });
selectKey = string.Join(",", selectKeyList);
}
var res = GetCreateFirstColumnsHeader(selectKey.Split(',').ToList(), realList, paramList);
var firstColumns = res.First().ToObject<Dictionary<string, int>>();
var resultList = res.Last().ToObject<List<Dictionary<string, object>>>();
List<string> newSelectKey = selectKey.Split(',').ToList();
List<ParamsModel> newParamList = new List<ParamsModel>();
// 全部参数顺序
foreach (var item in firstColumns)
{
Regex re = new Regex(@"[\u4e00-\u9fa5]+");
switch (re.IsMatch(item.Key))
{
case false:
{
var param = newSelectKey.GetRange(0, item.Value);
newParamList.AddRange(paramList.FindAll(it => param.Contains(it.field)));
newSelectKey.RemoveAll(it => newParamList.Select(it => it.field).ToList().Contains(it));
}
break;
default:
var childTable = paramList.FindAll(it => it.value.Contains(item.Key.TrimEnd(' ')));
childTable = childTable.FindAll(it => selectKey.Split(',').ToList().Contains(it.field));
newParamList.AddRange(childTable);
newSelectKey.RemoveAll(it => newParamList.Select(it => it.field).ToList().Contains(it));
break;
}
}
if (newParamList.Count > 0) newSelectKey = newParamList.Select(it => it.field).ToList();
try
{
List<string> columnList = new List<string>();
ExcelConfig excelconfig = new ExcelConfig();
excelconfig.FileName = string.Format("{0}.xls", fileName);
excelconfig.HeadFont = "微软雅黑";
excelconfig.HeadPoint = 10;
excelconfig.IsAllSizeColumn = true;
excelconfig.ColumnModel = new List<ExcelColumnModel>();
foreach (var item in newSelectKey)
{
ParamsModel isExist = new ParamsModel();
switch (isInlineEditor)
{
case true:
isExist = paramList.Find(p => p.field.Equals(string.Format("{0}_name", item)));
break;
default:
isExist = paramList.Find(p => p.field == item);
break;
}
if (isExist != null)
{
excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
columnList.Add(isExist.value);
}
}
string? addPath = Path.Combine(FileVariable.TemporaryFilePath, excelconfig.FileName);
var fs = (firstColumns == null || firstColumns.Count() < 1) ? ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(resultList, excelconfig, columnList) : ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(resultList, excelconfig, columnList, firstColumns);
ExcelExportHelper<Dictionary<string, object>>.Export(fs, addPath);
var fName = userId + "|" + excelconfig.FileName + "|xls";
return new
{
name = excelconfig.FileName,
url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fName, "JNPF")
};
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 模板导出.
/// </summary>
/// <param name="fileName">导出文件名.</param>
/// <param name="selectKey">selectKey.</param>
/// <param name="userId">用户ID.</param>
/// <param name="realList">数据集合.</param>
/// <param name="paramList">参数.</param>
/// <returns></returns>
public static dynamic GetTemplateExport(string fileName, string selectKey, string userId, List<Dictionary<string, object>> realList, List<ParamsModel> paramList = default)
{
var res = GetCreateFirstColumnsHeader(selectKey.Split(',').ToList(), realList, paramList);
var firstColumns = res.First().ToObject<Dictionary<string, int>>();
var resultList = res.Last().ToObject<List<Dictionary<string, object>>>();
List<string> newSelectKey = selectKey.Split(',').ToList();
try
{
List<string> columnList = new List<string>();
ExcelConfig excelconfig = new ExcelConfig();
excelconfig.FileName = string.Format("{0}.xls", fileName);
excelconfig.HeadFont = "微软雅黑";
excelconfig.HeadPoint = 10;
excelconfig.IsAllSizeColumn = true;
excelconfig.ColumnModel = new List<ExcelColumnModel>();
foreach (var item in newSelectKey)
{
ParamsModel isExist = new ParamsModel();
var import = realList.FirstOrDefault().Where(p => p.Key.Contains(string.Format("({0})", item)));
if (import.Any())
{
isExist = new ParamsModel()
{
field = item,
value = import.FirstOrDefault().Key
};
if (isExist != null)
{
excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value });
columnList.Add(isExist.value);
}
}
}
string? addPath = Path.Combine(FileVariable.TemporaryFilePath, excelconfig.FileName);
var fs = (firstColumns == null || firstColumns.Count() < 1) ? ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(realList, excelconfig, columnList) : ExcelExportHelper<Dictionary<string, object>>.ExportMemoryStream(realList, excelconfig, columnList, firstColumns);
ExcelExportHelper<Dictionary<string, object>>.Export(fs, addPath);
var fName = userId + "|" + excelconfig.FileName + "|xls";
return new
{
name = excelconfig.FileName,
url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fName, "JNPF")
};
}
catch (Exception)
{
throw;
}
}
}

View File

@@ -0,0 +1,271 @@
using JNPF.Common.Const;
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
using SqlSugar;
namespace JNPF.Common.Security;
/// <summary>
/// 代码生成帮助类.
/// </summary>
[SuppressSniffer]
public static class CodeGenHelper
{
public static string ConvertDataType(string dataType)
{
switch (dataType.ToLower())
{
case "text":
case "varchar":
case "char":
case "nvarchar":
case "nchar":
case "timestamp":
case "string":
return "string";
case "int":
case "smallint":
return "int";
case "tinyint":
return "byte";
case "bigint":
// sqlite数据库
case "integer":
return "long";
case "bit":
return "bool";
case "money":
case "smallmoney":
case "numeric":
case "decimal":
return "decimal";
case "real":
return "Single";
case "datetime":
case "datetime2":
case "smalldatetime":
case "date":
return "DateTime?";
case "float":
return "double";
case "image":
case "binary":
case "varbinary":
return "byte[]";
case "uniqueidentifier":
return "Guid";
default:
return "object";
}
}
/// <summary>
/// 数据类型转显示类型.
/// </summary>
/// <param name="dataType"></param>
/// <returns></returns>
public static string DataTypeToEff(string dataType)
{
if (string.IsNullOrEmpty(dataType)) return string.Empty;
return dataType switch
{
"string" => "input",
"int" => "inputnumber",
"long" => "input",
"float" => "input",
"double" => "input",
"decimal" => "input",
"bool" => "switch",
"Guid" => "input",
"DateTime" => "datepicker",
_ => "input",
};
}
/// <summary>
/// 是否通用字段.
/// </summary>
/// <param name="columnName"></param>
/// <returns></returns>
public static bool IsCommonColumn(string columnName)
{
var columnList = new List<string>()
{
"CreatedTime", "UpdatedTime", "CreatedUserId", "CreatedUserName", "UpdatedUserId", "UpdatedUserName", "IsDeleted"
};
return columnList.Contains(columnName);
}
/// <summary>
/// 数据列表生成分组表格.
/// </summary>
/// <param name="realList">数据列表.</param>
/// <param name="groupField">分组字段名.</param>
/// <param name="groupShowField">分组显示字段名.</param>
/// <returns></returns>
public static List<Dictionary<string, object>> GetGroupList(List<Dictionary<string, object>> realList, string groupField, string groupShowField)
{
if (realList.Any())
{
var fList = realList.FirstOrDefault().Select(x => x.Key).ToList();
var prop = fList.Where(x => x.Equals(groupShowField)).FirstOrDefault();
// 分组数据
Dictionary<string, List<Dictionary<string, object>>> groupDic = new Dictionary<string, List<Dictionary<string, object>>>();
foreach (var item in realList)
{
if (item.ContainsKey(groupField))
{
var groupDicKey = item[groupField] is null ? string.Empty : item[groupField].ToString();
if (!groupDic.ContainsKey(groupDicKey)) groupDic.Add(groupDicKey, new List<Dictionary<string, object>>()); // 初始化
item.Remove(groupField);
groupDic[groupDicKey].Add(item);
}
else
{
var groupDicKey = "null";
if (!groupDic.ContainsKey(groupDicKey)) groupDic.Add(groupDicKey, new List<Dictionary<string, object>>()); // 初始化
groupDic[groupDicKey].Add(item);
}
}
List<Dictionary<string, object>> realGroupDic = new List<Dictionary<string, object>>();
foreach (var item in groupDic)
{
Dictionary<string, object> dataMap = new Dictionary<string, object>();
dataMap.Add("top", true);
dataMap.Add("id", SnowflakeIdHelper.NextId());
dataMap.Add("children", item.Value);
if (!string.IsNullOrWhiteSpace(prop)) dataMap.Add(prop, item.Key);
else dataMap.Add(groupField, item.Key);
realGroupDic.Add(dataMap);
}
return realGroupDic;
}
else
{
return new List<Dictionary<string, object>>();
}
}
/// <summary>
/// 获取排序真实字段.
/// </summary>
/// <param name="sort">排序字段.</param>
/// <param name="replaceContent">取代内容.</param>
/// <param name="entityInfo">实体信息.</param>
/// <param name="tableType">表类型 0-主表,1-子表,2-副表.</param>
/// <returns></returns>
public static string GetSortRealField(string sort, string replaceContent, EntityInfo entityInfo, int tableType)
{
var field = string.Empty;
switch (tableType)
{
case 1:
if (sort.Contains(replaceContent))
{
field = entityInfo.Columns.Find(it => it.PropertyName.Equals(sort.Replace(replaceContent, "").ToUpperCase()))?.DbColumnName;
}
break;
case 2:
if (sort.Contains("_jnpf_"))
{
var queryField = sort.Replace("_jnpf_", "@").Split('@')[1];
field = entityInfo.Columns.Find(it => it.PropertyName.Equals(queryField.ToUpperCase()))?.DbColumnName;
}
break;
default:
field = entityInfo.Columns.Find(it => it.PropertyName.Equals(sort.ToUpperCase()))?.DbColumnName;
break;
}
return string.IsNullOrEmpty(field) ? null : field;
}
/// <summary>
/// 代码生成导出模板.
/// </summary>
/// <param name="jnpfKey">控件Key.</param>
/// <param name="multiple">是否多选.</param>
/// <param name="label">标题.</param>
/// <param name="format">时间格式化.</param>
/// <param name="level">等级.</param>
/// <returns></returns>
public static Dictionary<string, string> CodeGenTemplate(string jnpfKey, bool multiple, string label, string format, int level)
{
Dictionary<string, string> result = new Dictionary<string, string>();
switch (jnpfKey)
{
case JnpfKeyConst.CREATEUSER:
case JnpfKeyConst.MODIFYUSER:
case JnpfKeyConst.CREATETIME:
case JnpfKeyConst.MODIFYTIME:
case JnpfKeyConst.CURRORGANIZE:
case JnpfKeyConst.CURRPOSITION:
case JnpfKeyConst.CURRDEPT:
case JnpfKeyConst.BILLRULE:
result.Add(label, "系统自动生成");
break;
case JnpfKeyConst.COMSELECT:
result.Add(label, multiple ? "例:拓通智联/产品部,拓通智联/技术部" : "例:拓通智联/技术部");
break;
case JnpfKeyConst.DEPSELECT:
result.Add(label, multiple ? "例:产品部/部门编码,技术部/部门编码" : "例:技术部/部门编码");
break;
case JnpfKeyConst.POSSELECT:
result.Add(label, multiple ? "例:技术经理/岗位编码,技术员/岗位编码" : "例:技术员/岗位编码");
break;
case JnpfKeyConst.USERSELECT:
result.Add(label, multiple ? "例:张三/账号,李四/账号" : "例:张三/账号");
break;
case JnpfKeyConst.USERSSELECT:
result.Add(label, multiple ? "例:拓通智联/产品部,产品部/部门编码,技术经理/岗位编码,研发人员/角色编码,A分组/分组编码,张三/账号" : "例:李四/账号");
break;
case JnpfKeyConst.ROLESELECT:
result.Add(label, multiple ? "例:研发人员/角色编码,测试人员/角色编码" : "例:研发人员/角色编码");
break;
case JnpfKeyConst.GROUPSELECT:
result.Add(label, multiple ? "例:A分组/分组编码,B分组/分组编码" : "例:A分组/分组编码");
break;
case JnpfKeyConst.DATE:
result.Add(label, string.Format("例:{0}", format));
break;
case JnpfKeyConst.TIME:
result.Add(label, "例: HH:mm:ss");
break;
case JnpfKeyConst.ADDRESS:
switch (level)
{
case 0:
result.Add(label, multiple ? "例:福建省,广东省" : "例:福建省");
break;
case 1:
result.Add(label, multiple ? "例:福建省/莆田市,广东省/广州市" : "例:福建省/莆田市");
break;
case 2:
result.Add(label, multiple ? "例:福建省/莆田市/城厢区,广东省/广州市/荔湾区" : "例:福建省/莆田市/城厢区");
break;
case 3:
result.Add(label, multiple ? "例:福建省/莆田市/城厢区/霞林街道,广东省/广州市/荔湾区/沙面街道" : "例:福建省/莆田市/城厢区/霞林街道");
break;
}
break;
default:
result.Add(label, string.Empty);
break;
}
return result;
}
}

View File

@@ -0,0 +1,71 @@
using JNPF.DependencyInjection;
namespace JNPF.Common.Security;
/// <summary>
/// 比较器辅助类,用于快速创建<see cref="IComparer{T}"/>接口的实例.
/// </summary>
/// <example>
/// var comparer1 = Comparison[Person].CreateComparer(p => p.ID); var comparer2 = Comparison[Person].CreateComparer(p => p.Name); var comparer3 = Comparison[Person].CreateComparer(p => p.Birthday.Year).
/// </example>
/// <typeparam name="T">要比较的类型.</typeparam>
[SuppressSniffer]
public static class ComparisonHelper<T>
{
/// <summary>
/// 创建指定对比委托<paramref name="keySelector"/>的实例.
/// </summary>
public static IComparer<T> CreateComparer<TV>(Func<T, TV> keySelector)
{
return new CommonComparer<TV>(keySelector);
}
/// <summary>
/// 创建指定对比委托<paramref name="keySelector"/>与结果二次比较器<paramref name="comparer"/>的实例
/// </summary>
public static IComparer<T> CreateComparer<TV>(Func<T, TV> keySelector, IComparer<TV> comparer)
{
return new CommonComparer<TV>(keySelector, comparer);
}
/// <summary>
/// 常见的比较器.
/// </summary>
/// <typeparam name="TV">要比较的类型.</typeparam>
private class CommonComparer<TV> : IComparer<T>
{
private readonly IComparer<TV> _comparer;
private readonly Func<T, TV> _keySelector;
/// <summary>
/// 构造函数.
/// </summary>
/// <param name="keySelector"></param>
/// <param name="comparer"></param>
public CommonComparer(Func<T, TV> keySelector, IComparer<TV> comparer)
{
_keySelector = keySelector;
_comparer = comparer;
}
/// <summary>
/// 构造函数.
/// </summary>
/// <param name="keySelector"></param>
public CommonComparer(Func<T, TV> keySelector)
: this(keySelector, Comparer<TV>.Default)
{
}
/// <summary>
/// 比较.
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <returns></returns>
public int Compare(T x, T y)
{
return _comparer.Compare(_keySelector(x), _keySelector(y));
}
}
}

View File

@@ -0,0 +1,62 @@
using JNPF.DependencyInjection;
namespace JNPF.Common.Security;
/// <summary>
/// 相等比较辅助类,用于快速创建<see cref="IEqualityComparer{T}"/>的实例.
/// </summary>
/// <example>
/// var equalityComparer1 = EqualityHelper[Person].CreateComparer(p => p.ID);
/// var equalityComparer2 = EqualityHelper[Person].CreateComparer(p => p.Name);
/// var equalityComparer3 = EqualityHelper[Person].CreateComparer(p => p.Birthday.Year).
/// </example>
/// <typeparam name="T">要比较的类型.</typeparam>
[SuppressSniffer]
public static class EqualityHelper<T>
{
/// <summary>
/// 创建指定对比委托<paramref name="keySelector"/>的实例.
/// </summary>
public static IEqualityComparer<T> CreateComparer<TV>(Func<T, TV> keySelector)
{
return new CommonEqualityComparer<TV>(keySelector);
}
/// <summary>
/// 创建指定对比委托<paramref name="keySelector"/>与结果二次比较器<paramref name="comparer"/>的实例.
/// </summary>
public static IEqualityComparer<T> CreateComparer<TV>(Func<T, TV> keySelector, IEqualityComparer<TV> comparer)
{
return new CommonEqualityComparer<TV>(keySelector, comparer);
}
/// <summary>
/// 共同平等比较器.
/// </summary>
/// <typeparam name="TV">要比较的类型.</typeparam>
private class CommonEqualityComparer<TV> : IEqualityComparer<T>
{
private readonly IEqualityComparer<TV> _comparer;
private readonly Func<T, TV> _keySelector;
public CommonEqualityComparer(Func<T, TV> keySelector, IEqualityComparer<TV> comparer)
{
_keySelector = keySelector;
_comparer = comparer;
}
public CommonEqualityComparer(Func<T, TV> keySelector)
: this(keySelector, EqualityComparer<TV>.Default)
{ }
public bool Equals(T x, T y)
{
return _comparer.Equals(_keySelector(x), _keySelector(y));
}
public int GetHashCode(T obj)
{
return _comparer.GetHashCode(_keySelector(obj));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,161 @@
using JNPF.DependencyInjection;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;
namespace JNPF.Common.Helper
{
/// <summary>
/// Excel导入操作类
/// 版 本V3.2.0
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 日 期2017.03.12.
/// </summary>
[SuppressSniffer]
public class ExcelImportHelper
{
/// <summary>
/// 从Excel中获取数据到DataTable.
/// </summary>
/// <param name="filePath">Excel文件全路径(服务器路径).</param>
/// <param name="SheetIndex">要获取数据的工作表序号(从0开始).</param>
/// <param name="HeaderRowIndex">工作表标题行所在行号(从0开始).</param>
/// <returns></returns>
public static DataTable ToDataTable(string filePath, int SheetIndex = 0, int HeaderRowIndex = 0)
{
using (FileStream file = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
IWorkbook workbook = null;
// 2003
if (filePath.IndexOf(".xlsx") == -1)
workbook = new HSSFWorkbook(file);
else
workbook = new XSSFWorkbook(file);
string SheetName = workbook.GetSheetName(SheetIndex);
return ToDataTable(workbook, SheetName, HeaderRowIndex);
}
}
/// <summary>
/// 从Excel中获取数据到DataTable.
/// </summary>
/// <param name="filePath">Excel文件全路径(服务器路径).</param>
/// <param name="SheetIndex">要获取数据的工作表序号(从0开始).</param>
/// <param name="HeaderRowIndex">工作表标题行所在行号(从0开始).</param>
/// <returns></returns>
public static DataTable ToDataTable(string filePath, Stream sr, int SheetIndex = 0, int HeaderRowIndex = 0)
{
IWorkbook workbook = null;
if (filePath.IndexOf(".xlsx") == -1)//2003
{
workbook = new HSSFWorkbook(sr);
}
else
{
workbook = new XSSFWorkbook(sr);
}
string SheetName = workbook.GetSheetName(SheetIndex);
return ToDataTable(workbook, SheetName, HeaderRowIndex);
}
/// <summary>
/// 从Excel中获取数据到DataTable.
/// </summary>
/// <param name="workbook">要处理的工作薄.</param>
/// <param name="SheetName">要获取数据的工作表名称.</param>
/// <param name="HeaderRowIndex">工作表标题行所在行号(从0开始).</param>
/// <returns></returns>
public static DataTable ToDataTable(IWorkbook workbook, string SheetName, int HeaderRowIndex)
{
ISheet sheet = workbook.GetSheet(SheetName);
DataTable table = new DataTable();
try
{
IRow headerRow = sheet.GetRow(HeaderRowIndex);
int cellCount = headerRow.LastCellNum;
for (int i = headerRow.FirstCellNum; i < cellCount; i++)
{
if (headerRow.GetCell(i) != null && headerRow.GetCell(i).StringCellValue != null)
{
DataColumn column = new DataColumn(headerRow.GetCell(i).StringCellValue);
table.Columns.Add(column);
}
}
int rowCount = sheet.LastRowNum;
if (rowCount > 0)
{
#region ,DataTable
for (int i = (sheet.FirstRowNum); i <= sheet.LastRowNum; i++)
{
IRow row = sheet.GetRow(i);
DataRow dataRow = table.NewRow();
for (int j = row.FirstCellNum; j < cellCount; j++)
{
ICell cell = row.GetCell(j);
if (cell == null)
{
dataRow[j] = null;
}
else
{
//if (cell.CellType == CellType.Numeric && DateUtil.IsCellDateFormatted(cell))
//{
// dataRow[j] = cell.DateCellValue.ToString("yyyy/MM/dd").Trim();
//}
//else
//{
dataRow[j] = cell.ToString().Trim();
//}
}
}
table.Rows.Add(dataRow);
}
#endregion
}
}
catch (System.Exception ex)
{
table.Clear();
table.Columns.Clear();
table.Columns.Add("出错了");
DataRow dr = table.NewRow();
dr[0] = ex.Message;
table.Rows.Add(dr);
return table;
}
finally
{
// sheet.Dispose();
workbook = null;
sheet = null;
}
#region
for (int i = table.Rows.Count-1; i >= 0; i--)
{
bool isnull = true;
for (int j = 0; j < table.Columns.Count; j++)
{
if (table.Rows[i][j] != null)
{
if (table.Rows[i][j].ToString() != "")
{
isnull = false;
break;
}
}
}
if (isnull)
{
table.Rows[i].Delete();
}
}
#endregion
return table;
}
}
}

View File

@@ -0,0 +1,829 @@
using JNPF.Common.Configuration;
using JNPF.Common.Extension;
using JNPF.Common.Models;
using JNPF.DependencyInjection;
using System.Drawing;
using System.Drawing.Imaging;
using System.Text;
using System.Web;
namespace JNPF.Common.Security;
/// <summary>
/// FileHelper
/// 版 本V3.2.0
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 作 者JNPF开发平台组.
/// </summary>
[SuppressSniffer]
public class FileHelper
{
#region
/// <summary>
/// 返回绝对路径.
/// </summary>
/// <param name="filePath">相对路径.</param>
/// <returns></returns>
public static string GetAbsolutePath(string filePath)
{
return Directory.GetCurrentDirectory() + filePath;
}
#endregion
#region
/// <summary>
/// 检测指定目录是否存在.
/// </summary>
/// <param name="directoryPath">目录的绝对路径</param>
/// <returns></returns>
public static bool IsExistDirectory(string directoryPath)
{
return Directory.Exists(directoryPath);
}
#endregion
#region ,true
/// <summary>
/// 检测指定文件是否存在,如果存在则返回true.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static bool IsExistFile(string filePath)
{
return File.Exists(filePath);
}
/// <summary>
/// 检测指定文件是否存在,如果存在则返回true.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static bool Exists(string filePath)
{
return File.Exists(filePath);
}
#endregion
#region
/// <summary>
/// 获取指定目录中所有文件列表.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径.</param>
public static string[] GetFileNames(string directoryPath)
{
// 如果目录不存在,则抛出异常
if (!IsExistDirectory(directoryPath))
throw new FileNotFoundException();
return Directory.GetFiles(directoryPath);
}
/// <summary>
/// 获取指定目录中所有文件列表.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径.</param>
/// <param name="data">返回文件.</param>
/// <returns></returns>
public static List<FileInfo> GetAllFiles(string directoryPath, List<FileInfo>? data = null)
{
if (!IsExistDirectory(directoryPath))
return new List<FileInfo>();
List<FileInfo> listFiles = data == null ? new List<FileInfo>() : data;
DirectoryInfo directory = new DirectoryInfo(directoryPath);
DirectoryInfo[] directorys = directory.GetDirectories();
FileInfo[] fileInfos = directory.GetFiles();
if (fileInfos.Length > 0)
listFiles.AddRange(fileInfos);
foreach (DirectoryInfo itemDirectory in directorys)
{
GetAllFiles(itemDirectory.FullName, listFiles);
}
return listFiles;
}
#endregion
#region ,,使.
/// <summary>
/// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径.</param>
public static string[] GetDirectories(string directoryPath)
{
try
{
return Directory.GetDirectories(directoryPath);
}
catch (IOException)
{
throw;
}
}
#endregion
#region
/// <summary>
/// 获取指定目录及子目录中所有文件列表.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径.</param>
/// <param name="searchPattern">模式字符串,"*"代表0或N个字符"?"代表1个字符
/// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件.</param>
/// <param name="isSearchChild">是否搜索子目录.</param>
public static string[] GetFileNames(string directoryPath, string searchPattern, bool isSearchChild)
{
// 如果目录不存在,则抛出异常
if (!IsExistDirectory(directoryPath))
throw new FileNotFoundException();
try
{
if (isSearchChild)
return Directory.GetFiles(directoryPath, searchPattern, SearchOption.AllDirectories);
else
return Directory.GetFiles(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
}
catch (IOException)
{
throw;
}
}
#endregion
#region
/// <summary>
/// 创建目录.
/// </summary>
/// <param name="dir">要创建的目录路径包括目录名.</param>
public static void CreateDir(string dir)
{
if (dir.Length == 0) return;
if (!Directory.Exists(dir))
Directory.CreateDirectory(dir);
}
#endregion
#region
/// <summary>
/// 删除指定目录及其所有子目录.
/// </summary>
/// <param name="dir">要删除的目录路径和名称.</param>
public static void DeleteDirectory(string dir)
{
if (dir.Length == 0) return;
if (Directory.Exists(dir))
Directory.Delete(dir, true);
}
#endregion
#region
/// <summary>
/// 删除文件.
/// </summary>
/// <param name="file">要删除的文件路径和名称.</param>
public static void DeleteFile(string file)
{
if (File.Exists(file))
File.Delete(file);
}
/// <summary>
/// 删除文件.
/// </summary>
/// <param name="file">要删除的文件路径和名称.</param>
public static void Delete(string file)
{
if (File.Exists(file))
File.Delete(file);
}
#endregion
#region
/// <summary>
/// 创建文件.
/// </summary>
/// <param name="dir">带后缀的文件名.</param>
/// <param name="content">文件内容.</param>
public static void CreateFile(string dir, string content)
{
dir = dir.Replace("/", "\\");
if (dir.IndexOf("\\") > -1)
CreateDir(dir.Substring(0, dir.LastIndexOf("\\")));
StreamWriter sw = new StreamWriter(dir, false);
sw.Write(content);
sw.Close();
sw.Dispose();
}
/// <summary>
/// 创建文件.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static void CreateFile(string filePath)
{
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Close();
}
}
/// <summary>
/// 创建文件,并将字节流写入文件.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
/// <param name="buffer">二进制流数据.</param>
public static void CreateFile(string filePath, byte[] buffer)
{
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
}
#endregion
#region
/// <summary>
/// 移动文件(剪贴--粘贴).
/// </summary>
/// <param name="dir1">要移动的文件的路径及全名(包括后缀).</param>
/// <param name="dir2">文件移动到新的位置,并指定新的文件名.</param>
public static void MoveFile(string dir1, string dir2)
{
if (File.Exists(dir1))
File.Move(dir1, dir2);
}
#endregion
#region
/// <summary>
/// 复制文件.
/// </summary>
/// <param name="dir1">要复制的文件的路径已经全名(包括后缀).</param>
/// <param name="dir2">目标位置,并指定新的文件名.</param>
public static void CopyFile(string dir1, string dir2)
{
if (File.Exists(dir1))
File.Copy(dir1, dir2);
}
#endregion
#region
/// <summary>
/// 复制文件夹(递归).
/// </summary>
/// <param name="varFromDirectory">源文件夹路径.</param>
/// <param name="varToDirectory">目标文件夹路径.</param>
public static void CopyFolder(string varFromDirectory, string varToDirectory)
{
Directory.CreateDirectory(varToDirectory);
if (!Directory.Exists(varFromDirectory)) return;
string[] directories = Directory.GetDirectories(varFromDirectory);
if (directories.Length > 0)
{
foreach (string d in directories)
{
CopyFolder(d, varToDirectory + d.Substring(d.LastIndexOf("\\")));
}
}
string[] files = Directory.GetFiles(varFromDirectory);
if (files.Length > 0)
{
foreach (string s in files)
{
File.Copy(s, varToDirectory + s.Substring(s.LastIndexOf("\\")), true);
}
}
}
#endregion
#region
/// <summary>
/// 删除指定文件夹对应其他文件夹里的文件.
/// </summary>
/// <param name="varFromDirectory">指定文件夹路径.</param>
/// <param name="varToDirectory">对应其他文件夹路径.</param>
public static void DeleteFolderFiles(string varFromDirectory, string varToDirectory)
{
Directory.CreateDirectory(varToDirectory);
if (!Directory.Exists(varFromDirectory)) return;
string[] directories = Directory.GetDirectories(varFromDirectory);
if (directories.Length > 0)
{
foreach (string d in directories)
{
DeleteFolderFiles(d, varToDirectory + d.Substring(d.LastIndexOf("\\")));
}
}
string[] files = Directory.GetFiles(varFromDirectory);
if (files.Length > 0)
{
foreach (string s in files)
{
File.Delete(varToDirectory + s.Substring(s.LastIndexOf("\\")));
}
}
}
#endregion
#region ( )
/// <summary>
/// 从文件的绝对路径中获取文件名( 包含扩展名 ).
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static string GetFileName(string filePath)
{
// 获取文件的名称
FileInfo fi = new FileInfo(filePath);
return fi.Name;
}
#endregion
#region
/// <summary>
/// 获取一个文件的长度,单位为Byte.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static long GetFileSize(string filePath)
{
FileInfo fi = new FileInfo(filePath);
return fi.Length;
}
#endregion
#region BKBGBTB
/// <summary>
/// 计算文件大小函数(保留两位小数),Size为字节大小.
/// </summary>
/// <param name="size">初始文件大小.</param>
/// <returns></returns>
public static string ToFileSize(long size)
{
string m_strSize = string.Empty;
long factSize = 0;
factSize = size;
if (factSize < 1024.00)
m_strSize = factSize.ToString("F2") + " 字节";
else if (factSize >= 1024.00 && factSize < 1048576)
m_strSize = (factSize / 1024.00).ToString("F2") + " KB";
else if (factSize >= 1048576 && factSize < 1073741824)
m_strSize = (factSize / 1024.00 / 1024.00).ToString("F2") + " MB";
else if (factSize >= 1073741824)
m_strSize = (factSize / 1024.00 / 1024.00 / 1024.00).ToString("F2") + " GB";
return m_strSize;
}
#endregion
#region
/// <summary>
/// 将源文件的内容复制到目标文件中.
/// </summary>
/// <param name="sourceFilePath">源文件的绝对路径.</param>
/// <param name="destFilePath">目标文件的绝对路径.</param>
public static void Copy(string sourceFilePath, string destFilePath)
{
File.Copy(sourceFilePath, destFilePath, true);
}
#endregion
#region ReadAllBytes
/// <summary>
/// ReadAllBytes.
/// </summary>
/// <param name="path">path.</param>
/// <returns></returns>
public static byte[]? ReadAllBytes(string path)
{
try
{
return File.ReadAllBytes(path);
}
catch (Exception)
{
return null;
}
}
/// <summary>
/// 读取全部字符串.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string? ReadAllStr(string path)
{
string line = string.Empty;
FileStream fileStream = new FileStream(path, FileMode.Open);
using (StreamReader reader = new StreamReader(fileStream))
{
line = reader.ReadLine();
}
return line;
}
#endregion
#region
/// <summary>
/// 将文件读取到字符串中.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
public static string FileToString(string filePath)
{
return FileToString(filePath, Encoding.UTF8);
}
/// <summary>
/// 将文件读取到字符串中.
/// </summary>
/// <param name="filePath">文件的绝对路径.</param>
/// <param name="encoding">字符编码</param>
public static string FileToString(string filePath, Encoding encoding)
{
// 创建流读取器
StreamReader reader = new StreamReader(filePath, encoding);
try
{
// 读取流
return reader.ReadToEnd();
}
catch (Exception ex)
{
throw ex;
}
finally
{
// 关闭流读取器
reader.Close();
}
}
#endregion
#region
/// <summary>
/// 根据源图片生成高清晰缩略图.
/// </summary>
/// <param name="imgPath_old">源图(大图)物理路径.</param>
/// <param name="imgPath_new">缩略图物理路径(生成的缩略图将保存到该物理位置).</param>
/// <param name="width">缩略图宽度.</param>
/// <param name="height">缩略图高度.</param>
/// <param name="mode">缩略图缩放模式(取值"HW":指定高宽缩放,可能变形;取值"W":按指定宽度,高度按比例缩放;取值"H":按指定高度,宽度按比例缩放;取值"Cut":按指定高度和宽度裁剪,不变形);取值"DB":等比缩放,以值较大的作为标准进行等比缩放.</param>
/// <param name="imageType">即将生成缩略图的文件的扩展名(仅限JPG、GIF、PNG、BMP).</param>
public static void MakeThumbnail(string imgPath_old, string imgPath_new, int width, int height, string mode, string imageType, int xx, int yy)
{
if (IsExistFile(imgPath_old))
{
Image img = Image.FromFile(imgPath_old);
int towidth = width;
int toheight = height;
int x = 0;
int y = 0;
int ow = img.Width;
int oh = img.Height;
switch (mode)
{
// 指定高宽压缩
case "HW":
// 判断图形是什么形状
if ((double)img.Width / (double)img.Height > (double)width / (double)height)
{
towidth = width;
toheight = img.Height * width / img.Width;
}
else if ((double)img.Width / (double)img.Height == (double)width / (double)height)
{
towidth = width;
toheight = height;
}
else
{
toheight = height;
towidth = img.Width * height / img.Height;
}
break;
case "W":
// 指定宽,高按比例
toheight = img.Height * width / img.Width;
break;
case "H":
// 指定高,宽按比例
towidth = img.Width * height / img.Height;
break;
case "Cut":
// 指定高宽裁减(不变形)
if ((double)img.Width / (double)img.Height > (double)towidth / (double)toheight)
{
oh = img.Height;
ow = img.Height * towidth / toheight;
y = yy;
x = (img.Width - ow) / 2;
}
else
{
ow = img.Width;
oh = img.Width * height / towidth;
x = xx;
y = (img.Height - oh) / 2;
}
break;
case "DB":
// 按值较大的进行等比缩放(不变形)
if ((double)img.Width / (double)towidth < (double)img.Height / (double)toheight)
{
toheight = height;
towidth = img.Width * height / img.Height;
}
else
{
towidth = width;
toheight = img.Height * width / img.Width;
}
break;
default:
break;
}
// 新建一个bmp图片
Image bitmap = new Bitmap(towidth, toheight);
// 新建一个画板
Graphics g = Graphics.FromImage(bitmap);
// 设置高质量插值法
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
// 设置高质量,低速度呈现平滑程度
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
// 清空画布并以透明背景色填充
g.Clear(Color.Transparent);
// 在指定位置并且按指定大小绘制原图片的指定部分
g.DrawImage(img, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);
try
{
// 以jpg格式保存缩略图
switch (imageType.ToLower())
{
case "gif":
// 生成缩略图
bitmap.Save(imgPath_new, ImageFormat.Gif);
break;
case "jpg":
bitmap.Save(imgPath_new, ImageFormat.Jpeg);
break;
case "bmp":
bitmap.Save(imgPath_new, ImageFormat.Bmp);
break;
case "png":
bitmap.Save(imgPath_new, ImageFormat.Png);
break;
default:
bitmap.Save(imgPath_new, ImageFormat.Jpeg);
break;
}
bitmap.Save(imgPath_new);
}
catch (Exception)
{
throw;
}
finally
{
img.Dispose();
bitmap.Dispose();
g.Dispose();
}
}
}
#endregion
#region
/// <summary>
/// 获取文件类型.
/// </summary>
/// <param name="file">文件</param>
/// <returns></returns>
public static string? GetFileType(FileInfo file)
{
if (file.Exists)
{
string fileName = file.Name;
return fileName.Substring(fileName.LastIndexOf(".") + 1);
}
return string.Empty;
}
#endregion
#region
/// <summary>
/// 将文件路径转为内存流.
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
public static MemoryStream FileToStream(string fileName)
{
// 打开文件
FileStream fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
// 读取文件的 byte[]
byte[] bytes = new byte[fileStream.Length];
fileStream.Read(bytes, 0, bytes.Length);
fileStream.Close();
// 把 byte[] 转换成 Stream
return new MemoryStream(bytes);
}
#endregion
#region
/// <summary>
/// 根据文件大小获取指定前缀的可用文件名.
/// </summary>
/// <param name="folderPath">文件夹.</param>
/// <param name="prefix">文件前缀.</param>
/// <param name="size">文件大小(1m).</param>
/// <param name="ext">文件后缀(.log).</param>
/// <returns>可用文件名.</returns>
public static string GetAvailableFileWithPrefixOrderSize(string folderPath, string prefix, int size = 1 * 1024 * 1024, string ext = ".log")
{
DirectoryInfo allFiles = new DirectoryInfo(folderPath);
List<FileInfo> selectFiles = allFiles.GetFiles().Where(fi => fi.Name.ToLower().Contains(prefix.ToLower()) && fi.Extension.ToLower() == ext.ToLower() && fi.Length < size).OrderByDescending(d => d.Name).ToList();
if (selectFiles.Count > 0)
{
return selectFiles.FirstOrDefault().FullName;
}
return Path.Combine(folderPath, $@"{prefix}_{DateTime.Now.ParseToUnixTime()}.log");
}
#endregion
#region
/// <summary>
/// 普通下载.
/// </summary>
/// <param name="filePath">路径.</param>
/// <param name="fileName">文件名.</param>
public static void DownloadFile(string filePath, string fileName)
{
try
{
if (File.Exists(filePath))
{
byte[]? buff = ReadAllBytes(filePath);
Microsoft.AspNetCore.Http.HttpContext? httpContext = App.HttpContext;
httpContext.Response.ContentType = "application/octet-stream";
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
httpContext.Response.Headers.Add("Content-Length", buff.Length.ToString());
httpContext.Response.Body.WriteAsync(buff);
httpContext.Response.Body.Flush();
httpContext.Response.Body.Close();
}
}
catch (Exception)
{
}
}
/// <summary>
/// 普通下载.
/// </summary>
/// <param name="buffer">文件流.</param>
/// <param name="fileName">文件名.</param>
public static void DownloadFile(byte[] buffer, string fileName)
{
Microsoft.AspNetCore.Http.HttpContext? httpContext = App.HttpContext;
httpContext.Response.ContentType = "application/octet-stream";
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
httpContext.Response.Body.Write(buffer);
httpContext.Response.Body.Flush();
httpContext.Response.Body.Close();
}
#endregion
#region
/// <summary>
/// 添加附件:将临时文件夹的文件拷贝到正式文件夹里面.
/// </summary>
/// <param name="data"></param>
public static void CreateFile(List<AnnexModel> data)
{
if (data != null && data.Count > 0)
{
string temporaryFilePath = Path.Combine(KeyVariable.SystemPath, "TemporaryFile");
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
MoveFile(temporaryFilePath + item.FileId, systemFilePath + item.FileId);
}
}
}
/// <summary>
/// 更新附件.
/// </summary>
/// <param name="data"></param>
public static void UpdateFile(List<AnnexModel> data)
{
if (data != null)
{
string temporaryFilePath = Path.Combine(KeyVariable.SystemPath, "TemporaryFile");
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
if (item.FileType == "add")
{
MoveFile(temporaryFilePath + item.FileId, systemFilePath + item.FileId);
}
else if (item.FileType == "delete")
{
DeleteFile(systemFilePath + item.FileId);
}
}
}
}
/// <summary>
/// 删除附件.
/// </summary>
/// <param name="data"></param>
public static void DeleteFile(List<AnnexModel> data)
{
if (data != null && data.Count > 0)
{
string systemFilePath = KeyVariable.SystemPath;
foreach (AnnexModel item in data)
{
DeleteFile(systemFilePath + item.FileId);
}
}
}
#endregion
}

View File

@@ -0,0 +1,94 @@
using System.Security.Cryptography;
using System.Text;
namespace JNPF.Common.Security
{
/// <summary>
/// 字符串Hash操作类.
/// </summary>
public static class HashHelper
{
/// <summary>
/// 获取字符串的MD5哈希值默认编码为<see cref="Encoding.UTF8"/>.
/// </summary>
public static string GetMd5(string value, Encoding? encoding = null)
{
if (encoding == null)
encoding = Encoding.UTF8;
byte[] bytes = encoding.GetBytes(value);
return GetMd5(bytes);
}
/// <summary>
/// 获取字节数组的MD5哈希值.
/// </summary>
public static string GetMd5(byte[] bytes)
{
StringBuilder sb = new StringBuilder();
MD5 hash = MD5.Create();
bytes = hash.ComputeHash(bytes);
foreach (byte b in bytes)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
/// <summary>
/// 获取字符串的SHA1哈希值默认编码为<see cref="Encoding.UTF8"/>.
/// </summary>
public static string GetSha1(string value, Encoding? encoding = null)
{
StringBuilder sb = new StringBuilder();
SHA1 hash = SHA1.Create();
if (encoding == null)
encoding = Encoding.UTF8;
byte[] bytes = hash.ComputeHash(encoding.GetBytes(value));
foreach (byte b in bytes)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
/// <summary>
/// 获取字符串的Sha256哈希值默认编码为<see cref="Encoding.UTF8"/>.
/// </summary>
public static string GetSha256(string value, Encoding? encoding = null)
{
StringBuilder sb = new StringBuilder();
SHA256 hash = SHA256.Create();
if (encoding == null)
encoding = Encoding.UTF8;
byte[] bytes = hash.ComputeHash(encoding.GetBytes(value));
foreach (byte b in bytes)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
/// <summary>
/// 获取字符串的Sha512哈希值默认编码为<see cref="Encoding.UTF8"/>.
/// </summary>
public static string GetSha512(string value, Encoding? encoding = null)
{
StringBuilder sb = new StringBuilder();
SHA512 hash = SHA512.Create();
if (encoding == null)
encoding = Encoding.UTF8;
byte[] bytes = hash.ComputeHash(encoding.GetBytes(value));
foreach (byte b in bytes)
{
sb.AppendFormat("{0:x2}", b);
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,136 @@
using JNPF.JsonSerialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace JNPF.Common.Security;
/// <summary>
/// JsonHelper
/// 版 本V3.4.2
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 作 者JNPF开发平台组.
/// </summary>
public static class JsonHelper
{
/// <summary>
/// 序列化提供器.
/// </summary>
public static IJsonSerializerProvider _jsonSerializer = App.GetService(typeof(NewtonsoftJsonSerializerProvider), App.RootServices) as IJsonSerializerProvider;
/// <summary>
/// Object 转 JSON字符串.
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static string ToJsonString(this object obj)
{
return obj == null ? string.Empty : _jsonSerializer.Serialize(obj);
}
/// <summary>
/// Object 转 JSON字符串.
/// </summary>
/// <param name="obj"></param>
/// <param name="jsonSerializerOptions">序列化规则.</param>
/// <returns></returns>
public static string ToJsonString(this object obj, object jsonSerializerOptions = default)
{
return obj == null ? string.Empty : _jsonSerializer.Serialize(obj, jsonSerializerOptions);
}
/// <summary>
/// JSON 字符串转 Object.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json">对象.</param>
/// <returns></returns>
public static T ToObject<T>(this string json)
{
return _ = _jsonSerializer.Deserialize<T>(json) ?? default(T);
}
/// <summary>
/// JSON 字符串转 Object.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json">对象.</param>
/// <param name="jsonSerializerOptions">序列化规则.</param>
/// <returns></returns>
public static T ToObject<T>(this string json, object jsonSerializerOptions = default)
{
return _ = _jsonSerializer.Deserialize<T>(json, jsonSerializerOptions) ?? default(T);
}
/// <summary>
/// Object 转 对象.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json"></param>
/// <returns></returns>
public static T ToObject<T>(this object json)
{
return _ = ToJsonString(json).ToObject<T>() ?? default(T);
}
/// <summary>
/// Object 转 对象.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json"></param>
/// <param name="jsonSerializerOptions">序列化规则.</param>
/// <returns></returns>
public static T ToObject<T>(this object json, object jsonSerializerOptions = default)
{
return _ = ToJsonString(json, jsonSerializerOptions).ToObject<T>(jsonSerializerOptions) ?? default(T);
}
/// <summary>
/// 字符串转动态类型List.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json"></param>
/// <returns></returns>
public static List<T> ToList<T>(this string json)
{
return _ = _jsonSerializer.Deserialize<List<T>>(json) ?? null;
}
/// <summary>
/// 字符串转动态类型List.
/// </summary>
/// <typeparam name="T">动态类型.</typeparam>
/// <param name="json"></param>
/// <param name="jsonSerializerOptions">序列化规则.</param>
/// <returns></returns>
public static List<T> ToList<T>(this string json, object jsonSerializerOptions = default)
{
return _ = _jsonSerializer.Deserialize<List<T>>(json, jsonSerializerOptions) ?? null;
}
/// <summary>
/// 字符串 转 JObject.
/// </summary>
/// <param name="json">字符串.</param>
/// <returns></returns>
public static JObject ToObject(this string json)
{
return json == null ? JObject.Parse("{}") : JObject.Parse(json.Replace("&nbsp;", string.Empty));
}
/// <summary>
/// 字符串 转 JSON.
/// </summary>
/// <param name="json">字符串.</param>
/// <returns></returns>
public static string PraseToJson(string json)
{
JsonSerializer s = new JsonSerializer();
JsonReader reader = new JsonTextReader(new StringReader(json));
object jsonObject = s.Deserialize(reader);
StringWriter sWriter = new StringWriter();
JsonWriter writer = new JsonTextWriter(sWriter);
writer.Formatting = Formatting.Indented;
s.Serialize(writer, jsonObject);
return sWriter.ToString();
}
}

View File

@@ -0,0 +1,367 @@
using System.Diagnostics;
using System.Management;
using System.Runtime.InteropServices;
using JNPF.Common.Model.Machine;
using JNPF.DependencyInjection;
namespace JNPF.Common.Security;
/// <summary>
/// 获取服务器信息.
/// </summary>
[SuppressSniffer]
public static class MachineHelper
{
#region Linux
/// <summary>
/// 系统信息.
/// </summary>
/// <returns></returns>
public static SystemInfoModel GetSystemInfo_Linux()
{
try
{
var systemInfo = new SystemInfoModel();
var process = new Process
{
StartInfo = new ProcessStartInfo("ifconfig")
{
RedirectStandardOutput = true,
UseShellExecute = false
}
};
process.Start();
var hddInfo = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Dispose();
process.Close();
var lines = hddInfo.Split('\n');
foreach (var item in lines)
{
if (item.Contains("inet"))
{
var li = item.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
systemInfo.ip = li[1];
break;
}
}
TimeSpan P_TimeSpan = DateTime.Now.Subtract(DateTime.Now);
systemInfo.os = RuntimeInformation.OSDescription;
systemInfo.day = FormatTime((long)(DateTimeOffset.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds);
return systemInfo;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// CPU信息
/// </summary>
/// <returns></returns>
public static CpuInfoModel GetCpuInfo_Linux()
{
var cpuInfo = new CpuInfoModel();
cpuInfo.core = Environment.ProcessorCount + "个物理核心";
cpuInfo.logic = Environment.ProcessorCount + "个逻辑CPU";
cpuInfo.package = Environment.ProcessorCount + "个物理CPU";
cpuInfo.coreNumber = Environment.ProcessorCount;
var cpuInfoList = (File.ReadAllText(@"/proc/cpuinfo")).Split(' ').Where(o => o != string.Empty).ToList();
cpuInfo.name = string.Format("{0} {1} {2}", cpuInfoList[7], cpuInfoList[8], cpuInfoList[9]);
var psi = new ProcessStartInfo("top", " -b -n 1") { RedirectStandardOutput = true };
var proc = Process.Start(psi);
if (proc == null)
{
return cpuInfo;
}
else
{
using (var sr = proc.StandardOutput)
{
var index = 0;
while (!sr.EndOfStream)
{
if (index == 2)
{
GetCpuUsed(sr.ReadLine(), cpuInfo);
break;
}
sr.ReadLine();
index++;
}
if (!proc.HasExited)
{
proc.Kill();
}
}
}
return cpuInfo;
}
/// <summary>
/// 硬盘信息.
/// </summary>
/// <returns></returns>
public static DiskInfoModel GetDiskInfo_Linux()
{
var output = new DiskInfoModel();
var process = new Process
{
StartInfo = new ProcessStartInfo("df", "-h /")
{
RedirectStandardOutput = true,
UseShellExecute = false
}
};
process.Start();
var hddInfo = process.StandardOutput.ReadToEnd();
process.WaitForExit();
process.Dispose();
var lines = hddInfo.Split('\n');
foreach (var item in lines)
{
if (item.Contains("/dev/sda4") || item.Contains("/dev/mapper/cl-root") || item.Contains("/dev/mapper/centos-root"))
{
var li = item.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < li.Length; i++)
{
if (li[i].Contains("%"))
{
output = new DiskInfoModel()
{
total = li[i - 3],
used = li[i - 2],
available = li[i - 1],
usageRate = li[i].Replace("%", string.Empty)
};
break;
}
}
}
}
return output;
}
/// <summary>
/// 内存信息.
/// </summary>
/// <returns></returns>
public static MemoryInfoModel GetMemoryInfo_Linux()
{
var output = new MemoryInfoModel();
const string CPU_FILE_PATH = "/proc/meminfo";
var mem_file_info = File.ReadAllText(CPU_FILE_PATH);
var lines = mem_file_info.Split(new[] { '\n' });
int count = 0;
foreach (var item in lines)
{
if (item.StartsWith("MemTotal:"))
{
count++;
var tt = item.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
output.total = tt[1].Trim();
}
else if (item.StartsWith("MemAvailable:"))
{
count++;
var tt = item.Split(new[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
output.available = tt[1].Trim();
}
if (count >= 2) break;
}
long total = long.Parse(output.total.Replace(" kB", string.Empty));
long available = long.Parse(output.available.Replace(" kB", string.Empty));
long used = total - available;
decimal usageRate = (decimal)used / (decimal)total;
output.usageRate = (Math.Round(usageRate, 2, MidpointRounding.AwayFromZero) * 100).ToString();
output.used = used.ToString() + " kB";
return output;
}
/// <summary>
/// 获取cpu使用率.
/// </summary>
/// <param name="cpuInfo">%Cpu(s): 3.2 us, 0.0 sy, 0.0 ni, 96.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st.</param>
/// <param name="cpuOutput"></param>
private static void GetCpuUsed(string cpuInfo, CpuInfoModel cpuOutput)
{
try
{
var str = cpuInfo.Replace("%Cpu(s):", string.Empty).Trim();
var list = str.Split(",").ToList();
var dic = new Dictionary<string, string>();
foreach (var item in list)
{
var key = item.Substring(item.Length - 2, 2);
dic[key] = item.Replace(key, string.Empty);
}
cpuOutput.used = dic["us"];
cpuOutput.idle = dic["id"];
}
catch (Exception)
{
}
}
#endregion
#region Windows
/// <summary>
/// 系统信息.
/// </summary>
/// <returns></returns>
public static SystemInfoModel GetSystemInfo_Windows()
{
try
{
var systemInfo = new SystemInfoModel();
ManagementClass MC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection MOC = MC.GetInstances();
foreach (ManagementObject MO in MOC)
{
if ((bool)MO["IPEnabled"] == true)
{
string[] IPAddresses = (string[])MO["IPAddress"]; //获取本地的IP地址
if (IPAddresses.Length > 0)
systemInfo.ip = IPAddresses[0];
}
}
systemInfo.day = FormatTime((long)(DateTimeOffset.Now - Process.GetCurrentProcess().StartTime).TotalMilliseconds);
return systemInfo;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// CPU信息
/// </summary>
/// <returns></returns>
public static CpuInfoModel GetCpuInfo_Windows()
{
var cpuInfo = new CpuInfoModel();
ManagementObjectSearcher mos = new ManagementObjectSearcher("Select * from Win32_Processor");
foreach (ManagementObject mo in mos.Get())
{
cpuInfo.name = mo["Name"].ToString();
cpuInfo.coreNumber = int.Parse(mo["NumberOfCores"].ToString());
cpuInfo.core = mo["NumberOfCores"].ToString() + "个物理核心";
}
foreach (var item in new ManagementObjectSearcher("Select * from Win32_ComputerSystem").Get())
{
cpuInfo.package = item["NumberOfProcessors"].ToString() + "个物理CPU";
cpuInfo.logic = item["NumberOfLogicalProcessors"].ToString() + "个逻辑CPU";
}
PerformanceCounter oPerformanceCounter = new PerformanceCounter("Processor", "% Processor Time", "_Total");
cpuInfo.used = Math.Round((decimal)oPerformanceCounter.NextValue(), 2, MidpointRounding.AwayFromZero).ToString();
cpuInfo.idle = (100 - Convert.ToDouble(oPerformanceCounter.NextValue().ToString())).ToString() + "%";
return cpuInfo;
}
/// <summary>
/// 硬盘信息.
/// </summary>
/// <returns></returns>
public static DiskInfoModel GetDiskInfo_Windows()
{
var output = new DiskInfoModel();
long total = 0L;
long available = 0L;
foreach (var item in new ManagementObjectSearcher("Select * from win32_logicaldisk").Get())
{
available += Convert.ToInt64(item["FreeSpace"]);
total += Convert.ToInt64(item["Size"]);
}
long used = total - available;
decimal usageRate = (decimal)used / (decimal)total;
output.total = (total / (1024 * 1024 * 1024)).ToString() + "G";
output.available = (available / (1024 * 1024 * 1024)).ToString() + "G";
output.used = (used / (1024 * 1024 * 1024)).ToString() + "G";
output.usageRate = Math.Round(usageRate, 2, MidpointRounding.AwayFromZero).ToString();
return output;
}
/// <summary>
/// 内存信息.
/// </summary>
/// <returns></returns>
public static MemoryInfoModel GetMemoryInfo_Windows()
{
var output = new MemoryInfoModel();
#region
long bcs = 1024 * 1024 * 1024;
long total = 0;
long available = 0;
long used = 0;
double usageRate = 0.00;
ManagementClass mc = new ManagementClass("Win32_ComputerSystem");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
total = Convert.ToInt64(mo["TotalPhysicalMemory"]);
}
foreach (var item in new ManagementObjectSearcher("Select * from Win32_OperatingSystem").Get())
{
available = Convert.ToInt64(item["FreePhysicalMemory"]);
}
used = total - available;
usageRate = used / total;
output.total = (total / bcs).ToString() + "G";
output.available = (available / bcs).ToString() + "G";
output.used = (used / bcs).ToString() + "G";
output.usageRate = Math.Round((decimal)usageRate, 2, MidpointRounding.AwayFromZero).ToString();
#endregion
return output;
}
/// <summary>
/// 毫秒转天时分秒.
/// </summary>
/// <param name="ms"></param>
/// <returns></returns>
private static string FormatTime(long ms)
{
int ss = 1000;
int mi = ss * 60;
int hh = mi * 60;
int dd = hh * 24;
long day = ms / dd;
long hour = (ms - day * dd) / hh;
long minute = (ms - day * dd - hour * hh) / mi;
long second = (ms - day * dd - hour * hh - minute * mi) / ss;
string sDay = day < 10 ? "0" + day : string.Empty + day; // 天
string sHour = hour < 10 ? "0" + hour : string.Empty + hour; // 小时
string sMinute = minute < 10 ? "0" + minute : string.Empty + minute; // 分钟
string sSecond = second < 10 ? "0" + second : string.Empty + second; // 秒
return string.Format("{0} 天 {1} 小时 {2} 分 {3} 秒", sDay, sHour, sMinute, sSecond);
}
#endregion
}

View File

@@ -0,0 +1,135 @@
using System.Net.NetworkInformation;
using System.Text;
using JNPF.DependencyInjection;
using JNPF.JsonSerialization;
using JNPF.RemoteRequest.Extensions;
using Microsoft.AspNetCore.Http;
namespace JNPF.Common.Security;
/// <summary>
/// 网络操作
/// 版 本V3.0.0
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 作 者JNPF开发平台组.
/// </summary>
[SuppressSniffer]
public static class NetHelper
{
#region Ip(Ip)
/// <summary>
/// 获取Ip.
/// </summary>
public static string Ip
{
get
{
string result = string.Empty;
if (App.HttpContext != null)
result = GetWebClientIp();
return result.Equals("::1") ? "127.0.0.1" : result;
}
}
/// <summary>
/// 请求Url.
/// </summary>
public static string Url
{
get
{
return new StringBuilder().Append(App.HttpContext?.Request?.Scheme).Append("://")
.Append(App.HttpContext?.Request?.Host).Append(App.HttpContext?.Request?.PathBase)
.Append(App.HttpContext?.Request?.Path).Append(App.HttpContext?.Request?.QueryString).ToString();
}
}
/// <summary>
/// 得到客户端IP地址.
/// </summary>
/// <returns></returns>
private static string GetWebClientIp()
{
HttpContext httpContext = App.HttpContext;
string ip = httpContext?.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (string.IsNullOrEmpty(ip))
{
ip = App.HttpContext.Connection.RemoteIpAddress.ToString();
}
return ip;
}
#endregion
#region mac地址
/// <summary>
/// 返回描述本地计算机上的网络接口的对象(网络接口也称为网络适配器).
/// </summary>
/// <returns></returns>
public static NetworkInterface[] NetCardInfo()
{
return NetworkInterface.GetAllNetworkInterfaces();
}
/// <summary>
/// 通过NetworkInterface读取网卡Mac.
/// </summary>
/// <returns></returns>
public static List<string> GetMacByNetworkInterface()
{
List<string> macs = new List<string>();
NetworkInterface[] interfaces = NetworkInterface.GetAllNetworkInterfaces();
foreach (NetworkInterface ni in interfaces)
{
macs.Add(ni.GetPhysicalAddress().ToString());
}
return macs;
}
#endregion
#region Ip城市(Ip城市)
/// <summary>
/// 获取IP地址信息.
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static async Task<string> GetLocation(string ip)
{
string res = string.Empty;
try
{
string url = string.Format("https://sp0.baidu.com/8aQDcjqpAAV3otqbppnN2DJv/api.php?query={0}&resource_id=6006&ie=utf8&oe=gbk&format=json", ip);
string result = await url.GetAsStringAsync();
dataone? resJson = result.ToObject<obj>().data.FirstOrDefault();
string data = resJson?.location;
res = data != null ? data.Split(' ')[0] : "本地局域网";
}
catch
{
res = string.Empty;
}
return res;
}
/// <summary>
/// 百度接口.
/// </summary>
public class obj
{
public List<dataone>? data { get; set; }
}
public class dataone
{
public string? location { get; set; }
}
#endregion
}

View File

@@ -0,0 +1,77 @@
using Aspose.Cells;
using JNPF.DependencyInjection;
using Spire.Presentation;
namespace JNPF.Common.Security;
/// <summary>
/// PDF帮助类.
/// </summary>
[SuppressSniffer]
public class PDFHelper
{
/// <summary>
/// Aspose组件Excel转成pdf文件.
/// </summary>
/// <param name="fileName">word文件路径.</param>
public static void AsposeExcelToPDF(string fileName)
{
try
{
string pdfSavePath = fileName.Substring(0, fileName.LastIndexOf(".")) + ".pdf";
if (!FileHelper.IsExistFile(pdfSavePath))
{
Workbook excel = new Workbook(fileName);
if (excel != null)
excel.Save(pdfSavePath, SaveFormat.Pdf);
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// Aspose组件word转成pdf文件.
/// </summary>
/// <param name="fileName">word文件路径.</param>
public static void AsposeWordToPDF(string fileName)
{
try
{
string pdfSavePath = fileName.Substring(0, fileName.LastIndexOf(".")) + ".pdf";
if (!FileHelper.IsExistFile(pdfSavePath))
{
var document = new Aspose.Words.Document(fileName);
if (document != null)
document.Save(pdfSavePath, Aspose.Words.SaveFormat.Pdf);
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// PPT转换PDF.
/// </summary>
/// <param name="fileName">文件名称.</param>
public static void PPTToPDF(string fileName)
{
try
{
if (!FileHelper.IsExistFile(fileName.Substring(0, fileName.LastIndexOf(".")) + ".pdf"))
{
Presentation presentation = new Presentation();
presentation.LoadFromFile(fileName);
presentation.SaveToFile(fileName.Substring(0, fileName.LastIndexOf(".")) + ".pdf", FileFormat.PDF);
}
}
catch (Exception)
{
throw;
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,132 @@
using JNPF.DependencyInjection;
using System.Data;
using System.Reflection;
namespace JNPF.Common.Security;
/// <summary>
/// 树形结构查询
/// 版 本V3.2.0
/// 版 权拓通智联科技有限公司http://www.tuotong-tech.com
/// 作 者JNPF开发平台组.
/// </summary>
[SuppressSniffer]
public static class QueryTreeHelper
{
/// <summary>
/// 递归查询.
/// </summary>
/// <typeparam name="T">输出模型.</typeparam>
/// <param name="data">数据源.</param>
/// <param name="condition">查询条件.</param>
/// <param name="idSelector">主键.</param>
/// <param name="parentIdSelector">上级.</param>
/// <returns></returns>
public static List<T> TreeWhere<T>(this List<T> data, Predicate<T> condition, Func<T, string> idSelector, Func<T, string> parentIdSelector)
{
List<T> locateList = data.FindAll(condition);
List<T> treeList = new List<T>();
foreach (T entity in locateList)
{
treeList.Add(entity);
T currentNode = entity;
while (true)
{
string parentId = parentIdSelector(currentNode);
if (parentId == null)
break;
T upRecord = data.Find(a => idSelector(a) == parentId);
if (upRecord != null)
{
treeList.Add(upRecord);
currentNode = upRecord;
}
else
{
break;
}
}
}
return treeList.Distinct().ToList();
}
/// <summary>
/// 递归查询.
/// </summary>
/// <param name="data">数据源.</param>
/// <param name="condition">查询条件.</param>
/// <param name="idSelector">主键.</param>
/// <param name="parentIdSelector">上级.</param>
/// <returns></returns>
public static DataTable TreeWhere(this DataTable data, string condition, string idSelector = "F_Id", string parentIdSelector = "F_ParentId")
{
DataRow[] drs = data.Select(condition);
DataTable treeTable = data.Clone();
foreach (DataRow dr in drs)
{
treeTable.ImportRow(dr);
string pId = dr[parentIdSelector].ToString();
while (true)
{
if (string.IsNullOrEmpty(pId) && pId == "0")
break;
DataRow[] pdrs = data.Select(idSelector + "='" + pId + "'");
if (pdrs.Length > 0)
{
treeTable.ImportRow(pdrs[0]);
pId = pdrs[0][parentIdSelector].ToString();
}
else
{
break;
}
}
}
return treeTable.DefaultView.ToTable(true);
}
/// <summary>
/// 获取全部子节点.
/// </summary>
/// <typeparam name="T">输出模型.</typeparam>
/// <param name="data">数据源.</param>
/// <param name="idValue">主键值.</param>
/// <param name="idSelector">主键.</param>
/// <param name="parentIdSelector">上级.</param>
/// <returns></returns>
public static List<T> TreeChildNode<T>(this List<T> data, string idValue, Func<T, string> idSelector, Func<T, string> parentIdSelector)
{
T thisEntity = data.Find(a => idSelector(a) == idValue);
foreach (var prop in from PropertyInfo prop in thisEntity.GetType().GetProperties()
where prop.Name == "ParentId" || prop.Name == "parentId"
select prop)
{
prop.SetValue(thisEntity, "0", null);
break;
}
List<T> treeList = new List<T>();
treeList.Add(thisEntity);
ChildNode(data, idValue, idSelector, parentIdSelector, ref treeList);
return treeList;
}
#region Method
private static void ChildNode<T>(this List<T> data, string idValue, Func<T, string> idSelector, Func<T, string> parentIdSelector, ref List<T> treeNodes)
{
List<T> locateList = data.FindAll(a => parentIdSelector(a) == idValue);
if (locateList.Count > 0)
{
foreach (var item in locateList)
{
treeNodes.Add(item);
ChildNode(data, idSelector(item), idSelector, parentIdSelector, ref treeNodes);
}
}
}
#endregion
}

View File

@@ -0,0 +1,24 @@
using System.Reflection;
namespace JNPF.Common.Security;
/// <summary>
/// 反射帮助类.
/// </summary>
public static class ReflectionHelper
{
/// <summary>
/// 获取字段特性.
/// </summary>
/// <param name="field"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T GetDescriptionValue<T>(this FieldInfo field) where T : Attribute
{
// 获取字段的指定特性,不包含继承中的特性
object[] customAttributes = field.GetCustomAttributes(typeof(T), false);
// 如果没有数据返回null
return customAttributes.Length > 0 ? (T)customAttributes[0] : null;
}
}

View File

@@ -0,0 +1,67 @@
using System.Runtime.InteropServices;
using JNPF.Common.Cache;
using Yitter.IdGenerator;
namespace JNPF.Common.Security;
/// <summary>
/// 分布式雪花ID帮助类.
/// </summary>
public class SnowflakeIdHelper
{
// 定义dll路径
public const string RegWorkerId_DLL_NAME = "lib\\regworkerid_lib_v1.3.1\\yitidgengo.dll";
// 根据文档定义三个接口
// 注册一个 WorkerId会先注销所有本机已注册的记录
// ip: redis 服务器地址
// port: redis 端口
// password: redis 访问密码,可为空字符串“”
// maxWorkerId: 最大 WorkerId
[DllImport(RegWorkerId_DLL_NAME, EntryPoint = "RegisterOne", CallingConvention = CallingConvention.Cdecl, ExactSpelling = false)]
private static extern ushort RegisterOne(string ip, int port, string password, int maxWorkerId);
// 注销本机已注册的 WorkerId
[DllImport(RegWorkerId_DLL_NAME, EntryPoint = "UnRegister", CallingConvention = CallingConvention.Cdecl, ExactSpelling = false)]
private static extern void UnRegister();
// 检查本地WorkerId是否有效0-有效,其它-无效)
[DllImport(RegWorkerId_DLL_NAME, EntryPoint = "Validate", CallingConvention = CallingConvention.Cdecl, ExactSpelling = false)]
private static extern int Validate(int workerId);
/// <summary>
/// 缓存配置.
/// </summary>
private static CacheOptions _cacheOptions = App.GetConfig<CacheOptions>("Cache", true);
/// <summary>
/// 生成ID.
/// </summary>
/// <returns></returns>
public static string NextId()
{
// 这个if判断在高并发的情况下可能会有问题
if (YitIdHelper.IdGenInstance == null)
{
UnRegister();
// 如果不用自动注册WorkerId的话直接传一个数值就可以了
var workerId = RegisterOne(_cacheOptions.ip, _cacheOptions.port, _cacheOptions.password, 63);
// 创建 IdGeneratorOptions 对象,可在构造函数中输入 WorkerId
var options = new IdGeneratorOptions(workerId);
options.WorkerIdBitLength = 16; // 默认值6限定 WorkerId 最大值为2^6-1即默认最多支持64个节点。
options.SeqBitLength = 6; // 默认值6限制每毫秒生成的ID个数。若生成速度超过5万个/秒,建议加大 SeqBitLength 到 10。
// options.BaseTime = Your_Base_Time; // 如果要兼容老系统的雪花算法此处应设置为老系统的BaseTime。
// ...... 其它参数参考 IdGeneratorOptions 定义。
// 保存参数(务必调用,否则参数设置不生效):
YitIdHelper.SetIdGenerator(options);
// 以上过程只需全局一次且应在生成ID之前完成。
}
return YitIdHelper.NextId().ToString();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,145 @@
using JNPF.Common.Extension;
using JNPF.DependencyInjection;
namespace JNPF.Common.Security;
/// <summary>
/// 树结构帮助类.
/// </summary>
[SuppressSniffer]
public static class TreeHelper
{
/// <summary>
/// 建造树结构.
/// </summary>
/// <param name="allNodes">所有的节点.</param>
/// <param name="parentId">节点.</param>
/// <returns></returns>
public static List<T> ToTree<T>(this List<T> allNodes, string parentId = "0")
where T : TreeModel, new()
{
List<T> resData = new List<T>();
// 查找出父类对象
List<T> rootNodes = allNodes.FindAll(x => x.parentId == parentId || x.parentId.IsNullOrEmpty());
// 移除父类对象
allNodes.RemoveAll(x => x.parentId == parentId || x.parentId.IsNullOrEmpty());
resData = rootNodes;
resData.ForEach(aRootNode =>
{
aRootNode.hasChildren = HaveChildren(allNodes, aRootNode.id);
if (aRootNode.hasChildren)
{
aRootNode.children = _GetChildren(allNodes, aRootNode);
aRootNode.num = aRootNode.children.Count();
}
else
{
aRootNode.isLeaf = !aRootNode.hasChildren;
aRootNode.children = null;
}
});
return resData;
}
#region
/// <summary>
/// 获取所有子节点.
/// </summary>
/// <typeparam name="T">树模型TreeModel或继承它的模型.</typeparam>
/// <param name="nodes">所有节点列表.</param>
/// <param name="parentNode">父节点Id.</param>
/// <returns></returns>
private static List<object> _GetChildren<T>(List<T> nodes, T parentNode)
where T : TreeModel, new()
{
Type type = typeof(T);
var properties = type.GetProperties().ToList();
List<object> resData = new List<object>();
// 查找出父类对象
var children = nodes.FindAll(x => x.parentId == parentNode.id);
// 移除父类对象
nodes.RemoveAll(x => x.parentId == parentNode.id);
children.ForEach(aChildren =>
{
T newNode = new T();
resData.Add(newNode);
// 赋值属性
foreach (var aProperty in properties.Where(x => x.CanWrite))
{
var value = aProperty.GetValue(aChildren, null);
aProperty.SetValue(newNode, value);
}
newNode.hasChildren = HaveChildren(nodes, aChildren.id);
if (newNode.hasChildren)
{
newNode.children = _GetChildren(nodes, newNode);
}
else
{
newNode.isLeaf = !newNode.hasChildren;
newNode.children = null;
}
});
return resData;
}
/// <summary>
/// 判断当前节点是否有子节点.
/// </summary>
/// <typeparam name="T">树模型.</typeparam>
/// <param name="nodes">所有节点.</param>
/// <param name="nodeId">当前节点Id.</param>
/// <returns></returns>
private static bool HaveChildren<T>(List<T> nodes, string nodeId)
where T : TreeModel, new()
{
return nodes.Exists(x => x.parentId == nodeId);
}
#endregion
}
/// <summary>
/// 树模型基类.
/// </summary>
public class TreeModel
{
/// <summary>
/// 获取节点id.
/// </summary>
/// <returns></returns>
public string id { get; set; }
/// <summary>
/// 获取节点父id.
/// </summary>
/// <returns></returns>
public string parentId { get; set; }
/// <summary>
/// 是否有子级.
/// </summary>
public bool hasChildren { get; set; }
/// <summary>
/// 设置Children.
/// </summary>
public List<object>? children { get; set; } = new List<object>();
/// <summary>
/// 子节点数量.
/// </summary>
public int num { get; set; }
/// <summary>
/// 是否为子节点.
/// </summary>
public bool isLeaf { get; set; } = false;
}

View File

@@ -0,0 +1,34 @@
using System.Xml.Serialization;
namespace JNPF.Common.Security;
public static class XmlHelper
{
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type">类型</param>
/// <param name="xml">XML字符串</param>
/// <returns></returns>
public static object Deserialize(Type type, string xml)
{
using (StringReader sr = new StringReader(xml))
{
XmlSerializer xmldes = new XmlSerializer(type);
return xmldes.Deserialize(sr);
}
}
/// <summary>
/// 反序列化
/// </summary>
/// <param name="type"></param>
/// <param name="xml"></param>
/// <returns></returns>
public static object Deserialize(Type type, Stream stream)
{
XmlSerializer xmldes = new XmlSerializer(type);
return xmldes.Deserialize(stream);
}
}