😎1、增加用户密码历史记录 2、增加密码有效期验证 3、增加密码历史记录验证 4、增加扩展sqlsugar函数解密
This commit is contained in:
parent
687b7e9c38
commit
85bcd500ac
@ -106,6 +106,16 @@ public class ConfigConst
|
||||
/// </summary>
|
||||
public const string SysPasswordStrengthExpression = "sys_password_strength_expression";
|
||||
|
||||
/// <summary>
|
||||
/// 密码有效期验证
|
||||
/// </summary>
|
||||
public const string SysPasswordExpirationTime = "sys_password_expiration_time";
|
||||
|
||||
/// <summary>
|
||||
/// 密码历史记录验证
|
||||
/// </summary>
|
||||
public const string SysPasswordRecord = "sys_password_record";
|
||||
|
||||
/// <summary>
|
||||
/// Default 分组
|
||||
/// </summary>
|
||||
|
||||
28
Admin.NET/Admin.NET.Core/Entity/SysUserPasswordRecord.cs
Normal file
28
Admin.NET/Admin.NET.Core/Entity/SysUserPasswordRecord.cs
Normal file
@ -0,0 +1,28 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
/// 系统用户角色表
|
||||
/// </summary>
|
||||
[SugarTable(null, "系统用户密码记录表")]
|
||||
[SysTable]
|
||||
public class SysUserPasswordRecord : EntityBaseId
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "用户Id")]
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "密码", Length = 512)]
|
||||
[MaxLength(512)]
|
||||
public string Password { get; set; }
|
||||
}
|
||||
@ -61,6 +61,12 @@ public enum ErrorCodeEnum
|
||||
[ErrorCodeItemMetadata("旧密码输入错误")]
|
||||
D1004,
|
||||
|
||||
/// <summary>
|
||||
/// 密码已使用过,请更换其他密码
|
||||
/// </summary>
|
||||
[ErrorCodeItemMetadata("密码已使用过,请更换其他密码")]
|
||||
D1104,
|
||||
|
||||
/// <summary>
|
||||
/// 测试数据禁止更改admin密码
|
||||
/// </summary>
|
||||
|
||||
@ -43,18 +43,5 @@ public class LogJob : IJob
|
||||
|
||||
// 自定义日志
|
||||
_logger.LogInformation(msg);
|
||||
|
||||
// 默认 3个月/90天 强制修改一次密码(将最新修改密码时间置空)
|
||||
if (await sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysForceChangePassword))
|
||||
{
|
||||
var userIds = await db.Queryable<SysUser>()
|
||||
.Where(u => SqlFunc.IsNullOrEmpty(u.LastChangePasswordTime) || (DateTime.Now - (DateTime)u.LastChangePasswordTime).Days > 90)
|
||||
.Select(u => u.Id).ToListAsync(stoppingToken);
|
||||
|
||||
await db.Updateable<SysUser>()
|
||||
.SetColumns(u => new SysUser() { LastChangePasswordTime = null })
|
||||
.Where(u => userIds.Contains(u.Id))
|
||||
.ExecuteCommandAsync(stoppingToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -34,11 +34,13 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
new SysConfig{ Id=1300000000221, Name="租户隔离登录验证", Code=ConfigConst.SysTenantHostLogin, Value="False", SysFlag=YesNoEnum.Y, Remark="租户隔离登录验证", OrderNo=370, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000231, Name="数据校验日志", Code=ConfigConst.SysValidationLog, Value="True", SysFlag=YesNoEnum.Y, Remark="是否数据校验日志", OrderNo=130, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000241, Name="行政区划同步层级", Code=ConfigConst.SysRegionSyncLevel, Value="3", SysFlag=YesNoEnum.Y, Remark="行政区划同步层级 1-省级,2-市级,3-区县级,4-街道级,5-村级", OrderNo=140, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000251, Name="开启强制修改密码", Code=ConfigConst.SysForceChangePassword, Value="False", SysFlag=YesNoEnum.Y, Remark="开启强制修改密码", OrderNo=150, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
// 新业务系统记得更改密匙,通过接口(http://localhost:5005/api/sysCommon/smKeyPair)获取
|
||||
new SysConfig{ Id=1300000000261, Name="国密SM2密匙", Code=ConfigConst.SysSM2Key, Value="04851D329AA3E38C2E7670AFE70E6E70E92F8769CA27C8766B12209A0FFBA4493B603EF7A0B9B1E16F0E8930C0406EA0B179B68DF28E25334BDEC4AE76D907E9E9;3A61D1D30C6302DABFF36201D936D0143EEF0C850AF28C5CA6D5C045AF8C5C8A", SysFlag=YesNoEnum.Y, Remark="国密SM2密匙", OrderNo=160, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-11-21 00:00:00") },
|
||||
new SysConfig{ Id=1300000000271, Name="开启密码强度验证", Code=ConfigConst.SysPasswordStrength, Value="False", SysFlag=YesNoEnum.Y, Remark="开启强制修改密码", OrderNo=150, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000281, Name="密码强度验证正则表达式", Code=ConfigConst.SysPasswordStrengthExpression, Value="(?=^.{6,16}$)(?=.*\\d)(?=.*\\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\\n).*$", SysFlag=YesNoEnum.Y, Remark="必须须包含大小写字母、数字和特殊字符的组合,长度在6-16之间", OrderNo=150, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-11-21 00:00:00") },
|
||||
new SysConfig{ Id=1300000000251, Name="国密SM2密匙", Code=ConfigConst.SysSM2Key, Value="04851D329AA3E38C2E7670AFE70E6E70E92F8769CA27C8766B12209A0FFBA4493B603EF7A0B9B1E16F0E8930C0406EA0B179B68DF28E25334BDEC4AE76D907E9E9;3A61D1D30C6302DABFF36201D936D0143EEF0C850AF28C5CA6D5C045AF8C5C8A", SysFlag=YesNoEnum.Y, Remark="国密SM2密匙", OrderNo=160, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-11-21 00:00:00") },
|
||||
new SysConfig{ Id=1300000000261, Name="开启强制修改密码", Code=ConfigConst.SysForceChangePassword, Value="False", SysFlag=YesNoEnum.Y, Remark="开启强制修改密码", OrderNo=150, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000271, Name="开启密码强度验证", Code=ConfigConst.SysPasswordStrength, Value="False", SysFlag=YesNoEnum.Y, Remark="开启强制修改密码", OrderNo=170, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000281, Name="密码强度验证正则表达式", Code=ConfigConst.SysPasswordStrengthExpression, Value="(?=^.{6,16}$)(?=.*\\d)(?=.*\\W+)(?=.*[A-Z])(?=.*[a-z])(?!.*\\n).*$", SysFlag=YesNoEnum.Y, Remark="必须须包含大小写字母、数字和特殊字符的组合,长度在6-16之间", OrderNo=180, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-11-21 00:00:00") },
|
||||
new SysConfig{ Id=1300000000291, Name="密码时间有效期", Code=ConfigConst.SysPasswordExpirationTime, Value="0", SysFlag=YesNoEnum.Y, Remark="默认0表示永不过期,否则表示过期天数", OrderNo=190, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-17 00:00:00") },
|
||||
new SysConfig{ Id=1300000000301, Name="密码历史记录验证", Code=ConfigConst.SysPasswordRecord, Value="False", SysFlag=YesNoEnum.Y, Remark="是否验证历史密码禁止再次使用", OrderNo=200, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2024-12-17 00:00:00") },
|
||||
|
||||
new SysConfig{ Id=1310000000301, Name="系统主标题", Code=ConfigConst.SysWebTitle, Value="Admin.NET.Pro", SysFlag=YesNoEnum.Y, Remark="系统主标题", OrderNo=300, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1310000000311, Name="系统副标题", Code=ConfigConst.SysWebViceTitle, Value="Admin.NET.Pro", SysFlag=YesNoEnum.Y, Remark="系统副标题", OrderNo=310, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
|
||||
@ -284,6 +284,7 @@ public class SysConfigService : IDynamicApiController, ITransient
|
||||
var sysSecondVer = await GetConfigValueByCode<bool>(ConfigConst.SysSecondVer); // 登录二次验证
|
||||
var sysCaptcha = await GetConfigValueByCode<bool>(ConfigConst.SysCaptcha); // 图形验证码
|
||||
var sysForceChangePassword = await GetConfigValueByCode<bool>(ConfigConst.SysForceChangePassword); // 强制修改密码
|
||||
var sysPasswordExpirationTime = await GetConfigValueByCode<bool>(ConfigConst.SysPasswordExpirationTime); // 密码有效期
|
||||
var publicKey = App.GetConfig<string>("Cryptogram:PublicKey", true); // 获取密码加解密公钥配置
|
||||
|
||||
return new
|
||||
@ -299,6 +300,7 @@ public class SysConfigService : IDynamicApiController, ITransient
|
||||
SysSecondVer = sysSecondVer,
|
||||
SysCaptcha = sysCaptcha,
|
||||
SysForceChangePassword = sysForceChangePassword,
|
||||
SysPasswordExpirationTime = sysPasswordExpirationTime,
|
||||
PublicKey = publicKey
|
||||
};
|
||||
}
|
||||
|
||||
@ -353,6 +353,18 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
user.Password = CryptogramUtil.Encrypt(input.PasswordNew);
|
||||
}
|
||||
|
||||
// 验证历史密码记录
|
||||
var sysUserPasswordRecord = _sysUserRep.ChangeRepository<SqlSugarRepository<SysUserPasswordRecord>>();
|
||||
if (await _sysConfigService.GetConfigValueByCode<bool>(ConfigConst.SysPasswordRecord))
|
||||
{
|
||||
var md5 = MD5Encryption.Encrypt(input.PasswordNew);
|
||||
if (await sysUserPasswordRecord.IsAnyAsync(u => u.UserId == user.Id && u.Password == md5))
|
||||
throw Oops.Oh(ErrorCodeEnum.D1104);
|
||||
}
|
||||
// 增加密码历史记录(统一MD5存储)
|
||||
await sysUserPasswordRecord.InsertAsync(new SysUserPasswordRecord { UserId = user.Id, Password = MD5Encryption.Encrypt(input.PasswordNew) });
|
||||
|
||||
// 更新密码和最新修改时间
|
||||
user.LastChangePasswordTime = DateTime.Now;
|
||||
var rows = await _sysUserRep.AsUpdateable(user).UpdateColumns(u => new { u.Password, u.LastChangePasswordTime }).ExecuteCommandAsync();
|
||||
|
||||
@ -386,6 +398,25 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
return password;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证密码有效期
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[DisplayName("验证密码有效期")]
|
||||
public async Task<bool> VerifyPwdExpirationTime()
|
||||
{
|
||||
var sysConfig = await _sysConfigService.GetConfig(ConfigConst.SysPasswordExpirationTime);
|
||||
if (int.TryParse(sysConfig.Value, out int expirationTime) && expirationTime > 0)
|
||||
{
|
||||
var user = await _sysUserRep.GetByIdAsync(_userManager.UserId);
|
||||
if (user.LastChangePasswordTime == null)
|
||||
return false;
|
||||
if ((DateTime.Now - user.LastChangePasswordTime.Value).Days > expirationTime)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解除登录锁定 🔖
|
||||
/// </summary>
|
||||
|
||||
@ -73,6 +73,20 @@ public static class SqlSugarSetup
|
||||
if (config.DbSettings.EnableConnEncrypt)
|
||||
config.ConnectionString = CryptogramUtil.Decrypt(config.ConnectionString);
|
||||
|
||||
// SqlFunc 扩展函数
|
||||
var sqlFuncServices = new List<SqlFuncExternal>
|
||||
{
|
||||
// 密码解密
|
||||
new SqlFuncExternal()
|
||||
{
|
||||
UniqueMethodName = "SqlFuncDecrypt",
|
||||
MethodValue = (expInfo, dbType, expContext) =>
|
||||
{
|
||||
return CryptogramUtil.Decrypt(expInfo.Args[0].MemberName.ToString());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var configureExternalServices = new ConfigureExternalServices
|
||||
{
|
||||
EntityNameService = (type, entity) => // 处理表
|
||||
@ -95,6 +109,7 @@ public static class SqlSugarSetup
|
||||
column.DbColumnName = UtilMethods.ToUnderLine(column.DbColumnName); // 驼峰转下划线
|
||||
},
|
||||
DataInfoCacheService = new SqlSugarCache(),
|
||||
SqlFuncServices = sqlFuncServices
|
||||
};
|
||||
config.ConfigureExternalServices = configureExternalServices;
|
||||
config.InitKeyType = InitKeyType.Attribute;
|
||||
@ -116,6 +131,18 @@ public static class SqlSugarSetup
|
||||
config.MoreSettings.MaxParameterNameLength = 30;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// SqlFunc 扩展函数定义(密码解密)
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotSupportedException"></exception>
|
||||
public static string SqlFuncDecrypt<T>(T password)
|
||||
{
|
||||
throw new NotSupportedException("Can only be used in expressions");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 配置Aop
|
||||
/// </summary>
|
||||
|
||||
@ -127,7 +127,9 @@ const loadSysInfo = () => {
|
||||
themeConfig.value.secondVer = data.sysSecondVer;
|
||||
themeConfig.value.captcha = data.sysCaptcha;
|
||||
// 开启强制修改密码
|
||||
themeConfig.value.sysForceChangePassword = data.sysForceChangePassword;
|
||||
themeConfig.value.forceChangePassword = data.sysForceChangePassword;
|
||||
// 是否验证密码有效期
|
||||
themeConfig.value.passwordExpirationTime = data.sysPasswordExpirationTime;
|
||||
// 密码加解密公匙
|
||||
window.__env__.VITE_SM_PUBLIC_KEY = data.publicKey;
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ export const SysAuthApiAxiosParamCreator = function (configuration?: Configurati
|
||||
};
|
||||
},
|
||||
/**
|
||||
* 用户名/密码:superadmin/123456
|
||||
*
|
||||
* @summary 账号密码登录 🔖
|
||||
* @param {LoginInput} body
|
||||
* @param {*} [options] Override http request option.
|
||||
@ -528,7 +528,7 @@ export const SysAuthApiFp = function(configuration?: Configuration) {
|
||||
};
|
||||
},
|
||||
/**
|
||||
* 用户名/密码:superadmin/123456
|
||||
*
|
||||
* @summary 账号密码登录 🔖
|
||||
* @param {LoginInput} body
|
||||
* @param {*} [options] Override http request option.
|
||||
@ -644,7 +644,7 @@ export const SysAuthApiFactory = function (configuration?: Configuration, basePa
|
||||
return SysAuthApiFp(configuration).apiSysAuthLoginPhonePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
* 用户名/密码:superadmin/123456
|
||||
*
|
||||
* @summary 账号密码登录 🔖
|
||||
* @param {LoginInput} body
|
||||
* @param {*} [options] Override http request option.
|
||||
@ -745,7 +745,7 @@ export class SysAuthApi extends BaseAPI {
|
||||
return SysAuthApiFp(this.configuration).apiSysAuthLoginPhonePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
* 用户名/密码:superadmin/123456
|
||||
*
|
||||
* @summary 账号密码登录 🔖
|
||||
* @param {LoginInput} body
|
||||
* @param {*} [options] Override http request option.
|
||||
|
||||
@ -424,6 +424,49 @@ export const SysRegionApiAxiosParamCreator = function (configuration?: Configura
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划(民政部) 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysRegionSyncRegionMzbPost: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysRegion/syncRegionMzb`;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划数据(天地图行政区划) 🔖
|
||||
@ -641,6 +684,19 @@ export const SysRegionApiFp = function(configuration?: Configuration) {
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划(民政部) 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysRegionSyncRegionMzbPost(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
const localVarAxiosArgs = await SysRegionApiAxiosParamCreator(configuration).apiSysRegionSyncRegionMzbPost(options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划数据(天地图行政区划) 🔖
|
||||
@ -758,6 +814,15 @@ export const SysRegionApiFactory = function (configuration?: Configuration, base
|
||||
async apiSysRegionSyncRegionMcaCodePost(code: number, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultInt32>> {
|
||||
return SysRegionApiFp(configuration).apiSysRegionSyncRegionMcaCodePost(code, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划(民政部) 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysRegionSyncRegionMzbPost(options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return SysRegionApiFp(configuration).apiSysRegionSyncRegionMzbPost(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划数据(天地图行政区划) 🔖
|
||||
@ -876,6 +941,16 @@ export class SysRegionApi extends BaseAPI {
|
||||
public async apiSysRegionSyncRegionMcaCodePost(code: number, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultInt32>> {
|
||||
return SysRegionApiFp(this.configuration).apiSysRegionSyncRegionMcaCodePost(code, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划(民政部) 🔖
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysRegionApi
|
||||
*/
|
||||
public async apiSysRegionSyncRegionMzbPost(options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return SysRegionApiFp(this.configuration).apiSysRegionSyncRegionMzbPost(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 同步行政区划数据(天地图行政区划) 🔖
|
||||
|
||||
@ -18,6 +18,7 @@ import { Configuration } from '../configuration';
|
||||
// @ts-ignore
|
||||
import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } from '../base';
|
||||
import { AddUserInput } from '../models';
|
||||
import { AdminResultBoolean } from '../models';
|
||||
import { AdminResultGrantRoleOutput } from '../models';
|
||||
import { AdminResultInt32 } from '../models';
|
||||
import { AdminResultInt64 } from '../models';
|
||||
@ -656,6 +657,49 @@ export const SysUserApiAxiosParamCreator = function (configuration?: Configurati
|
||||
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 验证密码有效期
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysUserVerifyPwdExpirationTimePost: async (options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysUser/verifyPwdExpirationTime`;
|
||||
// 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;
|
||||
}
|
||||
|
||||
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};
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
@ -851,6 +895,19 @@ export const SysUserApiFp = function(configuration?: Configuration) {
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 验证密码有效期
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysUserVerifyPwdExpirationTimePost(options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultBoolean>>> {
|
||||
const localVarAxiosArgs = await SysUserApiAxiosParamCreator(configuration).apiSysUserVerifyPwdExpirationTimePost(options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
@ -989,6 +1046,15 @@ export const SysUserApiFactory = function (configuration?: Configuration, basePa
|
||||
async apiSysUserUpdatePost(body?: UpdateUserInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return SysUserApiFp(configuration).apiSysUserUpdatePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 验证密码有效期
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysUserVerifyPwdExpirationTimePost(options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultBoolean>> {
|
||||
return SysUserApiFp(configuration).apiSysUserVerifyPwdExpirationTimePost(options).then((request) => request(axios, basePath));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -1141,4 +1207,14 @@ export class SysUserApi extends BaseAPI {
|
||||
public async apiSysUserUpdatePost(body?: UpdateUserInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return SysUserApiFp(this.configuration).apiSysUserUpdatePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 验证密码有效期
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysUserApi
|
||||
*/
|
||||
public async apiSysUserVerifyPwdExpirationTimePost(options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultBoolean>> {
|
||||
return SysUserApiFp(this.configuration).apiSysUserVerifyPwdExpirationTimePost(options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,7 +125,7 @@ export interface AddPosInput {
|
||||
status?: StatusEnum;
|
||||
|
||||
/**
|
||||
* 在职人数
|
||||
* 在职人员
|
||||
*
|
||||
* @type {Array<SysUser>}
|
||||
* @memberof AddPosInput
|
||||
|
||||
@ -46,6 +46,7 @@ export enum DbType {
|
||||
NUMBER_25 = 25,
|
||||
NUMBER_26 = 26,
|
||||
NUMBER_27 = 27,
|
||||
NUMBER_28 = 28,
|
||||
NUMBER_900 = 900
|
||||
}
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export interface LoginInput {
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof LoginInput
|
||||
* @example 123456
|
||||
* @example 12345678
|
||||
*/
|
||||
password: string;
|
||||
|
||||
|
||||
@ -35,7 +35,7 @@ export interface LoginPhoneInput {
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof LoginPhoneInput
|
||||
* @example 123456
|
||||
* @example 1234
|
||||
*/
|
||||
code: string;
|
||||
|
||||
|
||||
@ -133,7 +133,7 @@ export interface PagePosOutput {
|
||||
status?: StatusEnum;
|
||||
|
||||
/**
|
||||
* 在职人数
|
||||
* 在职人员
|
||||
*
|
||||
* @type {Array<SysUser>}
|
||||
* @memberof PagePosOutput
|
||||
|
||||
@ -133,7 +133,7 @@ export interface PosOutput {
|
||||
status?: StatusEnum;
|
||||
|
||||
/**
|
||||
* 在职人数
|
||||
* 在职人员
|
||||
*
|
||||
* @type {Array<SysUser>}
|
||||
* @memberof PosOutput
|
||||
|
||||
@ -125,7 +125,7 @@ export interface UpdatePosInput {
|
||||
status?: StatusEnum;
|
||||
|
||||
/**
|
||||
* 在职人数
|
||||
* 在职人员
|
||||
*
|
||||
* @type {Array<SysUser>}
|
||||
* @memberof UpdatePosInput
|
||||
|
||||
@ -104,7 +104,7 @@ import { signalR } from '/@/views/system/onlineUser/signalR';
|
||||
import { Avatar, CircleCloseFilled, Loading, Lock } from '@element-plus/icons-vue';
|
||||
|
||||
import { clearAccessTokens, getAPI } from '/@/utils/axios-utils';
|
||||
import { SysAuthApi, SysNoticeApi } from '/@/api-services/api';
|
||||
import { SysAuthApi, SysNoticeApi, SysUserApi } from '/@/api-services/api';
|
||||
|
||||
// 引入组件
|
||||
const UserNews = defineAsyncComponent(() => import('/@/layout/navBars/topBar/userNews.vue'));
|
||||
@ -262,8 +262,8 @@ onMounted(async () => {
|
||||
// notice.readStatus = 1;
|
||||
// });
|
||||
|
||||
// 强制修改密码
|
||||
forceChangePassword();
|
||||
// 是否修改密码
|
||||
await changePassword();
|
||||
});
|
||||
// // 页面卸载时
|
||||
// onUnmounted(() => {
|
||||
@ -281,18 +281,28 @@ const receiveNotice = (msg: any) => {
|
||||
});
|
||||
Push.create('提示', {
|
||||
body: '你有一条新的消息',
|
||||
icon: 'logo.png', //public目录下的
|
||||
icon: 'logo.png', // public目录下的
|
||||
timeout: 4500, // 通知显示时间,单位为毫秒
|
||||
});
|
||||
};
|
||||
|
||||
// 开启强制修改密码
|
||||
const forceChangePassword = () => {
|
||||
var forceChangePasswordEnabled = themeConfig.value.sysForceChangePassword ?? true;
|
||||
if (!forceChangePasswordEnabled) return;
|
||||
// 修改密码
|
||||
const changePassword = async () => {
|
||||
// 开启强制修改密码
|
||||
var enabledForceChangePassword = themeConfig.value.forceChangePassword ?? true;
|
||||
if (enabledForceChangePassword) {
|
||||
if (userInfos.value.lastChangePasswordTime == null || userInfos.value.lastChangePasswordTime == undefined) {
|
||||
changePasswordRef.value?.openDialog();
|
||||
}
|
||||
}
|
||||
|
||||
if (userInfos.value.lastChangePasswordTime == null || userInfos.value.lastChangePasswordTime == undefined) {
|
||||
changePasswordRef.value?.openDialog();
|
||||
// 验证密码有效期
|
||||
var enabledPasswordExpirationTime = themeConfig.value.passwordExpirationTime ?? true;
|
||||
if (enabledPasswordExpirationTime) {
|
||||
var res = await getAPI(SysUserApi).apiSysUserVerifyPwdExpirationTimePost();
|
||||
if (!res.data.result) {
|
||||
changePasswordRef.value?.openDialog();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
3
Web/src/types/pinia.d.ts
vendored
3
Web/src/types/pinia.d.ts
vendored
@ -100,6 +100,7 @@ declare interface ThemeConfigState {
|
||||
icpUrl: string; // Icp地址
|
||||
secondVer: boolean; // 是否开启二级验证
|
||||
captcha: boolean; // 是否开启验证码
|
||||
sysForceChangePassword: boolean; // 是否开启强制修改密码
|
||||
forceChangePassword: boolean; // 是否开启强制修改密码
|
||||
passwordExpirationTime: boolean; // 是否验证密码有效期
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user