Merge remote-tracking branch 'upstream/main'
This commit is contained in:
commit
48d785e6cb
@ -65,4 +65,9 @@ public class ClaimConst
|
||||
/// 登录模式PC、APP
|
||||
/// </summary>
|
||||
public const string LoginMode = "LoginMode";
|
||||
|
||||
/// <summary>
|
||||
/// 最新密码修改时间
|
||||
/// </summary>
|
||||
public const string LastChangePasswordTime = "LastChangePasswordTime";
|
||||
}
|
||||
@ -81,6 +81,11 @@ public class ConfigConst
|
||||
/// </summary>
|
||||
public const string SysRegionSyncLevel = "sys_region_sync_level";
|
||||
|
||||
/// <summary>
|
||||
/// 开启强制修改密码
|
||||
/// </summary>
|
||||
public const string SysForceChangePassword = "sys_force_change_password";
|
||||
|
||||
/// <summary>
|
||||
/// Default 分组
|
||||
/// </summary>
|
||||
|
||||
@ -312,4 +312,35 @@ public partial class SysUser : EntityTenant
|
||||
[SugarColumn(ColumnDescription = "电子签名", Length = 512)]
|
||||
[MaxLength(512)]
|
||||
public string? Signature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最新密码修改时间
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnDescription = "最新密码修改时间")]
|
||||
public DateTime? LastChangePasswordTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证超级管理员类型,若账号类型为超级管理员则报错
|
||||
/// </summary>
|
||||
/// <param name="errorMsg">自定义错误消息</param>
|
||||
public void ValidateIsSuperAdminAccountType(ErrorCodeEnum? errorMsg = ErrorCodeEnum.D1014)
|
||||
{
|
||||
if (AccountType == AccountTypeEnum.SuperAdmin)
|
||||
{
|
||||
throw Oops.Oh(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证用户Id是否相同,若用户Id相同则报错
|
||||
/// </summary>
|
||||
/// <param name="userId">用户Id</param>
|
||||
/// <param name="errorMsg">自定义错误消息</param>
|
||||
public void ValidateIsUserId(long userId, ErrorCodeEnum? errorMsg = ErrorCodeEnum.D1001)
|
||||
{
|
||||
if (Id == userId)
|
||||
{
|
||||
throw Oops.Oh(errorMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,6 +4,8 @@
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using AngleSharp.Common;
|
||||
|
||||
namespace Admin.NET.Core;
|
||||
|
||||
/// <summary>
|
||||
@ -14,87 +16,89 @@ namespace Admin.NET.Core;
|
||||
public class EnumToDictJob : IJob
|
||||
{
|
||||
private readonly IServiceScopeFactory _scopeFactory;
|
||||
private readonly IJsonSerializerProvider _jsonSerializer;
|
||||
private const int OrderOffset = 10;
|
||||
private const string DefaultTagType = "info";
|
||||
|
||||
public EnumToDictJob(IServiceScopeFactory scopeFactory, IJsonSerializerProvider jsonSerializer)
|
||||
public EnumToDictJob(IServiceScopeFactory scopeFactory)
|
||||
{
|
||||
_scopeFactory = scopeFactory;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
}
|
||||
|
||||
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
|
||||
{
|
||||
using var serviceScope = _scopeFactory.CreateScope();
|
||||
var sysEnumService = serviceScope.ServiceProvider.GetRequiredService<SysEnumService>();
|
||||
// 获取数据库连接
|
||||
var db = serviceScope.ServiceProvider.GetRequiredService<ISqlSugarClient>().CopyNew();
|
||||
|
||||
// 获取枚举类型列表
|
||||
var enumTypeList = sysEnumService.GetEnumTypeList();
|
||||
var enumCodeList = enumTypeList.Select(u => u.TypeName);
|
||||
var sysDictTypeCodeList = await db.Queryable<SysDictType>().Where(u => enumCodeList.Contains(u.Code)).Select(u => u.Code).ToListAsync(stoppingToken);
|
||||
|
||||
// 查询数据库中已存在的枚举类型代码
|
||||
var sysDictTypeList = await db.Queryable<SysDictType>()
|
||||
.Includes(d => d.Children)
|
||||
.Where(d => enumCodeList.Contains(d.Code))
|
||||
.ToListAsync(stoppingToken);
|
||||
// 更新的枚举转换字典
|
||||
var uEnumType = enumTypeList.Where(u => sysDictTypeCodeList.Contains(u.TypeName)).ToList();
|
||||
var waitUpdateSysDictType = await db.Queryable<SysDictType>().Where(u => uEnumType.Any(a => a.TypeName == u.Code)).ToListAsync(stoppingToken);
|
||||
var waitUpdateSysDictTypeDict = waitUpdateSysDictType.ToDictionary(u => u.Code, u => u);
|
||||
var waitUpdateSysDictData = await db.Queryable<SysDictData>().Where(u => uEnumType.Any(a => a.TypeName == u.DictType.Code)).ToListAsync(stoppingToken);
|
||||
var uSysDictType = new List<SysDictType>();
|
||||
var uSysDictData = new List<SysDictData>();
|
||||
if (uEnumType.Count > 0)
|
||||
{
|
||||
uEnumType.ForEach(e =>
|
||||
{
|
||||
if (waitUpdateSysDictTypeDict.TryGetValue(e.TypeName, out SysDictType value))
|
||||
{
|
||||
var uDictType = value;
|
||||
uDictType.Name = e.TypeDescribe;
|
||||
uDictType.Remark = e.TypeRemark;
|
||||
var uDictData = waitUpdateSysDictData.Where(u => u.DictTypeId == uDictType.Id).ToList();
|
||||
if (uDictData.Count > 0)
|
||||
{
|
||||
uDictData.ForEach(dictData =>
|
||||
{
|
||||
var enumData = e.EnumEntities.Where(u => dictData.Code == u.Name).FirstOrDefault();
|
||||
if (enumData != null)
|
||||
{
|
||||
dictData.Value = enumData.Value.ToString();
|
||||
dictData.Code = enumData.Name;
|
||||
dictData.OrderNo = enumData.Value + 10;
|
||||
dictData.Name = enumData.Describe;
|
||||
dictData.TagType = enumData.Theme != "" ? enumData.Theme : dictData.TagType != "" ? dictData.TagType : "info";
|
||||
uSysDictData.Add(dictData);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!uSysDictType.Any(u => u.Id == uDictType.Id))
|
||||
uSysDictType.Add(uDictType);
|
||||
}
|
||||
});
|
||||
try
|
||||
{
|
||||
db.BeginTran();
|
||||
|
||||
if (uSysDictType.Count > 0)
|
||||
await db.Updateable(uSysDictType).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (uSysDictData.Count > 0)
|
||||
await db.Updateable(uSysDictData).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
db.CommitTran();
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
db.RollbackTran();
|
||||
Log.Error($"{context.Trigger.Description}更新枚举转换字典入库错误:" + _jsonSerializer.Serialize(error));
|
||||
throw new Exception($"{context.Trigger.Description}更新枚举转换字典入库错误");
|
||||
}
|
||||
}
|
||||
var updatedEnumCodes = sysDictTypeList.Select(u => u.Code);
|
||||
var updatedEnumType = enumTypeList.Where(u => updatedEnumCodes.Contains(u.TypeName)).ToList();
|
||||
var sysDictTypeDict = sysDictTypeList.ToDictionary(u => u.Code, u => u);
|
||||
var (updatedDictTypes, updatedDictDatas) = GetUpdatedDicts(updatedEnumType, sysDictTypeDict);
|
||||
|
||||
// 新增的枚举转换字典
|
||||
var iEnumType = enumTypeList.Where(u => !sysDictTypeCodeList.Contains(u.TypeName)).ToList();
|
||||
if (iEnumType.Count > 0)
|
||||
var newEnumType = enumTypeList.Where(u => !updatedEnumCodes.Contains(u.TypeName)).ToList();
|
||||
var (newDictTypes, newDictDatas) = GetNewSysDicts(newEnumType);
|
||||
|
||||
// 执行数据库操作
|
||||
try
|
||||
{
|
||||
db.BeginTran();
|
||||
|
||||
if (updatedDictTypes.Count > 0)
|
||||
await db.Updateable(updatedDictTypes).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (updatedDictDatas.Count > 0)
|
||||
await db.Updateable(updatedDictDatas).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (newDictTypes.Count > 0)
|
||||
await db.Insertable(newDictTypes).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (newDictDatas.Count > 0)
|
||||
await db.Insertable(newDictDatas).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
db.CommitTran();
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
db.RollbackTran();
|
||||
Log.Error($"系统枚举转换字典操作错误:{error.Message}\n堆栈跟踪:{error.StackTrace}", error);
|
||||
throw;
|
||||
}
|
||||
var originColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举转换字典");
|
||||
Console.ForegroundColor = originColor;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取需要新增的字典列表
|
||||
/// </summary>
|
||||
/// <param name="addEnumType"></param>
|
||||
/// <returns>
|
||||
/// 一个元组,包含以下元素:
|
||||
/// <list type="table">
|
||||
/// <item><term>SysDictTypes</term><description>字典类型列表</description></item>
|
||||
/// <item><term>SysDictDatas</term><description>字典数据列表</description></item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
private (List<SysDictType>, List<SysDictData>) GetNewSysDicts(List<EnumTypeOutput> addEnumType)
|
||||
{
|
||||
var newDictType = new List<SysDictType>();
|
||||
var newDictData = new List<SysDictData>();
|
||||
if (addEnumType.Count > 0)
|
||||
{
|
||||
// 新增字典类型
|
||||
var iDictType = iEnumType.Select(u => new SysDictType
|
||||
newDictType = addEnumType.Select(u => new SysDictType
|
||||
{
|
||||
Id = YitIdHelper.NextId(),
|
||||
Code = u.TypeName,
|
||||
@ -102,49 +106,70 @@ public class EnumToDictJob : IJob
|
||||
Remark = u.TypeRemark,
|
||||
Status = StatusEnum.Enable
|
||||
}).ToList();
|
||||
|
||||
// 新增字典数据
|
||||
var dictData = iEnumType.Join(iDictType, t1 => t1.TypeName, t2 => t2.Code, (t1, t2) => new
|
||||
newDictData = addEnumType.Join(newDictType, t1 => t1.TypeName, t2 => t2.Code, (t1, t2) => new
|
||||
{
|
||||
data = t1.EnumEntities.Select(u => new SysDictData
|
||||
Data = t1.EnumEntities.Select(u => new SysDictData
|
||||
{
|
||||
Id = YitIdHelper.NextId(), // 性能优化,使用BulkCopyAsync必须手动获取Id
|
||||
Id = YitIdHelper.NextId(),
|
||||
DictTypeId = t2.Id,
|
||||
Name = u.Describe,
|
||||
Value = u.Value.ToString(),
|
||||
Code = u.Name,
|
||||
Remark = t2.Remark,
|
||||
OrderNo = u.Value + 10,
|
||||
TagType = u.Theme != "" ? u.Theme : "info"
|
||||
OrderNo = u.Value + OrderOffset,
|
||||
TagType = u.Theme != "" ? u.Theme : DefaultTagType,
|
||||
}).ToList()
|
||||
}).ToList();
|
||||
var iDictData = new List<SysDictData>();
|
||||
dictData.ForEach(item =>
|
||||
{
|
||||
iDictData.AddRange(item.data);
|
||||
});
|
||||
try
|
||||
{
|
||||
db.BeginTran();
|
||||
}).SelectMany(x => x.Data).ToList();
|
||||
}
|
||||
return (newDictType, newDictData);
|
||||
}
|
||||
|
||||
if (iDictType.Count > 0)
|
||||
await db.Insertable(iDictType).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
if (iDictData.Count > 0)
|
||||
await db.Insertable(iDictData).ExecuteCommandAsync(stoppingToken);
|
||||
|
||||
db.CommitTran();
|
||||
}
|
||||
catch (Exception error)
|
||||
/// <summary>
|
||||
/// 获取需要更新的字典列表
|
||||
/// </summary>
|
||||
/// <param name="updatedEnumType"></param>
|
||||
/// <param name="sysDictTypeDict"></param>
|
||||
/// <returns>
|
||||
/// 一个元组,包含以下元素:
|
||||
/// <list type="table">
|
||||
/// <item><term>SysDictTypes</term><description>字典类型列表</description>
|
||||
/// </item>
|
||||
/// <item><term>SysDictDatas</term><description>字典数据列表</description>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </returns>
|
||||
private (List<SysDictType>, List<SysDictData>) GetUpdatedDicts(List<EnumTypeOutput> updatedEnumType, Dictionary<string, SysDictType> sysDictTypeDict)
|
||||
{
|
||||
var updatedSysDictTypes = new List<SysDictType>();
|
||||
var updatedSysDictData = new List<SysDictData>();
|
||||
foreach (var e in updatedEnumType)
|
||||
{
|
||||
if (sysDictTypeDict.TryGetValue(e.TypeName, out var value))
|
||||
{
|
||||
db.RollbackTran();
|
||||
Log.Error($"{context.Trigger.Description}新增枚举转换字典入库错误:" + _jsonSerializer.Serialize(error));
|
||||
throw new Exception($"{context.Trigger.Description}新增枚举转换字典入库错误");
|
||||
var updatedDictType = value;
|
||||
updatedDictType.Name = e.TypeDescribe;
|
||||
updatedDictType.Remark = e.TypeRemark;
|
||||
updatedSysDictTypes.Add(updatedDictType);
|
||||
var updatedDictData = updatedDictType.Children.Where(u => u.DictTypeId == updatedDictType.Id).ToList();
|
||||
|
||||
// 遍历需要更新的字典数据
|
||||
foreach (var dictData in updatedDictData)
|
||||
{
|
||||
var enumData = e.EnumEntities.Where(u => dictData.Code == u.Name).FirstOrDefault();
|
||||
if (enumData != null)
|
||||
{
|
||||
dictData.Value = enumData.Value.ToString();
|
||||
dictData.OrderNo = enumData.Value + OrderOffset;
|
||||
dictData.Name = enumData.Describe;
|
||||
dictData.TagType = enumData.Theme != "" ? enumData.Theme : dictData.TagType != "" ? dictData.TagType : DefaultTagType;
|
||||
updatedSysDictData.Add(dictData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var originColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = ConsoleColor.Green;
|
||||
Console.WriteLine($"【{DateTime.Now}】系统枚举转换字典");
|
||||
Console.ForegroundColor = originColor;
|
||||
return (updatedSysDictTypes, updatedSysDictData);
|
||||
}
|
||||
}
|
||||
@ -33,6 +33,8 @@ public class SysConfigSeedData : ISqlSugarEntitySeedData<SysConfig>
|
||||
new SysConfig{ Id=1300000000211, Name="域登录验证", Code=ConfigConst.SysDomainLogin, Value="False", SysFlag=YesNoEnum.Y, Remark="是否开启域登录验证", OrderNo=120, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
new SysConfig{ Id=1300000000221, 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=1300000000231, 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=1300000000241, Name="开启强制修改密码", Code=ConfigConst.SysForceChangePassword, Value="True", SysFlag=YesNoEnum.Y, Remark="开启强制修改密码", OrderNo=150, GroupCode=ConfigConst.SysDefaultGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
|
||||
new SysConfig{ Id=1300000000301, 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=1300000000311, 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") },
|
||||
new SysConfig{ Id=1300000000321, Name="系统描述", Code=ConfigConst.SysWebViceDesc, Value="站在巨人肩膀上的 .NET 通用权限开发框架", SysFlag=YesNoEnum.Y, Remark="系统描述", OrderNo=320, GroupCode=ConfigConst.SysWebConfigGroup, CreateTime=DateTime.Parse("2022-02-10 00:00:00") },
|
||||
|
||||
@ -230,6 +230,7 @@ public class SysAuthService : IDynamicApiController, ITransient
|
||||
{ ClaimConst.OrgName, user.SysOrg?.Name },
|
||||
{ ClaimConst.OrgType, user.SysOrg?.Type },
|
||||
{ ClaimConst.LoginMode, loginMode },
|
||||
{ ClaimConst.LastChangePasswordTime, user.LastChangePasswordTime },
|
||||
}, tokenExpire);
|
||||
|
||||
// 生成刷新Token令牌
|
||||
|
||||
@ -165,14 +165,9 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
[DisplayName("删除用户")]
|
||||
public virtual async Task DeleteUser(DeleteUserInput input)
|
||||
{
|
||||
var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id);
|
||||
if (user == null)
|
||||
return;
|
||||
|
||||
if (user.AccountType == AccountTypeEnum.SuperAdmin)
|
||||
throw Oops.Oh(ErrorCodeEnum.D1014);
|
||||
if (user.Id == _userManager.UserId)
|
||||
throw Oops.Oh(ErrorCodeEnum.D1001);
|
||||
var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
user.ValidateIsSuperAdminAccountType();
|
||||
user.ValidateIsUserId(_userManager.UserId);
|
||||
|
||||
// 若账号为租户默认账号则禁止删除
|
||||
var isTenantUser = await _sysUserRep.ChangeRepository<SqlSugarRepository<SysTenant>>().IsAnyAsync(u => u.UserId == input.Id);
|
||||
@ -206,7 +201,7 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
[DisplayName("查看用户基本信息")]
|
||||
public virtual async Task<SysUser> GetBaseInfo()
|
||||
{
|
||||
return await _sysUserRep.GetFirstAsync(u => u.Id == _userManager.UserId);
|
||||
return await _sysUserRep.GetByIdAsync(_userManager.UserId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -226,15 +221,15 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[UnitOfWork]
|
||||
[DisplayName("设置用户状态")]
|
||||
public virtual async Task<int> SetStatus(UserInput input)
|
||||
{
|
||||
if (_userManager.UserId == input.Id)
|
||||
throw Oops.Oh(ErrorCodeEnum.D1026);
|
||||
|
||||
var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
if (user.AccountType == AccountTypeEnum.SuperAdmin)
|
||||
throw Oops.Oh(ErrorCodeEnum.D1015);
|
||||
var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
user.ValidateIsSuperAdminAccountType(ErrorCodeEnum.D1015);
|
||||
|
||||
if (!Enum.IsDefined(typeof(StatusEnum), input.Status))
|
||||
throw Oops.Oh(ErrorCodeEnum.D3005);
|
||||
@ -285,7 +280,7 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
input.PasswordOld = CryptogramUtil.SM2Decrypt(input.PasswordOld);
|
||||
input.PasswordNew = CryptogramUtil.SM2Decrypt(input.PasswordNew);
|
||||
|
||||
var user = await _sysUserRep.GetFirstAsync(u => u.Id == _userManager.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
var user = await _sysUserRep.GetByIdAsync(_userManager.UserId) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
if (CryptogramUtil.CryptoType == CryptogramEnum.MD5.ToString())
|
||||
{
|
||||
if (user.Password != MD5Encryption.Encrypt(input.PasswordOld))
|
||||
@ -323,7 +318,7 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
[DisplayName("重置用户密码")]
|
||||
public virtual async Task<string> ResetPwd(ResetPwdUserInput input)
|
||||
{
|
||||
var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
var password = await _sysConfigService.GetConfigValue<string>(ConfigConst.SysPassword);
|
||||
user.Password = CryptogramUtil.Encrypt(password);
|
||||
await _sysUserRep.AsUpdateable(user).UpdateColumns(u => u.Password).ExecuteCommandAsync();
|
||||
@ -343,7 +338,7 @@ public class SysUserService : IDynamicApiController, ITransient
|
||||
[DisplayName("解除登录锁定")]
|
||||
public virtual async Task UnlockLogin(UnlockLoginInput input)
|
||||
{
|
||||
var user = await _sysUserRep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
var user = await _sysUserRep.GetByIdAsync(input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D0009);
|
||||
|
||||
// 清空密码错误次数
|
||||
var keyPasswordErrorTimes = $"{CacheConst.KeyPasswordErrorTimes}{user.Account}";
|
||||
|
||||
@ -106,4 +106,44 @@ public class DeleteMessageTemplateInput
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "订阅模板Id不能为空")]
|
||||
public string TemplateId { get; set; }
|
||||
}
|
||||
|
||||
public class UploadAvatarInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序用户身份标识
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "OpenId不能为空")]
|
||||
public string OpenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件
|
||||
/// </summary>
|
||||
[Required]
|
||||
public IFormFile File { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件类型
|
||||
/// </summary>
|
||||
public string FileType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文件路径
|
||||
/// </summary>
|
||||
public string Path { get; set; }
|
||||
}
|
||||
|
||||
public class SetNickNameInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 小程序用户身份标识
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "OpenId不能为空")]
|
||||
public string OpenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "昵称不能为空")]
|
||||
public string NickName { get; set; }
|
||||
}
|
||||
@ -15,14 +15,17 @@ public class SysWxOpenService : IDynamicApiController, ITransient
|
||||
private readonly SqlSugarRepository<SysOAuthUser> _sysOAuthUserRep;
|
||||
private readonly SysConfigService _sysConfigService;
|
||||
private readonly WechatApiClient _wechatApiClient;
|
||||
private readonly SysFileService _sysFileService;
|
||||
|
||||
public SysWxOpenService(SqlSugarRepository<SysOAuthUser> sysOAuthUserRep,
|
||||
SysConfigService sysConfigService,
|
||||
WechatApiClientFactory wechatApiClientFactory)
|
||||
WechatApiClientFactory wechatApiClientFactory,
|
||||
SysFileService sysFileService)
|
||||
{
|
||||
_sysOAuthUserRep = sysOAuthUserRep;
|
||||
_sysConfigService = sysConfigService;
|
||||
_wechatApiClient = wechatApiClientFactory.CreateWxOpenClient();
|
||||
_sysFileService = sysFileService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -131,6 +134,57 @@ public class SysWxOpenService : IDynamicApiController, ITransient
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 上传小程序头像
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[DisplayName("上传小程序头像")]
|
||||
public async Task<SysFile> UploadAvatar([FromForm] UploadAvatarInput input)
|
||||
{
|
||||
var wxUser = await _sysOAuthUserRep.GetFirstAsync(u => u.OpenId == input.OpenId);
|
||||
if (wxUser == null)
|
||||
throw Oops.Oh("未找到用户上传失败");
|
||||
|
||||
var res = await _sysFileService.UploadFile(new FileUploadInput { File = input.File, FileType = input.FileType, Path = input.Path });
|
||||
wxUser.Avatar = res.Url;
|
||||
await _sysOAuthUserRep.AsUpdateable(wxUser).IgnoreColumns(true).ExecuteCommandAsync();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设置小程序用户昵称
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
[HttpPost]
|
||||
public async Task SetNickName(SetNickNameInput input)
|
||||
{
|
||||
var wxUser = await _sysOAuthUserRep.GetFirstAsync(u => u.OpenId == input.OpenId);
|
||||
if (wxUser == null)
|
||||
throw Oops.Oh("未找到用户信息设置失败");
|
||||
wxUser.NickName = input.NickName;
|
||||
await _sysOAuthUserRep.AsUpdateable(wxUser).IgnoreColumns(true).ExecuteCommandAsync();
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取小程序用户信息
|
||||
/// </summary>
|
||||
/// <param name="openid"></param>
|
||||
/// <returns></returns>
|
||||
[AllowAnonymous]
|
||||
public async Task<dynamic> GetUserInfo(string openid)
|
||||
{
|
||||
var wxUser = await _sysOAuthUserRep.GetFirstAsync(u => u.OpenId == openid);
|
||||
if (wxUser == null)
|
||||
throw Oops.Oh("未找到用户信息获取失败");
|
||||
return new { nickName = wxUser.NickName, avator = wxUser.Avatar };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证签名 🔖
|
||||
/// </summary>
|
||||
|
||||
@ -26,6 +26,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.ReZero", "
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.ApprovalFlow", "Plugins\Admin.NET.Plugin.ApprovalFlow\Admin.NET.Plugin.ApprovalFlow.csproj", "{4124E31B-EA94-4EE3-9EC6-A565F1420AEA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.K3Cloud", "Plugins\Admin.NET.Plugin.K3Cloud\Admin.NET.Plugin.K3Cloud.csproj", "{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -64,6 +66,10 @@ Global
|
||||
{4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4124E31B-EA94-4EE3-9EC6-A565F1420AEA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
@ -73,6 +79,7 @@ Global
|
||||
{F6A002AD-CF7F-4771-8597-F12A50A93DAA} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
|
||||
{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
|
||||
{4124E31B-EA94-4EE3-9EC6-A565F1420AEA} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
|
||||
{9EB9C39E-E14F-443E-9AA3-EE417ABCBC1D} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {5CD801D7-984A-4F5C-8FA2-211B7A5EA9F3}
|
||||
|
||||
@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net6.0;net8.0</TargetFrameworks>
|
||||
<NoWarn>1701;1702;1591;8632</NoWarn>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>disable</Nullable>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<Copyright>Admin.NET</Copyright>
|
||||
<Description>Admin.NET 通用权限开发平台</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Configuration\**">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Admin.NET.Core\Admin.NET.Core.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
|
||||
|
||||
"K3Cloud": {
|
||||
// ERP地址
|
||||
"Url": "http://127.0.0.1/k3cloud/",
|
||||
// 帐套Id(数据中心ID)
|
||||
"AcctID": "XXXXXXXXX",
|
||||
// 应用Id
|
||||
"AppId": "XXXXXXXX",
|
||||
// 应用密钥
|
||||
"AppKey": "XXX",
|
||||
// 用户名称
|
||||
"UserName": "XXX",
|
||||
// 用户密码
|
||||
"UserPassword": "XXXX@2024",
|
||||
// 语言代码
|
||||
"LanguageCode": "2052"
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,8 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
global using Furion;
|
||||
global using Furion.ConfigurableOptions;
|
||||
@ -0,0 +1,45 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud;
|
||||
|
||||
public sealed class K3CloudOptions : IConfigurableOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// ERP业务站点地址
|
||||
/// </summary>
|
||||
public string Url { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 帐套Id(数据中心ID)
|
||||
/// </summary>
|
||||
public string AcctID { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用Id
|
||||
/// </summary>
|
||||
public string AppId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用密钥
|
||||
/// </summary>
|
||||
public string AppKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户名称
|
||||
/// </summary>
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户密码
|
||||
/// </summary>
|
||||
public string UserPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 语言代码
|
||||
/// </summary>
|
||||
public string LanguageCode { get; set; }
|
||||
}
|
||||
@ -0,0 +1,23 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud.Service;
|
||||
|
||||
/// <summary>
|
||||
/// ERP基础入参
|
||||
/// </summary>
|
||||
public class K3CloudBaeInput<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 表单Id
|
||||
/// </summary>
|
||||
public string formid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据包
|
||||
/// </summary>
|
||||
public T data { get; set; }
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud.Service;
|
||||
|
||||
public class K3CloudLoginInput
|
||||
{
|
||||
public List<string> parameters { get; set; }
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud.Service;
|
||||
|
||||
public class K3CloudLoginOutput
|
||||
{
|
||||
public string Message { get; set; }
|
||||
public string MessageCode { get; set; }
|
||||
public ErpLoginResultType LoginResultType { get; set; }
|
||||
}
|
||||
|
||||
public enum ErpLoginResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// 激活
|
||||
/// </summary>
|
||||
Activation = -7,
|
||||
|
||||
/// <summary>
|
||||
/// 云通行证未绑定Cloud账号
|
||||
/// </summary>
|
||||
EntryCloudUnBind = -6,
|
||||
|
||||
/// <summary>
|
||||
/// 需要表单处理
|
||||
/// </summary>
|
||||
DealWithForm = -5,
|
||||
|
||||
/// <summary>
|
||||
/// 登录警告
|
||||
/// </summary>
|
||||
Wanning = -4,
|
||||
|
||||
/// <summary>
|
||||
/// 密码验证不通过(强制的)
|
||||
/// </summary>
|
||||
PWInvalid_Required = -3,
|
||||
|
||||
/// <summary>
|
||||
/// 密码验证不通过(可选的)
|
||||
/// </summary>
|
||||
PWInvalid_Optional = -2,
|
||||
|
||||
/// <summary>
|
||||
/// 登录失败
|
||||
/// </summary>
|
||||
Failure = -1,
|
||||
|
||||
/// <summary>
|
||||
/// 用户或密码错误
|
||||
/// </summary>
|
||||
PWError = 0,
|
||||
|
||||
/// <summary>
|
||||
/// 登录成功
|
||||
/// </summary>
|
||||
Success = 1
|
||||
}
|
||||
@ -0,0 +1,66 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud.Service;
|
||||
|
||||
public class K3CloudPushResultOutput
|
||||
{
|
||||
public ErpPushResultInfo Result { get; set; }
|
||||
}
|
||||
|
||||
public class ErpPushResultInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Id
|
||||
/// </summary>
|
||||
public object? Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
public string? Number { get; set; }
|
||||
|
||||
public ErpPushResultInfo_ResponseStatus ResponseStatus { get; set; }
|
||||
}
|
||||
|
||||
public class ErpPushResultInfo_ResponseStatus
|
||||
{
|
||||
public bool IsSuccess { get; set; }
|
||||
public int? ErrorCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 错误代码MsgCode说明
|
||||
///0:默认
|
||||
///1:上下文丢失 会话过期
|
||||
///2:没有权限
|
||||
///3:操作标识为空
|
||||
///4:异常
|
||||
///5:单据标识为空
|
||||
///6:数据库操作失败
|
||||
///7:许可错误
|
||||
///8:参数错误
|
||||
///9:指定字段/值不存在
|
||||
///10:未找到对应数据
|
||||
///11:验证失败
|
||||
///12:不可操作
|
||||
///13:网控冲突
|
||||
///14:调用限制
|
||||
///15:禁止管理员登录
|
||||
/// </summary>
|
||||
public int? MsgCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 如果失败,具体失败原因
|
||||
/// </summary>
|
||||
public List<ErpPushResultInfo_Errors> Errors { get; set; }
|
||||
}
|
||||
|
||||
public class ErpPushResultInfo_Errors
|
||||
{
|
||||
public string FieldName { get; set; }
|
||||
public string Message { get; set; }
|
||||
public int DIndex { get; set; }
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using Furion.RemoteRequest;
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud.Service;
|
||||
|
||||
/// <summary>
|
||||
/// 金蝶云星空ERP接口
|
||||
/// </summary>
|
||||
[Client("K3Cloud")]
|
||||
public interface IK3CloudApi : IHttpDispatchProxy
|
||||
{
|
||||
/// <summary>
|
||||
/// 验证用户
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
[Post("Kingdee.BOS.WebApi.ServicesStub.AuthService.ValidateUser.common.kdsvc")]
|
||||
Task<K3CloudLoginOutput> ValidateUser([Body] K3CloudLoginInput input, [Interceptor(InterceptorTypes.Response)] Action<HttpClient, HttpResponseMessage> action = default);
|
||||
|
||||
/// <summary>
|
||||
/// 保存表单
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
[Post("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Save.common.kdsvc")]
|
||||
Task<K3CloudPushResultOutput> Save<T>([Body] K3CloudBaeInput<T> input, [Interceptor(InterceptorTypes.Request)] Action<HttpClient, HttpRequestMessage> action = default);
|
||||
|
||||
/// <summary>
|
||||
/// 提交表单
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
[Post("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Submit.common.kdsvc")]
|
||||
Task<K3CloudPushResultOutput> Submit<T>([Body] K3CloudBaeInput<T> input, [Interceptor(InterceptorTypes.Request)] Action<HttpClient, HttpRequestMessage> action = default);
|
||||
|
||||
/// <summary>
|
||||
/// 审核表单
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <param name="action"></param>
|
||||
/// <returns></returns>
|
||||
[Post("Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.Audit.common.kdsvc")]
|
||||
Task<K3CloudPushResultOutput> Audit<T>([Body] K3CloudBaeInput<T> input, [Interceptor(InterceptorTypes.Request)] Action<HttpClient, HttpRequestMessage> action = default);
|
||||
}
|
||||
31
Admin.NET/Plugins/Admin.NET.Plugin.K3Cloud/Startup.cs
Normal file
31
Admin.NET/Plugins/Admin.NET.Plugin.K3Cloud/Startup.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Admin.NET.Plugin.K3Cloud;
|
||||
|
||||
[AppStartup(100)]
|
||||
public class Startup : AppStartup
|
||||
{
|
||||
public void ConfigureServices(IServiceCollection services)
|
||||
{
|
||||
services.AddConfigurableOptions<K3CloudOptions>();
|
||||
services.AddRemoteRequest(options =>
|
||||
{
|
||||
options.AddHttpClient("K3Cloud", u =>
|
||||
{
|
||||
u.BaseAddress = new Uri(App.GetConfig<K3CloudOptions>("K3Cloud", true).Url);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
|
||||
{
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "admin.net.pro",
|
||||
"type": "module",
|
||||
"version": "2.4.33",
|
||||
"lastBuildTime": "2024.08.30",
|
||||
"lastBuildTime": "2024.09.01",
|
||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||
"author": "zuohuaijun",
|
||||
"license": "MIT",
|
||||
@ -26,7 +26,7 @@
|
||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||
"animate.css": "^4.1.1",
|
||||
"async-validator": "^4.2.5",
|
||||
"axios": "^1.7.5",
|
||||
"axios": "^1.7.6",
|
||||
"countup.js": "^2.8.0",
|
||||
"cropperjs": "^1.6.2",
|
||||
"echarts": "^5.5.1",
|
||||
@ -70,7 +70,7 @@
|
||||
"vue-router": "^4.4.3",
|
||||
"vue-signature-pad": "^3.0.2",
|
||||
"vue3-tree-org": "^4.2.2",
|
||||
"vxe-pc-ui": "^4.1.12",
|
||||
"vxe-pc-ui": "^4.1.15",
|
||||
"vxe-table": "^4.7.59",
|
||||
"vxe-table-plugin-element": "^4.0.4",
|
||||
"vxe-table-plugin-export-xlsx": "^4.0.5",
|
||||
|
||||
@ -20,10 +20,12 @@ import { BASE_PATH, COLLECTION_FORMATS, RequestArgs, BaseAPI, RequiredError } fr
|
||||
import { AddSubscribeMessageTemplateInput } from '../models';
|
||||
import { AdminResultGenerateQRImageOutput } from '../models';
|
||||
import { AdminResultObject } from '../models';
|
||||
import { AdminResultSysFile } from '../models';
|
||||
import { AdminResultWxOpenIdOutput } from '../models';
|
||||
import { AdminResultWxPhoneOutput } from '../models';
|
||||
import { GenerateQRImageInput } from '../models';
|
||||
import { SendSubscribeMessageInput } from '../models';
|
||||
import { SetNickNameInput } from '../models';
|
||||
import { WxOpenIdLoginInput } from '../models';
|
||||
/**
|
||||
* SysWxOpenApi - axios parameter creator
|
||||
@ -218,6 +220,170 @@ export const SysWxOpenApiAxiosParamCreator = function (configuration?: Configura
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 设置小程序用户昵称
|
||||
* @param {SetNickNameInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysWxOpenSetNickNamePost: async (body?: SetNickNameInput, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysWxOpen/setNickName`;
|
||||
// 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 上传小程序头像
|
||||
* @param {string} [openId]
|
||||
* @param {Blob} [file]
|
||||
* @param {string} [fileType]
|
||||
* @param {string} [path]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysWxOpenUploadAvatarPostForm: async (openId?: string, file?: Blob, fileType?: string, path?: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
const localVarPath = `/api/sysWxOpen/uploadAvatar`;
|
||||
// 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;
|
||||
const localVarFormParams = new FormData();
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
if (openId !== undefined) {
|
||||
localVarFormParams.append('OpenId', openId as any);
|
||||
}
|
||||
|
||||
if (file !== undefined) {
|
||||
localVarFormParams.append('File', file as any);
|
||||
}
|
||||
|
||||
if (fileType !== undefined) {
|
||||
localVarFormParams.append('FileType', fileType as any);
|
||||
}
|
||||
|
||||
if (path !== undefined) {
|
||||
localVarFormParams.append('Path', path as any);
|
||||
}
|
||||
|
||||
localVarHeaderParameter['Content-Type'] = 'multipart/form-data';
|
||||
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};
|
||||
localVarRequestOptions.data = localVarFormParams;
|
||||
|
||||
return {
|
||||
url: localVarUrlObj.pathname + localVarUrlObj.search + localVarUrlObj.hash,
|
||||
options: localVarRequestOptions,
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取小程序用户信息
|
||||
* @param {string} openid
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
apiSysWxOpenUserInfoOpenidGet: async (openid: string, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
|
||||
// verify required parameter 'openid' is not null or undefined
|
||||
if (openid === null || openid === undefined) {
|
||||
throw new RequiredError('openid','Required parameter openid was null or undefined when calling apiSysWxOpenUserInfoOpenidGet.');
|
||||
}
|
||||
const localVarPath = `/api/sysWxOpen/userInfo/{openid}`
|
||||
.replace(`{${"openid"}}`, encodeURIComponent(String(openid)));
|
||||
// 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: 'GET', ...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 验证签名 🔖
|
||||
@ -506,6 +672,51 @@ export const SysWxOpenApiFp = function(configuration?: Configuration) {
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 设置小程序用户昵称
|
||||
* @param {SetNickNameInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenSetNickNamePost(body?: SetNickNameInput, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<void>>> {
|
||||
const localVarAxiosArgs = await SysWxOpenApiAxiosParamCreator(configuration).apiSysWxOpenSetNickNamePost(body, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 上传小程序头像
|
||||
* @param {string} [openId]
|
||||
* @param {Blob} [file]
|
||||
* @param {string} [fileType]
|
||||
* @param {string} [path]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenUploadAvatarPostForm(openId?: string, file?: Blob, fileType?: string, path?: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultSysFile>>> {
|
||||
const localVarAxiosArgs = await SysWxOpenApiAxiosParamCreator(configuration).apiSysWxOpenUploadAvatarPostForm(openId, file, fileType, path, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取小程序用户信息
|
||||
* @param {string} openid
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenUserInfoOpenidGet(openid: string, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => Promise<AxiosResponse<AdminResultObject>>> {
|
||||
const localVarAxiosArgs = await SysWxOpenApiAxiosParamCreator(configuration).apiSysWxOpenUserInfoOpenidGet(openid, options);
|
||||
return (axios: AxiosInstance = globalAxios, basePath: string = BASE_PATH) => {
|
||||
const axiosRequestArgs :AxiosRequestConfig = {...localVarAxiosArgs.options, url: basePath + localVarAxiosArgs.url};
|
||||
return axios.request(axiosRequestArgs);
|
||||
};
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 验证签名 🔖
|
||||
@ -614,6 +825,39 @@ export const SysWxOpenApiFactory = function (configuration?: Configuration, base
|
||||
async apiSysWxOpenSendSubscribeMessagePost(body?: SendSubscribeMessageInput, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
|
||||
return SysWxOpenApiFp(configuration).apiSysWxOpenSendSubscribeMessagePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 设置小程序用户昵称
|
||||
* @param {SetNickNameInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenSetNickNamePost(body?: SetNickNameInput, options?: AxiosRequestConfig): Promise<AxiosResponse<void>> {
|
||||
return SysWxOpenApiFp(configuration).apiSysWxOpenSetNickNamePost(body, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 上传小程序头像
|
||||
* @param {string} [openId]
|
||||
* @param {Blob} [file]
|
||||
* @param {string} [fileType]
|
||||
* @param {string} [path]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenUploadAvatarPostForm(openId?: string, file?: Blob, fileType?: string, path?: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultSysFile>> {
|
||||
return SysWxOpenApiFp(configuration).apiSysWxOpenUploadAvatarPostForm(openId, file, fileType, path, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 获取小程序用户信息
|
||||
* @param {string} openid
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
*/
|
||||
async apiSysWxOpenUserInfoOpenidGet(openid: string, options?: AxiosRequestConfig): Promise<AxiosResponse<AdminResultObject>> {
|
||||
return SysWxOpenApiFp(configuration).apiSysWxOpenUserInfoOpenidGet(openid, options).then((request) => request(axios, basePath));
|
||||
},
|
||||
/**
|
||||
*
|
||||
* @summary 验证签名 🔖
|
||||
@ -711,6 +955,42 @@ export class SysWxOpenApi extends BaseAPI {
|
||||
public async apiSysWxOpenSendSubscribeMessagePost(body?: SendSubscribeMessageInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
|
||||
return SysWxOpenApiFp(this.configuration).apiSysWxOpenSendSubscribeMessagePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 设置小程序用户昵称
|
||||
* @param {SetNickNameInput} [body]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysWxOpenApi
|
||||
*/
|
||||
public async apiSysWxOpenSetNickNamePost(body?: SetNickNameInput, options?: AxiosRequestConfig) : Promise<AxiosResponse<void>> {
|
||||
return SysWxOpenApiFp(this.configuration).apiSysWxOpenSetNickNamePost(body, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 上传小程序头像
|
||||
* @param {string} [openId]
|
||||
* @param {Blob} [file]
|
||||
* @param {string} [fileType]
|
||||
* @param {string} [path]
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysWxOpenApi
|
||||
*/
|
||||
public async apiSysWxOpenUploadAvatarPostForm(openId?: string, file?: Blob, fileType?: string, path?: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultSysFile>> {
|
||||
return SysWxOpenApiFp(this.configuration).apiSysWxOpenUploadAvatarPostForm(openId, file, fileType, path, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 获取小程序用户信息
|
||||
* @param {string} openid
|
||||
* @param {*} [options] Override http request option.
|
||||
* @throws {RequiredError}
|
||||
* @memberof SysWxOpenApi
|
||||
*/
|
||||
public async apiSysWxOpenUserInfoOpenidGet(openid: string, options?: AxiosRequestConfig) : Promise<AxiosResponse<AdminResultObject>> {
|
||||
return SysWxOpenApiFp(this.configuration).apiSysWxOpenUserInfoOpenidGet(openid, options).then((request) => request(this.axios, this.basePath));
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @summary 验证签名 🔖
|
||||
|
||||
@ -399,6 +399,14 @@ export interface AddUserInput {
|
||||
*/
|
||||
signature?: string | null;
|
||||
|
||||
/**
|
||||
* 最新密码修改时间
|
||||
*
|
||||
* @type {Date}
|
||||
* @memberof AddUserInput
|
||||
*/
|
||||
lastChangePasswordTime?: Date | null;
|
||||
|
||||
/**
|
||||
* 账号
|
||||
*
|
||||
|
||||
@ -301,6 +301,7 @@ export * from './search';
|
||||
export * from './security-rule-set';
|
||||
export * from './send-subscribe-message-input';
|
||||
export * from './serialization-format';
|
||||
export * from './set-nick-name-input';
|
||||
export * from './signature-input';
|
||||
export * from './sm-key-pair-output';
|
||||
export * from './sms-verify-code-input';
|
||||
@ -370,6 +371,7 @@ export * from './sys-schedule';
|
||||
export * from './sys-user';
|
||||
export * from './sys-user-ext-org';
|
||||
export * from './sys-wechat-pay';
|
||||
export * from './sys-wx-open-upload-avatar-body';
|
||||
export * from './table-output';
|
||||
export * from './tenant-id-input';
|
||||
export * from './tenant-input';
|
||||
|
||||
38
Web/src/api-services/models/set-nick-name-input.ts
Normal file
38
Web/src/api-services/models/set-nick-name-input.ts
Normal file
@ -0,0 +1,38 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface SetNickNameInput
|
||||
*/
|
||||
export interface SetNickNameInput {
|
||||
|
||||
/**
|
||||
* 小程序用户身份标识
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SetNickNameInput
|
||||
*/
|
||||
openId: string;
|
||||
|
||||
/**
|
||||
* 昵称
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SetNickNameInput
|
||||
*/
|
||||
nickName: string;
|
||||
}
|
||||
@ -413,4 +413,12 @@ export interface SysUser {
|
||||
* @memberof SysUser
|
||||
*/
|
||||
signature?: string | null;
|
||||
|
||||
/**
|
||||
* 最新密码修改时间
|
||||
*
|
||||
* @type {Date}
|
||||
* @memberof SysUser
|
||||
*/
|
||||
lastChangePasswordTime?: Date | null;
|
||||
}
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
/* tslint:disable */
|
||||
/* eslint-disable */
|
||||
/**
|
||||
* Admin.NET 通用权限开发平台
|
||||
* 让 .NET 开发更简单、更通用、更流行。整合最新技术,模块插件式开发,前后端分离,开箱即用。<br/><u><b><font color='FF0000'> 👮不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!</font></b></u>
|
||||
*
|
||||
* OpenAPI spec version: 1.0.0
|
||||
*
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @export
|
||||
* @interface SysWxOpenUploadAvatarBody
|
||||
*/
|
||||
export interface SysWxOpenUploadAvatarBody {
|
||||
|
||||
/**
|
||||
* 小程序用户身份标识
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SysWxOpenUploadAvatarBody
|
||||
*/
|
||||
openId: string;
|
||||
|
||||
/**
|
||||
* 文件
|
||||
*
|
||||
* @type {Blob}
|
||||
* @memberof SysWxOpenUploadAvatarBody
|
||||
*/
|
||||
file: Blob;
|
||||
|
||||
/**
|
||||
* 文件类型
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SysWxOpenUploadAvatarBody
|
||||
*/
|
||||
fileType?: string;
|
||||
|
||||
/**
|
||||
* 文件路径
|
||||
*
|
||||
* @type {string}
|
||||
* @memberof SysWxOpenUploadAvatarBody
|
||||
*/
|
||||
path?: string;
|
||||
}
|
||||
@ -399,6 +399,14 @@ export interface UpdateUserInput {
|
||||
*/
|
||||
signature?: string | null;
|
||||
|
||||
/**
|
||||
* 最新密码修改时间
|
||||
*
|
||||
* @type {Date}
|
||||
* @memberof UpdateUserInput
|
||||
*/
|
||||
lastChangePasswordTime?: Date | null;
|
||||
|
||||
/**
|
||||
* 账号
|
||||
*
|
||||
|
||||
@ -414,6 +414,14 @@ export interface UserOutput {
|
||||
*/
|
||||
signature?: string | null;
|
||||
|
||||
/**
|
||||
* 最新密码修改时间
|
||||
*
|
||||
* @type {Date}
|
||||
* @memberof UserOutput
|
||||
*/
|
||||
lastChangePasswordTime?: Date | null;
|
||||
|
||||
/**
|
||||
* 机构名称
|
||||
*
|
||||
|
||||
@ -113,13 +113,13 @@
|
||||
<el-tab-pane label="修改密码">
|
||||
<el-form ref="ruleFormPasswordRef" :model="state.ruleFormPassword" label-width="auto">
|
||||
<el-form-item label="当前密码" prop="passwordOld" :rules="[{ required: true, message: '当前密码不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleFormPassword.passwordOld" type="password" autocomplete="off" />
|
||||
<el-input v-model="state.ruleFormPassword.passwordOld" type="password" autocomplete="off" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="新密码" prop="passwordNew" :rules="[{ required: true, message: '新密码不能为空', trigger: 'blur' }]">
|
||||
<el-input v-model="state.ruleFormPassword.passwordNew" type="password" autocomplete="off" />
|
||||
<el-input v-model="state.ruleFormPassword.passwordNew" type="password" autocomplete="off" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item label="确认密码" prop="passwordNew2" :rules="[{ validator: validatePassword, required: true, trigger: 'blur' }]">
|
||||
<el-input v-model="state.passwordNew2" type="password" autocomplete="off" />
|
||||
<el-input v-model="state.passwordNew2" type="password" autocomplete="off" show-password />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="ele-Refresh" @click="resetPassword">重 置</el-button>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user