Эх сурвалжийг харах

feat: 增加解除登录锁定

许俊杰 2 жил өмнө
parent
commit
b517a088dc

+ 1 - 0
Admin.NET/Admin.NET.Core/SeedData/SysMenuSeedData.cs

@@ -40,6 +40,7 @@ public class SysMenuSeedData : ISqlSugarEntitySeedData<SysMenu>
             new SysMenu{ Id=1310000000118, Pid=1310000000111, Title="重置密码", Permission="sysUser:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000118, Pid=1310000000111, Title="重置密码", Permission="sysUser:resetPwd", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000119, Pid=1310000000111, Title="设置状态", Permission="sysUser:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000119, Pid=1310000000111, Title="设置状态", Permission="sysUser:setStatus", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000120, Pid=1310000000111, Title="强制下线", Permission="sysOnlineUser:forceOffline", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000120, Pid=1310000000111, Title="强制下线", Permission="sysOnlineUser:forceOffline", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
+            new SysMenu{ Id=1310000000121, Pid=1310000000111, Title="解除登录锁定", Permission="sysUser:unlockLogin", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
 
 
             new SysMenu{ Id=1310000000131, Pid=1310000000101, Title="角色管理", Path="/system/role", Name="sysRole", Component="/system/role/index", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
             new SysMenu{ Id=1310000000131, Pid=1310000000101, Title="角色管理", Path="/system/role", Name="sysRole", Component="/system/role/index", Icon="ele-Help", Type=MenuTypeEnum.Menu, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=110 },
             new SysMenu{ Id=1310000000132, Pid=1310000000131, Title="查询", Permission="sysRole:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },
             new SysMenu{ Id=1310000000132, Pid=1310000000131, Title="查询", Permission="sysRole:page", Type=MenuTypeEnum.Btn, CreateTime=DateTime.Parse("2022-02-10 00:00:00"), OrderNo=100 },

+ 28 - 0
Admin.NET/Admin.NET.Core/Service/User/Dto/UserInput.cs

@@ -9,6 +9,9 @@
 
 
 namespace Admin.NET.Core.Service;
 namespace Admin.NET.Core.Service;
 
 
+/// <summary>
+/// 设置用户状态输入参数
+/// </summary>
 public class UserInput : BaseIdInput
 public class UserInput : BaseIdInput
 {
 {
     /// <summary>
     /// <summary>
@@ -17,6 +20,9 @@ public class UserInput : BaseIdInput
     public StatusEnum Status { get; set; }
     public StatusEnum Status { get; set; }
 }
 }
 
 
+/// <summary>
+/// 获取用户分页列表输入参数
+/// </summary>
 public class PageUserInput : BasePageInput
 public class PageUserInput : BasePageInput
 {
 {
     /// <summary>
     /// <summary>
@@ -40,6 +46,9 @@ public class PageUserInput : BasePageInput
     public long OrgId { get; set; }
     public long OrgId { get; set; }
 }
 }
 
 
+/// <summary>
+/// 增加用户输入参数
+/// </summary>
 public class AddUserInput : SysUser
 public class AddUserInput : SysUser
 {
 {
     /// <summary>
     /// <summary>
@@ -65,10 +74,16 @@ public class AddUserInput : SysUser
     public List<SysUserExtOrg> ExtOrgIdList { get; set; }
     public List<SysUserExtOrg> ExtOrgIdList { get; set; }
 }
 }
 
 
+/// <summary>
+/// 更新用户输入参数
+/// </summary>
 public class UpdateUserInput : AddUserInput
 public class UpdateUserInput : AddUserInput
 {
 {
 }
 }
 
 
+/// <summary>
+/// 删除用户输入参数
+/// </summary>
 public class DeleteUserInput : BaseIdInput
 public class DeleteUserInput : BaseIdInput
 {
 {
     /// <summary>
     /// <summary>
@@ -77,10 +92,16 @@ public class DeleteUserInput : BaseIdInput
     public long OrgId { get; set; }
     public long OrgId { get; set; }
 }
 }
 
 
+/// <summary>
+/// 重置用户密码输入参数
+/// </summary>
 public class ResetPwdUserInput : BaseIdInput
 public class ResetPwdUserInput : BaseIdInput
 {
 {
 }
 }
 
 
+/// <summary>
+/// 修改用户密码输入参数
+/// </summary>
 public class ChangePwdInput
 public class ChangePwdInput
 {
 {
     /// <summary>
     /// <summary>
@@ -95,4 +116,11 @@ public class ChangePwdInput
     [Required(ErrorMessage = "新密码不能为空")]
     [Required(ErrorMessage = "新密码不能为空")]
     [StringLength(20, MinimumLength = 5, ErrorMessage = "密码需要大于5个字符")]
     [StringLength(20, MinimumLength = 5, ErrorMessage = "密码需要大于5个字符")]
     public string PasswordNew { get; set; }
     public string PasswordNew { get; set; }
+}
+
+/// <summary>
+/// 解除登录锁定输入参数
+/// </summary>
+public class UnlockLoginInput : BaseIdInput
+{
 }
 }

+ 21 - 2
Admin.NET/Admin.NET.Core/Service/User/SysUserService.cs

@@ -22,6 +22,7 @@ public class SysUserService : IDynamicApiController, ITransient
     private readonly SysUserRoleService _sysUserRoleService;
     private readonly SysUserRoleService _sysUserRoleService;
     private readonly SysConfigService _sysConfigService;
     private readonly SysConfigService _sysConfigService;
     private readonly SysOnlineUserService _sysOnlineUserService;
     private readonly SysOnlineUserService _sysOnlineUserService;
+    private readonly SysCacheService _sysCacheService;
 
 
     public SysUserService(UserManager userManager,
     public SysUserService(UserManager userManager,
         SqlSugarRepository<SysUser> sysUserRep,
         SqlSugarRepository<SysUser> sysUserRep,
@@ -29,7 +30,8 @@ public class SysUserService : IDynamicApiController, ITransient
         SysUserExtOrgService sysUserExtOrgService,
         SysUserExtOrgService sysUserExtOrgService,
         SysUserRoleService sysUserRoleService,
         SysUserRoleService sysUserRoleService,
         SysConfigService sysConfigService,
         SysConfigService sysConfigService,
-        SysOnlineUserService sysOnlineUserService)
+        SysOnlineUserService sysOnlineUserService,
+        SysCacheService sysCacheService)
     {
     {
         _userManager = userManager;
         _userManager = userManager;
         _sysUserRep = sysUserRep;
         _sysUserRep = sysUserRep;
@@ -38,6 +40,7 @@ public class SysUserService : IDynamicApiController, ITransient
         _sysUserRoleService = sysUserRoleService;
         _sysUserRoleService = sysUserRoleService;
         _sysConfigService = sysConfigService;
         _sysConfigService = sysConfigService;
         _sysOnlineUserService = sysOnlineUserService;
         _sysOnlineUserService = sysOnlineUserService;
+        _sysCacheService = sysCacheService;
     }
     }
 
 
     /// <summary>
     /// <summary>
@@ -51,7 +54,7 @@ public class SysUserService : IDynamicApiController, ITransient
         // 获取用户拥有的机构集合
         // 获取用户拥有的机构集合
         var userOrgIdList = await _sysOrgService.GetUserOrgIdList();
         var userOrgIdList = await _sysOrgService.GetUserOrgIdList();
         List<long> orgList = null;
         List<long> orgList = null;
-        if (input.OrgId > 0)  // 指定机构查询时
+        if (input.OrgId > 0) // 指定机构查询时
         {
         {
             orgList = await _sysOrgService.GetChildIdListWithSelfById(input.OrgId);
             orgList = await _sysOrgService.GetChildIdListWithSelfById(input.OrgId);
             orgList = _userManager.SuperAdmin ? orgList : orgList.Where(u => userOrgIdList.Contains(u)).ToList();
             orgList = _userManager.SuperAdmin ? orgList : orgList.Where(u => userOrgIdList.Contains(u)).ToList();
@@ -276,6 +279,7 @@ public class SysUserService : IDynamicApiController, ITransient
         {
         {
             user.Password = CryptogramUtil.Encrypt(input.PasswordNew);
             user.Password = CryptogramUtil.Encrypt(input.PasswordNew);
         }
         }
+
         return await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync();
         return await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync();
     }
     }
 
 
@@ -294,6 +298,21 @@ public class SysUserService : IDynamicApiController, ITransient
         return password;
         return password;
     }
     }
 
 
+    /// <summary>
+    /// 解除登录锁定
+    /// </summary>
+    /// <param name="input"></param>
+    /// <returns></returns>
+    [DisplayName("解除登录锁定")]
+    public async Task UnlockLogin(UnlockLoginInput input)
+    {
+        var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
+
+        var keyErrorPasswordCount = $"{CacheConst.KeyErrorPasswordCount}{user.Account}";
+        // 清空密码错误次数
+        _sysCacheService.Remove(keyErrorPasswordCount);
+    }
+
     /// <summary>
     /// <summary>
     /// 获取用户拥有角色集合
     /// 获取用户拥有角色集合
     /// </summary>
     /// </summary>

+ 84 - 0
Web/src/api-services/apis/sys-user-api.ts

@@ -30,6 +30,7 @@ import { DeleteUserInput } from '../models';
 import { PageUserInput } from '../models';
 import { PageUserInput } from '../models';
 import { ResetPwdUserInput } from '../models';
 import { ResetPwdUserInput } from '../models';
 import { SysUser } from '../models';
 import { SysUser } from '../models';
+import { UnlockLoginInput } from '../models';
 import { UpdateUserInput } from '../models';
 import { UpdateUserInput } from '../models';
 import { UserInput } from '../models';
 import { UserInput } from '../models';
 import { UserRoleInput } from '../models';
 import { UserRoleInput } from '../models';
@@ -564,6 +565,54 @@ export const SysUserApiAxiosParamCreator = function (configuration?: Configurati
                 options: localVarRequestOptions,
                 options: localVarRequestOptions,
             };
             };
         },
         },
+        /**
+         * 
+         * @summary 解除登录锁定
+         * @param {UnlockLoginInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        apiSysUserUnlockLoginPost: async (body?: UnlockLoginInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
+            const localVarPath = `/api/sysUser/unlockLogin`;
+            // use dummy base URL string because the URL constructor only accepts absolute URLs.
+            const localVarUrlObj = new URL(localVarPath, 'https://example.com');
+            let baseOptions;
+            if (configuration) {
+                baseOptions = configuration.baseOptions;
+            }
+            const localVarRequestOptions :AxiosRequestConfig = { method: 'POST', ...baseOptions, ...options};
+            const localVarHeaderParameter = {} as any;
+            const localVarQueryParameter = {} as any;
+
+            // authentication Bearer required
+            // http bearer authentication required
+            if (configuration && configuration.accessToken) {
+                const accessToken = typeof configuration.accessToken === 'function'
+                    ? await configuration.accessToken()
+                    : await configuration.accessToken;
+                localVarHeaderParameter["Authorization"] = "Bearer " + accessToken;
+            }
+
+            localVarHeaderParameter['Content-Type'] = 'application/json-patch+json';
+
+            const query = new URLSearchParams(localVarUrlObj.search);
+            for (const key in localVarQueryParameter) {
+                query.set(key, localVarQueryParameter[key]);
+            }
+            for (const key in options.params) {
+                query.set(key, options.params[key]);
+            }
+            localVarUrlObj.search = (new URLSearchParams(query)).toString();
+            let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+            localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+            const needsSerialization = (typeof body !== "string") || localVarRequestOptions.headers['Content-Type'] === 'application/json';
+            localVarRequestOptions.data =  needsSerialization ? JSON.stringify(body !== undefined ? body : {}) : (body || "");
+
+            return {
+                url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
+                options: localVarRequestOptions,
+            };
+        },
         /**
         /**
          * 
          * 
          * @summary 更新用户
          * @summary 更新用户
@@ -774,6 +823,20 @@ export const SysUserApiFp = function(configuration?: Configuration) {
                 return axios.request(axiosRequestArgs);
                 return axios.request(axiosRequestArgs);
             };
             };
         },
         },
+        /**
+         * 
+         * @summary 解除登录锁定
+         * @param {UnlockLoginInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysUserUnlockLoginPost(body?: UnlockLoginInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
+            const localVarAxiosArgs = await SysUserApiAxiosParamCreator(configuration).apiSysUserUnlockLoginPost(body, options);
+            return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
+                const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
+                return axios.request(axiosRequestArgs);
+            };
+        },
         /**
         /**
          * 
          * 
          * @summary 更新用户
          * @summary 更新用户
@@ -906,6 +969,16 @@ export const SysUserApiFactory = function (configuration?: Configuration, basePa
         async apiSysUserSetStatusPost(body?: UserInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultInt32>> {
         async apiSysUserSetStatusPost(body?: UserInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultInt32>> {
             return SysUserApiFp(configuration).apiSysUserSetStatusPost(body, options).then((request) => request(axios, basePath));
             return SysUserApiFp(configuration).apiSysUserSetStatusPost(body, options).then((request) => request(axios, basePath));
         },
         },
+        /**
+         * 
+         * @summary 解除登录锁定
+         * @param {UnlockLoginInput} [body] 
+         * @param {*} [options] Override http request option.
+         * @throws {RequiredError}
+         */
+        async apiSysUserUnlockLoginPost(body?: UnlockLoginInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
+            return SysUserApiFp(configuration).apiSysUserUnlockLoginPost(body, options).then((request) => request(axios, basePath));
+        },
         /**
         /**
          * 
          * 
          * @summary 更新用户
          * @summary 更新用户
@@ -1046,6 +1119,17 @@ export class SysUserApi extends BaseAPI {
     public async apiSysUserSetStatusPost(body?: UserInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultInt32>> {
     public async apiSysUserSetStatusPost(body?: UserInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultInt32>> {
         return SysUserApiFp(this.configuration).apiSysUserSetStatusPost(body, options).then((request) => request(this.axios, this.basePath));
         return SysUserApiFp(this.configuration).apiSysUserSetStatusPost(body, options).then((request) => request(this.axios, this.basePath));
     }
     }
+    /**
+     * 
+     * @summary 解除登录锁定
+     * @param {UnlockLoginInput} [body] 
+     * @param {*} [options] Override http request option.
+     * @throws {RequiredError}
+     * @memberof SysUserApi
+     */
+    public async apiSysUserUnlockLoginPost(body?: UnlockLoginInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
+        return SysUserApiFp(this.configuration).apiSysUserUnlockLoginPost(body, options).then((request) => request(this.axios, this.basePath));
+    }
     /**
     /**
      * 
      * 
      * @summary 更新用户
      * @summary 更新用户

+ 1 - 1
Web/src/api-services/models/add-user-input.ts

@@ -24,7 +24,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 增加用户输入参数
  *
  *
  * @export
  * @export
  * @interface AddUserInput
  * @interface AddUserInput

+ 1 - 1
Web/src/api-services/models/change-pwd-input.ts

@@ -17,7 +17,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 修改用户密码输入参数
  *
  *
  * @export
  * @export
  * @interface ChangePwdInput
  * @interface ChangePwdInput

+ 1 - 1
Web/src/api-services/models/delete-user-input.ts

@@ -17,7 +17,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 删除用户输入参数
  *
  *
  * @export
  * @export
  * @interface DeleteUserInput
  * @interface DeleteUserInput

+ 1 - 0
Web/src/api-services/models/index.ts

@@ -248,6 +248,7 @@ export * from './tenant-output';
 export * from './tenant-type-enum';
 export * from './tenant-type-enum';
 export * from './tenant-user-input';
 export * from './tenant-user-input';
 export * from './trigger-status';
 export * from './trigger-status';
+export * from './unlock-login-input';
 export * from './update-code-gen-input';
 export * from './update-code-gen-input';
 export * from './update-config-input';
 export * from './update-config-input';
 export * from './update-db-column-input';
 export * from './update-db-column-input';

+ 1 - 1
Web/src/api-services/models/page-user-input.ts

@@ -17,7 +17,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 获取用户分页列表输入参数
  *
  *
  * @export
  * @export
  * @interface PageUserInput
  * @interface PageUserInput

+ 1 - 1
Web/src/api-services/models/reset-pwd-user-input.ts

@@ -17,7 +17,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 重置用户密码输入参数
  *
  *
  * @export
  * @export
  * @interface ResetPwdUserInput
  * @interface ResetPwdUserInput

+ 34 - 0
Web/src/api-services/models/unlock-login-input.ts

@@ -0,0 +1,34 @@
+/* tslint:disable */
+/* eslint-disable */
+/**
+ * Admin.NET 通用权限开发平台
+ * 让 .NET 开发更简单、更通用、更流行。前后端分离架构(.NET6/Vue3),开箱即用紧随前沿技术。<br/><a href='https://gitee.com/zuohuaijun/Admin.NET/'>https://gitee.com/zuohuaijun/Admin.NET</a>
+ *
+ * OpenAPI spec version: 1.0.0
+ * Contact: 515096995@qq.com
+ *
+ * NOTE: This class is auto generated by the swagger code generator program.
+ * https://github.com/swagger-api/swagger-codegen.git
+ * Do not edit the class manually.
+ */
+
+import {
+    
+} from ".";
+
+/**
+ * 解除登录锁定输入参数
+ *
+ * @export
+ * @interface UnlockLoginInput
+ */
+export interface UnlockLoginInput {
+
+    /**
+     * 主键Id
+     *
+     * @type {number}
+     * @memberof UnlockLoginInput
+     */
+    id: number;
+}

+ 1 - 1
Web/src/api-services/models/update-user-input.ts

@@ -24,7 +24,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 更新用户输入参数
  *
  *
  * @export
  * @export
  * @interface UpdateUserInput
  * @interface UpdateUserInput

+ 1 - 1
Web/src/api-services/models/user-input.ts

@@ -18,7 +18,7 @@ import {
 } from ".";
 } from ".";
 
 
 /**
 /**
- * 
+ * 设置用户状态输入参数
  *
  *
  * @export
  * @export
  * @interface UserInput
  * @interface UserInput

+ 18 - 0
Web/src/views/system/user/index.vue

@@ -131,6 +131,7 @@
 									<template #dropdown>
 									<template #dropdown>
 										<el-dropdown-menu>
 										<el-dropdown-menu>
 											<el-dropdown-item icon="ele-RefreshLeft" @click="resetUserPwd(scope.row)" :disabled="!auth('sysUser:resetPwd')"> 重置密码 </el-dropdown-item>
 											<el-dropdown-item icon="ele-RefreshLeft" @click="resetUserPwd(scope.row)" :disabled="!auth('sysUser:resetPwd')"> 重置密码 </el-dropdown-item>
+											<el-dropdown-item icon="ele-Unlock" @click="unlockLogin(scope.row)" :disabled="!auth('sysUser:unlockLogin')"> 解除登录锁定 </el-dropdown-item>
 											<el-dropdown-item icon="ele-Delete" @click="delUser(scope.row)" divided :disabled="!auth('sysUser:delete')"> 删除账号 </el-dropdown-item>
 											<el-dropdown-item icon="ele-Delete" @click="delUser(scope.row)" divided :disabled="!auth('sysUser:delete')"> 删除账号 </el-dropdown-item>
 										</el-dropdown-menu>
 										</el-dropdown-menu>
 									</template>
 									</template>
@@ -289,6 +290,23 @@ const resetUserPwd = async (row: any) => {
 		.catch(() => {});
 		.catch(() => {});
 };
 };
 
 
+// 解除登录锁定
+const unlockLogin = async (row: any) => {
+	ElMessageBox.confirm(`确定解除:【${row.account}】登录锁定?`, '提示', {
+		confirmButtonText: '确定',
+		cancelButtonText: '取消',
+		type: 'warning',
+	})
+		.then(async () => {
+			await getAPI(SysUserApi)
+				.apiSysUserUnlockLoginPost({ id: row.id })
+				.then(() => {
+					ElMessage.success('解除登录锁定成功');
+				});
+		})
+		.catch(() => {});
+};
+
 // 树组件点击
 // 树组件点击
 const nodeClick = async (node: any) => {
 const nodeClick = async (node: any) => {
 	state.queryParams.orgId = node.id;
 	state.queryParams.orgId = node.id;