配置文件升级+修改(重要更新!)

This commit is contained in:
赵正易 2025-06-09 09:22:59 +08:00
parent a548d8f3f2
commit d111c8c2c0
27 changed files with 1880 additions and 1 deletions

View File

@ -0,0 +1,13 @@
using AutoMapper;
namespace ZR.Admin.WebApi.AutoMapperProfile
{
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
}
}
}

View File

@ -0,0 +1,211 @@
using Infrastructure;
using Infrastructure.Extensions;
using Infrastructure.Model;
using Microsoft.AspNetCore.Mvc;
using MiniExcelLibs;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Web;
using Io = System.IO;
namespace WebApi.Controllers
{
public class BaseController : ControllerBase
{
public static string TIME_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";
/// <summary>
/// 返回成功封装
/// </summary>
/// <param name="data"></param>
/// <param name="timeFormatStr"></param>
/// <returns></returns>
protected IActionResult SUCCESS(object data, string timeFormatStr = "yyyy-MM-dd HH:mm:ss")
{
string jsonStr = GetJsonStr(GetApiResult(data != null ? ResultCode.SUCCESS : ResultCode.NO_DATA, data), timeFormatStr);
return Content(jsonStr, "application/json");
}
/// <summary>
/// json输出带时间格式的
/// </summary>
/// <param name="apiResult"></param>
/// <returns></returns>
protected IActionResult ToResponse(ApiResult apiResult)
{
string jsonStr = GetJsonStr(apiResult, TIME_FORMAT_FULL);
return Content(jsonStr, "application/json");
}
protected IActionResult ToResponse(long rows, string timeFormatStr = "yyyy-MM-dd HH:mm:ss")
{
string jsonStr = GetJsonStr(ToJson(rows), timeFormatStr);
return Content(jsonStr, "application/json");
}
protected IActionResult ToResponse(ResultCode resultCode, string msg = "")
{
return ToResponse(new ApiResult((int)resultCode, msg));
}
/// <summary>
/// 导出Excel
/// </summary>
/// <param name="path">完整文件路径</param>
/// <param name="fileName">带扩展文件名</param>
/// <returns></returns>
protected IActionResult ExportExcel(string path, string fileName)
{
//var webHostEnvironment = App.WebHostEnvironment;
if (!Path.Exists(path))
{
throw new CustomException(fileName + "文件不存在");
}
var stream = Io.File.OpenRead(path); //创建文件流
Response.Headers.Add("Access-Control-Expose-Headers", "Content-Disposition");
return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", HttpUtility.UrlEncode(fileName));
// return File(stream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",fileName);
}
#region
/// <summary>
/// 响应返回结果
/// </summary>
/// <param name="rows">受影响行数</param>
/// <param name="data"></param>
/// <returns></returns>
protected ApiResult ToJson(long rows, object? data = null)
{
return rows > 0 ? ApiResult.Success("success", data) : GetApiResult(ResultCode.FAIL);
}
/// <summary>
/// 全局Code使用
/// </summary>
/// <param name="resultCode"></param>
/// <param name="data"></param>
/// <returns></returns>
protected ApiResult GetApiResult(ResultCode resultCode, object? data = null)
{
var msg = resultCode.GetDescription();
return new ApiResult((int)resultCode, msg, data);
}
/// <summary>
///
/// </summary>
/// <param name="apiResult"></param>
/// <param name="timeFormatStr"></param>
/// <returns></returns>
private static string GetJsonStr(ApiResult apiResult, string timeFormatStr)
{
if (string.IsNullOrEmpty(timeFormatStr))
{
timeFormatStr = TIME_FORMAT_FULL;
}
var serializerSettings = new JsonSerializerSettings
{
// 设置为驼峰命名
ContractResolver = new CamelCasePropertyNamesContractResolver(),
DateFormatString = timeFormatStr
};
return JsonConvert.SerializeObject(apiResult, Formatting.Indented, serializerSettings);
}
#endregion
/// <summary>
/// 导出Excel
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="sheetName"></param>
/// <param name="fileName"></param>
protected string ExportExcel<T>(List<T> list, string sheetName, string fileName)
{
return ExportExcelMini(list, sheetName, fileName).Item1;
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <param name="sheetName"></param>
/// <param name="fileName"></param>
/// <returns></returns>
protected (string, string) ExportExcelMini<T>(List<T> list, string sheetName, string fileName)
{
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}{DateTime.Now:MM-dd-HHmmss}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
MiniExcel.SaveAs(fullPath, list, sheetName: sheetName);
return (sFileName, fullPath);
}
/// <summary>
/// 导出多个工作表(Sheet)
/// </summary>
/// <param name="sheets"></param>
/// <param name="fileName"></param>
/// <returns></returns>
protected (string, string) ExportExcelMini(Dictionary<string, object> sheets, string fileName)
{
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}{DateTime.Now:MM-dd-HHmmss}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "export", sFileName);
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
MiniExcel.SaveAs(fullPath, sheets);
return (sFileName, fullPath);
}
/// <summary>
/// 下载导入模板
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
/// <param name="list">空数据类型集合</param>
/// <param name="fileName">下载文件名</param>
/// <returns></returns>
protected (string, string) DownloadImportTemplate<T>(List<T> list, string fileName)
{
IWebHostEnvironment webHostEnvironment = App.WebHostEnvironment;
string sFileName = $"{fileName}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
//不存在模板创建模板
if (!Directory.Exists(fullPath))
{
Directory.CreateDirectory(Path.GetDirectoryName(fullPath));
MiniExcel.SaveAs(fullPath, list, overwriteFile: true);
}
return (sFileName, fullPath);
}
/// <summary>
/// 下载指定文件模板
/// </summary>
/// <param name="fileName">下载文件名</param>
/// <returns></returns>
protected (string, string) DownloadImportTemplate(string fileName)
{
IWebHostEnvironment webHostEnvironment = (IWebHostEnvironment)App.ServiceProvider.GetService(typeof(IWebHostEnvironment));
string sFileName = $"{fileName}.xlsx";
string fullPath = Path.Combine(webHostEnvironment.WebRootPath, "ImportTemplate", sFileName);
return (sFileName, fullPath);
}
}
}

View File

@ -0,0 +1,243 @@
using Microsoft.AspNetCore.Mvc;
using ZR.Admin.WebApi.Extensions;
using ZR.Model.MES.wms;
using ZR.Model.MES.wms.Dto;
using ZR.Service.mes.wms.IService;
namespace WebApi.Controllers.mes.wms
{
/// <summary>
/// 入库模块
/// </summary>
[Route("/mes/wm/entrywarehouse")]
public class WMentryWarehousing_productController : BaseController
{
private readonly IWMentryWarehousing_productService wm_entryWarehousing_productService;
public WMentryWarehousing_productController(IWMentryWarehousing_productService wm_entryWarehousing_productService)
{
this.wm_entryWarehousing_productService = wm_entryWarehousing_productService;
}
/// <summary>
/// 1. 判断是否为库位码
/// </summary>
/// <returns></returns>
[HttpGet("is_production_location")]
[Log(Title = "判断是否为库位码")]
public IActionResult IsProductionLocation(string production_location_code = "")
{
if (string.IsNullOrEmpty(production_location_code))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
// 查询 wm_info 表根据库位码查询在表中是否存在true false
bool state = this.wm_entryWarehousing_productService.IsProductionLoacation(production_location_code);
return ToResponse(new ApiResult(200, "success", state));
}
/// <summary>
/// 2. 判断是否为成品库箱子码
/// </summary>
/// <returns></returns>
[HttpGet("is_production_package")]
[Log(Title = "判断是否为成品库箱子码")]
public IActionResult IsProductionPackage(string package_code = "")
{
if (string.IsNullOrEmpty(package_code))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
int state = this.wm_entryWarehousing_productService.isProductionPackage(package_code);
string msg = null;
if (state == 0)
msg = "外箱标签码不存在";
else if (state == 1)
msg = "success";
else if (state == 2)
msg = "误扫码,不是外箱标签码";
return ToResponse(new ApiResult(200, msg, state));
}
/// <summary>
/// 3.判断是否为满箱
/// </summary>
/// <returns></returns>
[HttpGet("is_full_package")]
[Log(Title = "判断是否为满箱")]
public IActionResult IsFullPackage(string package_code = "")
{
if (string.IsNullOrEmpty(package_code))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
bool state = this.wm_entryWarehousing_productService.isFullPackage(package_code);
string msg = null;
if (state)
{
msg = "满箱";
}
else
{
msg = "零头箱";
}
return ToResponse(new ApiResult(200, msg, state));
}
/// <summary>
/// 4.入库
/// </summary>
/// <param name="wmgoodsDto"></param>
/// <returns></returns>
[HttpPost("into_product_warehouse")]
[Log(Title = "入库")]
public IActionResult IntoProductwarehouse([FromBody] WmgoodsDto wmgoodsDto)
{
try
{
if (wmgoodsDto == null)
{
return ToResponse(new ApiResult(200, "传入参数为空", false));
}
string msg = "";
string createName = HttpContext.GetName();
int num = this.wm_entryWarehousing_productService.IntoProductwarehouse(wmgoodsDto, createName);
if (num == 0)
{
msg = "入库数为0";
}
else if (num >= 1)
{
msg = "成功入库" + num + "箱";
}
return ToResponse(new ApiResult(200, msg, num));
}
catch (Exception e)
{
return ToResponse(new ApiResult(500, e.Message, e.Message));
}
}
/// <summary>
/// 获取库位已经存在箱子
/// </summary>
/// <param name="locationcode"></param>
/// <returns></returns>
[HttpGet("packagelist")]
[Log(Title = "获取库位已经存在箱子")]
public IActionResult Getpackagelist(string locationcode)
{
if (string.IsNullOrEmpty(locationcode))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
string msg = null;
List<WmGoodsNowProduction> productionList = this.wm_entryWarehousing_productService.Getpackagelist(locationcode);
return ToResponse(new ApiResult(200, msg, productionList));
}
/// <summary>
/// 解析外标签码
/// </summary>
/// <param name="code"></param>
/// <returns></returns>
[HttpGet("resolution_package")]
public IActionResult ResolutionPackage(string code = "")
{
try
{
if (string.IsNullOrEmpty(code))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
ResultionPackageCodeDto data = this.wm_entryWarehousing_productService.ResolutionPackage(code);
if (data == null)
{
return ToResponse(new ApiResult(500, "外标签解析异常", data));
}
return ToResponse(new ApiResult(200, "success", data));
}
catch (Exception ex)
{
return ToResponse(new ApiResult(500, ex.Message, "外标签解析异常"));
}
;
}
/// <summary>
/// 7 判断箱子是否存在成品库仓库里
/// </summary>
/// <param name="PatchCode"></param>
/// <returns></returns>
[HttpGet("is_existed_warehouse")]
public IActionResult IsExistedWarehouse(string originalCode = "")
{
if (string.IsNullOrEmpty(originalCode))
{
return ToResponse(new ApiResult(200, "传入为空", false));
}
string msg = null;
bool data = this.wm_entryWarehousing_productService.IsExistedWarehouse(originalCode);
if (data)
{
msg = "存在";
}
else
{
msg = "不存在";
}
return ToResponse(new ApiResult(200, msg, data));
}
/// <summary>
/// all.判断标签扫描结果是否可入库(综合结果判断)
/// </summary>
/// <returns></returns>
[HttpGet("checkWarehousing")]
[Log(Title = "判断标签扫描结果是否可入库")]
public IActionResult CheckWarehousing(string production_packcode = "", string location = "",
bool isStrict = false)
{
string msg = this.wm_entryWarehousing_productService.checkWarehousing(production_packcode, location, isStrict);
if ("ok".Equals(msg))
{
// 可入库
return ToResponse(new ApiResult(200, msg, true));
}
else
{
// 不可入库
return ToResponse(new ApiResult(200, msg, false));
}
}
}
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using U8Server.Util;
using WebApi.Controllers;
namespace U8Server.Controllers.v1
{
[ApiController]
[Route("/v1/u8/auth")]
public class V1U8AuthController : BaseController
{
private readonly ILogger<V1U8AuthController> _logger;
public V1U8AuthController(ILogger<V1U8AuthController> logger)
{
_logger = logger;
}
[HttpGet(Name = "getMd5")]
[Log(Title = "»ñÈ¡md5ÃØÔ¿")]
public string GetMd5()
{
return GetSign.GetBy16Md5();
}
}
}

View File

@ -0,0 +1,24 @@
using Microsoft.AspNetCore.Mvc;
using U8Server.Util;
using WebApi.Controllers;
namespace U8Server.Controllers.v1
{
[ApiController]
[Route("/v1/u8/warehouse")]
public class V1U8WarehouseController : BaseController
{
private readonly ILogger<V1U8WarehouseController> _logger;
public V1U8WarehouseController(ILogger<V1U8WarehouseController> logger)
{
_logger = logger;
}
[HttpGet(Name = "getMd52")]
[Log(Title = "»ñÈ¡md5ÃØÔ¿")]
public string GetMd5()
{
return GetSign.GetBy16Md5();
}
}
}

View File

@ -0,0 +1,68 @@
using System.Reflection;
namespace ZR.Admin.WebApi.Extensions
{
/// <summary>
/// App服务注册
/// </summary>
public static class AppServiceExtensions
{
/// <summary>
/// 注册引用程序域中所有有AppService标记的类的服务
/// </summary>
/// <param name="services"></param>
public static void AddAppService(this IServiceCollection services)
{
var cls = AppSettings.Get<string[]>("InjectClass");
if (cls == null || cls.Length <= 0)
{
throw new Exception("请更新appsettings类");
}
foreach (var item in cls)
{
Register(services, item);
}
}
private static void Register(IServiceCollection services, string item)
{
Assembly assembly = Assembly.Load(item);
foreach (var type in assembly.GetTypes())
{
var serviceAttribute = type.GetCustomAttribute<AppServiceAttribute>();
if (serviceAttribute != null)
{
var serviceType = serviceAttribute.ServiceType;
//情况1 适用于依赖抽象编程,注意这里只获取第一个
if (serviceType == null && serviceAttribute.InterfaceServiceType)
{
serviceType = type.GetInterfaces().FirstOrDefault();
}
//情况2 不常见特殊情况下才会指定ServiceType写起来麻烦
if (serviceType == null)
{
serviceType = type;
}
switch (serviceAttribute.ServiceLifetime)
{
case LifeTime.Singleton:
services.AddSingleton(serviceType, type);
break;
case LifeTime.Scoped:
services.AddScoped(serviceType, type);
break;
case LifeTime.Transient:
services.AddTransient(serviceType, type);
break;
default:
services.AddTransient(serviceType, type);
break;
}
//System.Console.WriteLine($"注册:{serviceType}");
}
}
}
}
}

View File

@ -0,0 +1,27 @@
namespace ZR.Admin.WebApi.Extensions
{
public static class CorsExtension
{
/// <summary>
/// 跨域配置
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
public static void AddCors(this IServiceCollection services, IConfiguration configuration)
{
var corsUrls = configuration.GetSection("corsUrls").Get<string[]>();
//配置跨域
services.AddCors(c =>
{
c.AddPolicy("Policy", policy =>
{
policy.WithOrigins(corsUrls ?? Array.Empty<string>())
.AllowAnyHeader()//允许任意头
.AllowCredentials()//允许cookie
.AllowAnyMethod();//允许任意方法
});
});
}
}
}

View File

@ -0,0 +1,120 @@
using SqlSugar;
using SqlSugar.IOC;
using ZR.Admin.WebApi.Framework;
using ZR.Model.System;
namespace ZR.Admin.WebApi.Extensions
{
public enum DataPermiEnum
{
None = 0,
/// <summary>
/// 全部数据权限
/// </summary>
All = 1,
/// <summary>
/// 仅本人数据权限
/// </summary>
SELF = 5,
/// <summary>
/// 部门数据权限
/// </summary>
DEPT = 3,
/// <summary>
/// 自定数据权限
/// </summary>
CUSTOM = 2,
/// <summary>
/// 部门及以下数据权限
/// </summary>
DEPT_CHILD = 4
}
/// <summary>
/// 数据权限
/// </summary>
public class DataPermi
{
/// <summary>
/// 数据过滤
/// </summary>
/// <param name="configId">多库id</param>
public static void FilterData(int configId)
{
//获取当前用户的信息
var user = JwtUtil.GetLoginUser(App.HttpContext);
if (user == null) return;
//管理员不过滤
if (user.RoleIds.Any(f => f.Equals(GlobalConstant.AdminRole))) return;
var db = DbScoped.SugarScope.GetConnectionScope(configId);
var expUser = Expressionable.Create<SysUser>();
var expRole = Expressionable.Create<SysRole>();
var expLoginlog = Expressionable.Create<SysLogininfor>();
foreach (var role in user.Roles.OrderBy(f => f.DataScope))
{
var dataScope = (DataPermiEnum)role.DataScope;
if (DataPermiEnum.All.Equals(dataScope))//所有权限
{
break;
}
else if (DataPermiEnum.CUSTOM.Equals(dataScope))//自定数据权限
{
//" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
expUser.Or(it => SqlFunc.Subqueryable<SysRoleDept>().Where(f => f.DeptId == it.DeptId && f.RoleId == role.RoleId).Any());
}
else if (DataPermiEnum.DEPT.Equals(dataScope))//本部门数据
{
expUser.Or(it => it.DeptId == user.DeptId);
}
else if (DataPermiEnum.DEPT_CHILD.Equals(dataScope))//本部门及以下数据
{
//SQl OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )
var allChildDepts = db.Queryable<SysDept>().ToChildList(it => it.ParentId, user.DeptId);
expUser.Or(it => allChildDepts.Select(f => f.DeptId).ToList().Contains(it.DeptId));
}
else if (DataPermiEnum.SELF.Equals(dataScope))//仅本人数据
{
expUser.Or(it => it.UserId == user.UserId);
expRole.Or(it => user.RoleIds.Contains(it.RoleKey));
expLoginlog.And(it => it.UserName == user.UserName);
}
}
db.QueryFilter.AddTableFilter(expUser.ToExpression());
db.QueryFilter.AddTableFilter(expRole.ToExpression());
db.QueryFilter.AddTableFilter(expLoginlog.ToExpression());
}
public static void FilterData1(int configId)
{
//获取当前用户的信息
var user = JwtUtil.GetLoginUser(App.HttpContext);
if (user == null) return;
var db = DbScoped.SugarScope.GetConnectionScope(configId);
foreach (var role in user.Roles.OrderBy(f => f.DataScope))
{
var dataScope = (DataPermiEnum)role.DataScope;
if (DataPermiEnum.All.Equals(dataScope))//所有权限
{
break;
}
else if (DataPermiEnum.CUSTOM.Equals(dataScope))//自定数据权限
{
}
else if (DataPermiEnum.DEPT.Equals(dataScope))//本部门数据
{
}
else if (DataPermiEnum.DEPT_CHILD.Equals(dataScope))//本部门及以下数据
{
}
else if (DataPermiEnum.SELF.Equals(dataScope))//仅本人数据
{
}
}
}
}
}

View File

@ -0,0 +1,208 @@
using Infrastructure.Extensions;
using SqlSugar;
using SqlSugar.IOC;
using ZR.Model;
using ZR.Model.System;
namespace ZR.Admin.WebApi.Extensions
{
/// <summary>
/// sqlsugar 数据处理
/// </summary>
public static class DbExtension
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
/// <summary>
/// 初始化db
/// </summary>
/// <param name="services"></param>
/// <param name="Configuration"></param>
/// <param name="environment"></param>
public static void AddDb(this IServiceCollection services, IConfiguration Configuration, IWebHostEnvironment environment)
{
List<DbConfigs> dbConfigs = Configuration.GetSection("DbConfigs").Get<List<DbConfigs>>();
var iocList = new List<IocConfig>();
foreach (var item in dbConfigs)
{
iocList.Add(new IocConfig()
{
ConfigId = item.ConfigId,
ConnectionString = item.Conn,
DbType = (IocDbType)item.DbType,
IsAutoCloseConnection = item.IsAutoCloseConnection
});
}
SugarIocServices.AddSqlSugar(iocList);
ICacheService cache = new SqlSugarCache();
SugarIocServices.ConfigurationSugar(db =>
{
var u = App.User;
if (u != null)
{
DataPermi.FilterData(0);
//ConfigId = 1的数据权限过滤
//DataPermi.FilterData1(1);
}
iocList.ForEach(iocConfig =>
{
SetSugarAop(db, iocConfig, cache);
});
});
}
/// <summary>
/// 数据库Aop设置
/// </summary>
/// <param name="db"></param>
/// <param name="iocConfig"></param>
/// <param name="cache"></param>
private static void SetSugarAop(SqlSugarClient db, IocConfig iocConfig, ICacheService cache)
{
var config = db.GetConnectionScope(iocConfig.ConfigId).CurrentConnectionConfig;
var showDbLog = AppSettings.Get<bool>("ShowDbLog");
string configId = config.ConfigId;
db.GetConnectionScope(configId).Aop.OnLogExecuting = (sql, pars) =>
{
if (showDbLog)
{
string log = $"【db{configId} SQL语句】{UtilMethods.GetSqlString(config.DbType, sql, pars)}\n";
if (sql.TrimStart().StartsWith("SELECT", StringComparison.OrdinalIgnoreCase))
{
logger.Info(log);
}
else if (sql.StartsWith("UPDATE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("INSERT", StringComparison.OrdinalIgnoreCase))
{
logger.Warn(log);
}
else if (sql.StartsWith("DELETE", StringComparison.OrdinalIgnoreCase) || sql.StartsWith("TRUNCATE", StringComparison.OrdinalIgnoreCase))
{
logger.Error(log);
}
else
{
log = $"【db{configId} SQL语句】dbo.{sql} {string.Join(", ", pars.Select(x => x.ParameterName + " = " + GetParsValue(x)))};\n";
logger.Info(log);
}
}
};
db.GetConnectionScope(configId).Aop.OnError = (ex) =>
{
//var pars = db.Utilities.SerializeObject(((SugarParameter[])ex.Parametres).ToDictionary(it => it.ParameterName, it => it.Value));
string sql = "【错误SQL】" + UtilMethods.GetSqlString(config.DbType, ex.Sql, (SugarParameter[])ex.Parametres) + "\r\n";
logger.Error(ex, $"{sql}\r\n{ex.Message}\r\n{ex.StackTrace}");
};
db.GetConnectionScope(configId).Aop.DataExecuting = (oldValue, entiyInfo) =>
{
};
//差异日志功能
db.GetConnectionScope(configId).Aop.OnDiffLogEvent = it =>
{
//操作前记录 包含: 字段描述 列名 值 表名 表描述
var editBeforeData = it.BeforeData;//插入Before为null之前还没进库
//操作后记录 包含: 字段描述 列名 值 表名 表描述
var editAfterData = it.AfterData;
var sql = it.Sql;
var parameter = it.Parameters;
var data = it.BusinessData;//这边会显示你传进来的对象
var time = it.Time;
var diffType = it.DiffType;//enum insert 、update and delete
if (diffType == DiffType.delete)
{
string name = App.UserName;
foreach (var item in editBeforeData)
{
var pars = db.Utilities.SerializeObject(item.Columns.ToDictionary(it => it.ColumnName, it => it.Value));
SqlDiffLog log = new()
{
BeforeData = pars,
BusinessData = data?.ToString(),
DiffType = diffType.ToString(),
Sql = sql,
TableName = item.TableName,
UserName = name,
AddTime = DateTime.Now,
ConfigId = configId
};
//logger.WithProperty("title", data).Info(pars);
db.GetConnectionScope(0).Insertable(log).ExecuteReturnSnowflakeId();
}
}
};
db.GetConnectionScope(configId).CurrentConnectionConfig.MoreSettings = new ConnMoreSettings()
{
IsAutoRemoveDataCache = true
};
db.GetConnectionScope(configId).CurrentConnectionConfig.ConfigureExternalServices = new ConfigureExternalServices()
{
DataInfoCacheService = cache,
EntityService = (c, p) =>
{
if (p.IsPrimarykey == true)//主键不能为null
{
p.IsNullable = false;
}
else if (p.ExtendedAttribute?.ToString() == ProteryConstant.NOTNULL.ToString())
{
p.IsNullable = false;
}
else//则否默认为null
{
p.IsNullable = true;
}
if (config.DbType == DbType.PostgreSQL)
{
if (c.Name == nameof(SysMenu.IsCache) || c.Name == nameof(SysMenu.IsFrame))
{
p.DataType = "char(1)";
}
}
#region Oracle
if (config.DbType == DbType.Oracle)
{
if (p.IsIdentity == true)
{
if (p.EntityName == nameof(SysUser))
{
p.OracleSequenceName = "SEQ_SYS_USER_USERID";
}
else if (p.EntityName == nameof(SysRole))
{
p.OracleSequenceName = "SEQ_SYS_ROLE_ROLEID";
}
else if (p.EntityName == nameof(SysDept))
{
p.OracleSequenceName = "SEQ_SYS_DEPT_DEPTID";
}
else if (p.EntityName == nameof(SysMenu))
{
p.OracleSequenceName = "SEQ_SYS_MENU_MENUID";
}
else
{
p.OracleSequenceName = "SEQ_ID";
}
}
}
#endregion
}
};
}
private static object GetParsValue(SugarParameter x)
{
if (x.DbType == System.Data.DbType.String || x.DbType == System.Data.DbType.DateTime || x.DbType == System.Data.DbType.String)
{
return "'" + x.Value + "'";
}
return x.Value;
}
}
}

View File

@ -0,0 +1,46 @@

using System.Reflection;
namespace ZR.Admin.WebApi.Extensions
{
public static class EntityExtension
{
public static TSource ToCreate<TSource>(this TSource source, HttpContext? context = null)
{
var types = source?.GetType();
if (types == null) return source;
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
types.GetProperty("CreateTime", flag)?.SetValue(source, DateTime.Now, null);
types.GetProperty("CreatedTime", flag)?.SetValue(source, DateTime.Now, null);
types.GetProperty("AddTime", flag)?.SetValue(source, DateTime.Now, null);
if(context != null)
{
types.GetProperty("CreateBy", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("Create_by", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("CreatedBy", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("UserId", flag)?.SetValue(source, context.GetUId(), null);
}
return source;
}
public static TSource ToUpdate<TSource>(this TSource source, HttpContext? context = null)
{
var types = source?.GetType();
if (types == null) return source;
BindingFlags flag = BindingFlags.Public | BindingFlags.IgnoreCase | BindingFlags.Instance;
types.GetProperty("UpdateTime", flag)?.SetValue(source, DateTime.Now, null);
types.GetProperty("Update_time", flag)?.SetValue(source, DateTime.Now, null);
types.GetProperty("UpdatedTime", flag)?.SetValue(source, DateTime.Now, null);
if(context != null)
{
types.GetProperty("UpdateBy", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("Update_by", flag)?.SetValue(source, context.GetName(), null);
types.GetProperty("UpdatedBy", flag)?.SetValue(source, context.GetName(), null);
}
return source;
}
}
}

View File

@ -0,0 +1,225 @@
using Infrastructure.Extensions;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using UAParser;
using ZR.Model.System;
namespace ZR.Admin.WebApi.Extensions
{
/// <summary>
/// HttpContext扩展类
/// </summary>
public static partial class HttpContextExtension
{
/// <summary>
/// 是否是ajax请求
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
{
throw new ArgumentNullException(nameof(request));
}
//return request.Headers.ContainsKey("X-Requested-With") &&
// request.Headers["X-Requested-With"].Equals("XMLHttpRequest");
return request.Headers["X-Requested-With"] == "XMLHttpRequest" || request.Headers != null && request.Headers["X-Requested-With"] == "XMLHttpRequest";
}
/// <summary>
/// 获取客户端IP
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetClientUserIp(this HttpContext context)
{
if (context == null) return "";
var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (string.IsNullOrEmpty(result))
{
result = context.Connection.RemoteIpAddress?.ToString();
}
if (string.IsNullOrEmpty(result))
throw new Exception("获取IP失败");
if (result.Contains("::1"))
result = "127.0.0.1";
result = result.Replace("::ffff:", "127.0.0.1");
result = result.Split(':')?.FirstOrDefault() ?? "127.0.0.1";
result = IsIP(result) ? result : "127.0.0.1";
return result;
}
/// <summary>
/// 判断是否IP
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsIP(string ip)
{
return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
}
/// <summary>
/// 获取登录用户id
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static long GetUId(this HttpContext context)
{
var uid = context.User.FindFirstValue(ClaimTypes.PrimarySid);
return !string.IsNullOrEmpty(uid) ? long.Parse(uid) : 0;
}
/// <summary>
/// 获取登录用户名
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string? GetName(this HttpContext context)
{
var uid = context.User?.Identity?.Name;
return uid;
}
/// <summary>
/// 判断是否是管理员
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static bool IsAdmin(this HttpContext context)
{
List<string> roles = new();
roles.Add($"{GlobalConstant.AdminRole}");
roles.Add("杨琳磊");
var userName = context.GetName();
return roles.Contains(userName);
}
/// <summary>
/// ClaimsIdentity
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static IEnumerable<ClaimsIdentity>? GetClaims(this HttpContext context)
{
return context.User?.Identities;
}
//public static int GetRole(this HttpContext context)
//{
// var roleid = context.User.FindFirstValue(ClaimTypes.Role) ?? "0";
// return int.Parse(roleid);
//}
public static string GetUserAgent(this HttpContext context)
{
return context.Request.Headers["User-Agent"];
}
/// <summary>
/// 获取请求令牌
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetToken(this HttpContext context)
{
return context.Request.Headers["Authorization"];
}
/// <summary>
/// 获取浏览器信息
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static ClientInfo GetClientInfo(this HttpContext context)
{
var str = context.GetUserAgent();
var uaParser = Parser.GetDefault();
ClientInfo c = uaParser.Parse(str);
return c;
}
/// <summary>
/// 获取请求Url
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string? GetRequestUrl(this HttpContext context)
{
return context != null ? context.Request.Path.Value : "";
}
/// <summary>
/// 获取请求参数
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetQueryString(this HttpContext context)
{
return context != null ? context.Request.QueryString.Value : "";
}
/// <summary>
/// 获取body请求参数
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public static string GetBody(this HttpContext context)
{
context.Request.EnableBuffering();
//context.Request.Body.Seek(0, SeekOrigin.Begin);
//using var reader = new StreamReader(context.Request.Body, Encoding.UTF8);
////需要使用异步方式才能获取
//return reader.ReadToEndAsync().Result;
string body = string.Empty;
var buffer = new MemoryStream();
context.Request.Body.Seek(0, SeekOrigin.Begin);
context.Request.Body.CopyToAsync(buffer);
buffer.Position = 0;
try
{
using StreamReader streamReader = new(buffer, Encoding.UTF8);
body = streamReader.ReadToEndAsync().Result;
}
finally
{
buffer?.Dispose();
}
return body;
}
/// <summary>
/// 设置请求参数
/// </summary>
/// <param name="operLog"></param>
/// <param name="context"></param>
public static void GetRequestValue(this HttpContext context, SysOperLog operLog)
{
string reqMethod = operLog.RequestMethod;
string param = string.Empty;
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod) || HttpMethods.IsDelete(reqMethod))
{
param = context.GetBody();
param = PwdRep().Replace(param, "***");
}
if (param.IsEmpty())
{
param = context.GetQueryString();
}
operLog.OperParam = param;
}
[GeneratedRegex("(?<=\"password\":\")[^\",]*")]
private static partial Regex PwdRep();
}
}

View File

@ -0,0 +1,64 @@
namespace ZR.Admin.WebApi.Extensions
{
public class SqlSugarCache : SqlSugar.ICacheService
{
public void Add<V>(string key, V value)
{
//RedisServer.Cache.Set(key, value, 3600 + RedisHelper.RandomExpired(5, 30));
CacheHelper.SetCache(key, value);
}
public void Add<V>(string key, V value, int cacheDurationInSeconds)
{
//RedisServer.Cache.Set(key, value, cacheDurationInSeconds);
CacheHelper.SetCaches(key, value, cacheDurationInSeconds);
}
public bool ContainsKey<V>(string key)
{
//return RedisServer.Cache.Exists(key);
return CacheHelper.Exists(key);
}
public V Get<V>(string key)
{
//return RedisServer.Cache.Get<V>(key);
return (V)CacheHelper.Get(key);
}
public IEnumerable<string> GetAllKey<V>()
{
//return RedisServer.Cache.Keys("*");
return CacheHelper.GetCacheKeys();
}
public V GetOrCreate<V>(string cacheKey, Func<V> create, int cacheDurationInSeconds = int.MaxValue)
{
if (ContainsKey<V>(cacheKey))
{
var result = Get<V>(cacheKey);
if (result == null)
{
return create();
}
else
{
return result;
}
}
else
{
var restul = create();
Add(cacheKey, restul, cacheDurationInSeconds);
return restul;
}
}
public void Remove<V>(string key)
{
//RedisServer.Cache.Del(key);
CacheHelper.Remove(key);
}
}
}

View File

@ -0,0 +1,170 @@
using Infrastructure.Extensions;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using ZR.Admin.WebApi.Extensions;
using ZR.Model.System.Dto;
using ZR.Service.System;
namespace ZR.Admin.WebApi.Framework
{
/// <summary>
/// 2020-11-20
/// </summary>
public class JwtUtil
{
/// <summary>
/// 获取用户身份信息
/// </summary>
/// <param name="httpContext"></param>
/// <returns></returns>
public static LoginUser GetLoginUser(HttpContext httpContext)
{
string token = httpContext.GetToken();
if (!string.IsNullOrEmpty(token))
{
return ValidateJwtToken(ParseToken(token));
}
return null;
}
/// <summary>
/// 生成token
/// </summary>
/// <param name="claims"></param>
/// <param name="jwtSettings"></param>
/// <returns></returns>
public static string GenerateJwtToken(List<Claim> claims, JwtSettings jwtSettings)
{
var authTime = DateTime.Now;
var expiresAt = authTime.AddMinutes(jwtSettings.Expire);
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
claims.Add(new Claim("Audience", jwtSettings.Audience));
claims.Add(new Claim("Issuer", jwtSettings.Issuer));
var tokenDescriptor = new SecurityTokenDescriptor
{
Subject = new ClaimsIdentity(claims),
Issuer = jwtSettings.Issuer,
Audience = jwtSettings.Audience,
IssuedAt = authTime,//token生成时间
Expires = expiresAt,
//NotBefore = authTime,
TokenType = "Bearer",
//对称秘钥,签名证书
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
};
var token = tokenHandler.CreateToken(tokenDescriptor);
return tokenHandler.WriteToken(token);
}
/// <summary>
/// 检查客户端和服务器的Token是否一样
/// </summary>
/// <returns></returns>
public static TokenValidationParameters ValidParameters()
{
JwtSettings jwtSettings = new();
AppSettings.Bind("JwtSettings", jwtSettings);
if (jwtSettings == null || jwtSettings.SecretKey.IsEmpty())
{
throw new Exception("JwtSettings获取失败");
}
var key = Encoding.ASCII.GetBytes(jwtSettings.SecretKey);
var tokenDescriptor = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
ValidateIssuer = true,
ValidateAudience = true,
ValidIssuer = jwtSettings.Issuer,
ValidAudience = jwtSettings.Audience,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateLifetime = true,//是否验证Token有效期使用当前时间与Token的Claims中的NotBefore和Expires对比
ClockSkew = TimeSpan.FromSeconds(30)
//RequireExpirationTime = true,//过期时间
};
return tokenDescriptor;
}
/// <summary>
/// 从令牌中获取数据声明
/// </summary>
/// <param name="token">令牌</param>
/// <returns></returns>
public static IEnumerable<Claim>? ParseToken(string token)
{
var tokenHandler = new JwtSecurityTokenHandler();
var validateParameter = ValidParameters();
token = token.Replace("Bearer ", "");
try
{
tokenHandler.ValidateToken(token, validateParameter, out SecurityToken validatedToken);
var jwtToken = tokenHandler.ReadJwtToken(token);
return jwtToken.Claims;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
// return null if validation fails
return null;
}
}
/// <summary>
/// jwt token校验 合法用户和其权限
/// </summary>
/// <param name="jwtToken"></param>
/// <returns></returns>
public static LoginUser? ValidateJwtToken(IEnumerable<Claim> jwtToken)
{
try
{
LoginUser loginUser = null;
//todo: ClaimTypes.UserData ??? 从何而来
var userData = jwtToken.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
if (userData != null)
{
loginUser = JsonConvert.DeserializeObject<LoginUser>(userData);
//todo 从缓存拿到权限,如果拿不到权限说明非法用户
var permissions = CacheService.GetUserPerms(GlobalConstant.UserPermKEY + loginUser?.UserId);
if (loginUser?.UserName == GlobalConstant.AdminRole)
{
permissions = new List<string>() { GlobalConstant.AdminPerm };
}
if (permissions == null) return null;
loginUser.Permissions = permissions;
}
return loginUser;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return null;
}
}
/// <summary>
///组装Claims
/// </summary>
/// <param name="user"></param>
/// <returns></returns>
public static List<Claim> AddClaims(LoginUser user)
{
var claims = new List<Claim>()
{
new Claim(ClaimTypes.PrimarySid, user.UserId.ToString()),
new Claim(ClaimTypes.Name, user.UserName),
new Claim(ClaimTypes.UserData, JsonConvert.SerializeObject(user))
};
return claims;
}
}
}

7
U8Server/GlobalUsing.cs Normal file
View File

@ -0,0 +1,7 @@
global using Infrastructure;
global using Infrastructure.Attribute;
global using Infrastructure.Enums;
global using Infrastructure.Model;
global using Mapster;
global using Microsoft.AspNetCore.Authorization;
global using ZR.Common;

View File

@ -0,0 +1,137 @@
using IPTools.Core;
using Microsoft.AspNetCore.Http.Features;
using NLog;
using System.Text.Encodings.Web;
using System.Text.Json;
using ZR.Admin.WebApi.Extensions;
using ZR.Model.System;
using ZR.Service.System.IService;
namespace ZR.Admin.WebApi.Middleware
{
/// <summary>
/// 全局异常处理中间件
/// 调用 app.UseMiddlewareGlobalExceptionMiddleware>();
/// </summary>
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate next;
private readonly ISysOperLogService SysOperLogService;
static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public GlobalExceptionMiddleware(RequestDelegate next, ISysOperLogService sysOperLog)
{
this.next = next;
this.SysOperLogService = sysOperLog;
}
public async Task Invoke(HttpContext context)
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception ex)
{
NLog.LogLevel logLevel = NLog.LogLevel.Info;
int code = (int)ResultCode.GLOBAL_ERROR;
string msg;
string error = string.Empty;
//自定义异常
if (ex is CustomException customException)
{
code = customException.Code;
msg = customException.Message;
error = customException.LogMsg;
}
else if (ex is ArgumentException)//参数异常
{
code = (int)ResultCode.PARAM_ERROR;
msg = ex.Message;
}
else
{
msg = "服务器好像出了点问题,请联系系统管理员...";
error = $"{ex.Message}";
logLevel = NLog.LogLevel.Error;
context.Response.StatusCode = 500;
}
var options = new JsonSerializerOptions
{
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
ApiResult apiResult = new(code, msg);
string responseResult = JsonSerializer.Serialize(apiResult, options).ToLower();
string ip = HttpContextExtension.GetClientUserIp(context);
var ip_info = IpTool.Search(ip);
SysOperLog sysOperLog = new()
{
Status = 1,
OperIp = ip,
OperUrl = HttpContextExtension.GetRequestUrl(context),
RequestMethod = context.Request.Method,
JsonResult = responseResult,
ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
OperName = HttpContextExtension.GetName(context),
OperLocation = ip_info.Province + " " + ip_info.City,
OperTime = DateTime.Now
};
HttpContextExtension.GetRequestValue(context, sysOperLog);
var endpoint = GetEndpoint(context);
if (endpoint != null)
{
var logAttribute = endpoint.Metadata.GetMetadata<LogAttribute>();
if (logAttribute != null)
{
sysOperLog.BusinessType = (int)logAttribute.BusinessType;
sysOperLog.Title = logAttribute?.Title;
sysOperLog.OperParam = logAttribute.IsSaveRequestData ? sysOperLog.OperParam : "";
sysOperLog.JsonResult = logAttribute.IsSaveResponseData ? sysOperLog.JsonResult : "";
}
}
LogEventInfo ei = new(logLevel, "GlobalExceptionMiddleware", error)
{
Exception = ex,
Message = error
};
ei.Properties["status"] = 1;//走正常返回都是通过走GlobalExceptionFilter不通过
ei.Properties["jsonResult"] = responseResult;
ei.Properties["requestParam"] = sysOperLog.OperParam;
ei.Properties["user"] = sysOperLog.OperName;
Logger.Log(ei);
context.Response.ContentType = "text/json;charset=utf-8";
await context.Response.WriteAsync(responseResult, System.Text.Encoding.UTF8);
string errorMsg = $"> 操作人:{sysOperLog.OperName}" +
$"\n> 操作地区:{sysOperLog.OperIp}({sysOperLog.OperLocation})" +
$"\n> 操作模块:{sysOperLog.Title}" +
$"\n> 操作地址:{sysOperLog.OperUrl}" +
$"\n> 错误信息:{msg}\n\n> {error}";
WxNoticeHelper.SendMsg("系统出错", errorMsg, "", WxNoticeHelper.MsgType.markdown);
SysOperLogService.InsertOperlog(sysOperLog);
}
public static Endpoint GetEndpoint(HttpContext context)
{
if (context == null)
{
throw new ArgumentNullException(nameof(context));
}
return context.Features.Get<IEndpointFeature>()?.Endpoint;
}
}
}

30
U8Server/Program.cs Normal file
View File

@ -0,0 +1,30 @@
using Nacos.AspNetCore.V2;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
//ÅäÖÃÖÐÐÄ
builder.Configuration.AddNacosV2Configuration(builder.Configuration.GetSection("NacosConfig"));
//·þÎñ×¢²á
builder.Services.AddNacosAspNet(builder.Configuration);
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
app.UseAuthorization();
app.MapControllers();
app.Run();

View File

@ -0,0 +1,31 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:62659",
"sslPort": 0
}
},
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5222",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

28
U8Server/U8Server.csproj Normal file
View File

@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="Mapster" Version="7.3.0" />
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.19" />
<PackageReference Include="nacos-sdk-csharp" Version="1.3.10" />
<PackageReference Include="nacos-sdk-csharp.AspNetCore" Version="1.3.10" />
<PackageReference Include="nacos-sdk-csharp.Extensions.Configuration" Version="1.3.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="UAParser" Version="3.1.47" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Infrastructure\Infrastructure.csproj" />
<ProjectReference Include="..\ZR.Service\ZR.Service.csproj" />
</ItemGroup>
</Project>

19
U8Server/Util/GetSign.cs Normal file
View File

@ -0,0 +1,19 @@
using System.Globalization;
using U8Server.Extensions;
namespace U8Server.Util
{
public class GetSign
{
public static string GetBy16Md5()
{
string appId = "gN9yId!!lfwaRoi3";
string appSecret = "xr35$IQAutBRX1UYhgOUY#CqChI#Y3b$";
string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture);
string key = $"{appSecret}{appId}{timestamp}{appSecret}";
string sign = key.ToMD5Encrypt(uppercase: false, is16bit: true)
?? throw new InvalidOperationException("MD5加密失败");
return sign;
}
}
}

View File

@ -0,0 +1,110 @@
using System.Security.Cryptography;
using System.Text;
namespace U8Server.Util
{
//
// 摘要:
// MD5 加密
public static class MD5Encryption
{
//
// 摘要:
// MD5 比较
//
// 参数:
// text:
// 加密文本
//
// hash:
// MD5 字符串
//
// uppercase:
// 是否输出大写加密,默认 false
//
// is16:
// 是否输出 16 位
//
// 返回结果:
// bool
public static bool Compare(string text, string hash, bool uppercase = false, bool is16 = false)
{
return Compare(Encoding.UTF8.GetBytes(text), hash, uppercase, is16);
}
//
// 摘要:
// MD5 加密
//
// 参数:
// text:
// 加密文本
//
// uppercase:
// 是否输出大写加密,默认 false
//
// is16:
// 是否输出 16 位
public static string Encrypt(string text, bool uppercase = false, bool is16 = false)
{
return Encrypt(Encoding.UTF8.GetBytes(text), uppercase, is16);
}
//
// 摘要:
// MD5 加密
//
// 参数:
// bytes:
// 字节数组
//
// uppercase:
// 是否输出大写加密,默认 false
//
// is16:
// 是否输出 16 位
public static string Encrypt(byte[] bytes, bool uppercase = false, bool is16 = false)
{
byte[] array = MD5.HashData(bytes);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < array.Length; i++)
{
stringBuilder.Append(array[i].ToString("x2"));
}
string text = stringBuilder.ToString();
string text2 = ((!is16) ? text : text.Substring(8, 16));
if (uppercase)
{
return text2.ToUpper();
}
return text2;
}
//
// 摘要:
// MD5 比较
//
// 参数:
// bytes:
// 字节数组
//
// hash:
// MD5 字符串
//
// uppercase:
// 是否输出大写加密,默认 false
//
// is16:
// 是否输出 16 位
//
// 返回结果:
// bool
public static bool Compare(byte[] bytes, string hash, bool uppercase = false, bool is16 = false)
{
string value = Encrypt(bytes, uppercase, is16);
return hash.Equals(value, StringComparison.OrdinalIgnoreCase);
}
}
}

View File

@ -0,0 +1,20 @@
using U8Server.Util;
namespace U8Server.Extensions
{
public static class StringExtensions
{
/// <summary>
/// 对字符串进行 MD5 加密(扩展方法)
/// </summary>
/// <param name="input">待加密的字符串</param>
/// <param name="uppercase">是否返回大写形式</param>
/// <param name="is16bit">是否返回 16 位 MD5默认 32 位)</param>
/// <returns>加密后的字符串</returns>
public static string ToMD5Encrypt(this string input, bool uppercase = false, bool is16bit = false)
{
// 直接调用现有的 MD5Encryption.Encrypt 方法
return MD5Encryption.Encrypt(input, uppercase, is16bit);
}
}
}

View File

@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}

21
U8Server/appsettings.json Normal file
View File

@ -0,0 +1,21 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"NacosConfig": {
"Listeners": [
{
"Optional": false,
"DataId": "U8ServerConfig",
"Group": "DEFAULT_GROUP"
}
],
//
"ServerAddresses": [ "http://127.0.0.1:8848" ], // Nacos
"Namespace": ""// public
},
"AllowedHosts": "*"
}

View File

@ -3,6 +3,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using Nacos.AspNetCore.V2;
using System.Text.Json.Serialization;
using ZR.Admin.WebApi.AutoMapperProfile;
using ZR.Admin.WebApi.Extensions;
@ -14,9 +15,12 @@ using ZR.Common.Cache;
using ZR.Common.MqttHelper;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
//配置中心
//builder.Configuration.AddNacosV2Configuration(builder.Configuration.GetSection("NacosConfig"));
//服务注册
//builder.Services.AddNacosAspNet(builder.Configuration);
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

View File

@ -36,6 +36,9 @@
<PackageReference Include="AspNetCoreRateLimit" Version="5.0.0" />
<PackageReference Include="Lazy.Captcha.Core" Version="2.0.3" />
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
<PackageReference Include="nacos-sdk-csharp" Version="1.3.10" />
<PackageReference Include="nacos-sdk-csharp.AspNetCore" Version="1.3.10" />
<PackageReference Include="nacos-sdk-csharp.Extensions.Configuration" Version="1.3.10" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NPOI" Version="2.7.0" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />

View File

@ -16,5 +16,17 @@
"QualityOfServiceLevel": "AtLeastOnce"
}
]
},
"NacosConfig": {
"Listeners": [
{
"Optional": false,
"DataId": "MesServerConfig",
"Group": "DEFAULT_GROUP"
}
],
//
"ServerAddresses": [ "http://127.0.0.1:8848" ], // Nacos
"Namespace": "" // public
}
}

View File

@ -19,6 +19,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZR.Repository", "ZR.Reposit
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZR.CodeGenerator", "ZR.CodeGenerator\ZR.CodeGenerator.csproj", "{B353DE0B-12C6-4C15-909A-DB68F71D5AE9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "U8Server", "U8Server\U8Server.csproj", "{B1F5C2C3-8E09-4140-A573-C19FD2E33ADE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -57,6 +59,10 @@ Global
{B353DE0B-12C6-4C15-909A-DB68F71D5AE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B353DE0B-12C6-4C15-909A-DB68F71D5AE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B353DE0B-12C6-4C15-909A-DB68F71D5AE9}.Release|Any CPU.Build.0 = Release|Any CPU
{B1F5C2C3-8E09-4140-A573-C19FD2E33ADE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B1F5C2C3-8E09-4140-A573-C19FD2E33ADE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B1F5C2C3-8E09-4140-A573-C19FD2E33ADE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B1F5C2C3-8E09-4140-A573-C19FD2E33ADE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE