Merge branch 'Test_IRC_Net8' of https://gitea.frp.extimaging.com/XCKJ/irc-netcore-api into Test_IRC_Net8
continuous-integration/drone/push Build is passing Details

Test_IRC_Net8
he 2026-02-09 17:12:20 +08:00
commit 0862182f8e
7 changed files with 214 additions and 35 deletions

View File

@ -39,6 +39,8 @@ namespace IRaCIS.Core.API._PipelineExtensions.Serilog
var requestBodyPayload = await ReadRequestBody(context.Request); var requestBodyPayload = await ReadRequestBody(context.Request);
context.Items["RequestBody"] = requestBodyPayload;
using (LogContext.PushProperty("RequestBody", requestBodyPayload)) using (LogContext.PushProperty("RequestBody", requestBodyPayload))
{ {
//await _next.Invoke() //await _next.Invoke()

View File

@ -3,7 +3,7 @@
"SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021", "SecurityKey": "ShangHaiZhanYing_SecurityKey_SHzyyl@2021",
"Issuer": "Extimaging", "Issuer": "Extimaging",
"Audience": "EICS", "Audience": "EICS",
"TokenExpireMinute": "10080"//7 "TokenExpireMinute": "10080" //7
}, },
"IpRateLimiting": { "IpRateLimiting": {
"EnableEndpointRateLimiting": true, "EnableEndpointRateLimiting": true,
@ -43,6 +43,12 @@
} }
] ]
}, },
"WeComNoticeConfig": {
"IsOpenWeComNotice": true,
"WebhookUrl": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=4355b98e-1e72-4678-8dfb-2fc6ad0bf449", //4355b98e-1e72-4678-8dfb-2fc6ad0bf449 //cdd97aab-d256-4f07-9145-a0a2b1555322
"APINoticeUserList": [ "ZhouHang" ],
"VueNoticeUserList": [ "wangxiaoshuang" ]
},
"IRaCISImageStore": { "IRaCISImageStore": {
"SwitchingMode": "RemainingDiskCapacity", "SwitchingMode": "RemainingDiskCapacity",
"SwitchingRatio": 80, "SwitchingRatio": 80,

View File

@ -1,18 +1,22 @@
using Microsoft.AspNetCore.Mvc; using IRaCIS.Core.Application.Helper.OtherTool;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using Microsoft.AspNetCore.Mvc.ModelBinding.Binders; using Microsoft.AspNetCore.Mvc.ModelBinding.Binders;
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata; using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Newtonsoft.Json; using Newtonsoft.Json;
using System;
using System.Reflection; using System.Reflection;
using static System.Runtime.InteropServices.JavaScript.JSType;
namespace IRaCIS.Core.Application.Filter; namespace IRaCIS.Core.Application.Filter;
public class ModelActionFilter(IStringLocalizer _localizer) : ActionFilterAttribute, IActionFilter public class ModelActionFilter(IStringLocalizer _localizer, IConfiguration _config, IUserInfo _userInfo) : ActionFilterAttribute, IActionFilter
{ {
@ -27,6 +31,49 @@ public class ModelActionFilter(IStringLocalizer _localizer) : ActionFilterAttrib
.Select(e => e.ErrorMessage) .Select(e => e.ErrorMessage)
.ToArray(); .ToArray();
var request = context.HttpContext.Request;
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:VueNoticeUserList").Get<string[]>();
var requestBody = context.HttpContext.Items["RequestBody"] as string;
// 🔔 异步告警(不要阻塞请求)
_ = WeComNotifier.SendAlertAsync(
webhook: webhook,
alert: new WeComAlert
{
Env = baseUrl,
UserName = _userInfo.UserName.IsNotNullOrEmpty()? $"{_userInfo.UserName}({_userInfo.UserTypeShortName})": "匿名",
Api = $"{request.Method} {request.Path}",
Message = $"前端传递参数,后端模型验证失败\n 具体信息:{JsonConvert.SerializeObject(validationErrors)}",
JsonData = requestBody,
AtUsers = userList ?? []
}
);
}
}
catch (Exception ex)
{
Log.Logger.Error($"模型验证过滤器里发送企业微信出现错误:{ex.Message}");
}
//---提供给接口的参数无效。 //---提供给接口的参数无效。
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject(validationErrors))); context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["ModelAction_InvalidAPIParameter"] + JsonConvert.SerializeObject(validationErrors)));
} }

View File

@ -1,13 +1,16 @@
using IRaCIS.Core.Domain.Share; using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Domain.Share;
using IRaCIS.Core.Infrastructure; using IRaCIS.Core.Infrastructure;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters; using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Localization; using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
namespace IRaCIS.Core.Application.Filter; namespace IRaCIS.Core.Application.Filter;
public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, IStringLocalizer _localizer) : Attribute, IExceptionFilter public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, IStringLocalizer _localizer, IConfiguration _config, IUserInfo _userInfo) : Attribute, IExceptionFilter
{ {
public void OnException(ExceptionContext context) public void OnException(ExceptionContext context)
@ -48,6 +51,43 @@ public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, ISt
context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message) context.Result = new JsonResult(ResponseOutput.NotOk(_localizer["Project_ExceptionContactDeveloper"] + (exception.InnerException is null ? (exception.Message)
: (exception.Message + "Inner ExceptionMsg:" + exception.InnerException?.Message)), ApiResponseCodeEnum.ProgramException)); : (exception.Message + "Inner ExceptionMsg:" + exception.InnerException?.Message)), ApiResponseCodeEnum.ProgramException));
try
{
bool isOpenWeComNotice = _config.GetValue<bool>("WeComNoticeConfig:IsOpenWeComNotice");
if (isOpenWeComNotice)
{
string webhook = _config["WeComNoticeConfig:WebhookUrl"] ?? string.Empty;
var uri = new Uri(_config["SystemEmailSendConfig:SiteUrl"]);
var baseUrl = uri.GetLeftPart(UriPartial.Authority);
var userList = _config.GetSection("WeComNoticeConfig:APINoticeUserList").Get<string[]>();
var requestBody = context.HttpContext.Items["RequestBody"] as string;
var alert = new WeComAlert
{
Env = baseUrl,
UserName = $"{_userInfo.UserName}({_userInfo.UserTypeShortName})",
Api = context.HttpContext.Request.Path,
Message = exception.Message,
JsonData = requestBody,
Stack = exception.StackTrace,
AtUsers = userList ?? []
};
_ = WeComNotifier.SendAlertAsync(webhook, alert);
}
}
catch (Exception ex)
{
_logger.LogError($"异常过滤器里发送企业微信出现错误:{ex.Message}");
}
} }
context.ExceptionHandled = true;//标记当前异常已经被处理过了 context.ExceptionHandled = true;//标记当前异常已经被处理过了
@ -58,6 +98,7 @@ public class ProjectExceptionFilter(ILogger<ProjectExceptionFilter> _logger, ISt
_logger.LogError(errorInfo); _logger.LogError(errorInfo);
//_logger.LogError(exception, exception.Message); //_logger.LogError(exception, exception.Message);
} }
else else

View File

@ -0,0 +1,98 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using RestSharp;
using System.Net;
using System.Threading.Tasks;
using IdentityModel;
namespace IRaCIS.Core.Application.Helper.OtherTool;
public class WeComAlert
{
public string Env { get; set; } = "";
public string UserName { get; set; } = "";
public string Api { get; set; } = "";
public string Message { get; set; } = "";
public string? JsonData { get; set; }
public string? Stack { get; set; }
public bool HasStack => !string.IsNullOrWhiteSpace(Stack);
public string[] AtUsers { get; set; } = [];
}
public static class WeComNotifier
{
public static async Task SendAlertAsync(string webhook, WeComAlert alert)
{
try
{
var client = new RestClient();
var request = new RestRequest(webhook, Method.Post);
var time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
// 处理 @
var atText = alert.AtUsers != null && alert.AtUsers.Any()
? string.Join("", alert.AtUsers.Select(u => $" <@{u}>"))
: "";
// 处理堆栈
var stack = alert.Stack;
if (!string.IsNullOrWhiteSpace(stack))
{
stack = stack.Replace("\n", "\n> ");
if (stack.Length > 1200)
stack = stack[..1200] + "...(已截断)";
}
var markdown = $@"## 🚨 系统告警
> {atText}
> **** [{alert.Env}]({alert.Env})
> **** {time}
> **** {alert.UserName}
> **** {alert.Api}
###
<font color=""warning"">{alert.Message}</font>";
if (!string.IsNullOrWhiteSpace(alert.JsonData))
{
markdown += $@"
> **📦 JSON **
```json
{alert.JsonData}
```";
}
if (!string.IsNullOrWhiteSpace(stack))
{
markdown += $@"
###
<font color=""comment"">{stack}</font>";
}
var payload = new
{
msgtype = "markdown",
markdown = new { content = markdown }
};
request.AddHeader("Content-Type", "application/json");
request.AddStringBody(JsonConvert.SerializeObject(payload), DataFormat.Json);
await client.ExecuteAsync(request);
}
catch (Exception ex)
{
Log.Logger.Error("企业微信告警发送失败: " + ex.Message);
}
}
}

View File

@ -6,6 +6,7 @@ using IRaCIS.Application.Contracts;
using IRaCIS.Core.Application.BusinessFilter; using IRaCIS.Core.Application.BusinessFilter;
using IRaCIS.Core.Application.Contracts; using IRaCIS.Core.Application.Contracts;
using IRaCIS.Core.Application.Helper; using IRaCIS.Core.Application.Helper;
using IRaCIS.Core.Application.Helper.OtherTool;
using IRaCIS.Core.Application.Service.BusinessFilter; using IRaCIS.Core.Application.Service.BusinessFilter;
using IRaCIS.Core.Application.ViewModel; using IRaCIS.Core.Application.ViewModel;
using IRaCIS.Core.Domain; using IRaCIS.Core.Domain;
@ -109,10 +110,13 @@ namespace IRaCIS.Core.Application.Service
//创建一个模型验证的方法 //创建一个模型验证的方法
[AllowAnonymous] [AllowAnonymous]
[HttpPost] [HttpPost("{email}")]
public async Task<IResponseOutput> PostModelVerify(ModelVerifyCommand modelVerify) public async Task<IResponseOutput> PostModelVerify(ModelVerifyCommand modelVerify)
{ {
var webhook = "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=cdd97aab-d256-4f07-9145-a0a2b1555322";
//await WeComNotifier.SendErrorAsync(webhook, "http://irc.test.extimaging.com/login", new Exception("测试异常"), new[] { "ZhouHang" });
//throw new Exception("手动测试异常抛出");
return ResponseOutput.Ok(modelVerify); return ResponseOutput.Ok(modelVerify);
} }

View File

@ -43,10 +43,16 @@ server:
from_secret: test_ssh_pwd from_secret: test_ssh_pwd
steps: steps:
- name: publish-test-irc - name: publish-test-irc
commands: commands:
- bash /opt/1panel/xc-deploy-new/Test_IRC_Swarm/devops-publish/test-branch-publish.sh - bash /opt/1panel/xc-deploy-new/Test_IRC_Swarm/devops-publish/test-branch-publish.sh
- name: notify-wecom
commands:
- bash /opt/1panel/xc-deploy-new/devops-center/drone-notify-wecom.sh "$DRONE_BUILD_STATUS" "$DRONE_REPO_NAME" "$DRONE_BRANCH" "$DRONE_BUILD_NUMBER" "4355b98e-1e72-4678-8dfb-2fc6ad0bf449" "$DRONE_COMMIT_MESSAGE" "$DRONE_COMMIT_AUTHOR" "Test_IRC_API Test_IRC_SCP_API" "irc.test.extimaging.com"
when:
status:
- success
- failure
trigger: trigger:
branch: branch:
- Test_IRC_Net8 - Test_IRC_Net8
@ -81,32 +87,7 @@ trigger:
branch: branch:
- Test_Study_Net8 - Test_Study_Net8
---
kind: pipeline
type: ssh
name: ssh-linux-test-hir
platform:
os: Linux
arch: 386
clone:
disable: true #禁用默认克隆
server:
host: 106.14.89.110
user: root
password:
from_secret: test_ssh_pwd
steps:
- name: publish-test-hir
commands:
- bash /opt/1panel/xc-deploy-new/Test_HIR/devops-publish/test-branch-publish.sh
trigger:
branch:
- Test_HIR