Parcourir la source

!1062 系统完善
Merge pull request !1062 from Hans/next

zuohuaijun il y a 1 an
Parent
commit
c38c4536c9

+ 1 - 1
Admin.NET/Admin.NET.Core/Const/CacheConst.cs

@@ -90,4 +90,4 @@ public class CacheConst
     /// 黑名单
     /// </summary>
     public const string KeyBlacklist = "sys_blacklist:";
-}
+}

+ 26 - 0
Admin.NET/Admin.NET.Core/Const/SysToDoEventConst.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core;
+
+/// <summary>
+/// 系统事件常量
+/// </summary>
+public class SysToDoEventConst
+{
+
+    /// <summary>
+    /// 增加异常日志
+    /// </summary>
+    public const string AddExLog = "Add:ExLog";
+    /// <summary>
+    /// 发送异常邮件
+    /// </summary>
+    public const string SendErrorMail = "Send:ErrorMail";
+
+
+
+}

+ 2 - 2
Admin.NET/Admin.NET.Core/EventBus/AppEventSubscriber.cs

@@ -23,7 +23,7 @@ public class AppEventSubscriber : IEventSubscriber, ISingleton, IDisposable
     /// </summary>
     /// <param name="context"></param>
     /// <returns></returns>
-    [EventSubscribe("Add:ExLog")]
+    [EventSubscribe(SysToDoEventConst.AddExLog)]
     public async Task CreateExLog(EventHandlerExecutingContext context)
     {
         var rep = _serviceScope.ServiceProvider.GetRequiredService<SqlSugarRepository<SysLogEx>>();
@@ -35,7 +35,7 @@ public class AppEventSubscriber : IEventSubscriber, ISingleton, IDisposable
     /// </summary>
     /// <param name="context"></param>
     /// <returns></returns>
-    [EventSubscribe("Send:ErrorMail")]
+    [EventSubscribe(SysToDoEventConst.SendErrorMail)]
     public async Task SendOrderErrorMail(EventHandlerExecutingContext context)
     {
         //var mailTempPath = Path.Combine(App.WebHostEnvironment.WebRootPath, "Temp\\ErrorMail.tp");

+ 1 - 1
Admin.NET/Admin.NET.Core/Logging/DatabaseLoggingWriter.cs

@@ -123,7 +123,7 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter, IDisposable
                 // 将异常日志发送到邮件
                 if (await _sysConfigService.GetConfigValue<bool>(CommonConst.SysErrorMail))
                 {
-                    await App.GetRequiredService<IEventPublisher>().PublishAsync("Send:ErrorMail", loggingMonitor.exception);
+                    await App.GetRequiredService<IEventPublisher>().PublishAsync(SysToDoEventConst.SendErrorMail, loggingMonitor.exception);
                 }
 
                 return;

+ 1 - 1
Admin.NET/Admin.NET.Core/Service/Job/DbJobPersistence.cs

@@ -195,4 +195,4 @@ public class DbJobPersistence : IJobPersistence
             await db.Insertable(jobTriggerRecord).ExecuteCommandAsync();
         }
     }
-}
+}

+ 50 - 0
Admin.NET/Admin.NET.Core/Service/Job/JobMonitor.cs

@@ -0,0 +1,50 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Core.Service;
+
+/// <summary>
+/// 作业执行监视器
+/// </summary>
+public class JobMonitor : IJobMonitor, IDisposable
+{
+    private readonly IEventPublisher _eventPublisher;
+    private readonly IServiceScope _serviceScope;
+    private readonly SysConfigService _sysConfigService; // 参数配置服务
+    public JobMonitor(IServiceScopeFactory scopeFactory)
+    {
+
+        _serviceScope = scopeFactory.CreateScope();
+        _sysConfigService = _serviceScope.ServiceProvider.GetRequiredService<SysConfigService>();
+        _eventPublisher = _serviceScope.ServiceProvider.GetRequiredService<IEventPublisher>(); ;
+    }
+
+
+
+    public async Task OnExecutedAsync(JobExecutedContext context, CancellationToken stoppingToken)
+    {
+        if (await _sysConfigService.GetConfigValue<bool>(CommonConst.SysErrorMail) && context.Exception != null)
+        {
+            var errorInfo = $"【{context.Trigger.Description}】出现错误:{context.Exception.InnerException}";
+            // 将异常日志发送到邮件
+            await _eventPublisher.PublishAsync(SysToDoEventConst.SendErrorMail, errorInfo);
+        }
+
+    }
+
+    public Task OnExecutingAsync(JobExecutingContext context, CancellationToken stoppingToken)
+    {
+        return Task.CompletedTask;
+    }
+
+    /// <summary>
+    /// 释放服务作用域
+    /// </summary>
+    public void Dispose()
+    {
+        _serviceScope.Dispose();
+    }
+}

+ 1 - 0
Admin.NET/Admin.NET.Web.Core/Startup.cs

@@ -52,6 +52,7 @@ public class Startup : AppStartup
         services.AddSchedule(options =>
         {
             options.AddPersistence<DbJobPersistence>(); // 添加作业持久化器
+            options.AddMonitor<JobMonitor>(); //添加作业执行监视器
         });
         // 脱敏检测
         services.AddSensitiveDetection();

BIN
Web/src/assets/bg.svg


+ 14 - 3
Web/src/views/login/component/account.vue

@@ -1,4 +1,5 @@
 <template>
+	<el-tooltip :visible="state.capsLockVisible" effect="light" content="大写锁定已打开" placement="top">
 	<el-form ref="ruleFormRef" :model="state.ruleForm" size="large" :rules="state.rules" class="login-content-form">
 		<el-form-item class="login-animation1" prop="account">
 			<el-input ref="accountRef" text placeholder="请输入账号" v-model="state.ruleForm.account" clearable autocomplete="off" @keyup.enter.native="handleSignIn">
@@ -55,7 +56,7 @@
 		<div class="font12 mt30 login-animation4 login-msg">{{ $t('message.mobile.msgText') }}</div>
 		<!-- <el-button type="primary" round v-waves @click="weixinSignIn" :loading="state.loading.signIn"></el-button> -->
 	</el-form>
-
+	</el-tooltip>
 	<div class="dialog-header">
 		<el-dialog v-model="state.rotateVerifyVisible" :show-close="false">
 			<DragVerifyImgRotate
@@ -73,7 +74,7 @@
 </template>
 
 <script lang="ts" setup name="loginAccount">
-import { reactive, computed, ref, onMounted, defineAsyncComponent } from 'vue';
+import { reactive, computed, ref, onMounted, defineAsyncComponent, onUnmounted } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import { ElMessage, InputInstance } from 'element-plus';
 import { useI18n } from 'vue-i18n';
@@ -122,6 +123,7 @@ const state = reactive({
 	secondVerEnabled: false,
 	captchaEnabled: false,
 	isPassRotate: false,
+	capsLockVisible: false,
 });
 onMounted(async () => {
 	// 若URL带有Token参数(第三方登录)
@@ -134,9 +136,18 @@ onMounted(async () => {
 	var res1 = await getAPI(SysAuthApi).apiSysAuthLoginConfigGet();
 	state.secondVerEnabled = res1.data.result.secondVerEnabled ?? true;
 	state.captchaEnabled = res1.data.result.captchaEnabled ?? true;
-
 	getCaptcha();
+	// Caps Lock检测
+	document.addEventListener('keyup', handleKeyPress);
+});
+onUnmounted(() => {
+	document.removeEventListener('keyup', handleKeyPress);
 });
+const handleKeyPress = (e:any) => {
+	const isCapsLockOn = e.getModifierState('CapsLock');
+	state.capsLockVisible = isCapsLockOn;
+};
+
 // 获取验证码
 const getCaptcha = async () => {
 	if (!state.captchaEnabled) return;

+ 23 - 0
Web/src/views/login/index.vue

@@ -136,6 +136,11 @@ onMounted(() => {
 		width: 50%;
 		float: right;
 		background: var(--el-color-white);
+		background-image: url('../../assets/bg.svg');
+		background-size: 100% auto;
+		background-position: 50% calc(50% - 15px);
+		background-attachment: fixed;
+		background-repeat: no-repeat;
 		.login-right-warp {
 			border: 1px solid var(--el-color-primary-light-3);
 			border-radius: 3px;
@@ -255,6 +260,24 @@ onMounted(() => {
 				}
 			}
 		}
+		/* 在这里可以添加一个伪元素来覆盖原内容,实现磨砂效果 */
+		.login-right-warp::before {
+			content: '';
+			position: absolute;
+			top: 0;
+			left: 0;
+			width: 100%;
+			height: 100%;
+			background-color: rgba(255, 255, 255, 1);
+			filter: blur(4px); /* 调整模糊半径以改变磨砂效果强度 */
+			z-index: 1;
+		}
+
+		/* 保持原有内容可见,放置在伪元素下方 */
+		.login-right-warp > * {
+			position: relative;
+			z-index: 2;
+		}
 	}
 }
 .copyright {