AFR对接

master
zhangxiaofeng 11 months ago
parent 44e761a2d8
commit 1c6d9a55e5

@ -0,0 +1,148 @@
using NPOI.SS.Formula.Functions;
namespace djy.Model
{
/// <summary>
/// 通用返回信息类
/// </summary>
public class MessageModel<T>
{
/// <summary>
/// 状态码
/// </summary>
public int code { get; set; } = 200;
/// <summary>
/// 操作是否成功
/// </summary>
public bool success { get; set; } = false;
/// <summary>
/// 返回信息
/// </summary>
public string message { get; set; } = "";
/// <summary>
/// 开发者信息
/// </summary>
public string msgDev { get; set; }
/// <summary>
/// 返回数据集合
/// </summary>
public T data { get; set; }
/// <summary>
/// 返回成功
/// </summary>
/// <param name="msg">消息</param>
/// <returns></returns>
public static MessageModel<T> Success(string msg)
{
return Message(true, msg, default);
}
/// <summary>
/// 返回成功
/// </summary>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static MessageModel<T> Success(string msg, T data)
{
return Message(true, msg, data);
}
/// <summary>
/// 返回失败
/// </summary>
/// <param name="msg">消息</param>
/// <returns></returns>
public static MessageModel<T> Fail(string msg)
{
return Message(false, msg, default);
}
/// <summary>
/// 返回失败
/// </summary>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static MessageModel<T> Fail(string msg, T data)
{
return Message(false, msg, data);
}
/// <summary>
/// 返回消息
/// </summary>
/// <param name="success">失败/成功</param>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
private static MessageModel<T> Message(bool success, string msg, T data)
{
return new MessageModel<T>() { message = msg, data = data, success = success };
}
}
/// <summary>
///
/// </summary>
public class MessageModel
{
/// <summary>
/// 状态码
/// </summary>
public int code { get; set; } = 200;
/// <summary>
/// 操作是否成功
/// </summary>
public bool success { get; set; } = false;
/// <summary>
/// 返回信息
/// </summary>
public string message { get; set; } = "";
/// <summary>
/// 返回数据集合
/// </summary>
public object data { get; set; }
/// <summary>
/// 返回成功
/// </summary>
/// <param name="msg">消息</param>
/// <returns></returns>
public static MessageModel Success(string msg)
{
return Message(true, msg, default);
}
/// <summary>
/// 返回成功
/// </summary>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
public static MessageModel Success(string msg, object data)
{
return Message(true, msg, data);
}
/// <summary>
/// 返回失败
/// </summary>
/// <param name="msg">消息</param>
/// <returns></returns>
public static MessageModel Fail(string msg)
{
return Message(false, msg, default);
}
/// <summary>
/// 返回消息
/// </summary>
/// <param name="success">失败/成功</param>
/// <param name="msg">消息</param>
/// <param name="data">数据</param>
/// <returns></returns>
private static MessageModel Message(bool success, string msg, object data)
{
return new MessageModel() { message = msg, data = data, success = success };
}
}
}

@ -0,0 +1,55 @@
using Common.Utilities;
using djy.Model;
using djy_AfrApi.HttpContextUser;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
namespace djy_AfrApi.Controllers
{
public class AfrController : ApiBase
{
private readonly ILogger logger;
private readonly IUser user;
private readonly ILogger bigLogger;
public AfrController(ILogger<AfrController> logger, ILoggerFactory loggerFactory, IUser user)
{
this.logger = logger;
this.user = user;
// 获取ILogger对象
bigLogger = loggerFactory.CreateLogger("BigDataLogger"); // 通过指定名称获取ILogger对象
}
#region 查询接口
[HttpGet("Load")]
public async Task<MessageModel> Load()
{
return MessageModel.Success("12312", new { ff = "11", fff = "22" });
}
[HttpGet("[action]")]
[AllowAnonymous]
public async Task<MessageModel> Reveive()
{
var r = MessageModel.Success("555", new { ff = "44", fff = "33" });
return r;
}
#endregion
#region 新增/编辑
#endregion
#region 删除
#endregion
#region 第三方接口
#endregion
}
}

@ -0,0 +1,301 @@
using Common;
using Common.DJYModel;
using Common.Extensions;
using Common.Tools;
using djy.IService.Djy;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Linq;
namespace djy_AfrApi.Controllers
{
/// <summary>
/// api接口基类
/// </summary>
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class ApiBase : Controller
{
#region http数据获取
/// <summary>
/// 创建日志
/// </summary>
/// <param name="Message">内容</param>
/// <param name="GroupName"></param>
/// <param name="DataJson"></param>
/// <param name="ObjGid"></param>
/// <param name="ResultJson"></param>
protected void _LogsAdd(string Message, string GroupName = null, object DataJson = null, string ObjGid = null, object ResultJson = null)
{
var toolsserver = IOC.AddServer<IToolsService>();
toolsserver.LogsAdd(Message, GroupName, DataJson, ObjGid, ResultJson);
}
/// <summary>
/// 获取大简云设置权限
/// </summary>
/// <param name="KeyName">keyname标识</param>
/// <returns></returns>
protected DJyUserAuthorityDto GetDJyUserAuthority(string KeyName) {
var _djyserver = IOC.AddServer<IDjyUserService>();
var rs= _djyserver.GetUserAuthority(GetLoginId,KeyName);
if (rs.Status)
{
return rs.Data;
}
else {
return null;
}
}
/// <summary>
/// 获取登录详情信息
/// </summary>
/// <param name="UserGid"></param>
protected User GetUserInfo(Guid? UserGid = null)
{
var _suser = IOC.AddServer<IDjyUserService>();
if (UserGid == null)
{ UserGid = GetLoginId; }
var rs = _suser.GetUserInfo(UserGid.ToString());
if (rs.Status)
{
return rs.Data;
}
else
{ return null; }
}
/// <summary>
/// 统一获取大简云权限查询权限的userid companyid 没有权限则指定userid和companyid 为不存的guid值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="BindData"></param>
/// <param name="KeyName">模块keyname标识</param>
/// <param name="type">0 查询查看权限 1 操作更新权限 默认 0</param>
/// <returns></returns>
protected UserAuthorityDto GetUserAuthorityToFormDto(string KeyName,int type=0 ) {
//本人的绑定UserId 全部 userid 和 compayid不做绑定 注册公司的 绑定 companyid 没有权限则指定userid和companyid 为不存的guid值
var RetrunData = new UserAuthorityDto();
var _djyserver = IOC.AddServer<IDjyUserService>();
User User;
User = null;
var uuid = GetLoginId.ToString();
var userrs = _djyserver.GetUserInfo(GetLoginId.ToString());
var notguid = Guid.Parse("00000000-0000-0000-0000-000000000001");
RetrunData.CompayId = null;
if (userrs.Status)
{
User = userrs.Data;
RetrunData.CompayId = Guid.Parse(User.CompId);
}
if (User == null)
{
RetrunData.UserId = notguid;
RetrunData.CompayId = notguid;
}
var aut = GetDJyUserAuthority(KeyName);
if (aut != null)
{//根据权限处理 _userid 和 _companyid 值
RetrunData.IsPower = true;
var _useraut= aut.Visiblerange;
if (type == 1) {
_useraut = aut.Operaterange;
}
switch (_useraut) {
case 0://全部
RetrunData.UserId = null;
RetrunData.CompayId = null;
break;
case 1://本公司
RetrunData.UserId = null;
RetrunData.CompayId = Guid.Parse(User.CompId);
break;
case 3://本人
RetrunData.UserId = GetLoginId;
RetrunData.CompayId = null;
break;
case 4://无权限或或默认权限
//_uerid = notguid;
//_companyid = notguid;
RetrunData.UserId = null;
RetrunData.CompayId = null;
break;
case 7://注册公司
RetrunData.UserId = null;
RetrunData.CompayId = Guid.Parse( User.CompId);
break;
default:
RetrunData.UserId = notguid;
RetrunData.CompayId = notguid;
break;
}
}
else
{
RetrunData.UserId = GetLoginId;
RetrunData.CompayId = null;
RetrunData.IsPower = true;
}
//if (sysOptionConfig.Webconfig.IsDev)
//{
// RetrunData.UserId = null;
// RetrunData.CompayId =null;
// RetrunData.IsPower = true;
//}
return RetrunData;
}
/// <summary>
/// 获取登录Id
/// </summary>
protected Guid? GetLoginId { get { return Guid.Parse(GetClaimsValue("loginid")); } }
/// <summary>
/// 获取登录类型
/// </summary>
protected EnumUser.UserType GetLoginType
{
get
{
var type = GetClaimsValue("logintype");
if (type.Isint())
{
return (EnumUser.UserType)int.Parse(type);
}
else { return EnumUser.UserType.All; }
}
}
/// <summary>
/// 根据key获取claims值 没有则返回null
/// </summary>
/// <param name="Key"></param>
/// <param name="IsDecrtypt">是否是加密</param>
/// <returns></returns>
protected string GetClaimsValue(string Key, bool IsDecrtypt = true)
{
try
{
var claims = HttpContext.User.Claims;
var id = claims.SingleOrDefault(s => s.Type == Key);
if (id == null)
{
return "0";
}
return IsDecrtypt ? _DecryptDES(id.Value) : id.Value;
}
catch {
return null;
}
}
/// <summary>
/// DES解密
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
protected static string _DecryptDES(string value)
{
return SafeTools.DecryptDES(value, sysOptionConfig.Webconfig.DesKey);
}
#endregion
}
/// <summary>
///api接口基类
/// </summary>
/// <typeparam name="IS">接口类型比如 Iservice</typeparam>
public class ApiBase<IS> : ApiBase
{
/// <summary>
///
/// </summary>
protected IS _server = IOC.AddServer<IS>();
/// <summary>
/// 执行指定的方法
/// </summary>
/// <param name="methodName">方法名称</param>
/// <param name="parameters">参数对象队列</param>
/// <returns></returns>
protected object _InvokeServer(string methodName, object[] parameters)
{
return _server.GetType().GetMethod(methodName).Invoke(_server, parameters);
}
}
/// <summary>
/// api接口基类
/// </summary>
/// <typeparam name="IS">接口类型比如 Iservice</typeparam>
/// <typeparam name="D">Dto Model</typeparam>
/// <typeparam name="T">Tables数据表model</typeparam>
public class ApiBase<IS, D, T> : ApiBase<IS>
{
/// <summary>
/// 根据Id获取实体
/// </summary>
/// <param name="Id"></param>
/// <returns></returns>
protected virtual object _GetId(long Id)
{
return _InvokeServer("GetId", new object[] { Id });
}
/// <summary>
///基础的创建接口 提交创建对象
/// </summary>
/// <param name="Dto"></param>
/// <returns></returns>
protected virtual object _Add(T Dto)
{
return _InvokeServer("Add", new object[] { Dto });
}
/// <summary>
/// 最基础的更新接口 传递要更新的数据对象 必须有Id
/// </summary>
/// <param name="Dto"></param>
/// <returns></returns>
protected virtual object _Up(T Dto)
{
return _InvokeServer("Up", new object[] { Dto, null, null });
}
/// <summary>
/// 最基础的删除接口 [1,2,3]
/// </summary>
/// <param name="Idlist"></param>
/// <returns></returns>
protected virtual object _Del(long[] Idlist)
{
return _InvokeServer("Del", new object[] { Idlist });
}
}
}

@ -0,0 +1,58 @@
using Common.Helpers;
using Common.Utilities;
using djy.Service.DjyService;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
namespace djy_AfrApi.Filter
{
public class GlobalExceptionsFilter : IExceptionFilter
{
private readonly IHostEnvironment env;
private readonly ILogger<GlobalExceptionsFilter> _logger;
public GlobalExceptionsFilter(IHostEnvironment env, ILogger<GlobalExceptionsFilter> logger)
{
this.env = env;
this._logger = logger;
}
public void OnException(ExceptionContext context)
{
var json = new Response
{
Message = context.Exception.Message,//错误信息
Code = 500 //500异常
};
//if (env.IsDevelopment())
//{
// json.MessageDev = context.Exception.StackTrace;//堆栈信息
//}
var res = new ContentResult();
res.Content = JsonConvert.SerializeObject(json);
context.Result = res;
//进行错误日志记录
_logger.LogError(WriteLog("GlobalExceptionsFilter中捕获的全局异常", context.Exception));
}
/// <summary>
/// 自定义返回格式
/// </summary>
/// <param name="throwMsg"></param>
/// <param name="ex"></param>
/// <returns></returns>
public string WriteLog(string throwMsg, Exception ex)
{
return string.Format("\r\n【自定义错误】{0} \r\n【异常类型】{1} \r\n【异常信息】{2} \r\n【堆栈调用】{3}\r\n自定义异常结束", new object[] { throwMsg,
ex.GetType().Name, ex.Message, ex.StackTrace });
}
}
}

@ -0,0 +1,42 @@
using Common.DJYModel;
using djy.IService.Djy;
using Microsoft.AspNetCore.Http;
using System;
using System.Linq;
namespace djy_AfrApi.HttpContextUser
{
public class AspNetUser : IUser
{
private readonly IHttpContextAccessor accessor;
private readonly IDjyUserService userService;
public AspNetUser(IHttpContextAccessor accessor, IDjyUserService userService)
{
this.accessor = accessor;
this.userService = userService;
}
public User CurrentUser
{
get
{
var user = accessor.HttpContext.Items["CurrentUser"] as User;
if (user != null)
{
accessor.HttpContext.Items["CurrentUser"] = user;
return user;
}
var userId = accessor.HttpContext.User?.Claims?.FirstOrDefault(c => c.Type == "loginid")?.Value;
var user2 = userService.GetUserInfo(userId);
if (user2.Data != null) return user2.Data;
throw new Exception("获取当前登录用户时发生异常");
}
}
public string CompId => CurrentUser.CompId;
public string CompName => CurrentUser.COMNAME;
public string GID => CurrentUser.GID;
public string ShowName => CurrentUser.SHOWNAME;
}
}

@ -0,0 +1,13 @@
using Common.DJYModel;
namespace djy_AfrApi.HttpContextUser
{
public interface IUser
{
User CurrentUser { get; }
string CompName { get; }
string CompId { get; }
string GID { get; }
string ShowName { get; }
}
}

@ -0,0 +1,60 @@
using djy.Model;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Net;
using System.Threading.Tasks;
namespace djy_AfrApi.Middlewares
{
public class ExceptionHandlerMiddleware
{
private readonly RequestDelegate _next;
public ExceptionHandlerMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext context)
{
try
{
//_ = int.Parse("");
await _next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private async Task HandleExceptionAsync(HttpContext context, Exception e)
{
if (e == null) return;
// TODO :记录日志
await WriteExceptionAsync(context, e).ConfigureAwait(false);
}
private static async Task WriteExceptionAsync(HttpContext context, Exception e)
{
var message = e.Message;
switch (e)
{
case UnauthorizedAccessException:
context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
break;
default:
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
break;
}
context.Response.ContentType = "application/json";
await context.Response
.WriteAsync(JsonConvert.SerializeObject(new MessageModel() { code = 500, message = message }))
.ConfigureAwait(false);
}
}
}

@ -0,0 +1,38 @@
using djy_AfrApi.Milldlewares;
using Microsoft.AspNetCore.Builder;
namespace djy_AfrApi.Middlewares
{
public static class MiddlewareHelpers
{
/// <summary>
/// 异常处理
/// </summary>
public static IApplicationBuilder UseExceptionHandlerMiddle(this IApplicationBuilder app)
{
return app.UseMiddleware<ExceptionHandlerMiddleware>();
}
/// <summary>
/// 处理特殊情况下的响应格式401、403
/// </summary>
public static IApplicationBuilder UseUnifyResultMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<UnifyResultMiddleware>();
}
/// <summary>
/// 二次验证授权并保存当前登录人User对象为了和ISF、AMS逻辑保持一致
/// </summary>
public static IApplicationBuilder UseNextAuthorizationMiddle(this IApplicationBuilder app)
{
return app.UseMiddleware<NextAuthorizationMiddleware>();
}
// 记录请求和响应数据
public static IApplicationBuilder UseRequRespLogMiddleware(this IApplicationBuilder app)
{
return app.UseMiddleware<RequRespLogMiddleware>();
}
}
}

@ -0,0 +1,63 @@
using Common.DJYModel;
using Common.Utilities;
using djy.IService.Djy;
using djy.Model;
using djy.Service;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
namespace djy_AfrApi.Milldlewares
{
public class NextAuthorizationMiddleware
{
private readonly RequestDelegate _next;
private readonly IDjyUserService _userService;
public NextAuthorizationMiddleware(RequestDelegate next, IDjyUserService userService)
{
_next = next;
_userService = userService;
}
public async Task InvokeAsync(HttpContext context)
{
var endpoint = context.GetEndpoint();
if (endpoint?.Metadata.GetMetadata<IAllowAnonymous>() == null)
{
// 因为ISF/AMS这步验证始终都无效所以这里先不做验证
//if (context.Request.Path.Value.Contains("/Load"))
//{
// var userId = context.User?.Claims?.FirstOrDefault(c => c.Type == "loginid")?.Value;
// var aut = _userService.GetUserAuthority(Guid.Parse(userId), "modAfrList");
//}
var userId = context.User?.Claims?.FirstOrDefault(c => c.Type == "loginid")?.Value;
var user = _userService.GetUserInfo(userId);
if (user.Data == null)
{
MessageModel result = new MessageModel()
{
code = 401,
message = "登录过期(未查询到此用户),请重新登录!"
};
context.Response.ContentType = "application/json";
await context.Response.WriteAsync(JsonConvert.SerializeObject(result)).ConfigureAwait(false);
}
else
{
context.Items["CurrentUser"] = user.Data;
await _next(context);
}
}
else
{
await _next(context);
}
}
}
}

@ -0,0 +1,102 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Threading.Tasks;
namespace djy_AfrApi.Milldlewares
{
public class RequRespLogMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger _logger;
private Stopwatch _stopwatch;
public RequRespLogMiddleware(RequestDelegate next, ILoggerFactory loggerFactory)
{
_next = next;
_logger = loggerFactory.CreateLogger("RequRespLogger");
_stopwatch = new Stopwatch();
}
public async Task InvokeAsync(HttpContext context)
{
if (context.Request.Path.Value.Contains("api"))
{
_stopwatch.Restart();
context.Request.EnableBuffering();
//// 存储请求数据
var request = context.Request;
var sr = new StreamReader(request.Body);
RequestLogInfo requestResponse = new RequestLogInfo()
{
Path = request.Path,
QueryString = request.QueryString.ToString(),
BodyData = await sr.ReadToEndAsync()
};
var content = JsonConvert.SerializeObject(requestResponse);
if (!string.IsNullOrEmpty(content))
{
_logger.LogInformation($"请求 - {context.TraceIdentifier}{Environment.NewLine}{content}");
request.Body.Position = 0;
}
// 存储响应数据
using (MemoryStream memoryStream = new MemoryStream())
{
// 使用自定义的响应流,将所有写入重定向到内存流
var originalBodyStream = context.Response.Body;
context.Response.Body = memoryStream;
try
{
await _next(context);
_stopwatch.Stop();
// 从内存流读取响应内容
memoryStream.Seek(0, SeekOrigin.Begin);
string responseBody = new StreamReader(memoryStream).ReadToEnd();
// 记录响应内容
_logger.LogInformation($"响应 - {context.TraceIdentifier} - {_stopwatch.ElapsedMilliseconds}ms{Environment.NewLine}StatusCode:{context.Response.StatusCode}{Environment.NewLine}{responseBody}");
// 将响应内容写回原始响应流
memoryStream.Seek(0, SeekOrigin.Begin);
await memoryStream.CopyToAsync(originalBodyStream);
}
finally
{
// 恢复原始响应流
context.Response.Body = originalBodyStream;
}
}
}
else
{
await _next(context);
}
}
}
class RequestLogInfo
{
/// <summary>
/// 请求地址
/// </summary>
public string Path { get; set; }
/// <summary>
/// 请求参数
/// </summary>
public string QueryString { get; set; }
/// <summary>
/// Body参数
/// </summary>
public string BodyData { get; set; }
}
}

@ -0,0 +1,37 @@
using djy.Model;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System.Threading.Tasks;
namespace djy_AfrApi.Milldlewares
{
/// <summary>
/// 处理特殊情况下的响应格式401、403
/// </summary>
public class UnifyResultMiddleware
{
private readonly RequestDelegate _next;
public UnifyResultMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext context)
{
await _next(context);
if (context.Response.StatusCode == 401 || context.Response.StatusCode == 403)
{
context.Response.ContentType = "application/json";
await context.Response
.WriteAsync(JsonConvert.SerializeObject(
new MessageModel()
{
code = context.Response.StatusCode,
message = "授权验证失败或已过期,请重新登录!"
}))
.ConfigureAwait(false);
}
}
}
}

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
autoReload="true"
throwConfigExceptions="false"
internalLogLevel="Off" >
<!--autoReload修改后自动加载可能会有延迟-->
<!--throwConfigExceptionsNLog日志系统抛出异常-->
<!--internalLogLevel内部日志的级别-->
<!--internalLogFile内部日志保存路径日志的内容大概就是NLog的版本信息配置文件的地址等等-->
<targets>
<target name="info" xsi:type="File" maxArchiveFiles="30" archiveAboveSize="10240000"
fileName="${basedir}/Logs/${shortdate}/info.txt"
layout="${longdate} | ${level} | ${message}" />
<!-- 请求响应日志记录 -->
<target name="requResp" xsi:type="File" maxArchiveFiles="30" archiveAboveSize="10240000"
fileName="${basedir}/Logs/${shortdate}/requResp.txt"
layout="${longdate} | ${level} | ${message}" />
<!--只保存error级别的日志可以快速知道是否有异常产生-->
<target name="error" xsi:type="File" maxArchiveFiles="30" archiveAboveSize="10240000"
fileName="${basedir}/Logs/${shortdate}/error.txt"
layout="${longdate} | ${level} | ${message} ${onexception:${exception:format=tostring} ${newline} ${stacktrace} ${newline}" />
<!--保存大数据量的日志,采用异步的方式-->
<target name="big" xsi:type="AsyncWrapper">
<target xsi:type="File" maxArchiveFiles="30" archiveAboveSize="10240000"
fileName="${basedir}/Logs/${shortdate}/bigData.txt"
layout="${longdate} | ${level} | ${message}" />
</target>
<!-- write log message to database -->
<target name="db" xsi:type="AsyncWrapper" queueLimit="5000" overflowAction="Discard">
<target type="Database" dbProvider="mssql"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=EFinance;Persist Security Info=True;User ID=sa;Password=123456;">
<commandText>
INSERT INTO Log(Timestamp,Level,Message,Action,Amount,StackTrace) VALUES(@time_stamp, @level, @message, @action, @amount, @stacktrace);
</commandText>
<!-- database connection parameters -->
<parameter name="@time_stamp" layout="${date}" />
<parameter name="@level" layout="${level:uppercase=true}" />
<parameter name="@message" layout="${message}" />
<parameter name="@action" layout="${event-context:item=Action}" />
<parameter name="@amount" layout="${event-context:item=Amount}" />
<parameter name="@stacktrace" layout="${stacktrace}" />
</target>
</target>
</targets>
<rules>
<!--TRACE,DEBUG,INFO,WARN,ERROR,FATAL-->
<!--此路由设置了final所以当此路由被匹配到时。不会再匹配此路由下面的路由。未匹配到此路由时才会继续匹配下一个路由-->
<logger name="Microsoft.*" maxlevel="Warning" final="true" />
<logger name="BigDataLogger" writeTo="big" final="true"/>
<logger name="RequRespLogger" writeTo="requResp" final="true"/>
<logger name="*" writeTo="info" minlevel="INFO"/>
<logger name="*" writeTo="error" minlevel="ERROR" />
</rules>
</nlog>

@ -0,0 +1,29 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using NLog.Extensions.Logging;
using NLog.Web;
namespace djy_AfrApi
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
}).ConfigureLogging(logging =>
{
logging.ClearProviders();
//logging.SetMinimumLevel(LogLevel.Information);
logging.AddConsole();
logging.AddDebug();
}).UseNLog();
}
}

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

@ -0,0 +1,161 @@
using Common;
using djy.Service.DjyService;
using djy_AfrApi.Filter;
using djy_AfrApi.HttpContextUser;
using djy_AfrApi.Middlewares;
using FreeRedis;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.IdentityModel.Logging;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using System.Linq;
using System.Reflection;
namespace djy_AfrApi
{
public class Startup
{
public Startup(IConfiguration configuration,IHostEnvironment hostEnvironment)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddHttpContextAccessor();
services.AddScoped<IUser, AspNetUser>();
services.AddControllers(o =>
{
o.Filters.Add(typeof(GlobalExceptionsFilter));
})
.AddNewtonsoftJson(options =>
{
//忽略循环引用
options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
//是否使用驼峰样式的key
//options.SerializerSettings.ContractResolver = new DefaultContractResolver();
options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
//设置时间格式
options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
//忽略Model中为null的属性
//options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
//设置本地时间而非UTC时间
options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
//添加Enum转string
options.SerializerSettings.Converters.Add(new StringEnumConverter());
})
.ConfigureApiBehaviorOptions(options =>
{
options.InvalidModelStateResponseFactory = context =>
{
var result = new BadRequestObjectResult(context.HttpContext);
return result;
};
});
services.AddHttpClient();
//读取配置信息
Configuration.Bind("WebConfig", sysOptionConfig.Webconfig);
sysOptionConfig._Configuration = Configuration;
// 注入redis客户端
RedisClient cli = new RedisClient(sysOptionConfig.Webconfig.Redis + ",defaultDatabase=" + sysOptionConfig.Webconfig.RedisDb);
services.AddSingleton<IRedisClient>(cli);
services.AddAuthentication("Bearer").AddJwtBearer("Bearer", option =>
{
option.Authority = sysOptionConfig.Webconfig.IdentServerUrl;//授权服务的URl地址
option.RequireHttpsMetadata = false;//是否使用了https
option.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters { ValidateAudience = false };
IdentityModelEventSource.ShowPII = true;
});
//初始化数据库连接池
DbContext.DbBusInit();
////批量循环依赖注册
var ISList = Assembly.Load("djy.IService").GetTypes().Where(w => w.Name.EndsWith("Service") && w.Name.StartsWith("I"));
var Slist = Assembly.Load("djy.Service").GetTypes().Where(w => w.Name.EndsWith("Service"));
foreach (var Is in ISList)
{
var sname = Slist.FirstOrDefault(w => w.Name == Is.Name.Substring(1));
if (sname != null)
{
services.AddTransient(Is, sname);
}
}
services.AddAutoMapper(typeof(AutoMapperConfig));
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "djy_AfrApi", Version = "v1" });
});
IOC.container = services;
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "djy_AfrApi v1"));
}
// 记录请求响应数据
app.UseRequRespLogMiddleware();
// 处理特殊情况下的响应格式401、403
app.UseUnifyResultMiddleware();
// 异常处理中间件
app.UseExceptionHandlerMiddle();
app.UseRouting();
//DefaultFilesOptions defaultFiles = new DefaultFilesOptions();
//defaultFiles.DefaultFileNames.Clear();
//defaultFiles.DefaultFileNames.Add("index.html");
//app.UseDefaultFiles(defaultFiles);
//app.UseStaticFiles();
//跨域处理
app.UseCors(builder =>
{
builder.AllowAnyHeader();
builder.AllowAnyMethod();
//builder.WithOrigins("http://www.baidu.com");//跨域配置
builder.AllowAnyOrigin();
});
//认证
app.UseAuthentication();
//授权
app.UseAuthorization();
// 二次验证授权并保存当前登录人User对象为了和ISF、AMS逻辑保持一致
app.UseNextAuthorizationMiddle();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

@ -0,0 +1,68 @@
{
// 使
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Urls": "http://*:30818",
"WebConfig": {
"IdentServerUrl": "http://60.209.125.238:40501",
"WebId": 236,
"Area": "山东省|青岛市|市南区",
"DesKey": "2Fv6I7oV6AlCFEbN",
"jwt_Audience": "admin",
"jwt_Issuer": "shuosoft",
"jwt_Secretkey": "IBFoxBpwAW2rSDIsYiHJL5aZ3Rpr5Uaph4t6Eqm2Fv6I7oV6AlCFEbNWRXyJT653iOFIbWOcOF3sMRSSUelRSbIL6RzOCOfIk3hhxyn9Aj4HxEE08zqlRloA0CWX7MQ0",
"jwt_Expiration": 1440,
"StrFilte": "肏,妈妈,操你妈,草泥马,屌,傻逼,骚逼,王八蛋,你妈的,+,=,-,_,/,*,&,@,.,,,*",
"ShopPower": 1,
"ConnName": "sqldb",
"cache_time": 10,
"WebHostUrl": "http://127.0.0.1:30818",
"Redis": "192.168.0.80:6379,password=,defaultDatabase=12",
"RedisDb": 12,
"Rbmq_Host": "",
"Rbmq_UserName": "admin",
"Rbmq_Password": "admin",
"Rbmq_Sqlhost": "Data Source =60.209.125.238; Initial Catalog=djy_logs; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true",
"DapperDbString": "Data Source =60.209.125.238,32009; Initial Catalog=DevAMS; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;",
"DataConnList": [
{
"SysKey": "AMS",
"TitleName": "AMS",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=DevAMS; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;"
},
{
"SysKey": "Common",
"TitleName": "Common",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=DevCommonDB; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;"
},
{
"SysKey": "djydb",
"TitleName": "pingtai",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=TestDsPingTai; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true"
},
{
"SysKey": "logsdb",
"TitleName": "日志库",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=TestDjyLogs; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true"
}
]
}
}

@ -0,0 +1,69 @@
{
// 使
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Urls": "http://*:待配置待配置待配置待配置待配置待配置待配置待配置",
"WebConfig": {
"IdentServerUrl": "http://djy-identity.myshipping.net",
"WebId": 236,
"Area": "山东省|青岛市|市南区",
"DesKey": "2Fv6I7oV6AlCFEbN",
"jwt_Audience": "admin",
"jwt_Issuer": "shuosoft",
"jwt_Secretkey": "IBFoxBpwAW2rSDIsYiHJL5aZ3Rpr5Uaph4t6Eqm2Fv6I7oV6AlCFEbNWRXyJT653iOFIbWOcOF3sMRSSUelRSbIL6RzOCOfIk3hhxyn9Aj4HxEE08zqlRloA0CWX7MQ0",
"jwt_Expiration": 1440,
"StrFilte": "肏,妈妈,操你妈,草泥马,屌,傻逼,骚逼,王八蛋,你妈的,+,=,-,_,/,*,&,@,.,,,*",
"ShopPower": 1,
"ConnName": "sqldb",
"cache_time": 10,
"WebHostUrl": "https://zh-userapi.jingyiji.net",
"Redis": "172.31.85.169:6379,defaultDatabase=待配置,",
"RedisDb": "待配置",
"Rbmq_Host": "172.31.85.169:13866",
"Rbmq_UserName": "ams",
"Rbmq_Password": "djy_ams",
"Rbmq_Sqlhost": "Data Source =172.31.85.154; Initial Catalog=djy_logs; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true",
"DapperDbString": "Data Source =172.31.85.161; Initial Catalog=AMS; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true;",
"DataConnList": [
{
"SysKey": "AMS",
"TitleName": "AMS",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source=172.31.85.161; Initial Catalog=AMS; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true;"
},
{
"SysKey": "Common",
"TitleName": "Common",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source=172.31.85.161; Initial Catalog=CommonDB; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true;"
},
{
"SysKey": "djydb",
"TitleName": "pingtai",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =172.31.85.154; Initial Catalog=DsPingTai; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true"
},
{
"SysKey": "logsdb",
"TitleName": "日志库",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source=172.31.85.154,1433; Initial Catalog=djy_logs; Persist Security Info=True; User ID =sa; Password=QDdjy#2020*;pooling=true"
}
]
}
}

@ -0,0 +1,68 @@
{
// 使
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"Urls": "http://*:待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置",
"WebConfig": {
"IdentServerUrl": "http://60.209.125.238:40501",
"WebId": 236,
"Area": "山东省|青岛市|市南区",
"DesKey": "2Fv6I7oV6AlCFEbN",
"jwt_Audience": "admin",
"jwt_Issuer": "shuosoft",
"jwt_Secretkey": "IBFoxBpwAW2rSDIsYiHJL5aZ3Rpr5Uaph4t6Eqm2Fv6I7oV6AlCFEbNWRXyJT653iOFIbWOcOF3sMRSSUelRSbIL6RzOCOfIk3hhxyn9Aj4HxEE08zqlRloA0CWX7MQ0",
"jwt_Expiration": 1440,
"StrFilte": "肏,妈妈,操你妈,草泥马,屌,傻逼,骚逼,王八蛋,你妈的,+,=,-,_,/,*,&,@,.,,,*",
"ShopPower": 1,
"ConnName": "sqldb",
"cache_time": 10,
"WebHostUrl": "http://127.0.0.1:30818",
"Redis": "192.168.0.80:6379,password=,defaultDatabase=待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置",
"RedisDb": "待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置待配置",
"Rbmq_Host": "",
"Rbmq_UserName": "admin",
"Rbmq_Password": "admin",
"Rbmq_Sqlhost": "Data Source =60.209.125.238; Initial Catalog=djy_logs; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true",
"DapperDbString": "Data Source =60.209.125.238,32009; Initial Catalog=DevAMS; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;",
"DataConnList": [
{
"SysKey": "AMS",
"TitleName": "AMS",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=DevAMS; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;"
},
{
"SysKey": "Common",
"TitleName": "Common",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=DevCommonDB; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true;"
},
{
"SysKey": "djydb",
"TitleName": "pingtai",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=TestDsPingTai; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true"
},
{
"SysKey": "logsdb",
"TitleName": "日志库",
"Index": 100,
"DataType": 1,
"Status": 0,
"ConnString": "Data Source =60.209.125.238,32009; Initial Catalog=TestDjyLogs; Persist Security Info=True; User ID =sa; Password=sa@djy.net;pooling=true"
}
]
}
}

@ -0,0 +1,34 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Milldlewares\FluentResponseBodyMiddleware.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="FreeRedis" Version="1.2.11" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="5.0.17" />
<PackageReference Include="NLog.Database" Version="5.2.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.7" />
<PackageReference Include="IdentityServer4.AccessTokenValidation" Version="3.0.1" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="5.0.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Djy.Common\Common.csproj" />
<ProjectReference Include="..\djy.IService\djy.IService.csproj" />
<ProjectReference Include="..\djy.Model\djy.Model.csproj" />
<ProjectReference Include="..\djy.Service\djy.Service.csproj" />
</ItemGroup>
<ItemGroup>
<Content Update="NLog.config">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
</Project>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Controller_SelectedScaffolderID>ApiControllerEmptyScaffolder</Controller_SelectedScaffolderID>
<Controller_SelectedScaffolderCategoryPath>root/Common/Api</Controller_SelectedScaffolderCategoryPath>
<ActiveDebugProfile>djy_AfrApi</ActiveDebugProfile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DebuggerFlavor>ProjectDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

@ -75,9 +75,20 @@ namespace djy_IsfApi
}
response.ContentType = "application/json";
await response.WriteAsync(JsonSerializer.Serialize(rr, new JsonSerializerOptions(JsonSerializerDefaults.Web))).ConfigureAwait(false);
/*
*
{
"code": 401,
"Status": false,
"message": "授权验证失败或已过期,请重新登录",
"getTime": 1703135086,
"runTime": 1238.5565,
"data": null,
"memoData": null
}
*/
}
}

@ -25,7 +25,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "djy.Service", "djy.Service\
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "djy_IsfApi", "djy_IsfApi\djy_IsfApi.csproj", "{B9B3283E-FA06-4B06-88F1-5680AC4E5F26}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "djy_Report", "djy_Report\djy_Report.csproj", "{A201194B-42CA-41BF-8123-7DB5D332C940}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "djy_Report", "djy_Report\djy_Report.csproj", "{A201194B-42CA-41BF-8123-7DB5D332C940}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "djy_AfrApi", "djy_AfrApi\djy_AfrApi.csproj", "{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@ -61,6 +63,10 @@ Global
{A201194B-42CA-41BF-8123-7DB5D332C940}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A201194B-42CA-41BF-8123-7DB5D332C940}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A201194B-42CA-41BF-8123-7DB5D332C940}.Release|Any CPU.Build.0 = Release|Any CPU
{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -73,6 +79,7 @@ Global
{263A1D6E-4453-419E-8FFB-06F3AC18AAC9} = {1E6EFB04-DE56-4879-81CB-0DDEAB09EBCB}
{B9B3283E-FA06-4B06-88F1-5680AC4E5F26} = {E3B4DD84-D374-432C-AEA9-782D33748578}
{A201194B-42CA-41BF-8123-7DB5D332C940} = {E3B4DD84-D374-432C-AEA9-782D33748578}
{E798A4EC-13E8-4681-8DB7-CB9F3C32A3EE} = {E3B4DD84-D374-432C-AEA9-782D33748578}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {822B0661-DA88-4792-AAF3-C508FB88AF3B}

Loading…
Cancel
Save