diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/DTOs/PageLockDto.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/DTOs/PageLockDto.cs
new file mode 100644
index 000000000..07396938f
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/DTOs/PageLockDto.cs
@@ -0,0 +1,24 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public class PageLockDto : SfsAuthDtoBase
+{
+ ///
+ /// 菜单代码
+ ///
+ public string MenuCode { get; set; }
+
+ ///
+ /// 用户账户
+ ///
+ public string UserAccount { get; set; }
+
+ ///
+ /// 登录时间
+ ///
+ public string LoginTime { get; set; }
+
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/IPageLockAppService.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/IPageLockAppService.cs
new file mode 100644
index 000000000..37536fc3a
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/IPageLockAppService.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public interface IPageLockAppService : ISfsAuthCrudAppService
+{
+ Task LockLoginAsync(string menuCode,string userAccount);
+ Task LockLogoutAsync(string menuCode, string userAccount);
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateInput.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateInput.cs
new file mode 100644
index 000000000..631b06a9d
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateInput.cs
@@ -0,0 +1,5 @@
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public class PageLockCreateInput : PageLockCreateUpdateInputBase
+{
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateUpdateInputBase.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateUpdateInputBase.cs
new file mode 100644
index 000000000..97bde1ddd
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockCreateUpdateInputBase.cs
@@ -0,0 +1,24 @@
+using System;
+using System.ComponentModel.DataAnnotations;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public abstract class PageLockCreateUpdateInputBase : SfsAuthCreateUpdateInputBase
+{
+ ///
+ /// 菜单代码
+ ///
+ public string MenuCode { get; set; }
+
+ ///
+ /// 用户账户
+ ///
+ public string UserAccount { get; set; }
+
+ ///
+ /// 登录时间
+ ///
+ public string LoginTime { get; set; }
+
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockUpdateInput.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockUpdateInput.cs
new file mode 100644
index 000000000..c5bd103d8
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/Inputs/PageLockUpdateInput.cs
@@ -0,0 +1,14 @@
+using System.ComponentModel.DataAnnotations;
+using Volo.Abp.Domain.Entities;
+
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public class PageLockUpdateInput : PageLockCreateUpdateInputBase, IHasConcurrencyStamp
+{
+ ///
+ /// 乐观锁
+ ///
+ [Display(Name = "乐观锁")]
+ [Required(ErrorMessage = "{0}是必填项")]
+ public string ConcurrencyStamp { get; set; }
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/PageLockPermissions.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/PageLockPermissions.cs
new file mode 100644
index 000000000..9df8b09df
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/PageLock/PageLockPermissions.cs
@@ -0,0 +1,27 @@
+using Volo.Abp.Authorization.Permissions;
+using Win_in.Sfs.Auth.Domain;
+using Win_in.Sfs.Auth.Permissions;
+
+namespace Win_in.Sfs.Auth.Application.Contracts;
+
+public static class PageLockPermissions
+{
+ public const string Default = AuthPermissions.GroupName + "." + nameof(PageLock);
+ public const string Create = Default + "." + AuthPermissions.CreateStr;
+ public const string Update = Default + "." + AuthPermissions.UpdateStr;
+ public const string Delete = Default + "." + AuthPermissions.DeleteStr;
+
+ //POA菜单
+ public const string PageLock = AuthPermissions.GroupName + "." + nameof(PageLock);
+
+ public static void AddPageLockPermission(this PermissionGroupDefinition permissionGroup)
+ {
+ var PageLockPermission = permissionGroup.AddPermission(Default, AuthPermissionDefinitionProvider.L(nameof(PageLock)));
+ PageLockPermission.AddChild(Create, AuthPermissionDefinitionProvider.L(AuthPermissions.CreateStr));
+ PageLockPermission.AddChild(Update, AuthPermissionDefinitionProvider.L(AuthPermissions.UpdateStr));
+ PageLockPermission.AddChild(Delete, AuthPermissionDefinitionProvider.L(AuthPermissions.DeleteStr));
+
+ permissionGroup.AddPermission(PageLock, AuthPermissionDefinitionProvider.L(nameof(PageLock)));
+
+ }
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/Permissions/AuthPermissionDefinitionProvider.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/Permissions/AuthPermissionDefinitionProvider.cs
index bf2fe27f7..4e9efc6b2 100644
--- a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/Permissions/AuthPermissionDefinitionProvider.cs
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application.Contracts/Permissions/AuthPermissionDefinitionProvider.cs
@@ -21,6 +21,7 @@ public class AuthPermissionDefinitionProvider : PermissionDefinitionProvider
authGroup.AddUserMenuPermission();
authGroup.AddUserWorkGroupPermission();
authGroup.AddDepartmentPermission();
+ authGroup.AddPageLockPermission();
}
public static LocalizableString L(string name)
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAppService.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAppService.cs
new file mode 100644
index 000000000..451aab42b
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAppService.cs
@@ -0,0 +1,76 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using DocumentFormat.OpenXml.Office2010.Excel;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Volo.Abp;
+using Volo.Abp.Application.Dtos;
+using Volo.Abp.Identity;
+using Volo.Abp.ObjectMapping;
+using Volo.Abp.PermissionManagement;
+using Volo.Abp.Uow;
+using Volo.Abp.Users;
+using Win_in.Sfs.Auth.Application.Contracts;
+using Win_in.Sfs.Auth.Domain;
+using Win_in.Sfs.Shared.Domain.Shared;
+
+namespace Win_in.Sfs.Auth.Application;
+
+[AllowAnonymous]
+[Route($"{AuthConsts.RootPath}page-lock")]
+public class PageLockAppService :
+ SfsAuthCrudAppServiceBase,
+ IPageLockAppService
+{
+
+ public PageLockAppService(
+ IPageLockRepository repository) : base(repository)
+ {
+ base.CreatePolicyName = PageLockPermissions.Create;
+ base.UpdatePolicyName = PageLockPermissions.Update;
+ base.DeletePolicyName = PageLockPermissions.Delete;
+ }
+
+ [HttpGet("lock-login")]
+ [AllowAnonymous]
+ [UnitOfWork]
+ public async Task LockLoginAsync(string menuCode,string userAccount)
+ {
+ var pageLock=await _repository.GetListAsync(p=>p.MenuCode==menuCode).ConfigureAwait(false);
+ if (pageLock.Count == 1&& pageLock.First().UserAccount== userAccount)
+ {
+ return;
+ }
+
+ if (pageLock.Count>1)
+ {
+ throw new UserFriendlyException($"该页面已被多人锁定锁定,请联系管理员清除锁定信息");
+ }
+
+ if (pageLock.Count == 1 && userAccount != pageLock.First().UserAccount)
+ {
+ throw new UserFriendlyException($"该页面已被{pageLock.First().UserAccount}用户锁定");
+ }
+
+ await _repository.InsertAsync(new PageLock()
+ {
+ UserAccount = userAccount,
+ LoginTime = DateTime.Now.ToString("yyyy-MM-dd HH:ss:mm"),
+ MenuCode = menuCode
+ }).ConfigureAwait(false);
+ }
+
+ [HttpGet("lock-logout")]
+ [AllowAnonymous]
+ [UnitOfWork]
+ public async Task LockLogoutAsync(string menuCode, string userAccount)
+ {
+ var pageLock = await _repository.GetListAsync(p => p.MenuCode == menuCode&&p.UserAccount==userAccount).ConfigureAwait(false);
+ if (pageLock.Count==1)
+ {
+ await _repository.DeleteAsync(pageLock.First()).ConfigureAwait(false);
+ }
+ }
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAutoMapperProfile.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAutoMapperProfile.cs
new file mode 100644
index 000000000..e691700a8
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Application/PageLock/PageLockAutoMapperProfile.cs
@@ -0,0 +1,29 @@
+using AutoMapper;
+using Volo.Abp.AutoMapper;
+using Win_in.Sfs.Auth.Application.Contracts;
+using Win_in.Sfs.Auth.Domain;
+
+namespace Win_in.Sfs.Auth.Application;
+
+public class PageLockAutoMapperProfile : Profile
+{
+ public PageLockAutoMapperProfile()
+ {
+ CreateMap()
+ .IgnoreAuditedObjectProperties()
+ ;
+
+ CreateMap()
+ .IgnoreAuditedObjectProperties()
+ .Ignore(x => x.ConcurrencyStamp)
+ .Ignore(x => x.Id)
+ ;
+
+ CreateMap()
+ .IgnoreAuditedObjectProperties()
+
+ .Ignore(x => x.Id)
+ ;
+ ;
+ }
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/IUserMenuRepository.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/IUserMenuRepository.cs
new file mode 100644
index 000000000..89b6af484
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/IUserMenuRepository.cs
@@ -0,0 +1,5 @@
+namespace Win_in.Sfs.Auth.Domain;
+
+public interface IPageLockRepository : ISfsAuthRepository
+{
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/PageLock.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/PageLock.cs
new file mode 100644
index 000000000..4d2eecdc7
--- /dev/null
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.Domain/PageLock/PageLock.cs
@@ -0,0 +1,22 @@
+using System;
+using Win_in.Sfs.Auth.Domain;
+
+namespace Win_in.Sfs.Auth.Domain;
+
+public class PageLock : SfsAuthAggregateRootBase
+{
+ ///
+ /// 菜单代码
+ ///
+ public string MenuCode { get; set; }
+
+ ///
+ /// 用户账户
+ ///
+ public string UserAccount { get; set; }
+
+ ///
+ /// 登录时间
+ ///
+ public string LoginTime { get; set; }
+}
diff --git a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.EntityFrameworkCore/EntityFrameworkCore/AuthDbContext.cs b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.EntityFrameworkCore/EntityFrameworkCore/AuthDbContext.cs
index 933ea1060..f9aaa1d6b 100644
--- a/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.EntityFrameworkCore/EntityFrameworkCore/AuthDbContext.cs
+++ b/be/Hosts/Auth.Host/src/Win_in.Sfs.Auth.EntityFrameworkCore/EntityFrameworkCore/AuthDbContext.cs
@@ -70,6 +70,7 @@ public class AuthDbContext :
public DbSet