添加项目文件。
This commit is contained in:
20
common/Tnb.Common/Security/CodeGenAuthorizeHelper.cs
Normal file
20
common/Tnb.Common/Security/CodeGenAuthorizeHelper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
305
common/Tnb.Common/Security/CodeGenExportDataHelper.cs
Normal file
305
common/Tnb.Common/Security/CodeGenExportDataHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
271
common/Tnb.Common/Security/CodeGenHelper.cs
Normal file
271
common/Tnb.Common/Security/CodeGenHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
71
common/Tnb.Common/Security/ComparisonHelper.cs
Normal file
71
common/Tnb.Common/Security/ComparisonHelper.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
62
common/Tnb.Common/Security/EqualityHelper.cs
Normal file
62
common/Tnb.Common/Security/EqualityHelper.cs
Normal 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
1171
common/Tnb.Common/Security/ExcelExportHelper.cs
Normal file
1171
common/Tnb.Common/Security/ExcelExportHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
161
common/Tnb.Common/Security/ExcelImportHelper.cs
Normal file
161
common/Tnb.Common/Security/ExcelImportHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
829
common/Tnb.Common/Security/FileHelper.cs
Normal file
829
common/Tnb.Common/Security/FileHelper.cs
Normal 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 获取文件大小并以B,KB,GB,TB
|
||||
|
||||
/// <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
|
||||
}
|
||||
94
common/Tnb.Common/Security/HashHelper.cs
Normal file
94
common/Tnb.Common/Security/HashHelper.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
136
common/Tnb.Common/Security/JsonHelper.cs
Normal file
136
common/Tnb.Common/Security/JsonHelper.cs
Normal 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(" ", 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();
|
||||
}
|
||||
}
|
||||
367
common/Tnb.Common/Security/MachineHelper.cs
Normal file
367
common/Tnb.Common/Security/MachineHelper.cs
Normal 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
|
||||
}
|
||||
135
common/Tnb.Common/Security/NetHelper.cs
Normal file
135
common/Tnb.Common/Security/NetHelper.cs
Normal 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
|
||||
}
|
||||
77
common/Tnb.Common/Security/PDFHelper.cs
Normal file
77
common/Tnb.Common/Security/PDFHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
271
common/Tnb.Common/Security/PinyinHelper.cs
Normal file
271
common/Tnb.Common/Security/PinyinHelper.cs
Normal file
File diff suppressed because one or more lines are too long
132
common/Tnb.Common/Security/QueryTreeHelper.cs
Normal file
132
common/Tnb.Common/Security/QueryTreeHelper.cs
Normal 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
|
||||
}
|
||||
24
common/Tnb.Common/Security/ReflectionHelper.cs
Normal file
24
common/Tnb.Common/Security/ReflectionHelper.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
67
common/Tnb.Common/Security/SnowflakeIdHelper.cs
Normal file
67
common/Tnb.Common/Security/SnowflakeIdHelper.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
1107
common/Tnb.Common/Security/SuperQueryHelper.cs
Normal file
1107
common/Tnb.Common/Security/SuperQueryHelper.cs
Normal file
File diff suppressed because it is too large
Load Diff
145
common/Tnb.Common/Security/TreeHelper.cs
Normal file
145
common/Tnb.Common/Security/TreeHelper.cs
Normal 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;
|
||||
}
|
||||
34
common/Tnb.Common/Security/XmlHelper.cs
Normal file
34
common/Tnb.Common/Security/XmlHelper.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user