v3.4.6
This commit is contained in:
@@ -53,4 +53,9 @@ public class LoginInput
|
||||
/// 未绑定 成功登录后 自动绑定 缓存 Key.
|
||||
/// </summary>
|
||||
public string jnpf_ticket { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单点登录票据.
|
||||
/// </summary>
|
||||
public string online_ticket { get; set; }
|
||||
}
|
||||
@@ -35,6 +35,12 @@ using JNPF.Systems.Entitys.Model.Permission.SocialsUser;
|
||||
using JNPF.Systems.Interfaces.Permission;
|
||||
using JNPF.Extras.CollectiveOAuth.Models;
|
||||
using JNPF.Common.Models;
|
||||
using JNPF.Common.Options;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using JNPF.Common.Core.Handlers;
|
||||
using JNPF.Message.Interfaces.Message;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
|
||||
using Aop.Api.Domain;
|
||||
|
||||
namespace JNPF.OAuth;
|
||||
|
||||
@@ -45,6 +51,11 @@ namespace JNPF.OAuth;
|
||||
[Route("api/[controller]")]
|
||||
public class OAuthService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置文档.
|
||||
/// </summary>
|
||||
private readonly OauthOptions _oauthOptions = App.GetConfig<OauthOptions>("OAuth", true);
|
||||
|
||||
/// <summary>
|
||||
/// 用户仓储.
|
||||
/// </summary>
|
||||
@@ -125,6 +136,10 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
private SqlSugarScope _sqlSugarClient;
|
||||
|
||||
private readonly ISendMessageService _sendMessageService;
|
||||
|
||||
private readonly IMHandler _imHandler;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="OAuthService"/>类型的新实例.
|
||||
/// </summary>
|
||||
@@ -138,13 +153,15 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
IModuleFormService formService,
|
||||
ISysConfigService sysConfigService,
|
||||
ISocialsUserService socialsUserService,
|
||||
ISendMessageService sendMessageService,
|
||||
IOptions<ConnectionStringsOptions> connectionOptions,
|
||||
IOptions<TenantOptions> tenantOptions,
|
||||
ISqlSugarClient sqlSugarClient,
|
||||
IHttpContextAccessor httpContextAccessor,
|
||||
ICacheManager cacheManager,
|
||||
IUserManager userManager,
|
||||
IEventPublisher eventPublisher)
|
||||
IEventPublisher eventPublisher,
|
||||
IMHandler imHandler)
|
||||
{
|
||||
_captchaHandler = captchaHandler;
|
||||
_userRepository = userRepository;
|
||||
@@ -155,6 +172,7 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
_formService = formService;
|
||||
_sysConfigService = sysConfigService;
|
||||
_socialsUserService = socialsUserService;
|
||||
_sendMessageService = sendMessageService;
|
||||
_connectionStrings = connectionOptions.Value;
|
||||
_tenant = tenantOptions.Value;
|
||||
_sqlSugarClient = (SqlSugarScope)sqlSugarClient;
|
||||
@@ -162,6 +180,7 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
_cacheManager = cacheManager;
|
||||
_userManager = userManager;
|
||||
_eventPublisher = eventPublisher;
|
||||
_imHandler = imHandler;
|
||||
}
|
||||
|
||||
#region Get
|
||||
@@ -290,12 +309,15 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
|
||||
if ((loginOutput.userInfo.systemIds.Any() && !loginOutput.userInfo.systemIds.Any(x => x.id.Equals(loginOutput.userInfo.systemId))) || loginOutput.userInfo.systemId.IsNullOrEmpty())
|
||||
{
|
||||
var defaultItem = loginOutput.userInfo.systemIds.Find(x => x.enCode.Equals("mainSystem"));
|
||||
if (defaultItem == null) defaultItem = loginOutput.userInfo.systemIds.FirstOrDefault();
|
||||
loginOutput.userInfo.systemId = defaultItem.id;
|
||||
defaultItem.currentSystem = true;
|
||||
await _userRepository.AsUpdateable().SetColumns(x => x.SystemId == loginOutput.userInfo.systemId).Where(x => x.Id.Equals(userId)).ExecuteCommandAsync();
|
||||
loginOutput.menuList = await _moduleService.GetUserTreeModuleList(type);
|
||||
if (loginOutput.userInfo.systemIds.Any())
|
||||
{
|
||||
var defaultItem = loginOutput.userInfo.systemIds.Find(x => x.enCode.Equals("mainSystem"));
|
||||
if (defaultItem == null) defaultItem = loginOutput.userInfo.systemIds.FirstOrDefault();
|
||||
loginOutput.userInfo.systemId = defaultItem.id;
|
||||
defaultItem.currentSystem = true;
|
||||
await _userRepository.AsUpdateable().SetColumns(x => x.SystemId == loginOutput.userInfo.systemId).Where(x => x.Id.Equals(userId)).ExecuteCommandAsync();
|
||||
loginOutput.menuList = await _moduleService.GetUserTreeModuleList(type);
|
||||
}
|
||||
}
|
||||
|
||||
if (!loginOutput.userInfo.systemIds.Any()) loginOutput.menuList.Clear();
|
||||
@@ -357,24 +379,26 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Logout")]
|
||||
public async Task Logout()
|
||||
public async Task Logout([FromQuery] string ticket)
|
||||
{
|
||||
var tenantId = _userManager.TenantId ?? "default";
|
||||
var userId = _userManager.UserId ?? "admim";
|
||||
var httpContext = _httpContextAccessor.HttpContext;
|
||||
httpContext.SignoutToSwagger();
|
||||
|
||||
// 清除IM中的webSocket, modified by PhilPan 改为在IMHandle中处理
|
||||
//var list = await GetOnlineUserList();
|
||||
//if (list != null)
|
||||
//{
|
||||
// var onlineUser = list.Find(it => it.tenantId == _userManager.TenantId && it.userId == _userManager.UserId);
|
||||
// if (onlineUser != null)
|
||||
// {
|
||||
// list.RemoveAll((x) => x.connectionId == onlineUser.connectionId);
|
||||
// await SetOnlineUserList(list);
|
||||
// }
|
||||
//}
|
||||
// 清除IM中的webSocket
|
||||
var list = await GetOnlineUserList(tenantId);
|
||||
if (list != null)
|
||||
{
|
||||
var onlineUser = list.Find(it => it.tenantId == tenantId && it.userId == userId);
|
||||
if (onlineUser != null)
|
||||
{
|
||||
list.RemoveAll((x) => x.connectionId == onlineUser.connectionId);
|
||||
await SetOnlineUserList(list, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
await DelUserInfo();
|
||||
await DelUserInfo(tenantId, userId);
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -431,9 +455,15 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
options = JNPFTenantExtensions.GetLinkToCustom(tenantId, result.data.linkList);
|
||||
}
|
||||
}
|
||||
|
||||
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
if (!"default".Equals(tenantId) && _tenant.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
_sqlSugarClient.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == tenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -563,9 +593,13 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
{ ClaimConst.CLAINMADMINISTRATOR, userAnyPwd.IsAdministrator },
|
||||
{ ClaimConst.TENANTID, options.ConfigId },
|
||||
{ ClaimConst.CONNECTIONCONFIG, options},
|
||||
{ ClaimConst.SINGLELOGIN, (int)sysConfig.singleLogin }
|
||||
{ ClaimConst.SINGLELOGIN, (int)sysConfig.singleLogin },
|
||||
{ ClaimConst.OnlineTicket, input.online_ticket }
|
||||
}, tokenTimeout);
|
||||
|
||||
// 单点登录标识缓存
|
||||
if (_oauthOptions.Enabled) _cacheManager.Set("OnlineTicket_" + input.online_ticket, options.ConfigId);
|
||||
|
||||
// 设置Swagger自动登录
|
||||
_httpContextAccessor.HttpContext.SigninToSwagger(accessToken);
|
||||
|
||||
@@ -635,8 +669,7 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
}
|
||||
}
|
||||
|
||||
return new
|
||||
{
|
||||
return new {
|
||||
theme = user.Theme == null ? "classic" : user.Theme,
|
||||
token = string.Format("Bearer {0}", accessToken)
|
||||
};
|
||||
@@ -676,6 +709,63 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
await _userRepository.AsUpdateable(userInfo).ExecuteCommandAsync();
|
||||
return new { code = 200, msg = "注销成功" };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单点登录退出.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("Logout/auth2")]
|
||||
[AllowAnonymous]
|
||||
public async Task OnlineLogout()
|
||||
{
|
||||
var ticket = _httpContextAccessor.HttpContext.Request.Form["ticket"];
|
||||
var tenantId = await _cacheManager.GetAsync("OnlineTicket_" + ticket);
|
||||
if (ticket.IsNotEmptyOrNull())
|
||||
{
|
||||
await _cacheManager.DelAsync("OnlineTicket_" + ticket);
|
||||
var userId = _userManager.GetAdminUserId();
|
||||
var userOnlineList = new List<UserOnlineModel>();
|
||||
userOnlineList = await GetOnlineUserList(tenantId);
|
||||
var userOnline = userOnlineList.Find(x => x.onlineTicket.Equals(ticket));
|
||||
if (userOnline != null)
|
||||
{
|
||||
userId = userOnline.userId;
|
||||
await _imHandler.SendMessageAsync(userOnline.connectionId, new { method = "logout", msg = "此账号已在其他地方登陆" }.ToJsonString());
|
||||
}
|
||||
|
||||
// 清除IM中的webSocket
|
||||
if (userOnlineList != null)
|
||||
{
|
||||
var onlineUser = userOnlineList.Find(it => it.tenantId == tenantId && it.userId == userId);
|
||||
if (onlineUser != null)
|
||||
{
|
||||
userOnlineList.RemoveAll((x) => x.connectionId == onlineUser.connectionId);
|
||||
await SetOnlineUserList(userOnlineList, tenantId);
|
||||
}
|
||||
}
|
||||
|
||||
await DelUserInfo(tenantId, userId);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 密码过期提醒.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("updatePasswordMessage")]
|
||||
public async Task PwdMessage()
|
||||
{
|
||||
var sysConfigInfo = await _sysConfigService.GetInfo();
|
||||
// 密码修改时间.
|
||||
var changePasswordDate = _userManager.User.ChangePasswordDate.IsNullOrEmpty() ? _userManager.User.CreatorTime : _userManager.User.ChangePasswordDate;
|
||||
// 提醒时间
|
||||
var remindDate = changePasswordDate.ParseToDateTime().AddDays(sysConfigInfo.updateCycle - sysConfigInfo.updateInAdvance);
|
||||
if (sysConfigInfo.passwordIsUpdatedRegularly == 1 && remindDate < DateTime.Now)
|
||||
{
|
||||
await _sendMessageService.SendMessageSystem("XTXXTX001");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateMethod
|
||||
@@ -740,9 +830,9 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
/// 获取在线用户列表.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<List<UserOnlineModel>> GetOnlineUserList()
|
||||
private async Task<List<UserOnlineModel>> GetOnlineUserList(string tenantId)
|
||||
{
|
||||
string cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYONLINEUSER, _userManager.ConnectionConfig.ConfigId);
|
||||
string cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYONLINEUSER, tenantId);
|
||||
return await _cacheManager.GetAsync<List<UserOnlineModel>>(cacheKey);
|
||||
}
|
||||
|
||||
@@ -751,18 +841,18 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <param name="onlineList">在线用户列表.</param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> SetOnlineUserList(List<UserOnlineModel> onlineList)
|
||||
private async Task<bool> SetOnlineUserList(List<UserOnlineModel> onlineList, string tenantId)
|
||||
{
|
||||
string cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYONLINEUSER, _userManager.ConnectionConfig.ConfigId);
|
||||
string cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYONLINEUSER, tenantId);
|
||||
return await _cacheManager.SetAsync(cacheKey, onlineList);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除用户登录信息缓存.
|
||||
/// </summary>
|
||||
private async Task<bool> DelUserInfo()
|
||||
private async Task<bool> DelUserInfo(string tenantId, string userId)
|
||||
{
|
||||
string cacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, _userManager.ConnectionConfig.ConfigId, _userManager.UserId);
|
||||
string cacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, userId);
|
||||
return await _cacheManager.DelAsync(cacheKey);
|
||||
}
|
||||
|
||||
@@ -1109,15 +1199,25 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
{
|
||||
var loginConfigModel = new SocialsLoginConfigModel();
|
||||
|
||||
// 追加第三方登录配置
|
||||
var loginList = _socialsUserService.GetLoginList(CommonConst.PARAMS_JNPF_TICKET.ToUpper());
|
||||
if (loginList == null) return loginConfigModel;
|
||||
if (loginList.Any())
|
||||
if (_oauthOptions.Enabled)
|
||||
{
|
||||
loginConfigModel.socialsList = loginList.ToObject<List<object>>();
|
||||
loginConfigModel.redirect = false;
|
||||
var url = _oauthOptions.LoginPath + "/" + _oauthOptions.DefaultSSO;
|
||||
loginConfigModel.redirect = true;
|
||||
loginConfigModel.url = url;
|
||||
loginConfigModel.ticketParams = CommonConst.PARAMS_JNPF_TICKET;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 追加第三方登录配置
|
||||
var loginList = _socialsUserService.GetLoginList(CommonConst.PARAMS_JNPF_TICKET.ToUpper());
|
||||
if (loginList == null) return loginConfigModel;
|
||||
if (loginList.Any())
|
||||
{
|
||||
loginConfigModel.socialsList = loginList.ToObject<List<object>>();
|
||||
loginConfigModel.redirect = false;
|
||||
loginConfigModel.ticketParams = CommonConst.PARAMS_JNPF_TICKET;
|
||||
}
|
||||
}
|
||||
|
||||
return loginConfigModel;
|
||||
}
|
||||
@@ -1132,10 +1232,10 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
public dynamic GetTicket()
|
||||
{
|
||||
SocialsLoginTicketModel ticketModel = new SocialsLoginTicketModel();
|
||||
var curDate = DateTime.Now.AddMinutes(5); // 默认过期5分钟.
|
||||
var curDate = DateTime.Now.AddMinutes(_oauthOptions.TicketTimeout); // 默认过期5分钟.
|
||||
ticketModel.ticketTimeout = curDate.ParseToUnixTime();
|
||||
var key = "SocialsLogin_" + Yitter.IdGenerator.YitIdHelper.NextId().ToString();
|
||||
_cacheManager.Set(key, ticketModel.ToJsonString(), TimeSpan.FromMinutes(5));
|
||||
var key = "SocialsLogin_" + SnowflakeIdHelper.NextId();
|
||||
_cacheManager.Set(key, ticketModel.ToJsonString(), TimeSpan.FromMinutes(_oauthOptions.TicketTimeout));
|
||||
return key;
|
||||
}
|
||||
|
||||
@@ -1158,4 +1258,264 @@ public class OAuthService : IDynamicApiController, ITransient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 单点登录.
|
||||
|
||||
/// <summary>
|
||||
/// 单点登录接口.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Login/{type}")]
|
||||
[AllowAnonymous]
|
||||
[IgnoreLog]
|
||||
[NonUnify]
|
||||
public async Task<dynamic> LoginByType(string type, [FromQuery] Dictionary<string, string> input)
|
||||
{
|
||||
#region Cas
|
||||
//if (type.ToLower().Equals("cas"))
|
||||
//{
|
||||
// var ticket = input.ContainsKey(CommonConst.PARAMS_JNPF_TICKET) ? input[CommonConst.PARAMS_JNPF_TICKET].ToString() : string.Empty;
|
||||
// var ticketModel = _cacheManager.Get<SocialsLoginTicketModel>(ticket);
|
||||
// if (ticketModel == null) return "登录票据已失效";
|
||||
|
||||
// var casTicket = input.ContainsKey(CommonConst.CAS_Ticket) ? input[CommonConst.CAS_Ticket].ToString() : string.Empty;
|
||||
// if (casTicket.IsNotEmptyOrNull())
|
||||
// {
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var loginUrl = _oauthOptions.SSO.Cas.ServerLoginUrl;
|
||||
// //http://sso.maxkey.top:8527/sign/authz/cas/?service=http://sa-oauth-client.demo.maxkey.top:8002
|
||||
|
||||
// loginUrl = Extras.CollectiveOAuth.Utils.UrlBuilder.fromBaseUrl(loginUrl)
|
||||
// .queryParam("service", _oauthOptions.LoginPath + "/cas")
|
||||
// .queryParam(CommonConst.PARAMS_JNPF_TICKET, ticket)
|
||||
// .build();
|
||||
// _httpContextAccessor.HttpContext.Response.Redirect(loginUrl);
|
||||
// }
|
||||
//}
|
||||
#endregion
|
||||
|
||||
if (type.ToLower().Equals("auth2"))
|
||||
{
|
||||
var ticket = string.Empty;
|
||||
if (input.ContainsKey(CommonConst.PARAMS_JNPF_TICKET) && input[CommonConst.PARAMS_JNPF_TICKET].IsNotEmptyOrNull())
|
||||
{
|
||||
ticket = input[CommonConst.PARAMS_JNPF_TICKET];
|
||||
var ticketModel = _cacheManager.Get<SocialsLoginTicketModel>(ticket);
|
||||
if (ticketModel == null) return "登录票据已失效";
|
||||
}
|
||||
|
||||
var code = input.ContainsKey(CommonConst.Code) ? input[CommonConst.Code] : string.Empty;
|
||||
|
||||
// 接受CODE 进行登录
|
||||
if (code.IsNotEmptyOrNull())
|
||||
{
|
||||
try
|
||||
{
|
||||
await loginByCode(code, ticket);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// 更新登录结果
|
||||
return e.Message;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
redirectLogin(ticket);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跳转单点登录页面.
|
||||
/// </summary>
|
||||
protected void redirectLogin(string ticket)
|
||||
{
|
||||
var loginUrl = _oauthOptions.SSO.Auth2.AuthorizeUrl;
|
||||
var tmpAuthCallbackUrl = _oauthOptions.LoginPath + "/auth2";
|
||||
//http://sso.maxkey.top:8527/sign/authz/oauth/v20/authorize?response_type=code&client_id=745057899234983936&redirect_uri=http://sa-oauth-client.demo.maxkey.top:8002/&scope=all
|
||||
|
||||
if (ticket.IsNotEmptyOrNull())
|
||||
{
|
||||
tmpAuthCallbackUrl = Extras.CollectiveOAuth.Utils.UrlBuilder.fromBaseUrl(tmpAuthCallbackUrl)
|
||||
.queryParam(CommonConst.PARAMS_JNPF_TICKET, ticket)
|
||||
.build();
|
||||
}
|
||||
|
||||
loginUrl = Extras.CollectiveOAuth.Utils.UrlBuilder.fromBaseUrl(loginUrl)
|
||||
.queryParam("response_type", CommonConst.Code)
|
||||
.queryParam("client_id", _oauthOptions.SSO.Auth2.ClientId)
|
||||
.queryParam("scope", "read")
|
||||
.queryParam("redirect_uri", tmpAuthCallbackUrl)
|
||||
.build();
|
||||
|
||||
_httpContextAccessor.HttpContext.Response.Redirect(loginUrl);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Oauth2登录.
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="ticket"></param>
|
||||
protected async Task loginByCode(string code, string ticket)
|
||||
{
|
||||
var token = await getAccessToken(code);
|
||||
var remoteUserInfo = await getRemoteInfo(token);
|
||||
//var userId = remoteUserInfo.getOrDefault("accounts.username", remoteUserInfo["username"]).ToString();
|
||||
var userId = remoteUserInfo.ContainsKey("accounts.username") ? remoteUserInfo["accounts.username"].ToString() : remoteUserInfo["username"].ToString();
|
||||
var userAccount = string.Empty;
|
||||
if (_tenant.MultiTenancy)
|
||||
{
|
||||
var instId = remoteUserInfo["institution"].ToString();
|
||||
userAccount = instId + "@" + userId;
|
||||
}
|
||||
else
|
||||
{
|
||||
userAccount = userId;
|
||||
}
|
||||
|
||||
// 登录账号
|
||||
var loginInput = await GetUserInfoByUserAccount(userAccount);
|
||||
loginInput.online_ticket = remoteUserInfo["online_ticket"].ToString();
|
||||
var loginRes = await Login(loginInput);
|
||||
|
||||
var jnpfTicket = _cacheManager.Get<SocialsLoginTicketModel>(ticket);
|
||||
if (jnpfTicket.IsNotEmptyOrNull())
|
||||
{
|
||||
// 修改 缓存 状态
|
||||
jnpfTicket.status = (int)SocialsLoginTicketStatus.Success;
|
||||
jnpfTicket.value = loginRes.token;
|
||||
_cacheManager.Set(ticket, jnpfTicket.ToJsonString(), TimeSpan.FromMinutes(_oauthOptions.TicketTimeout));
|
||||
}
|
||||
else
|
||||
{
|
||||
var url = string.Format("{0}?token={1}&theme={2}", _oauthOptions.SucessFrontUrl, loginRes.token, loginRes.theme);
|
||||
_httpContextAccessor.HttpContext.Response.Redirect(url);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取OAUTH2 AccessToken.
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<string> getAccessToken(string code)
|
||||
{
|
||||
var reqUrl = _oauthOptions.SSO.Auth2.AccessTokenUrl
|
||||
.AddUrlQuery(string.Format("grant_type={0}", "authorization_code"))
|
||||
.AddUrlQuery(string.Format("client_id={0}", _oauthOptions.SSO.Auth2.ClientId))
|
||||
.AddUrlQuery(string.Format("client_secret={0}", _oauthOptions.SSO.Auth2.ClientSecret))
|
||||
.AddUrlQuery(string.Format("redirect_uri={0}", _oauthOptions.LoginPath + "/auth2"))
|
||||
.AddUrlQuery(string.Format("code={0}", code));
|
||||
|
||||
var response = await reqUrl.GetAsStringAsync();
|
||||
Dictionary<string, object> result = null;
|
||||
try
|
||||
{
|
||||
result = response.ToObject<Dictionary<string, object>>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// log.error("解析Auth2 access_token失败", e);
|
||||
}
|
||||
|
||||
if (result == null || !result.ContainsKey("access_token"))
|
||||
{
|
||||
throw new Exception("Auth2: 获取access_token失败");
|
||||
}
|
||||
|
||||
var access_token = result["access_token"].ToString();
|
||||
|
||||
// log.debug("Auth2 Token: {}", access_token);
|
||||
return access_token;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户信息.
|
||||
/// </summary>
|
||||
/// <param name="access_token"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<Dictionary<string, object>> getRemoteInfo(string access_token)
|
||||
{
|
||||
var reqUrl = _oauthOptions.SSO.Auth2.UserInfoUrl
|
||||
.AddUrlQuery(string.Format("access_token={0}", access_token));
|
||||
var response = await reqUrl.GetAsStringAsync();
|
||||
|
||||
Dictionary<string, object> result = null;
|
||||
try
|
||||
{
|
||||
// log.debug("Auth2 User: {}", response);
|
||||
result = response.ToObject<Dictionary<string, object>>();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// log.error("解析Auth2 用户信息失败", e);
|
||||
}
|
||||
|
||||
if (result == null || !result.ContainsKey("username"))
|
||||
{
|
||||
// log.error(response);
|
||||
throw new Exception("Auth2: 获取远程用户信息失败");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private async Task<LoginInput> GetUserInfoByUserAccount(string account)
|
||||
{
|
||||
ConnectionConfigOptions options = JNPFTenantExtensions.GetLinkToOrdinary(_connectionStrings.ConfigId, _connectionStrings.DBName);
|
||||
UserAgent userAgent = new UserAgent(App.HttpContext);
|
||||
if (_tenant.MultiTenancy)
|
||||
{
|
||||
// 分割账号
|
||||
var tenantAccount = account.Split('@');
|
||||
var tenantId = tenantAccount.FirstOrDefault();
|
||||
if (tenantAccount.Length == 1)
|
||||
account = "admin";
|
||||
else
|
||||
account = tenantAccount[1];
|
||||
|
||||
var interFace = string.Format("{0}{1}", _tenant.MultiTenancyDBInterFace, tenantId);
|
||||
var response = await interFace.GetAsStringAsync();
|
||||
var result = response.ToObject<RESTfulResult<TenantInterFaceOutput>>();
|
||||
if (result.code != 200)
|
||||
{
|
||||
throw Oops.Oh(result.msg);
|
||||
}
|
||||
else if (result.data.dotnet == null && result.data.linkList == null)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1025);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.data.linkList == null || result.data.linkList?.Count == 0)
|
||||
{
|
||||
options = JNPFTenantExtensions.GetLinkToOrdinary(tenantId, result.data.dotnet);
|
||||
}
|
||||
else if (result.data.dotnet == null)
|
||||
{
|
||||
options = JNPFTenantExtensions.GetLinkToCustom(tenantId, result.data.linkList);
|
||||
}
|
||||
}
|
||||
|
||||
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
}
|
||||
|
||||
var userEntity = _sqlSugarClient.Queryable<UserEntity>().Single(u => u.Account == account && u.DeleteMark == null);
|
||||
return new LoginInput()
|
||||
{
|
||||
account = userEntity.Account,
|
||||
password = userEntity.Password,
|
||||
isSocialsLoginCallBack = true
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -11,6 +11,7 @@
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\common\Tnb.Common.Core\Tnb.Common.Core.csproj" />
|
||||
<ProjectReference Include="..\..\message\Tnb.Message.Interfaces\Tnb.Message.Interfaces.csproj" />
|
||||
<ProjectReference Include="..\Tnb.Systems.Interfaces\Tnb.Systems.Interfaces.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
using System.Text.Json.Serialization;
|
||||
using JNPF.DependencyInjection;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Dto.User;
|
||||
|
||||
/// <summary>
|
||||
/// 当前用户默认值信息输出.
|
||||
/// </summary>
|
||||
[SuppressSniffer]
|
||||
public class GetDefaultCurrentValueInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 部门Ids.
|
||||
/// </summary>
|
||||
public List<string> DepartIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户Ids.
|
||||
/// </summary>
|
||||
public List<string> UserIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色Ids.
|
||||
/// </summary>
|
||||
public List<string> RoleIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 岗位Ids.
|
||||
/// </summary>
|
||||
public List<string> PositionIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分组Ids.
|
||||
/// </summary>
|
||||
public List<string> GroupIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// .
|
||||
/// </summary>
|
||||
public string Keyword { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
namespace JNPF.Systems.Entitys.Dto.System.CommonWords
|
||||
{
|
||||
public class CommonWordsInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 自然主键.
|
||||
/// </summary>
|
||||
public string id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用id.
|
||||
/// </summary>
|
||||
public List<string> systemIds { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 应用名称.
|
||||
/// </summary>
|
||||
public List<string> systemNames { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// 常用语.
|
||||
/// </summary>
|
||||
public string commonWordsText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 常用语类型(0:系统,1:个人).
|
||||
/// </summary>
|
||||
public int commonWordsType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序.
|
||||
/// </summary>
|
||||
public long sortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效标志.
|
||||
/// </summary>
|
||||
public int? enabledMark { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace JNPF.Systems.Entitys.Dto.System.CommonWords;
|
||||
|
||||
public class CommonWordsOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 自然主键.
|
||||
/// </summary>
|
||||
public string id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用id.
|
||||
/// </summary>
|
||||
public string systemId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用名称.
|
||||
/// </summary>
|
||||
public string systemNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 常用语.
|
||||
/// </summary>
|
||||
public string commonWordsText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 常用语类型(0:系统,1:个人).
|
||||
/// </summary>
|
||||
public int commonWordsType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序.
|
||||
/// </summary>
|
||||
public long sortCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 有效标志.
|
||||
/// </summary>
|
||||
public int? enabledMark { get; set; }
|
||||
}
|
||||
@@ -62,4 +62,9 @@ public class PrintDevCrInput
|
||||
/// 打印模板.
|
||||
/// </summary>
|
||||
public string printTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纸张参数.
|
||||
/// </summary>
|
||||
public string pageParam { get; set; }
|
||||
}
|
||||
@@ -67,4 +67,9 @@ public class PrintDevInfoOutput
|
||||
/// 打印模板.
|
||||
/// </summary>
|
||||
public string printTemplate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 纸张参数.
|
||||
/// </summary>
|
||||
public string pageParam { get; set; }
|
||||
}
|
||||
@@ -17,4 +17,9 @@ public class PrintDevSqlDataQuery
|
||||
/// 参数.
|
||||
/// </summary>
|
||||
public string formId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 模板id.
|
||||
/// </summary>
|
||||
public List<string> ids { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
namespace JNPF.Systems.Entitys.Dto.System.PrintLog;
|
||||
|
||||
public class PrintLogOutuut
|
||||
{
|
||||
/// <summary>
|
||||
/// id.
|
||||
/// </summary>
|
||||
public string id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印人.
|
||||
/// </summary>
|
||||
public string printMan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印时间.
|
||||
/// </summary>
|
||||
public DateTime? printTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印条数.
|
||||
/// </summary>
|
||||
public int? printNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印功能名称.
|
||||
/// </summary>
|
||||
public string printTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印模板id.
|
||||
/// </summary>
|
||||
public string printId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using JNPF.Common.Filter;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Dto.System.PrintLog;
|
||||
|
||||
public class PrintLogQuery : PageInputBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 开始时间.
|
||||
/// </summary>
|
||||
public long? startTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 结束时间.
|
||||
/// </summary>
|
||||
public long? endTime { get; set; }
|
||||
}
|
||||
@@ -346,4 +346,71 @@ public class SysConfigOutput
|
||||
/// 链接点击几次后失效.
|
||||
/// </summary>
|
||||
public int unClickNum { get; set; }
|
||||
|
||||
#region 密码策略
|
||||
/// <summary>
|
||||
/// 密码定期更新开关.
|
||||
/// </summary>
|
||||
public int passwordIsUpdatedRegularly { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新周期.
|
||||
/// </summary>
|
||||
public int updateCycle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 提前N天提醒更新.
|
||||
/// </summary>
|
||||
public int updateInAdvance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码强度限制开关.
|
||||
/// </summary>
|
||||
public int passwordStrengthLimit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最小长度开关.
|
||||
/// </summary>
|
||||
public int passwordLengthMin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 密码最小长度限制.
|
||||
/// </summary>
|
||||
public int passwordLengthMinNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含数字.
|
||||
/// </summary>
|
||||
public int containsNumbers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含小写字母.
|
||||
/// </summary>
|
||||
public int includeLowercaseLetters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含大写字母.
|
||||
/// </summary>
|
||||
public int includeUppercaseLetters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否包含字符.
|
||||
/// </summary>
|
||||
public int containsCharacters { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否禁用旧密码开关.
|
||||
/// </summary>
|
||||
public int disableOldPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 禁用旧密码个数.
|
||||
/// </summary>
|
||||
public int disableTheNumberOfOldPasswords { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始密码强制修改开关.
|
||||
/// </summary>
|
||||
public int mandatoryModificationOfInitialPassword { get; set; }
|
||||
#endregion
|
||||
}
|
||||
11
system/Tnb.Systems.Entitys/Dto/System/System/SystemQuery.cs
Normal file
11
system/Tnb.Systems.Entitys/Dto/System/System/SystemQuery.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using JNPF.Common.Filter;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Dto.System.System;
|
||||
|
||||
public class SystemQuery : KeywordInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 开启 1 0 禁用.
|
||||
/// </summary>
|
||||
public string enableMark { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
using JNPF.Common.Contracts;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Entity.Permission;
|
||||
|
||||
/// <summary>
|
||||
/// 用户旧密码记录表.
|
||||
/// </summary>
|
||||
[SugarTable("BASE_USER_OLD_PASSWORD")]
|
||||
public class UserOldPasswordEntity : EntityBase<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户ID.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_USERID")]
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户ID.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_Account")]
|
||||
public string Account { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 账户.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_OldPassword")]
|
||||
public string OldPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 秘钥.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_Secretkey")]
|
||||
public string Secretkey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_CreatorTime")]
|
||||
public DateTime CreatorTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户ID.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_TenantId")]
|
||||
public string TenantId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using JNPF.Common.Contracts;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Entity.System;
|
||||
|
||||
/// <summary>
|
||||
/// 常用语
|
||||
/// 版 本:V3.2
|
||||
/// 版 权:引迈信息技术有限公司(https://www.jnpfsoft.com)
|
||||
/// 作 者:JNPF开发平台组
|
||||
/// 日 期:2021-06-01.
|
||||
/// </summary>
|
||||
[SugarTable("BASE_COMMONWORDS")]
|
||||
public class CommonWordsEntity : CLDEntityBase
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用id.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_SYSTEMIDS")]
|
||||
public string SystemIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 应用名称.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_SYSTEMNAMES")]
|
||||
public string SystemNames { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 常用语.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_COMMONWORDSTEXT")]
|
||||
public string CommonWordsText { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 常用语类型(0:系统,1:个人).
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_COMMONWORDSTYPE")]
|
||||
public int CommonWordsType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 排序.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_SORTCODE")]
|
||||
public long SortCode { get; set; }
|
||||
}
|
||||
@@ -73,4 +73,6 @@ public class PrintDevEntity : CLDEntityBase
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PRINTTEMPLATE")]
|
||||
public string PrintTemplate { get; set; }
|
||||
[SugarColumn(ColumnName = "F_PAGEPARAM")]
|
||||
public string PageParam { get; set; }
|
||||
}
|
||||
47
system/Tnb.Systems.Entitys/Entity/System/PrintLogEntity.cs
Normal file
47
system/Tnb.Systems.Entitys/Entity/System/PrintLogEntity.cs
Normal file
@@ -0,0 +1,47 @@
|
||||
using JNPF.Common.Const;
|
||||
using JNPF.Common.Contracts;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems.Entitys.Entity.System;
|
||||
|
||||
/// <summary>
|
||||
/// 打印模板日志
|
||||
/// 版 本:V3.2
|
||||
/// 版 权:引迈信息技术有限公司(https://www.jnpfsoft.com)
|
||||
/// 作 者:JNPF开发平台组
|
||||
/// 日 期:2021-06-01.
|
||||
/// </summary>
|
||||
[SugarTable("BASE_PRINT_LOG")]
|
||||
[Tenant(ClaimConst.TENANTID)]
|
||||
public class PrintLogEntity : EntityBase<string>
|
||||
{
|
||||
/// <summary>
|
||||
/// 打印人.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PrintMan")]
|
||||
public string PrintMan { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印时间.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PrintTime")]
|
||||
public DateTime? PrintTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印条数.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PrintNum")]
|
||||
public int? PrintNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印功能名称.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PrintTitle")]
|
||||
public string PrintTitle { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 打印模板id.
|
||||
/// </summary>
|
||||
[SugarColumn(ColumnName = "F_PrintId")]
|
||||
public string PrintId { get; set; }
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
namespace JNPF.Systems.Entitys.Model.Permission.User;
|
||||
|
||||
public class UserInfo
|
||||
{
|
||||
private static readonly long serialVersionUID = 6402443942083382236L;
|
||||
|
||||
public static readonly string CLASS_TYPE = "UserInfo";
|
||||
|
||||
public static readonly string DEFAULT_PASSWORD_SUFFIX = "MaxKey@888";
|
||||
|
||||
string sessionId { get; set; }
|
||||
|
||||
public string id { get; set; }
|
||||
public string username { get; set; }
|
||||
public string password { get; set; }
|
||||
public string decipherable { get; set; }
|
||||
public string sharedSecret { get; set; }
|
||||
public string sharedCounter { get; set; }
|
||||
/**
|
||||
* "Employee", "Supplier","Dealer","Contractor",Partner,Customer "Intern",
|
||||
* "Temp", "External", and "Unknown" .
|
||||
*/
|
||||
public string userType { get; set; }
|
||||
|
||||
public string userState { get; set; }
|
||||
|
||||
public string windowsAccount { get; set; }
|
||||
|
||||
// for user name
|
||||
public string displayName { get; set; }
|
||||
public string nickName { get; set; }
|
||||
public string nameZhSpell { get; set; }
|
||||
public string nameZhShortSpell { get; set; }
|
||||
public string givenName { get; set; }
|
||||
public string middleName { get; set; }
|
||||
public string familyName { get; set; }
|
||||
public string honorificPrefix { get; set; }
|
||||
public string honorificSuffix { get; set; }
|
||||
public string formattedName { get; set; }
|
||||
|
||||
public int married { get; set; }
|
||||
public int gender { get; set; }
|
||||
public string birthDate { get; set; }
|
||||
public byte[] picture { get; set; }
|
||||
public string pictureBase64 { get; set; }
|
||||
public string pictureId { get; set; }
|
||||
public int idType { get; set; }
|
||||
public string idCardNo { get; set; }
|
||||
public string webSite { get; set; }
|
||||
public string startWorkDate { get; set; }
|
||||
|
||||
// for security
|
||||
public int authnType { get; set; }
|
||||
public string email { get; set; }
|
||||
|
||||
public int emailVerified { get; set; }
|
||||
public string mobile { get; set; }
|
||||
|
||||
public int mobileVerified { get; set; }
|
||||
|
||||
public string passwordQuestion { get; set; }
|
||||
|
||||
public string passwordAnswer { get; set; }
|
||||
// for apps login public
|
||||
public int appLoginAuthnType { get; set; }
|
||||
public string appLoginPassword { get; set; }
|
||||
public string protectedApps { get; set; }
|
||||
public Dictionary<string, string> protectedAppsMap { get; set; }
|
||||
|
||||
public string passwordLastSetTime { get; set; }
|
||||
public int badPasswordCount { get; set; }
|
||||
public string badPasswordTime { get; set; }
|
||||
public string unLockTime { get; set; }
|
||||
public int isLocked { get; set; }
|
||||
public string lastLoginTime { get; set; }
|
||||
public string lastLoginIp { get; set; }
|
||||
public string lastLogoffTime { get; set; }
|
||||
public int passwordSetType { get; set; }
|
||||
public int loginCount { get; set; }
|
||||
public string regionHistory { get; set; }
|
||||
public string passwordHistory { get; set; }
|
||||
|
||||
public string locale { get; set; }
|
||||
public string timeZone { get; set; }
|
||||
public string preferredLanguage { get; set; }
|
||||
|
||||
// for work
|
||||
public string workCountry { get; set; }
|
||||
public string workRegion { get; set; }// province
|
||||
public string workLocality { get; set; }// city
|
||||
public string workStreetAddress { get; set; }
|
||||
public string workAddressFormatted { get; set; }
|
||||
public string workEmail { get; set; }
|
||||
public string workPhoneNumber { get; set; }
|
||||
public string workPostalCode { get; set; }
|
||||
public string workFax { get; set; }
|
||||
|
||||
public string workOfficeName { get; set; }
|
||||
// for home
|
||||
public string homeCountry { get; set; }
|
||||
public string homeRegion { get; set; }// province
|
||||
public string homeLocality { get; set; }// city
|
||||
public string homeStreetAddress { get; set; }
|
||||
public string homeAddressFormatted { get; set; }
|
||||
public string homeEmail { get; set; }
|
||||
public string homePhoneNumber { get; set; }
|
||||
public string homePostalCode { get; set; }
|
||||
public string homeFax { get; set; }
|
||||
// for company
|
||||
public string employeeNumber { get; set; }
|
||||
public string costCenter { get; set; }
|
||||
public string organization { get; set; }
|
||||
public string division { get; set; }
|
||||
public string departmentId { get; set; }
|
||||
public string department { get; set; }
|
||||
public string jobTitle { get; set; }
|
||||
public string jobLevel { get; set; }
|
||||
public string managerId { get; set; }
|
||||
public string manager { get; set; }
|
||||
public string assistantId { get; set; }
|
||||
public string assistant { get; set; }
|
||||
public string entryDate { get; set; }
|
||||
public string quitDate { get; set; }
|
||||
|
||||
// for social contact
|
||||
public string defineIm { get; set; }
|
||||
public int weixinFollow { get; set; }
|
||||
|
||||
public string theme { get; set; }
|
||||
/*
|
||||
* for extended Attribute from userType extraAttribute for database
|
||||
* extraAttributeName & extraAttributeValue for page submit
|
||||
*/
|
||||
public string extraAttribute { get; set; }
|
||||
public string extraAttributeName { get; set; }
|
||||
public string extraAttributeValue { get; set; }
|
||||
public Dictionary<string, string> extraAttributeMap { get; set; }
|
||||
|
||||
public int online { get; set; }
|
||||
|
||||
public string ldapDn { get; set; }
|
||||
|
||||
public int gridList { get; set; }
|
||||
|
||||
public string createdBy { get; set; }
|
||||
public string createdDate { get; set; }
|
||||
public string modifiedBy { get; set; }
|
||||
public string modifiedDate { get; set; }
|
||||
public int status { get; set; }
|
||||
string description { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 租户Id.
|
||||
/// </summary>
|
||||
public string instId { get; set; }
|
||||
|
||||
private string instName;
|
||||
|
||||
string syncId { get; set; }
|
||||
|
||||
string syncName { get; set; }
|
||||
|
||||
string originId { get; set; }
|
||||
|
||||
string originId2 { get; set; }
|
||||
|
||||
string gradingUserId { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return "UserInfo{" +
|
||||
"id='" + id + '\'' +
|
||||
", username='" + username + '\'' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
public class MqMessage
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string topic { get; set; }
|
||||
public string actionType { get; set; }
|
||||
public string sendTime { get; set; }
|
||||
public object content { get; set; }
|
||||
public UserInfo userInfo { get; set; }
|
||||
|
||||
public MqMessage()
|
||||
{
|
||||
}
|
||||
|
||||
public MqMessage(string id, string topic, string actionType, string sendTime, object content, UserInfo userInfo)
|
||||
{
|
||||
this.id = id;
|
||||
this.topic = topic;
|
||||
this.actionType = actionType;
|
||||
this.sendTime = sendTime;
|
||||
this.content = content;
|
||||
this.userInfo = userInfo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,4 +86,5 @@ public interface IUsersService
|
||||
/// <param name="select">select 选择字段表达式.</param>
|
||||
/// <returns></returns>
|
||||
Task<List<UserEntity>> GetUserListByExp(Expression<Func<UserEntity, bool>> expression, Expression<Func<UserEntity, UserEntity>> select);
|
||||
Task<bool> Receive(string message);
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.IO.Compression;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
using JNPF.Common.Captcha.General;
|
||||
@@ -80,7 +81,7 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Uploader/Preview")]
|
||||
public async Task<dynamic> Preview(string fileName)
|
||||
public async Task<dynamic> Preview(string fileName, string fileDownloadUrl)
|
||||
{
|
||||
string[]? typeList = new string[] { "doc", "docx", "xls", "xlsx", "ppt", "pptx", "pdf", "jpg", "jpeg", "gif", "png", "bmp" };
|
||||
string? type = fileName.Split('.').LastOrDefault();
|
||||
@@ -92,7 +93,7 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
switch (_appOptions.PreviewType)
|
||||
{
|
||||
case PreviewType.kkfile:
|
||||
previewUrl = KKFileUploaderPreview(fileName);
|
||||
previewUrl = KKFileUploaderPreview(fileName, fileDownloadUrl);
|
||||
break;
|
||||
case PreviewType.yozo:
|
||||
previewUrl = await YoZoUploaderPreview(fileName, 5, 1);
|
||||
@@ -154,10 +155,15 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
/// 下载.
|
||||
/// </summary>
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="type"></param>
|
||||
[HttpGet("down/{fileName}")]
|
||||
public async Task FileDown(string fileName)
|
||||
public async Task FileDown(string fileName, [FromQuery] string type)
|
||||
{
|
||||
string? systemFilePath = Path.Combine(FileVariable.SystemFilePath, fileName);
|
||||
if (type.IsNotEmptyOrNull())
|
||||
{
|
||||
systemFilePath = Path.Combine(_fileManager.GetPathByType(type), fileName);
|
||||
}
|
||||
var fileStreamResult = await _fileManager.DownloadFileByType(systemFilePath, fileName);
|
||||
byte[] bytes = new byte[fileStreamResult.FileStream.Length];
|
||||
|
||||
@@ -190,6 +196,39 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
return new { name = fileName, url = string.Format("/api/file/Download?encryption={0}", encryptStr) };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全部下载.
|
||||
/// </summary>
|
||||
/// <param name="type">图片类型.</param>
|
||||
/// <param name="fileName">文件名称.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("PackDownload/{type}")]
|
||||
public async Task<dynamic> DownloadAll(string type, [FromBody] List<FileControlsModel> input)
|
||||
{
|
||||
var fileName = RandomExtensions.NextLetterAndNumberString(new Random(), 7);
|
||||
//临时目录
|
||||
string directoryPath = Path.Combine(App.GetConfig<AppOptions>("JNPF_App", true).SystemPath, "TemporaryFile", fileName);
|
||||
Directory.CreateDirectory(directoryPath);
|
||||
foreach (var item in input)
|
||||
{
|
||||
string filePath = Path.Combine(GetPathByType(type), item.fileId.Replace("@", "."));
|
||||
await _fileManager.CopyFile(filePath, Path.Combine(directoryPath, item.fileName));
|
||||
}
|
||||
// 压缩文件
|
||||
string downloadPath = directoryPath + ".zip";
|
||||
|
||||
// 判断是否存在同名称文件
|
||||
if (File.Exists(downloadPath))
|
||||
File.Delete(downloadPath);
|
||||
|
||||
ZipFile.CreateFromDirectory(directoryPath, downloadPath);
|
||||
if (!App.Configuration["OSS:Provider"].Equals("Invalid"))
|
||||
await UploadFileByType(downloadPath, "SystemPath", string.Format("文件{0}.zip", fileName));
|
||||
var downloadFileName = string.Format("{0}|{1}.zip|TemporaryFile", _userManager.UserId, fileName);
|
||||
_cacheManager.Set(fileName + ".zip", string.Empty);
|
||||
return new { downloadName = string.Format("文件{0}.zip", fileName), downloadVo = new { name = fileName, url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(downloadFileName, "JNPF") } };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下载文件链接.
|
||||
/// </summary>
|
||||
@@ -268,16 +307,17 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
[HttpPost("Uploader/{type}")]
|
||||
[AllowAnonymous]
|
||||
[IgnoreLog]
|
||||
public async Task<dynamic> Uploader(string type, IFormFile file)
|
||||
public async Task<dynamic> Uploader(string type, [FromForm] ChunkModel input)
|
||||
{
|
||||
string? fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
|
||||
string? fileType = Path.GetExtension(input.file.FileName).Replace(".", string.Empty);
|
||||
if (!AllowFileType(fileType, type))
|
||||
throw Oops.Oh(ErrorCode.D1800);
|
||||
string filePath = GetPathByType(type);
|
||||
string fileName = string.Format("{0}{1}{2}", DateTime.Now.ToString("yyyyMMdd"), RandomExtensions.NextLetterAndNumberString(new Random(), 5), Path.GetExtension(file.FileName));
|
||||
var stream = file.OpenReadStream();
|
||||
await _fileManager.UploadFileByType(stream, filePath, fileName);
|
||||
return new { name = fileName, url = string.Format("/api/File/Image/{0}/{1}", type, fileName), fileSize = file.Length, fileExtension = fileType };
|
||||
string saveFileName = string.Format("{0}{1}{2}", DateTime.Now.ToString("yyyyMMdd"), RandomExtensions.NextLetterAndNumberString(new Random(), 5), Path.GetExtension(input.file.FileName));
|
||||
var stream = input.file.OpenReadStream();
|
||||
input.type = type;
|
||||
_fileManager.GetChunkModel(input, saveFileName);
|
||||
await _fileManager.UploadFileByType(stream, input.folder, saveFileName);
|
||||
return new FileControlsModel { name = input.fileName, url = string.Format("/api/File/Image/{0}/{1}", type, input.fileName), fileExtension = fileType, fileSize = input.file.Length, fileName = input.fileName };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -364,12 +404,18 @@ public class FileService : IFileService, IDynamicApiController, ITransient
|
||||
/// KKFile 文件预览.
|
||||
/// </summary>
|
||||
/// <param name="fileName">文件名称.</param>
|
||||
/// <param name="fileDownloadUrl">文件地址.</param>
|
||||
/// <returns></returns>
|
||||
public string KKFileUploaderPreview(string fileName)
|
||||
public string KKFileUploaderPreview(string fileName, string fileDownloadUrl)
|
||||
{
|
||||
var domain = App.Configuration["JNPF_APP:Domain"];
|
||||
var filePath = (domain + "/api/File/down/" + fileName).ToBase64String();
|
||||
|
||||
if (fileDownloadUrl.IsNotEmptyOrNull())
|
||||
{
|
||||
var list = fileDownloadUrl.Split('/');
|
||||
var type = list.Length > 4 ? list[4] : string.Empty;
|
||||
filePath = string.Format("{0}{1}{2}?type={3}", domain, "/api/File/down/", fileName, type).ToBase64String();
|
||||
}
|
||||
var kkFileDoMain = App.Configuration["JNPF_APP:KKFileDomain"];
|
||||
var kkurl = kkFileDoMain + "/onlinePreview?url=";
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JNPF.Common.Const;
|
||||
using Aop.Api.Domain;
|
||||
using JNPF.Common.Const;
|
||||
using JNPF.Common.Core.Handlers;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
@@ -453,7 +454,7 @@ public class AuthorizeService : IAuthorizeService, IDynamicApiController, ITrans
|
||||
_authorizeRepository.AsSugarClient().Ado.RollbackTran();
|
||||
}
|
||||
|
||||
if(input.objectId.Any()) await ForcedOffline(input.objectId); // 编辑角色权限退出角色的登录用户
|
||||
if (input.objectId.Any() && !input.itemType.Equals("portal")) await ForcedOffline(input.objectId); // 编辑角色权限退出角色的登录用户
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1083,7 +1084,7 @@ public class AuthorizeService : IAuthorizeService, IDynamicApiController, ITrans
|
||||
/// <returns></returns>
|
||||
private async Task<bool> DelUserInfo(string tenantId, string userId)
|
||||
{
|
||||
var cacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, tenantId, userId);
|
||||
var cacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, userId);
|
||||
return await _cacheManager.DelAsync(cacheKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -172,13 +172,16 @@ public class DepartmentService : IDepartmentService, IDynamicApiController, ITra
|
||||
var pItems = treeList.Select(x => x.organizeIds.FirstOrDefault()).Distinct().ToList();
|
||||
pItems.ForEach(item =>
|
||||
{
|
||||
var addItem = orgTree.Find(x => x.Id.Equals(item)).Adapt<DepartmentSelectorOutput>();
|
||||
if (addItem.type != null && addItem.type.Equals("company")) addItem.icon = "icon-ym icon-ym-tree-organization3";
|
||||
addItem.fullName = orgTree.FirstOrDefault(x => x.Id.Equals(addItem.id))?.Description;
|
||||
addItem.organize = addItem.fullName;
|
||||
addItem.organizeIds = addItem.organizeIdTree.Split(",").ToList();
|
||||
addItem.disabled = true;
|
||||
if (!treeList.Any(x => x.id.Equals(addItem.id))) treeList.Add(addItem);
|
||||
if (treeList.Select(x => x.id).Contains(item))
|
||||
{
|
||||
var addItem = orgTree.Find(x => x.Id.Equals(item)).Adapt<DepartmentSelectorOutput>();
|
||||
if (addItem.type != null && addItem.type.Equals("company")) addItem.icon = "icon-ym icon-ym-tree-organization3";
|
||||
addItem.fullName = orgTree.FirstOrDefault(x => x.Id.Equals(addItem.id))?.Description;
|
||||
addItem.organize = addItem.fullName;
|
||||
addItem.organizeIds = addItem.organizeIdTree.Split(",").ToList();
|
||||
addItem.disabled = true;
|
||||
if (!treeList.Any(x => x.id.Equals(addItem.id))) treeList.Add(addItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Contracts;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
@@ -86,10 +87,10 @@ public class OrganizeAdministratorService : IOrganizeAdministratorService, IDyna
|
||||
var userIdList = await _repository.AsSugarClient().Queryable<UserRelationEntity>().Where(x => x.ObjectType.Equals("Organize") && orgIds.Contains(x.ObjectId)).Select(x => x.UserId).ToListAsync();
|
||||
var organizeAdmin = await _repository.AsSugarClient().Queryable<OrganizeAdministratorEntity>().Where(x => !SqlFunc.ToString(x.UserId).Equals(_userManager.UserId))
|
||||
.WhereIF(!_userManager.IsAdministrator, x => orgIds.Contains(x.OrganizeId) && userIdList.Contains(x.UserId))
|
||||
.Select(x => x.UserId).ToListAsync();
|
||||
.Select(x => new { x.UserId, x.CreatorTime }).ToListAsync();
|
||||
|
||||
var data = await _repository.AsSugarClient().Queryable<UserEntity>()
|
||||
.Where(x => organizeAdmin.Contains(x.Id) && x.DeleteMark == null)
|
||||
.Where(x => organizeAdmin.Select(xx => xx.UserId).Contains(x.Id) && x.DeleteMark == null)
|
||||
.WhereIF(input.keyword.IsNotEmptyOrNull(), x => x.Account.Contains(input.keyword) || x.RealName.Contains(input.keyword))
|
||||
.Select(x => new OrganizeAdministratorListOutput()
|
||||
{
|
||||
@@ -109,6 +110,7 @@ public class OrganizeAdministratorService : IOrganizeAdministratorService, IDyna
|
||||
// 获取用户组织集合
|
||||
List<string>? roleOrgList = orgUserIdAll.Where(x => x.UserId == item.id).Select(x => x.ObjectId).ToList();
|
||||
item.organizeId = string.Join(" , ", orgTreeNameList.Where(x => roleOrgList.Contains(x.Id)).Select(x => x.Description));
|
||||
item.creatorTime = organizeAdmin.Find(x => x.UserId.Equals(item.id)).CreatorTime;
|
||||
}
|
||||
|
||||
return PageResult<OrganizeAdministratorListOutput>.SqlSugarPageResult(data);
|
||||
|
||||
@@ -11,6 +11,7 @@ using JNPF.JsonSerialization;
|
||||
using JNPF.LinqBuilder;
|
||||
using JNPF.Systems.Entitys.Dto.Organize;
|
||||
using JNPF.Systems.Entitys.Dto.SysConfig;
|
||||
using JNPF.Systems.Entitys.Dto.User;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using JNPF.Systems.Entitys.System;
|
||||
using JNPF.Systems.Interfaces.Permission;
|
||||
@@ -215,13 +216,16 @@ public class OrganizeService : IOrganizeService, IDynamicApiController, ITransie
|
||||
var pItems = treeList.Select(x => x.organizeIds.FirstOrDefault()).Distinct().ToList();
|
||||
pItems.ForEach(item =>
|
||||
{
|
||||
var addItem = orgTree.Find(x => x.Id.Equals(item)).Adapt<OrganizeSelectorOutput>();
|
||||
if (addItem.type != null && addItem.type.Equals("company")) addItem.icon = "icon-ym icon-ym-tree-organization3";
|
||||
addItem.fullName = orgTree.FirstOrDefault(x => x.Id.Equals(addItem.id))?.Description;
|
||||
addItem.organize = addItem.fullName;
|
||||
addItem.organizeIds = addItem.organizeIdTree.Split(",").ToList();
|
||||
addItem.disabled = true;
|
||||
if (!treeList.Any(x => x.id.Equals(addItem.id))) treeList.Add(addItem);
|
||||
if (treeList.Select(x => x.id).Contains(item))
|
||||
{
|
||||
var addItem = orgTree.Find(x => x.Id.Equals(item)).Adapt<OrganizeSelectorOutput>();
|
||||
if (addItem.type != null && addItem.type.Equals("company")) addItem.icon = "icon-ym icon-ym-tree-organization3";
|
||||
addItem.fullName = orgTree.FirstOrDefault(x => x.Id.Equals(addItem.id))?.Description;
|
||||
addItem.organize = addItem.fullName;
|
||||
addItem.organizeIds = addItem.organizeIdTree.Split(",").ToList();
|
||||
addItem.disabled = true;
|
||||
if (!treeList.Any(x => x.id.Equals(addItem.id))) treeList.Add(addItem);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -282,6 +286,23 @@ public class OrganizeService : IOrganizeService, IDynamicApiController, ITransie
|
||||
|
||||
#region POST
|
||||
|
||||
/// <summary>
|
||||
/// 根据组织Id List 获取当前所属组织(部门).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("getDefaultCurrentValueDepartmentId")]
|
||||
public async Task<dynamic> GetDefaultCurrentValueDepartmentId([FromBody] GetDefaultCurrentValueInput input)
|
||||
{
|
||||
var depId = _repository.AsSugarClient().Queryable<UserEntity>().Where(x => x.Id.Equals(_userManager.UserId)).Select(x => x.OrganizeId).First();
|
||||
|
||||
if (input.DepartIds == null || !input.DepartIds.Any()) return new { departmentId = depId };
|
||||
var userRelationList = _repository.AsSugarClient().Queryable<UserRelationEntity>().Where(x => input.DepartIds.Contains(x.ObjectId))
|
||||
.Select(x => x.UserId).ToList();
|
||||
|
||||
if (userRelationList.Contains(_userManager.UserId)) return new { userId = depId };
|
||||
else return new { departmentId = string.Empty };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过部门id获取部门列表.
|
||||
/// </summary>
|
||||
@@ -295,19 +316,19 @@ public class OrganizeService : IOrganizeService, IDynamicApiController, ITransie
|
||||
queryWhere = queryWhere.And(x => x.DeleteMark == null);
|
||||
List<OrganizeListOutput>? data = await _repository.AsQueryable().Where(queryWhere)
|
||||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword)).Select(a => new OrganizeListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
organizeIdTree = a.OrganizeIdTree,
|
||||
type = a.Category,
|
||||
parentId = a.ParentId,
|
||||
lastFullName = a.FullName,
|
||||
fullName = a.FullName,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
icon = a.Category.Equals("company") ? "icon-ym icon-ym-tree-organization3" : "icon-ym icon-ym-tree-department1",
|
||||
sortCode = a.SortCode,
|
||||
isLeaf = true
|
||||
}).ToListAsync();
|
||||
{
|
||||
id = a.Id,
|
||||
organizeIdTree = a.OrganizeIdTree,
|
||||
type = a.Category,
|
||||
parentId = a.ParentId,
|
||||
lastFullName = a.FullName,
|
||||
fullName = a.FullName,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
icon = a.Category.Equals("company") ? "icon-ym icon-ym-tree-organization3" : "icon-ym icon-ym-tree-department1",
|
||||
sortCode = a.SortCode,
|
||||
isLeaf = true
|
||||
}).ToListAsync();
|
||||
|
||||
// 获取所有组织
|
||||
List<OrganizeEntity>? allOrgList = GetOrgListTreeName();
|
||||
@@ -398,7 +419,7 @@ public class OrganizeService : IOrganizeService, IDynamicApiController, ITransie
|
||||
});
|
||||
});
|
||||
|
||||
if (adminlist.Any()) await _repository.AsSugarClient().Insertable(adminlist).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
|
||||
if(adminlist.Any()) await _repository.AsSugarClient().Insertable(adminlist).CallEntityMethod(m => m.Create()).ExecuteReturnEntityAsync();
|
||||
#endregion
|
||||
|
||||
#region 第三方同步
|
||||
|
||||
@@ -124,78 +124,29 @@ public class PositionService : IPositionService, IDynamicApiController, ITransie
|
||||
childOrgIds.AddRange(_repository.AsSugarClient().Queryable<OrganizeEntity>().ToChildList(x => x.ParentId, input.organizeId).Select(x => x.Id).ToList());
|
||||
childOrgIds = childOrgIds.Distinct().ToList();
|
||||
}
|
||||
var strChildOrgIds = string.Join(",", childOrgIds);
|
||||
var data = await _repository.AsSugarClient().Queryable<PositionEntity, OrganizeEntity, DictionaryDataEntity>(
|
||||
(a, b, c) => new JoinQueryInfos(JoinType.Left, b.Id == a.OrganizeId, JoinType.Left, a.Type == c.EnCode && c.DictionaryTypeId == "dae93f2fd7cd4df999d32f8750fa6a1e"))
|
||||
|
||||
SqlSugarPagedList<PositionListOutput>? data = new SqlSugarPagedList<PositionListOutput>();
|
||||
if (childOrgIds.Any())
|
||||
{
|
||||
// 拼接查询
|
||||
List<ISugarQueryable<PositionListOutput>>? listQuery = new List<ISugarQueryable<PositionListOutput>>();
|
||||
foreach (string item in childOrgIds)
|
||||
// 组织机构
|
||||
.WhereIF(childOrgIds.Any(), a => childOrgIds.Contains(a.OrganizeId))
|
||||
.WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.OrganizeId))
|
||||
|
||||
// 关键字(名称、编码)
|
||||
.WhereIF(!input.keyword.IsNullOrEmpty(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||||
.Where(a => a.DeleteMark == null).OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc).OrderBy(a => a.LastModifyTime, OrderByType.Desc)
|
||||
.Select((a, b, c) => new PositionListOutput
|
||||
{
|
||||
var quer = _repository.AsQueryable()
|
||||
|
||||
// 组织机构
|
||||
.Where(a => item.Equals(a.OrganizeId))
|
||||
.WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.OrganizeId))
|
||||
.WhereIF(!input.keyword.IsNullOrEmpty(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||||
.Select(a => new PositionListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
type = SqlFunc.Subqueryable<DictionaryDataEntity>().Where(d => d.EnCode.Equals(a.Type) && d.DictionaryTypeId == "dae93f2fd7cd4df999d32f8750fa6a1e").Select(d => d.FullName),
|
||||
department = SqlFunc.Subqueryable<OrganizeEntity>().Where(o => o.Id.Equals(a.OrganizeId)).Select(o => o.FullName),
|
||||
organizeId = SqlFunc.Subqueryable<OrganizeEntity>().Where(o => o.Id.Equals(a.OrganizeId)).Select(o => o.OrganizeIdTree),
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
description = a.Description,
|
||||
sortCode = a.SortCode
|
||||
});
|
||||
listQuery.Add(quer);
|
||||
}
|
||||
|
||||
data = await _repository.AsSugarClient().UnionAll(listQuery)
|
||||
.Select(a => new PositionListOutput
|
||||
{
|
||||
id = a.id,
|
||||
fullName = a.fullName,
|
||||
enCode = a.enCode,
|
||||
type = a.type,
|
||||
department = a.department,
|
||||
organizeId = a.organizeId,
|
||||
enabledMark = a.enabledMark,
|
||||
creatorTime = a.creatorTime,
|
||||
description = a.description,
|
||||
sortCode = a.sortCode
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = await _repository.AsSugarClient().Queryable<PositionEntity, OrganizeEntity, DictionaryDataEntity>(
|
||||
(a, b, c) => new JoinQueryInfos(JoinType.Left, b.Id == a.OrganizeId, JoinType.Left, a.Type == c.EnCode && c.DictionaryTypeId == "dae93f2fd7cd4df999d32f8750fa6a1e"))
|
||||
|
||||
// 组织机构
|
||||
.WhereIF(childOrgIds.Any(), a => childOrgIds.Contains(a.OrganizeId))
|
||||
.WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.OrganizeId))
|
||||
|
||||
// 关键字(名称、编码)
|
||||
.WhereIF(!input.keyword.IsNullOrEmpty(), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||||
.Where(a => a.DeleteMark == null).OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc).OrderBy(a => a.LastModifyTime, OrderByType.Desc)
|
||||
.Select((a, b, c) => new PositionListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
type = c.FullName,
|
||||
department = b.FullName,
|
||||
organizeId = b.OrganizeIdTree,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
description = a.Description,
|
||||
sortCode = a.SortCode
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
}
|
||||
id = a.Id,
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
type = c.FullName,
|
||||
department = b.FullName,
|
||||
organizeId = b.OrganizeIdTree,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
description = a.Description,
|
||||
sortCode = a.SortCode
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
|
||||
// 处理组织树 名称
|
||||
List<OrganizeEntity>? orgList = _organizeService.GetOrgListTreeName();
|
||||
|
||||
@@ -102,62 +102,42 @@ public class RoleService : IRoleService, IDynamicApiController, ITransient
|
||||
SqlSugarPagedList<RoleListOutput>? data = new SqlSugarPagedList<RoleListOutput>();
|
||||
if (childOrgIds.Any())
|
||||
{
|
||||
// 拼接查询
|
||||
List<ISugarQueryable<RoleListOutput>>? listQuery = new List<ISugarQueryable<RoleListOutput>>();
|
||||
foreach (string item in childOrgIds)
|
||||
{
|
||||
var quer = _repository.AsSugarClient().Queryable<OrganizeRelationEntity, RoleEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.ObjectId))
|
||||
.Where((a, b) => item == a.OrganizeId)
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => b.FullName.Contains(pageInput.keyword) || b.EnCode.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.ObjectId))
|
||||
.Where((a, b) => b.DeleteMark == null)
|
||||
data = await _repository.AsSugarClient().Queryable<RoleEntity, OrganizeRelationEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.ObjectId))
|
||||
.Where((a, b) => childOrgIds.Contains(b.OrganizeId)).Where((a, b) => a.DeleteMark == null)
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => a.FullName.Contains(pageInput.keyword) || a.EnCode.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator, (a, b) => dataScope.Contains(b.OrganizeId))
|
||||
.GroupBy((a, b) => new { a.Id, a.Type, a.GlobalMark, a.EnCode, a.FullName, a.EnabledMark, a.CreatorTime, a.SortCode })
|
||||
.Select((a, b) => new RoleListOutput
|
||||
{
|
||||
id = b.Id,
|
||||
parentId = b.Type,
|
||||
type = SqlFunc.IIF(b.GlobalMark == 1, "全局", "组织"),
|
||||
enCode = b.EnCode,
|
||||
fullName = b.FullName,
|
||||
enabledMark = b.EnabledMark,
|
||||
creatorTime = b.CreatorTime,
|
||||
sortCode = b.SortCode
|
||||
});
|
||||
listQuery.Add(quer);
|
||||
}
|
||||
var sql = _repository.AsSugarClient().UnionAll(listQuery).Where(a => !SqlFunc.IsNullOrEmpty(a.id)).ToSqlString();
|
||||
data = await _repository.AsSugarClient().UnionAll(listQuery).Where(a => !SqlFunc.IsNullOrEmpty(a.id))
|
||||
.GroupBy(a => new { a.id, a.parentId, a.type, a.creatorTime, a.enCode, a.fullName, a.sortCode, a.enabledMark })
|
||||
.Select(a => new RoleListOutput
|
||||
{
|
||||
id = a.id,
|
||||
parentId = a.parentId,
|
||||
type = a.type,
|
||||
creatorTime = a.creatorTime,
|
||||
enCode = a.enCode,
|
||||
fullName = a.fullName,
|
||||
sortCode = a.sortCode
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
id = a.Id,
|
||||
parentId = a.Type,
|
||||
type = SqlFunc.IIF(a.GlobalMark == 1, "全局", "组织"),
|
||||
enCode = a.EnCode,
|
||||
fullName = a.FullName,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
sortCode = a.SortCode
|
||||
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = await _repository.AsSugarClient().Queryable<RoleEntity>()
|
||||
.WhereIF(input.organizeId == "0", a => a.GlobalMark == 1)
|
||||
.WhereIF(!_userManager.IsAdministrator, a => a.GlobalMark == 0)
|
||||
.WhereIF(!_userManager.IsAdministrator, a => a.GlobalMark == 1)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
|
||||
.Where(a => a.DeleteMark == null)
|
||||
.Select((a) => new RoleListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
parentId = a.Type,
|
||||
type = SqlFunc.IIF(a.GlobalMark == 1, "全局", "组织"),
|
||||
enCode = a.EnCode,
|
||||
fullName = a.FullName,
|
||||
description = a.Description,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
sortCode = a.SortCode
|
||||
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
data = await _repository.AsSugarClient().Queryable<RoleEntity, OrganizeRelationEntity>((a, b) => new JoinQueryInfos(JoinType.Left, a.Id == b.ObjectId))
|
||||
.Where((a, b) => a.DeleteMark == null)
|
||||
.WhereIF(input.organizeId == "0", (a, b) => a.GlobalMark == 1)
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => a.FullName.Contains(pageInput.keyword) || a.EnCode.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator && input.organizeId != "0", (a, b) => dataScope.Contains(b.OrganizeId))
|
||||
.GroupBy((a, b) => new { a.Id, a.Type, a.GlobalMark, a.EnCode, a.FullName, a.EnabledMark, a.CreatorTime, a.SortCode })
|
||||
.Select((a, b) => new RoleListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
parentId = a.Type,
|
||||
type = SqlFunc.IIF(a.GlobalMark == 1, "全局", "组织"),
|
||||
enCode = a.EnCode,
|
||||
fullName = a.FullName,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorTime = a.CreatorTime,
|
||||
sortCode = a.SortCode
|
||||
}).MergeTable().OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
}
|
||||
|
||||
#region 处理 多组织
|
||||
@@ -169,11 +149,8 @@ public class RoleService : IRoleService, IDynamicApiController, ITransient
|
||||
// 获取组织集合
|
||||
var organizeList = orgUserIdAll.Where(x => x.ObjectId == item.id).Select(x => x.OrganizeId).ToList();
|
||||
item.organizeInfo = string.Join(" ; ", orgTreeNameList.Where(x => organizeList.Contains(x.Id)).Select(x => x.Description));
|
||||
item.sortCode = 999;
|
||||
if (organizeList.Contains(input.organizeId)) item.sortCode = 0;
|
||||
}
|
||||
|
||||
data.list = data.list.OrderBy(x => x.sortCode).ToList();
|
||||
#endregion
|
||||
|
||||
return PageResult<RoleListOutput>.SqlSugarPageResult(data);
|
||||
|
||||
@@ -354,7 +354,7 @@ public class SocialsUserService : ISocialsUserService, IDynamicApiController, IT
|
||||
return new WeChatOpenAuthRequest(clientConfig, authStateCache);
|
||||
|
||||
case DefaultAuthSourceEnum.WECHAT_ENTERPRISE:
|
||||
//return new WeChatEnterpriseAuthRequest(clientConfig, authStateCache);
|
||||
//return new WeChatEnterpriseAuthRequest(clientConfig, authStateCache);
|
||||
|
||||
case DefaultAuthSourceEnum.WECHAT_ENTERPRISE_SCAN:
|
||||
clientConfig.redirectUri = HttpUtility.UrlEncode(clientConfig.redirectUri);
|
||||
@@ -554,4 +554,5 @@ public class SocialsUserService : ISocialsUserService, IDynamicApiController, IT
|
||||
var socialName = resData.username.IsNullOrWhiteSpace() ? resData.nickname : resData.username;
|
||||
return await GetUserInfo(model.source, uuid, socialName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -17,6 +17,7 @@ using JNPF.Systems.Entitys.Model.UsersCurrent;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using JNPF.Systems.Entitys.System;
|
||||
using JNPF.Systems.Interfaces.Permission;
|
||||
using JNPF.Systems.Interfaces.System;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
@@ -50,11 +51,21 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
/// </summary>
|
||||
private readonly ICacheManager _cacheManager;
|
||||
|
||||
/// <summary>
|
||||
/// 系统配置.
|
||||
/// </summary>
|
||||
private readonly ISysConfigService _sysConfigService;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 操作权限服务.
|
||||
/// </summary>
|
||||
private readonly OnlineUserService _onlineUserService;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="UsersCurrentService"/>类型的新实例.
|
||||
/// </summary>
|
||||
@@ -63,12 +74,16 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
IAuthorizeService authorizeService,
|
||||
IOrganizeService organizeService,
|
||||
ICacheManager cacheManager,
|
||||
ISysConfigService sysConfigService,
|
||||
OnlineUserService onlineUserService,
|
||||
IUserManager userManager)
|
||||
{
|
||||
_repository = userRepository;
|
||||
_authorizeService = authorizeService;
|
||||
_organizeService = organizeService;
|
||||
_cacheManager = cacheManager;
|
||||
_sysConfigService = sysConfigService;
|
||||
_onlineUserService = onlineUserService;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
@@ -126,7 +141,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
position = string.Empty,
|
||||
positionId = a.PositionId,
|
||||
organizeId = a.OrganizeId,
|
||||
manager = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id.Equals(a.Id)).Select(x => SqlFunc.MergeString(x.RealName, "/", x.Account)),
|
||||
manager = SqlFunc.Subqueryable<UserEntity>().Where(x => x.Id.Equals(a.ManagerId)).Select(x => SqlFunc.MergeString(x.RealName, "/", x.Account)),
|
||||
roleId = string.Empty,
|
||||
roleIds = a.RoleId,
|
||||
creatorTime = a.CreatorTime,
|
||||
@@ -305,6 +320,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
if (MD5Encryption.Encrypt(input.oldPassword + user.Secretkey) != user.Password.ToLower())
|
||||
throw Oops.Oh(ErrorCode.D5007);
|
||||
string? imageCode = await GetCode(input.timestamp);
|
||||
await PwdStrategy(input);
|
||||
if (!input.code.ToLower().Equals(imageCode.ToLower()))
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D5015);
|
||||
@@ -312,15 +328,14 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
else
|
||||
{
|
||||
await DelCode(input.timestamp);
|
||||
await DelUserInfo(string.Format("{0}_{1}", _userManager.TenantId, user.Id));
|
||||
await DelUserInfo(_userManager.TenantId, user.Id);
|
||||
await _onlineUserService.ForcedOffline(user.Id);
|
||||
}
|
||||
|
||||
user.Password = MD5Encryption.Encrypt(input.password + user.Secretkey);
|
||||
user.ChangePasswordDate = DateTime.Now;
|
||||
user.LastModifyTime = DateTime.Now;
|
||||
user.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new {
|
||||
it.Password,
|
||||
it.ChangePasswordDate,
|
||||
it.LastModifyUserId,
|
||||
@@ -341,8 +356,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
userInfo.IsAdministrator = Convert.ToInt32(_userManager.IsAdministrator);
|
||||
userInfo.LastModifyTime = DateTime.Now;
|
||||
userInfo.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(userInfo).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(userInfo).UpdateColumns(it => new {
|
||||
it.RealName,
|
||||
it.Signature,
|
||||
it.Gender,
|
||||
@@ -376,8 +390,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
user.Theme = input.theme;
|
||||
user.LastModifyTime = DateTime.Now;
|
||||
user.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new {
|
||||
it.Theme,
|
||||
it.LastModifyUserId,
|
||||
it.LastModifyTime
|
||||
@@ -396,8 +409,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
user.Language = input.language;
|
||||
user.LastModifyTime = DateTime.Now;
|
||||
user.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new {
|
||||
it.Language,
|
||||
it.LastModifyUserId,
|
||||
it.LastModifyTime
|
||||
@@ -416,8 +428,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
user.HeadIcon = name;
|
||||
user.LastModifyTime = DateTime.Now;
|
||||
user.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(user).UpdateColumns(it => new {
|
||||
it.HeadIcon,
|
||||
it.LastModifyUserId,
|
||||
it.LastModifyTime
|
||||
@@ -468,8 +479,17 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
if (input.menuType.Equals(1))
|
||||
{
|
||||
// 系统下没有菜单不允许切换.
|
||||
if (!await _repository.AsSugarClient().Queryable<ModuleEntity>().AnyAsync(x => x.SystemId.Equals(input.majorId) && x.DeleteMark == null && x.Category.Equals("App")))
|
||||
throw Oops.Oh(ErrorCode.D4009);
|
||||
var mList = await _repository.AsSugarClient().Queryable<ModuleEntity>().Where(x => x.SystemId.Equals(input.majorId) && x.DeleteMark == null && x.Category.Equals("App")).Select(x => x.Id).ToListAsync();
|
||||
if (!mList.Any()) throw Oops.Oh(ErrorCode.D4009);
|
||||
|
||||
List<string>? roleList = await _userManager.GetUserOrgRoleIds(userInfo.RoleId, userInfo.OrganizeId);
|
||||
|
||||
// 非管理员 没有任何权限 切换失败
|
||||
if (!_userManager.IsAdministrator && !_repository.AsSugarClient().Queryable<AuthorizeEntity>()
|
||||
.Where(x => x.ObjectType == "Role" && x.ItemType == "module" && roleList.Contains(x.ObjectId))
|
||||
.Where(x => mList.Contains(x.ItemId)).Any())
|
||||
throw Oops.Oh(ErrorCode.D5023);
|
||||
|
||||
userInfo.SystemId = input.majorId;
|
||||
}
|
||||
else
|
||||
@@ -501,8 +521,7 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
|
||||
userInfo.LastModifyTime = DateTime.Now;
|
||||
userInfo.LastModifyUserId = _userManager.UserId;
|
||||
int isOk = await _repository.AsUpdateable(userInfo).UpdateColumns(it => new
|
||||
{
|
||||
int isOk = await _repository.AsUpdateable(userInfo).UpdateColumns(it => new {
|
||||
it.OrganizeId,
|
||||
it.PositionId,
|
||||
it.LastModifyUserId,
|
||||
@@ -709,14 +728,48 @@ public class UsersCurrentService : IUsersCurrentService, IDynamicApiController,
|
||||
/// <summary>
|
||||
/// 删除用户登录信息缓存.
|
||||
/// </summary>
|
||||
/// <param name="tenantId">租户ID.</param>
|
||||
/// <param name="userId">用户ID.</param>
|
||||
/// <returns></returns>
|
||||
private Task<bool> DelUserInfo(string userId)
|
||||
private Task<bool> DelUserInfo(string tenantId, string userId)
|
||||
{
|
||||
string? cacheKey = string.Format("{0}{1}", CommonConst.CACHEKEYUSER, userId);
|
||||
string? cacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, userId);
|
||||
_cacheManager.DelAsync(cacheKey);
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 密码策略验证.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task PwdStrategy(UsersCurrentActionsModifyPasswordInput input)
|
||||
{
|
||||
// 系统配置信息
|
||||
var sysInfo = await _sysConfigService.GetInfo();
|
||||
// 禁用旧密码
|
||||
if (sysInfo.disableOldPassword == 1 && sysInfo.disableTheNumberOfOldPasswords > 0)
|
||||
{
|
||||
var oldPwdList = _repository.AsSugarClient().Queryable<UserOldPasswordEntity>().Where(x => x.UserId == _userManager.UserId).OrderByDescending(o => o.CreatorTime).Take(sysInfo.disableTheNumberOfOldPasswords).ToList();
|
||||
if (oldPwdList.Any())
|
||||
{
|
||||
foreach (var item in oldPwdList)
|
||||
{
|
||||
if (MD5Encryption.Encrypt(input.password + item.Secretkey) == item.OldPassword.ToLower())
|
||||
throw Oops.Oh(ErrorCode.D5026);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 保存旧密码数据
|
||||
var oldPwdEntity = new UserOldPasswordEntity();
|
||||
oldPwdEntity.Id = SnowflakeIdHelper.NextId();
|
||||
oldPwdEntity.UserId = _userManager.UserId;
|
||||
oldPwdEntity.Account = _userManager.Account;
|
||||
oldPwdEntity.OldPassword = MD5Encryption.Encrypt(input.password + _userManager.User.Secretkey);
|
||||
oldPwdEntity.Secretkey = _userManager.User.Secretkey;
|
||||
oldPwdEntity.CreatorTime = DateTime.Now;
|
||||
oldPwdEntity.TenantId = _userManager.TenantId;
|
||||
_repository.AsSugarClient().Insertable(oldPwdEntity).ExecuteCommand();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
using JNPF.Common.Configuration;
|
||||
using Aop.Api.Domain;
|
||||
using JNPF.Common.Configuration;
|
||||
using JNPF.Common.Const;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Core.Manager.Files;
|
||||
using JNPF.Common.Dtos.OAuth;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
@@ -9,27 +11,42 @@ using JNPF.Common.Helper;
|
||||
using JNPF.Common.Manager;
|
||||
using JNPF.Common.Models.NPOI;
|
||||
using JNPF.Common.Models.User;
|
||||
using JNPF.Common.Options;
|
||||
using JNPF.Common.Security;
|
||||
using JNPF.DatabaseAccessor;
|
||||
using JNPF.DataEncryption;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.RemoteRequest.Extensions;
|
||||
using JNPF.Systems.Entitys.Dto.Organize;
|
||||
using JNPF.Systems.Entitys.Dto.Role;
|
||||
using JNPF.Systems.Entitys.Dto.SysConfig;
|
||||
using JNPF.Systems.Entitys.Dto.User;
|
||||
using JNPF.Systems.Entitys.Dto.UserRelation;
|
||||
using JNPF.Systems.Entitys.Enum;
|
||||
using JNPF.Systems.Entitys.Model.Permission.User;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using JNPF.Systems.Entitys.System;
|
||||
using JNPF.Systems.Interfaces.Permission;
|
||||
using JNPF.Systems.Interfaces.System;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NPOI.SS.Formula.Eval;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Org.BouncyCastle.Ocsp;
|
||||
using Qiniu.Util;
|
||||
using Senparc.NeuChar.App.AppStore;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Linq.Expressions;
|
||||
using System.Security.Principal;
|
||||
using System.Text.Json.Nodes;
|
||||
|
||||
namespace JNPF.Systems;
|
||||
|
||||
@@ -40,6 +57,11 @@ namespace JNPF.Systems;
|
||||
[Route("api/permission/[controller]")]
|
||||
public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 配置文档.
|
||||
/// </summary>
|
||||
private readonly OauthOptions _oauthOptions = App.GetConfig<OauthOptions>("OAuth", true);
|
||||
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
@@ -80,6 +102,16 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// SqlSugarClient客户端.
|
||||
/// </summary>
|
||||
private SqlSugarScope _sqlSugarClient;
|
||||
|
||||
/// <summary>
|
||||
/// 多租户配置选项.
|
||||
/// </summary>
|
||||
private readonly TenantOptions _tenant;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="UsersService"/>类型的新实例.
|
||||
/// </summary>
|
||||
@@ -91,6 +123,8 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
ISynThirdInfoService synThirdInfoService,
|
||||
ICacheManager cacheManager,
|
||||
IFileManager fileService,
|
||||
ISqlSugarClient sqlSugarClient,
|
||||
IOptions<TenantOptions> tenantOptions,
|
||||
IUserManager userManager)
|
||||
{
|
||||
_repository = userRepository;
|
||||
@@ -101,6 +135,8 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
_cacheManager = cacheManager;
|
||||
_synThirdInfoService = synThirdInfoService;
|
||||
_fileManager = fileService;
|
||||
_tenant = tenantOptions.Value;
|
||||
_sqlSugarClient = (SqlSugarScope)sqlSugarClient;
|
||||
}
|
||||
|
||||
#region GET
|
||||
@@ -140,70 +176,26 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
ErrorStrategy configLockType = (ErrorStrategy)Enum.Parse(typeof(ErrorStrategy), config?.Value);
|
||||
|
||||
SqlSugarPagedList<UserListOutput>? data = new SqlSugarPagedList<UserListOutput>();
|
||||
if (childOrgIds.Any())
|
||||
{
|
||||
// 拼接查询
|
||||
List<ISugarQueryable<UserListOutput>>? listQuery = new List<ISugarQueryable<UserListOutput>>();
|
||||
foreach (string item in childOrgIds)
|
||||
{
|
||||
var quer = _repository.AsSugarClient().Queryable<UserRelationEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId))
|
||||
.Where((a, b) => item == a.ObjectId)
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => b.Account.Contains(pageInput.keyword) || b.RealName.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator, a => dataScope.Contains(a.ObjectId))
|
||||
.Where((a, b) => b.DeleteMark == null && !b.Id.Equals("admin"))
|
||||
.Select((a, b) => new UserListOutput
|
||||
{
|
||||
id = b.Id,
|
||||
account = b.Account,
|
||||
realName = b.RealName,
|
||||
headIcon = b.HeadIcon,
|
||||
creatorTime = b.CreatorTime,
|
||||
gender = b.Gender,
|
||||
mobilePhone = b.MobilePhone,
|
||||
sortCode = b.SortCode,
|
||||
unLockTime = b.UnLockTime,
|
||||
enabledMark = b.EnabledMark
|
||||
});
|
||||
listQuery.Add(quer);
|
||||
}
|
||||
|
||||
data = await _repository.AsSugarClient().UnionAll(listQuery)
|
||||
.GroupBy(a => new { a.id, a.account, a.realName, a.creatorTime, a.gender, a.mobilePhone, a.sortCode, a.enabledMark, a.unLockTime })
|
||||
.Select(a => new UserListOutput
|
||||
{
|
||||
id = a.id,
|
||||
account = a.account,
|
||||
realName = a.realName,
|
||||
creatorTime = a.creatorTime,
|
||||
gender = a.gender,
|
||||
mobilePhone = a.mobilePhone,
|
||||
sortCode = a.sortCode,
|
||||
enabledMark = SqlFunc.IIF(configLockType == ErrorStrategy.Delay && a.enabledMark == 2 && a.unLockTime < DateTime.Now, 1, a.enabledMark)
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
var userHeadIcon = await _repository.AsQueryable().Where(x => data.list.Select(xx => xx.id).Contains(x.Id)).Select(x => new { Id = x.Id, headIcon = x.HeadIcon }).ToListAsync();
|
||||
foreach (var item in data.list) item.headIcon = "/api/File/Image/userAvatar/" + userHeadIcon.Find(x => x.Id.Equals(item.id)).headIcon;
|
||||
}
|
||||
else
|
||||
{
|
||||
data = await _repository.AsSugarClient().Queryable<UserRelationEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId))
|
||||
.Where((a, b) => b.DeleteMark == null && !b.Id.Equals("admin"))
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => b.Account.Contains(pageInput.keyword) || b.RealName.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator, (a, b) => dataScope.Contains(a.ObjectId))
|
||||
.OrderBy((a, b) => b.SortCode).OrderBy((a, b) => b.CreatorTime, OrderByType.Desc).OrderBy((a, b) => b.LastModifyTime, OrderByType.Desc)
|
||||
.GroupBy((a, b) => new { b.Id, b.Account, b.RealName, b.CreatorTime, b.LastModifyTime, b.Gender, b.MobilePhone, b.SortCode, b.EnabledMark, b.UnLockTime })
|
||||
.Select((a, b) => new UserListOutput
|
||||
{
|
||||
id = b.Id,
|
||||
account = b.Account,
|
||||
realName = b.RealName,
|
||||
headIcon = SqlFunc.Subqueryable<UserEntity>().Where(e => e.Id == b.Id).Select(u => SqlFunc.MergeString("/api/File/Image/userAvatar/", u.HeadIcon)),
|
||||
creatorTime = b.CreatorTime,
|
||||
gender = b.Gender,
|
||||
mobilePhone = b.MobilePhone,
|
||||
sortCode = b.SortCode,
|
||||
enabledMark = SqlFunc.IIF(configLockType == ErrorStrategy.Delay && b.EnabledMark == 2 && b.UnLockTime < DateTime.Now, 1, b.EnabledMark)
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
}
|
||||
data = await _repository.AsSugarClient().Queryable<UserRelationEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId))
|
||||
.Where((a, b) => b.DeleteMark == null && !b.Account.Equals("admin"))
|
||||
.WhereIF(childOrgIds.Any(), (a, b) => childOrgIds.Contains(a.ObjectId))
|
||||
.WhereIF(!pageInput.keyword.IsNullOrEmpty(), (a, b) => b.Account.Contains(pageInput.keyword) || b.RealName.Contains(pageInput.keyword))
|
||||
.WhereIF(!_userManager.IsAdministrator, (a, b) => dataScope.Contains(a.ObjectId))
|
||||
.OrderBy((a, b) => b.SortCode).OrderBy((a, b) => b.CreatorTime, OrderByType.Desc).OrderBy((a, b) => b.LastModifyTime, OrderByType.Desc)
|
||||
.GroupBy((a, b) => new { b.Id, b.Account, b.RealName, b.CreatorTime, b.LastModifyTime, b.Gender, b.MobilePhone, b.SortCode, b.EnabledMark, b.UnLockTime })
|
||||
.Select((a, b) => new UserListOutput
|
||||
{
|
||||
id = b.Id,
|
||||
account = b.Account,
|
||||
realName = b.RealName,
|
||||
headIcon = SqlFunc.Subqueryable<UserEntity>().Where(e => e.Id == b.Id).Select(u => SqlFunc.MergeString("/api/File/Image/userAvatar/", u.HeadIcon)),
|
||||
creatorTime = b.CreatorTime,
|
||||
gender = b.Gender,
|
||||
mobilePhone = b.MobilePhone,
|
||||
sortCode = b.SortCode,
|
||||
enabledMark = SqlFunc.IIF(configLockType == ErrorStrategy.Delay && b.EnabledMark == 2 && b.UnLockTime < DateTime.Now, 1, b.EnabledMark)
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
|
||||
#region 处理 用户 多组织
|
||||
|
||||
@@ -214,11 +206,8 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
// 获取用户组织集合
|
||||
item.organizeList = orgUserIdAll.Where(x => x.UserId == item.id).Select(x => x.ObjectId).ToList();
|
||||
item.organize = string.Join(" ; ", orgTreeNameList.Where(x => item.organizeList.Contains(x.Id)).Select(x => x.Description));
|
||||
item.sortCode = 999;
|
||||
if (item.organizeList.Contains(input.organizeId)) item.sortCode = 0;
|
||||
}
|
||||
|
||||
data.list = data.list.OrderBy(x => x.sortCode).ToList();
|
||||
#endregion
|
||||
|
||||
return PageResult<UserListOutput>.SqlSugarPageResult(data);
|
||||
@@ -323,8 +312,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
.Where((a, b) => b.ObjectType == "Organize" && orgList.Contains(b.ObjectId)).Where((a, b) => a.EnabledMark == 1 && a.DeleteMark == null)
|
||||
.Where((a, b) => a.RealName.Contains(input.keyword) || a.Account.Contains(input.keyword))
|
||||
.GroupBy((a, b) => new { a.Id, a.RealName, a.Account, a.EnabledMark })
|
||||
.Select((a, b) => new
|
||||
{
|
||||
.Select((a, b) => new {
|
||||
id = a.Id,
|
||||
fullName = SqlFunc.MergeString(a.RealName, "/", a.Account),
|
||||
enabledMark = a.EnabledMark,
|
||||
@@ -369,8 +357,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
var res = await _repository.AsSugarClient().Queryable<UserEntity, UserRelationEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.UserId == a.Id))
|
||||
.Where((a, b) => b.ObjectType == "Organize" && b.ObjectId == input.organizeId).Where((a, b) => a.EnabledMark == 1 && a.DeleteMark == null)
|
||||
.GroupBy((a, b) => new { a.Id, a.RealName, a.Account, a.EnabledMark })
|
||||
.Select((a, b) => new
|
||||
{
|
||||
.Select((a, b) => new {
|
||||
id = a.Id,
|
||||
fullName = SqlFunc.MergeString(a.RealName, "/", a.Account),
|
||||
enabledMark = a.EnabledMark,
|
||||
@@ -527,6 +514,24 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
|
||||
#region POST
|
||||
|
||||
/// <summary>
|
||||
/// 根据用户Id List 获取当前用户Id.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("getDefaultCurrentValueUserId")]
|
||||
public async Task<dynamic> GetDefaultCurrentValueUserId([FromBody] GetDefaultCurrentValueInput input)
|
||||
{
|
||||
if ((input.UserIds == null || !input.UserIds.Any()) && (input.DepartIds == null || !input.DepartIds.Any()) && (input.PositionIds == null || !input.PositionIds.Any())
|
||||
&& (input.RoleIds == null || !input.RoleIds.Any()) && (input.GroupIds == null || !input.GroupIds.Any())) return new { userId = _userManager.UserId };
|
||||
|
||||
var userRelationList = _repository.AsSugarClient().Queryable<UserRelationEntity>().Select(x => new UserRelationEntity() { UserId = x.UserId, ObjectId = x.ObjectId }).ToList();
|
||||
var userIdList = userRelationList.Where(x => input.UserIds.Contains(x.UserId) || input.DepartIds.Contains(x.ObjectId)
|
||||
|| input.PositionIds.Contains(x.ObjectId) || input.RoleIds.Contains(x.ObjectId) || input.GroupIds.Contains(x.ObjectId)).Select(x => x.UserId).ToList();
|
||||
|
||||
if (userIdList.Contains(_userManager.UserId)) return new { userId = _userManager.UserId };
|
||||
else return new { userId = string.Empty };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取.
|
||||
/// </summary>
|
||||
@@ -534,16 +539,14 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
[HttpPost("GetUserList")]
|
||||
public async Task<dynamic> GetUserList([FromBody] UserRelationInput input)
|
||||
{
|
||||
var data = await _repository.AsSugarClient().Queryable<UserEntity, OrganizeEntity>((u, org) => new JoinQueryInfos(JoinType.Inner, u.OrganizeId == org.Id))
|
||||
.Where((u, org) => u.EnabledMark > 0 && u.DeleteMark == null)
|
||||
.Where((u, org) => input.userId.Contains(u.Id))
|
||||
.Select((u, org) => new OrganizeMemberListOutput()
|
||||
var data = await _repository.AsQueryable().Where(it => it.EnabledMark > 0 && it.DeleteMark == null)
|
||||
.Where(it => input.userId.Contains(it.Id))
|
||||
.Select(it => new OrganizeMemberListOutput()
|
||||
{
|
||||
id = u.Id,
|
||||
fullName = SqlFunc.MergeString(u.RealName, "/", u.Account),
|
||||
headIcon = SqlFunc.MergeString("/api/File/Image/userAvatar/", u.HeadIcon),
|
||||
enabledMark = u.EnabledMark,
|
||||
type = org.FullName,
|
||||
id = it.Id,
|
||||
fullName = SqlFunc.MergeString(it.RealName, "/", it.Account),
|
||||
headIcon = SqlFunc.MergeString("/api/File/Image/userAvatar/", it.HeadIcon),
|
||||
enabledMark = it.EnabledMark,
|
||||
}).ToListAsync();
|
||||
|
||||
data = data.OrderBy(x => input.userId.IndexOf(x.id)).ToList();
|
||||
@@ -561,6 +564,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
var oids = userList.Where(x => x.UserId.Equals(item.id)).Select(x => x.ObjectId).ToList();
|
||||
var oTree = orgList.Where(x => oids.Contains(x.Id)).Select(x => x.Description).ToList();
|
||||
item.organize = string.Join(",", oTree);
|
||||
//item.type = org.fullName;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -804,15 +808,12 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
if (input.roleIds != null) input.departIds.AddRange(input.roleIds);
|
||||
if (input.groupIds != null) input.departIds.AddRange(input.groupIds);
|
||||
if (!input.departIds.Any()) return PageResult<UserListOutput>.SqlSugarPageResult(data);
|
||||
data = await _repository.AsSugarClient().Queryable<UserRelationEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId))
|
||||
var ids = await _repository.AsSugarClient().Queryable<UserRelationEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.UserId))
|
||||
.Where((a, b) => b.DeleteMark == null)
|
||||
.WhereIF(input.departIds.Any() || input.userIds.Any(), (a, b) => input.departIds.Contains(a.ObjectId) || input.userIds.Contains(b.Id))
|
||||
.WhereIF(input.pagination.keyword.IsNotEmptyOrNull(), (a, b) => b.Account.Contains(input.pagination.keyword) || b.RealName.Contains(input.pagination.keyword))
|
||||
.Select((a, b) => new UserListOutput()
|
||||
{
|
||||
id = b.Id
|
||||
}).Distinct().ToPagedListAsync(input.pagination.currentPage, input.pagination.pageSize);
|
||||
data = await _repository.AsQueryable().Where(x => data.list.Select(xx => xx.id).Contains(x.Id)).Select(x => new UserListOutput()
|
||||
.Select((a, b) => b.Id).Distinct().ToListAsync();
|
||||
data = await _repository.AsQueryable().Where(x => ids.Contains(x.Id)).Select(x => new UserListOutput()
|
||||
{
|
||||
id = x.Id,
|
||||
organizeId = x.OrganizeId,
|
||||
@@ -821,8 +822,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
headIcon = SqlFunc.MergeString("/api/File/Image/userAvatar/", x.HeadIcon),
|
||||
gender = x.Gender,
|
||||
mobilePhone = x.MobilePhone
|
||||
}).ToPagedListAsync(1, input.pagination.pageSize);
|
||||
|
||||
}).ToPagedListAsync(input.pagination.currentPage, input.pagination.pageSize);
|
||||
if (data.list.Any())
|
||||
{
|
||||
var orgList = _organizeService.GetOrgListTreeName();
|
||||
@@ -1075,6 +1075,9 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// 单点登录同步
|
||||
await syncUserInfo(entity, "create", _userManager.TenantId);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
@@ -1130,6 +1133,9 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// 单点登录同步
|
||||
await syncUserInfo(entity, "delete", _userManager.TenantId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1142,6 +1148,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
public async Task Update(string id, [FromBody] UserUpInput input)
|
||||
{
|
||||
UserEntity? oldUserEntity = await _repository.GetFirstAsync(it => it.Id == id);
|
||||
input.roleId = input.roleId == null ? string.Empty : input.roleId;
|
||||
|
||||
// 超级管理员 只有 admin 账号才有变更权限
|
||||
if (_userManager.UserId != oldUserEntity.Id && oldUserEntity.IsAdministrator == 1 && _userManager.Account != "admin")
|
||||
@@ -1233,8 +1240,7 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
try
|
||||
{
|
||||
// 更新用户记录
|
||||
int newEntity = await _repository.AsUpdateable(entity).UpdateColumns(it => new
|
||||
{
|
||||
int newEntity = await _repository.AsUpdateable(entity).UpdateColumns(it => new {
|
||||
it.Account,
|
||||
it.RealName,
|
||||
it.QuickQuery,
|
||||
@@ -1315,6 +1321,9 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
// 单点登录同步
|
||||
await syncUserInfo(entity, "update", _userManager.TenantId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1372,7 +1381,9 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
|
||||
if (!(isOk > 0)) throw Oops.Oh(ErrorCode.D5005);
|
||||
|
||||
// 强制将用户提掉线
|
||||
// 单点登录同步
|
||||
entity.Password = input.userPassword;
|
||||
await syncUserInfo(entity, "modifyPassword", _userManager.TenantId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1794,6 +1805,8 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
|
||||
#endregion
|
||||
|
||||
#region PrivateMethod
|
||||
|
||||
/// <summary>
|
||||
/// 获取集合中的组织 树,根据上级ID.
|
||||
/// </summary>
|
||||
@@ -2256,5 +2269,244 @@ public class UsersService : IUsersService, IDynamicApiController, ITransient
|
||||
|
||||
return output;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 单点登录 数据同步
|
||||
|
||||
/// <summary>
|
||||
/// 同步数据导maxkey.
|
||||
/// </summary>
|
||||
/// <param name="userEntity"></param>
|
||||
/// <param name="method"></param>
|
||||
/// <param name="tenantId"></param>
|
||||
public async Task syncUserInfo(UserEntity userEntity, string method, string tenantId)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_oauthOptions.Enabled)
|
||||
{
|
||||
var userName = string.Format("{0}:{1}", _oauthOptions.Pull.UserName, _oauthOptions.Pull.Password).ToBase64String();
|
||||
|
||||
// http调用结果
|
||||
HttpResponse execute = null;
|
||||
var map = parse(userEntity);
|
||||
tenantId = tenantId != null && tenantId.Length > 0 ? tenantId : "1";
|
||||
if (tenantId.Equals("default")) tenantId = "1";
|
||||
map.Add("instId", tenantId);
|
||||
|
||||
// 得到userId
|
||||
// String username = userEntity.get("id") != null && userEntity.get("id").toString().length() > 0 ? userEntity.get("id").toString() : null;
|
||||
|
||||
Dictionary<string, object> jsonObject = null;
|
||||
var resString = string.Empty;
|
||||
var headers = new Dictionary<string, object>();
|
||||
headers.Add("Authorization", _oauthOptions.Pull.CredentialType + " " + userName);
|
||||
|
||||
if (method.Equals("create"))
|
||||
{
|
||||
resString = await (_oauthOptions.Pull.CreateRestAddress + "?appId=" + _oauthOptions.Pull.UserName).SetHeaders(headers).SetBody(map).PostAsStringAsync();
|
||||
}
|
||||
else if (method.Equals("update"))
|
||||
{
|
||||
resString = await (_oauthOptions.Pull.ReplaceRestAddress + "?appId=" + _oauthOptions.Pull.UserName).SetHeaders(headers).SetBody(map).PutAsStringAsync();
|
||||
}
|
||||
else if (method.Equals("delete"))
|
||||
{
|
||||
resString = await (_oauthOptions.Pull.DeleteRestAddress + "?appId=" + _oauthOptions.Pull.UserName).SetHeaders(headers).SetBody(map).DeleteAsStringAsync();
|
||||
}
|
||||
else if (method.Equals("modifyPassword"))
|
||||
{
|
||||
resString = await (_oauthOptions.Pull.ChangePasswordRestAddress + "?appId=" + _oauthOptions.Pull.UserName).SetHeaders(headers).SetBody(map).PostAsStringAsync();
|
||||
}
|
||||
|
||||
// else if (method.Equals("modifyPassword")) {
|
||||
// jsonObject = HttpUtil.httpRequest(_oauthOptions.Pull.getGetRestAddress() + username
|
||||
// , "GET"
|
||||
// , null, _oauthOptions.Pull.getCredentialType() + " " + _oauthOptions.Pull.getUserName() + "Og==" + _oauthOptions.Pull.getPassword()
|
||||
// , null);
|
||||
// }
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, object> parse(UserEntity userEntity)
|
||||
{
|
||||
var map = new Dictionary<string, object>();
|
||||
|
||||
// map.Add("id", userEntity.get("id"));
|
||||
map.Add("username", userEntity.Account);
|
||||
map.Add("password", userEntity.Password);
|
||||
map.Add("mobile", userEntity.MobilePhone);
|
||||
map.Add("email", userEntity.Email);
|
||||
map.Add("gender", (int)userEntity.Gender == 1 ? 2 : 1);
|
||||
map.Add("createdBy", userEntity.CreatorUserId);
|
||||
map.Add("createdDate", userEntity.CreatorTime);
|
||||
map.Add("modifiedBy", userEntity.LastModifyUserId);
|
||||
map.Add("modifiedDate", userEntity.LastModifyTime);
|
||||
map.Add("displayName", userEntity.RealName);
|
||||
|
||||
// map.Add("managerId", userEntity.get("managerId"));
|
||||
// map.Add("departmentId", userEntity.get("organizeId"));
|
||||
map.Add("loginCount", userEntity.LogSuccessCount);
|
||||
map.Add("badPasswordCount", userEntity.LogErrorCount);
|
||||
map.Add("lastLoginIp", userEntity.LastLogIP);
|
||||
map.Add("lastLoginTime", userEntity.LastLogTime);
|
||||
map.Add("status", userEntity.EnabledMark != null ? (userEntity.EnabledMark == 1 ? 1 : 4) : 4);
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据单点服务端消息 同步用户信息到数据库.
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
[NonAction]
|
||||
public async Task<bool> Receive(string message)
|
||||
{
|
||||
bool isSuccess;
|
||||
var map = new Dictionary<string, object>();
|
||||
try
|
||||
{
|
||||
var mqMessage = message.ToObject<MqMessage>();
|
||||
|
||||
// 转成用户实体类
|
||||
var userInfo = mqMessage.content.ToObject<UserInfo>();
|
||||
var userEntity = new UserEntity();
|
||||
userEntity.Id = userInfo.id;
|
||||
userEntity.Account = userInfo.username;
|
||||
userEntity.MobilePhone = userInfo.mobile;
|
||||
userEntity.Email = userInfo.email;
|
||||
userEntity.Gender = userInfo.gender;
|
||||
userEntity.CreatorTime = userInfo.createdDate.IsNullOrWhiteSpace() ? null : userInfo.createdDate?.ParseToLong().TimeStampToDateTime();
|
||||
userEntity.CreatorUserId = userInfo.createdBy;
|
||||
userEntity.LastModifyUserId = userInfo.modifiedBy;
|
||||
userEntity.LastModifyTime = userInfo.modifiedDate.IsNullOrWhiteSpace() ? null : userInfo.modifiedDate?.ParseToLong().TimeStampToDateTime();
|
||||
userEntity.RealName = userInfo.displayName;
|
||||
userEntity.LogSuccessCount = userInfo.loginCount;
|
||||
userEntity.LogErrorCount = userInfo.badPasswordCount;
|
||||
userEntity.LastLogIP = userInfo.lastLoginIp;
|
||||
userEntity.LastLogTime = userInfo.lastLoginTime.IsNullOrWhiteSpace() ? null : userInfo.lastLoginTime?.ParseToLong().TimeStampToDateTime();
|
||||
userEntity.EnabledMark = userInfo.status == 1 ? 1 : 0;
|
||||
userEntity.HeadIcon = "001.png";
|
||||
|
||||
if (_tenant.MultiTenancy)
|
||||
{
|
||||
ConnectionConfigOptions options = new ConnectionConfigOptions();
|
||||
var interFace = string.Format("{0}{1}", _tenant.MultiTenancyDBInterFace, userInfo.instId);
|
||||
var response = interFace.GetAsStringAsync().Result;
|
||||
var result = response.ToObject<UnifyResult.RESTfulResult<TenantInterFaceOutput>>();
|
||||
if (result.code != 200)
|
||||
{
|
||||
throw Oops.Oh(result.msg);
|
||||
}
|
||||
else if (result.data.dotnet == null && result.data.linkList == null)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.D1025);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (result.data.linkList == null || result.data.linkList?.Count == 0)
|
||||
{
|
||||
options = JNPFTenantExtensions.GetLinkToOrdinary(userInfo.instId, result.data.dotnet);
|
||||
}
|
||||
else if (result.data.dotnet == null)
|
||||
{
|
||||
options = JNPFTenantExtensions.GetLinkToCustom(userInfo.instId, result.data.linkList);
|
||||
}
|
||||
}
|
||||
if (!"default".Equals(userInfo.instId) && _tenant.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
_sqlSugarClient.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == userInfo.instId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sqlSugarClient.AddConnection(JNPFTenantExtensions.GetConfig(options));
|
||||
_sqlSugarClient.ChangeDatabase(userInfo.instId);
|
||||
}
|
||||
}
|
||||
|
||||
isSuccess = await process(userEntity, mqMessage.actionType, userInfo.instId);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// _logger.error("同步用户失败", e);
|
||||
isSuccess = false;
|
||||
}
|
||||
|
||||
if (!isSuccess)
|
||||
{
|
||||
// _logger.info("消息消费失败:" + message);
|
||||
}
|
||||
else
|
||||
{
|
||||
// _logger.debug("同步用户信息, {}", JSONObject.toJSONString(map));
|
||||
}
|
||||
|
||||
return isSuccess;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 保存到数据库处理逻辑.
|
||||
/// </summary>
|
||||
/// <param name="actionType"></param>
|
||||
/// <param name="instId"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<bool> process(UserEntity entity, string actionType, string instId)
|
||||
{
|
||||
if (actionType.Equals("CREATE_ACTION"))
|
||||
{
|
||||
if (_sqlSugarClient.Queryable<UserEntity>().Any(x => x.Account.Equals(entity.Account) && x.DeleteMark == null)) return true;
|
||||
entity.Secretkey = Guid.NewGuid().ToString();
|
||||
entity.Password = MD5Encryption.Encrypt(MD5Encryption.Encrypt(CommonConst.DEFAULTPASSWORD) + entity.Secretkey);
|
||||
|
||||
UserRelationEntity? entityRelation = new UserRelationEntity();
|
||||
entityRelation.Id = SnowflakeIdHelper.NextId();
|
||||
entityRelation.ObjectType = "Organize";
|
||||
entityRelation.ObjectId = _sqlSugarClient.Queryable<OrganizeEntity>().First(x => x.ParentId.Equals("-1")).Id;
|
||||
entityRelation.SortCode = 0;
|
||||
entityRelation.UserId = entity.Id;
|
||||
entityRelation.CreatorTime = DateTime.Now;
|
||||
entityRelation.CreatorUserId = entity.CreatorUserId;
|
||||
_sqlSugarClient.Insertable(entityRelation).ExecuteCommand(); // 批量新增用户关系
|
||||
|
||||
// 新增用户记录
|
||||
return await _sqlSugarClient.Insertable(entity).CallEntityMethod(m => m.Create()).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync() > 0;
|
||||
}
|
||||
else if (actionType.Equals("UPDATE_ACTION"))
|
||||
{
|
||||
var oldEntity = await _sqlSugarClient.Queryable<UserEntity>().FirstAsync(x => x.Account.Equals(entity.Account) && x.DeleteMark == null);
|
||||
entity.Id = oldEntity.Id;
|
||||
return await _sqlSugarClient.Updateable(entity).CallEntityMethod(m => m.LastModify()).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync() > 0;
|
||||
}
|
||||
else if (actionType.Equals("DELETE_ACTION"))
|
||||
{
|
||||
var oldEntity = await _sqlSugarClient.Queryable<UserEntity>().FirstAsync(x => x.Account.Equals(entity.Account) && x.DeleteMark == null);
|
||||
oldEntity.EnabledMark = 0;
|
||||
|
||||
// 同步删除用户 只能 该状态为 : 禁用
|
||||
return await _sqlSugarClient.Updateable(oldEntity).CallEntityMethod(m => m.LastModify()).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync() > 0;
|
||||
|
||||
}
|
||||
else if (actionType.Equals("PASSWORD_ACTION"))
|
||||
{
|
||||
return await _sqlSugarClient.Updateable<UserEntity>().SetColumns(it => new UserEntity()
|
||||
{
|
||||
Password = entity.Password,
|
||||
ChangePasswordDate = SqlFunc.GetDate(),
|
||||
LastModifyUserId = _userManager.UserId,
|
||||
LastModifyTime = SqlFunc.GetDate()
|
||||
}).Where(it => it.Id == entity.Id).ExecuteCommandAsync() > 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
//_logger.info("Other Action , will sikp it ...");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
184
system/Tnb.Systems/System/CommonWordsService.cs
Normal file
184
system/Tnb.Systems/System/CommonWordsService.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.Systems.Entitys.Dto.System.CommonWords;
|
||||
using JNPF.Systems.Entitys.Entity.System;
|
||||
using JNPF.Systems.Entitys.System;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems.System;
|
||||
|
||||
/// <summary>
|
||||
/// 常用语.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "System", Name = "CommonWords", Order = 200)]
|
||||
[Route("api/system/[controller]")]
|
||||
public class CommonWordsService : IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<CommonWordsEntity> _repository;
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="ModuleService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public CommonWordsService(
|
||||
ISqlSugarRepository<CommonWordsEntity> repository,
|
||||
IUserManager userManager)
|
||||
{
|
||||
_repository = repository;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 列表.
|
||||
/// </summary>
|
||||
/// <param name="input">参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("")]
|
||||
public async Task<dynamic> GetList([FromQuery] PageInputBase input)
|
||||
{
|
||||
var list = await _repository.AsSugarClient().Queryable<CommonWordsEntity>()
|
||||
.Where(a => a.CommonWordsType == 0 && a.DeleteMark == null)
|
||||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => SqlFunc.ToString(a.SystemNames).Contains(input.keyword) || SqlFunc.ToString(a.CommonWordsText).Contains(input.keyword))
|
||||
.OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||||
.Select(a => new CommonWordsOutput()
|
||||
{
|
||||
id = a.Id,
|
||||
systemNames = SqlFunc.ToString(a.SystemNames),
|
||||
commonWordsText = SqlFunc.ToString(a.CommonWordsText),
|
||||
sortCode = a.SortCode,
|
||||
enabledMark = a.EnabledMark,
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<CommonWordsOutput>.SqlSugarPageResult(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取信息.
|
||||
/// </summary>
|
||||
/// <param name="id">主键id.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
var data = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var output = new CommonWordsInput();
|
||||
if (data.IsNotEmptyOrNull())
|
||||
{
|
||||
output.id = data.Id;
|
||||
output.commonWordsText = data.CommonWordsText;
|
||||
output.sortCode = data.SortCode;
|
||||
output.enabledMark = data.EnabledMark;
|
||||
output.commonWordsType = data.CommonWordsType;
|
||||
foreach (var item in data.SystemIds.Split(","))
|
||||
{
|
||||
var systemEntity = await _repository.AsSugarClient().Queryable<SystemEntity>().FirstAsync(x => x.Id == item && x.EnabledMark == 1 && x.DeleteMark == null);
|
||||
if (systemEntity.IsNotEmptyOrNull())
|
||||
{
|
||||
output.systemIds.Add(systemEntity.Id);
|
||||
output.systemNames.Add(systemEntity.FullName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 下拉列表.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("Selector")]
|
||||
public async Task<dynamic> GetSelector()
|
||||
{
|
||||
var list = await _repository.AsSugarClient().Queryable<CommonWordsEntity>()
|
||||
.Where(a => (a.CommonWordsType == 0 || a.CreatorUserId == _userManager.UserId) && a.SystemIds.Contains(_userManager.User.SystemId) && a.EnabledMark == 1 && a.DeleteMark == null)
|
||||
.OrderBy(a => a.CommonWordsType, OrderByType.Desc).OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||||
.Select(a => new CommonWordsOutput()
|
||||
{
|
||||
id = a.Id,
|
||||
systemNames = SqlFunc.ToString(a.SystemNames),
|
||||
commonWordsText = SqlFunc.ToString(a.CommonWordsText),
|
||||
sortCode = a.SortCode,
|
||||
enabledMark = a.EnabledMark,
|
||||
commonWordsType = a.CommonWordsType,
|
||||
}).ToListAsync();
|
||||
return new { list = list };
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新建.
|
||||
/// </summary>
|
||||
/// <param name="input">实体对象.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("")]
|
||||
public async Task Create([FromBody] CommonWordsInput input)
|
||||
{
|
||||
var entity = input.Adapt<CommonWordsEntity>();
|
||||
if (input.systemIds.Any())
|
||||
{
|
||||
entity.SystemIds = string.Join(",", input.systemIds);
|
||||
entity.SystemNames = string.Join(",", input.systemNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.SystemIds = _userManager.User.SystemId;
|
||||
entity.SystemNames = _repository.AsSugarClient().Queryable<SystemEntity>().First(x => x.Id == _userManager.User.SystemId && x.DeleteMark == null).FullName;
|
||||
}
|
||||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
if (isOk < 1)
|
||||
throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <param name="id">主键值.</param>
|
||||
/// <param name="input">实体对象.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
public async Task Update(string id, [FromBody] CommonWordsInput input)
|
||||
{
|
||||
var entity = input.Adapt<CommonWordsEntity>();
|
||||
if (input.systemIds.Any())
|
||||
{
|
||||
entity.SystemIds = string.Join(",", input.systemIds);
|
||||
entity.SystemNames = string.Join(",", input.systemNames);
|
||||
}
|
||||
else
|
||||
{
|
||||
entity.SystemIds = _userManager.User.SystemId;
|
||||
entity.SystemNames = _repository.AsSugarClient().Queryable<SystemEntity>().First(x => x.Id == _userManager.User.SystemId && x.DeleteMark == null).FullName;
|
||||
}
|
||||
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <param name="id">主键.</param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task Delete(string id)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,11 +1,7 @@
|
||||
using System.ArrayExtensions;
|
||||
using System.Collections;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using JNPF.Common.Configuration;
|
||||
using JNPF.Common.Contracts;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Core.Manager.Files;
|
||||
using JNPF.Common.Dtos.DataBase;
|
||||
@@ -26,8 +22,6 @@ using Mapster;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using Org.BouncyCastle.Asn1.Cms;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems;
|
||||
@@ -101,30 +95,41 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
/// <param name="input">过滤条件.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}/Tables")]
|
||||
public async Task<dynamic> GetList(string id, [FromQuery] KeywordInput input)
|
||||
public async Task<dynamic> GetList(string id, [FromQuery] PageInputBase input)
|
||||
{
|
||||
var link = await _dbLinkService.GetInfo(id);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var tables = _dataBaseManager.GetDBTableList(tenantLink);
|
||||
//tables = tables.Where((x, i) => tables.FindIndex(z => z.Name == x.Name) == i).ToList();
|
||||
//var output = tables.Adapt<List<DatabaseTableListOutput>>();
|
||||
if (!string.IsNullOrEmpty(input.keyword))
|
||||
try
|
||||
{
|
||||
var keyword = input.keyword.ToLower();
|
||||
tables = tables.FindAll(d => d.table.ToLower().Contains(keyword) || (d.tableName.IsNotEmptyOrNull() && d.tableName.ToLower().Contains(keyword)));
|
||||
var link = await _dbLinkService.GetInfo(id);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var tables = _dataBaseManager.GetTableInfos(tenantLink);
|
||||
tables = tables.Where((x, i) => tables.FindIndex(z => z.Name == x.Name) == i).ToList();//去重
|
||||
var output = tables.Adapt<List<DatabaseTableListOutput>>();
|
||||
if (!string.IsNullOrEmpty(input.keyword))
|
||||
output = output.FindAll(d => d.table.ToLower().Contains(input.keyword.ToLower()) || (d.tableName.IsNotEmptyOrNull() && d.tableName.ToLower().Contains(input.keyword.ToLower())));
|
||||
return PageResult<DatabaseTableListOutput>.SqlSugarPageResult(new SqlSugarPagedList<DatabaseTableListOutput>()
|
||||
{
|
||||
list = output.OrderBy(x => x.table).Skip((input.currentPage - 1) * input.pageSize).Take(input.pageSize).OrderBy(x => x.table).ToList(),
|
||||
pagination = new Pagination()
|
||||
{
|
||||
CurrentPage = input.currentPage,
|
||||
PageSize = input.pageSize,
|
||||
Total = output.Count
|
||||
}
|
||||
});
|
||||
}
|
||||
if (tenantLink.DbType.ToLower().Equals("dm"))
|
||||
catch (Exception ex)
|
||||
{
|
||||
GetTableCount(tables, tenantLink);
|
||||
return PageResult<DatabaseTableListOutput>.SqlSugarPageResult(new SqlSugarPagedList<DatabaseTableListOutput>()
|
||||
{
|
||||
list = new List<DatabaseTableListOutput>(),
|
||||
pagination = new Pagination()
|
||||
{
|
||||
CurrentPage = input.currentPage,
|
||||
PageSize = input.pageSize,
|
||||
Total = 0
|
||||
}
|
||||
});
|
||||
}
|
||||
return new { list = tables.OrderBy(x => x.table).ToList() };
|
||||
//try
|
||||
//{
|
||||
//}
|
||||
//catch (Exception ex)
|
||||
//{
|
||||
// return new { list = new List<DatabaseTableListOutput>() };
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -186,8 +191,7 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
if (string.IsNullOrEmpty(tableName)) return new PageResult();
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var output = _dataBaseManager.GetDataBaseTableInfo(tenantLink, tableName);
|
||||
var data = _dataBaseManager.GetData(tenantLink, tableName);
|
||||
output.hasTableData = data.Rows.Count > 0;
|
||||
output.hasTableData = _dataBaseManager.IsAnyData(tenantLink, tableName);
|
||||
return output;
|
||||
}
|
||||
|
||||
@@ -262,6 +266,8 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
if (_dataBaseManager.IsAnyTable(tenantLink, input.tableInfo.newTable))
|
||||
throw Oops.Oh(ErrorCode.D1503);
|
||||
if (input.tableInfo.newTable.Length >= 30) throw Oops.Oh(ErrorCode.D1514);
|
||||
if (input.tableFieldList.Any(x => x.field.Length >= 30)) throw Oops.Oh(ErrorCode.D1515);
|
||||
var tableInfo = input.tableInfo.Adapt<DbTableModel>();
|
||||
tableInfo.table = input.tableInfo.newTable;
|
||||
var tableFieldList = input.tableFieldList.Adapt<List<DbTableFieldModel>>();
|
||||
@@ -280,10 +286,12 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
public async Task Update(string linkId, [FromBody] DatabaseTableUpInput input)
|
||||
{
|
||||
var link = await _dbLinkService.GetInfo(linkId);
|
||||
if (input.tableInfo.newTable.Length >= 30) throw Oops.Oh(ErrorCode.D1514);
|
||||
if (input.tableFieldList.Any(x => x.field.Length >= 30)) throw Oops.Oh(ErrorCode.D1515);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var oldFieldList = _dataBaseManager.GetFieldList(tenantLink, input.tableInfo.table).Adapt<List<TableFieldOutput>>();
|
||||
oldFieldList = _dataBaseManager.ViewDataTypeConversion(oldFieldList, _dataBaseManager.ToDbType(tenantLink.DbType));
|
||||
var oldTableInfo = _dataBaseManager.GetDBTableList(tenantLink).Find(m => m.table == input.tableInfo.table).Adapt<DbTableModel>();
|
||||
var oldTableInfo = _dataBaseManager.GetTableInfos(tenantLink).Find(m => m.Name == input.tableInfo.table).Adapt<DbTableModel>();
|
||||
var data = _dataBaseManager.GetData(tenantLink, input.tableInfo.table);
|
||||
if (data.Rows.Count > 0)
|
||||
throw Oops.Oh(ErrorCode.D1508);
|
||||
@@ -313,6 +321,7 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
{
|
||||
try
|
||||
{
|
||||
if (input.tableFieldList.Any(x => x.field.Length >= 30)) throw Oops.Oh(ErrorCode.D1515);
|
||||
var link = await _dbLinkService.GetInfo(linkId);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
_dataBaseManager.AddTableColumn(tenantLink, input.tableInfo.table, input.tableFieldList.Adapt<List<DbTableFieldModel>>());
|
||||
@@ -631,7 +640,7 @@ public class DataBaseService : IDynamicApiController, ITransient
|
||||
{"tool_", "Tnb.EquipMgr.Entities" },
|
||||
{"qc_", "Tnb.QcMgr.Entities" },
|
||||
};
|
||||
var allTables = sugar.DbMaintenance.GetTableInfoList().WhereIF(!string.IsNullOrEmpty(tbName), t=>t.Name == tbName);
|
||||
var allTables = sugar.DbMaintenance.GetTableInfoList().WhereIF(!string.IsNullOrEmpty(tbName), t => t.Name == tbName);
|
||||
foreach (var tbl in allTables)
|
||||
{
|
||||
var prefix = tbl.Name.Split('_')[0] + "_";
|
||||
|
||||
@@ -21,6 +21,7 @@ using JNPF.Common.Security;
|
||||
using JNPF.DatabaseAccessor;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.Extras.DatabaseAccessor.SqlSugar.Models;
|
||||
using JNPF.Extras.Thirdparty.JSEngine;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.LinqBuilder;
|
||||
@@ -506,19 +507,65 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
ConnectionString = string.Format($"{App.Configuration["ConnectionStrings:DefaultConnection"]}", result.data.dotnet)
|
||||
});
|
||||
}
|
||||
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
if (!"default".Equals(tenantId) && KeyVariable.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
_sqlSugarClient.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == tenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
}
|
||||
}
|
||||
var interfaceOauthEntity = await _sqlSugarClient.Queryable<InterfaceOauthEntity>().FirstAsync(x => x.AppId == appId && x.DeleteMark == null && x.EnabledMark == 1);
|
||||
if (interfaceOauthEntity == null) return null;
|
||||
var ymDate = DateTime.Now.ParseToUnixTime().ToString();
|
||||
var authorization = GetVerifySignature(interfaceOauthEntity, intefaceId, ymDate);
|
||||
return new
|
||||
{
|
||||
return new {
|
||||
YmDate = ymDate,
|
||||
Authorization = authorization,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 复制.
|
||||
/// </summary>
|
||||
/// <param name="id">主键值.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id}/Actions/Copy")]
|
||||
public async Task ActionsCopy(string id)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var random = RandomExtensions.NextLetterAndNumberString(new Random(), 5).ToLower();
|
||||
entity.FullName = string.Format("{0}.副本{1}", entity.FullName, random);
|
||||
entity.EnCode = string.Format("{0}{1}", entity.EnCode, random);
|
||||
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
|
||||
throw Oops.Oh(ErrorCode.COM1009);
|
||||
entity.EnabledMark = 0;
|
||||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
if (isOk < 1)
|
||||
throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 预览接口字段.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("{id}/Actions/GetFields")]
|
||||
[UnitOfWork]
|
||||
public async Task<dynamic> GetFields(string id, [FromBody] DataInterfacePreviewInput input)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (await Preview(id, input)).ToObject<List<Dictionary<string, object>>>().FirstOrDefault().Keys.ToList();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.COM1020);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region PublicMethod
|
||||
@@ -549,7 +596,7 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
/// 根据不同类型请求接口.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="type">0 : 分页 1 :详情 ,其他 原始.</param>
|
||||
/// <param name="type">0 : 分页 1 :详情 2:数据视图 ,其他 原始.</param>
|
||||
/// <param name="tenantId"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
@@ -579,36 +626,61 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
});
|
||||
}
|
||||
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
if (!"default".Equals(tenantId) && KeyVariable.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
_sqlSugarClient.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == tenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
}
|
||||
_configId = tenantId;
|
||||
_dbName = result.data.dotnet;
|
||||
}
|
||||
|
||||
var data = await _sqlSugarClient.Queryable<DataInterfaceEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var data = await _sqlSugarClient.CopyNew().Queryable<DataInterfaceEntity>().FirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
if (data == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
|
||||
// 远端数据(sql过滤)
|
||||
if (input.IsNotEmptyOrNull())
|
||||
{
|
||||
var columnList = new List<string>();
|
||||
if (input.keyword.IsNotEmptyOrNull())
|
||||
input.columnOptions.Split(",").ToList().ForEach(x => columnList.Add(string.Format("{0} like '%{1}%'", x, input.keyword)));
|
||||
|
||||
if (columnList.Any() && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} ", data.Query.TrimEnd(';'), string.Join(" or ", columnList));
|
||||
else if (!string.IsNullOrWhiteSpace(input.relationField) && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} like '%{2}%' ", data.Query.TrimEnd(';'), input.relationField, input.keyword);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.propsValue) && !string.IsNullOrWhiteSpace(input.id))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} = '{2}' ", data.Query.TrimEnd(';'), input.propsValue, input.id);
|
||||
if (!string.IsNullOrWhiteSpace(input.propsValue) && input.ids.Any())
|
||||
data.Query = string.Format("select * from ({0}) t where {1} in ('{2}') ", data.Query.TrimEnd(';'), input.propsValue, string.Join("','", input.ids));
|
||||
if (input.columnOptions.IsNotEmptyOrNull() && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
if (type == 2 && !2.Equals(data.DataType) && (input.queryJson.IsNotEmptyOrNull() || input.sidx.IsNotEmptyOrNull()))
|
||||
{
|
||||
var whereStr = new List<string>();
|
||||
input.columnOptions.Split(",").ToList().ForEach(item => whereStr.Add(string.Format(" {0} like '%{1}%' ", item, input.keyword)));
|
||||
data.Query = string.Format("select * from ({0}) t where {1} ", data.Query.TrimEnd(';'), string.Join(" or ", whereStr));
|
||||
if (input.queryJson.IsNotEmptyOrNull())
|
||||
{
|
||||
var sqlFields = input.queryJson.ToObject<Dictionary<string, string>>();
|
||||
var whereList = new List<string>();
|
||||
foreach (var item in sqlFields)
|
||||
{
|
||||
if (item.Key.Contains("jnpf_searchType_equals_")) whereList.Add(string.Format("{0} = '{1}' ", item.Key.Replace("jnpf_searchType_equals_", string.Empty), item.Value));
|
||||
else whereList.Add(string.Format("{0} like '%{1}%' ", item.Key, item.Value));
|
||||
}
|
||||
data.Query = string.Format("select * from ({0}) t where {1} ", data.Query.TrimEnd(';'), string.Join(" and ", whereList));
|
||||
}
|
||||
if (input.sidx.IsNotEmptyOrNull()) data.Query = string.Format("{0} order by {1} {2}", data.Query.TrimEnd(';'), input.sidx, input.sort);
|
||||
}
|
||||
else
|
||||
{
|
||||
var columnList = new List<string>();
|
||||
if (input.keyword.IsNotEmptyOrNull())
|
||||
input.columnOptions.Split(",").ToList().ForEach(x => columnList.Add(string.Format("{0} like '%{1}%'", x, input.keyword)));
|
||||
|
||||
if (columnList.Any() && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} ", data.Query.TrimEnd(';'), string.Join(" or ", columnList));
|
||||
else if (!string.IsNullOrWhiteSpace(input.relationField) && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} like '%{2}%' ", data.Query.TrimEnd(';'), input.relationField, input.keyword);
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(input.propsValue) && !string.IsNullOrWhiteSpace(input.id))
|
||||
data.Query = string.Format("select * from ({0}) t where {1} = '{2}' ", data.Query.TrimEnd(';'), input.propsValue, input.id);
|
||||
if (!string.IsNullOrWhiteSpace(input.propsValue) && input.ids.Any())
|
||||
data.Query = string.Format("select * from ({0}) t where {1} in ('{2}') ", data.Query.TrimEnd(';'), input.propsValue, string.Join("','", input.ids));
|
||||
if (input.columnOptions.IsNotEmptyOrNull() && !string.IsNullOrWhiteSpace(input.keyword))
|
||||
{
|
||||
var whereStr = new List<string>();
|
||||
input.columnOptions.Split(",").ToList().ForEach(item => whereStr.Add(string.Format(" {0} like '%{1}%' ", item, input.keyword)));
|
||||
data.Query = string.Format("select * from ({0}) t where {1} ", data.Query.TrimEnd(';'), string.Join(" or ", whereStr));
|
||||
}
|
||||
}
|
||||
if (input.paramList.IsNotEmptyOrNull() && input.paramList.Count > 0)
|
||||
{
|
||||
@@ -625,12 +697,11 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
if (1.Equals(data.DataType))
|
||||
{
|
||||
var resTable = await GetData(data);
|
||||
if (type == 0)
|
||||
if (type == 0 || type == 2)
|
||||
{
|
||||
// 分页
|
||||
var dt = GetPageToDataTable(resTable, input.currentPage, input.pageSize);
|
||||
output = new
|
||||
{
|
||||
output = new {
|
||||
pagination = new PageResult()
|
||||
{
|
||||
currentPage = input.currentPage,
|
||||
@@ -677,8 +748,7 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
// });
|
||||
//}
|
||||
resList = resList.FindAll(x => x.Where(xx => xx.Value != null && xx.Value.Contains(input.keyword)).Any());
|
||||
output = new
|
||||
{
|
||||
output = new {
|
||||
pagination = new PageResult()
|
||||
{
|
||||
currentPage = input.currentPage,
|
||||
@@ -699,6 +769,47 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
return resList.FindAll(x => x.ContainsKey(input.propsValue) && x.Any(it => input.ids.Contains(it.Value)));
|
||||
}
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
if (input.queryJson.IsNotEmptyOrNull() || input.sidx.IsNotEmptyOrNull())
|
||||
{
|
||||
if (input.queryJson.IsNotEmptyOrNull())
|
||||
{
|
||||
var querList = input.queryJson.ToObject<Dictionary<string, string>>();
|
||||
foreach (var item in querList)
|
||||
{
|
||||
if (item.Key.Contains("jnpf_searchType_equals_")) resList = resList.Where(x => x[item.Key.Replace("jnpf_searchType_equals_", "")].Equals(item.Value)).ToList();
|
||||
else resList = resList.Where(x => x[item.Key].Contains(item.Value)).ToList();
|
||||
}
|
||||
}
|
||||
if (input.sidx.IsNotEmptyOrNull())
|
||||
{
|
||||
if (input.sort.Equals("desc")) resList = resList.OrderBy(x => x[input.sidx]).ToList();
|
||||
else resList = resList.OrderByDescending(x => x[input.sidx]).ToList();
|
||||
}
|
||||
output = new {
|
||||
pagination = new PageResult()
|
||||
{
|
||||
currentPage = input.currentPage,
|
||||
pageSize = input.pageSize,
|
||||
total = resList.Count
|
||||
},
|
||||
list = resList.Skip((input.currentPage - 1) * input.pageSize).Take(input.pageSize).ToList(),
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
output = new {
|
||||
pagination = new PageResult()
|
||||
{
|
||||
currentPage = input.currentPage,
|
||||
pageSize = input.pageSize,
|
||||
total = resList.Count
|
||||
},
|
||||
list = resList.Skip((input.currentPage - 1) * input.pageSize).Take(input.pageSize).ToList(),
|
||||
};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
output = result;
|
||||
@@ -800,12 +911,12 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
}
|
||||
else
|
||||
{
|
||||
dataProcessingResults = resList.ToJsonString();
|
||||
dataProcessingResults = resList;
|
||||
}
|
||||
break;
|
||||
// 静态数据
|
||||
case 2:
|
||||
dataProcessingResults = resList.ToJsonString();
|
||||
dataProcessingResults = resList;
|
||||
break;
|
||||
}
|
||||
if (!dataProcessingResults.IsNullOrEmpty())
|
||||
@@ -868,11 +979,11 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
var link = new DbLinkEntity();
|
||||
if (!_sqlSugarClient.AsTenant().IsAnyConnection(_configId))
|
||||
{
|
||||
link = await _sqlSugarClient.Queryable<DbLinkEntity>().FirstAsync(x => x.Id == dbLinkId && x.DeleteMark == null);
|
||||
link = await _sqlSugarClient.CopyNew().Queryable<DbLinkEntity>().FirstAsync(x => x.Id == dbLinkId && x.DeleteMark == null);
|
||||
}
|
||||
else
|
||||
{
|
||||
link = await _repository.AsSugarClient().Queryable<DbLinkEntity>().FirstAsync(x => x.Id == dbLinkId && x.DeleteMark == null);
|
||||
link = await _repository.AsSugarClient().CopyNew().Queryable<DbLinkEntity>().FirstAsync(x => x.Id == dbLinkId && x.DeleteMark == null);
|
||||
}
|
||||
|
||||
var tenantLink = link ?? await GetTenantDbLink();
|
||||
@@ -880,7 +991,7 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
sql = await GetSqlParameter(sql, parameter);
|
||||
if (reqMethod.Equals("3"))
|
||||
{
|
||||
return _dataBaseManager.GetInterFaceData(tenantLink, sql, parameter.ToArray());
|
||||
return _dataBaseManager.GetInterFaceDataCopyNew(tenantLink, sql, parameter.ToArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -914,16 +1025,23 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
dicHerader[key.field] = key.defaultValue;
|
||||
}
|
||||
|
||||
switch (entity?.RequestMethod)
|
||||
try
|
||||
{
|
||||
case "6":
|
||||
result = (await entity.Path.SetHeaders(dicHerader).SetQueries(dic).GetAsStringAsync()).ToObject<JObject>();
|
||||
break;
|
||||
case "7":
|
||||
result = (await entity.Path.SetHeaders(dicHerader).SetBody(dic).PostAsStringAsync()).ToObject<JObject>();
|
||||
break;
|
||||
switch (entity.RequestMethod)
|
||||
{
|
||||
case "6":
|
||||
result = (await entity.Path.SetHeaders(dicHerader).SetQueries(dic).GetAsStringAsync()).ToObject<JObject>();
|
||||
break;
|
||||
case "7":
|
||||
result = (await entity.Path.SetHeaders(dicHerader).SetBody(dic).PostAsStringAsync()).ToObject<JObject>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result.ContainsKey("data") ? result["data"].ToObject<JObject>() : result;
|
||||
catch (Exception e)
|
||||
{
|
||||
throw Oops.Oh(ErrorCode.COM1018);
|
||||
}
|
||||
return result.ContainsKey("data") && result["data"].IsNotEmptyOrNull() ? result["data"].ToObject<JObject>() : result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1158,7 +1276,14 @@ public class DataInterfaceService : IDataInterfaceService, IDynamicApiController
|
||||
});
|
||||
}
|
||||
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
if (!"default".Equals(tenantId) && KeyVariable.MultiTenancyType.Equals("COLUMN"))
|
||||
{
|
||||
_sqlSugarClient.QueryFilter.AddTableFilter<ITenantFilter>(it => it.TenantId == tenantId);
|
||||
}
|
||||
else
|
||||
{
|
||||
_sqlSugarClient.ChangeDatabase(tenantId);
|
||||
}
|
||||
_configId = tenantId;
|
||||
_dbName = result.data.dotnet;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ using JNPF.Systems.Entitys.System;
|
||||
using JNPF.Systems.Interfaces.System;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems;
|
||||
@@ -43,21 +42,17 @@ public class DbLinkService : IDbLinkService, IDynamicApiController, ITransient
|
||||
/// </summary>
|
||||
private readonly IDataBaseManager _dataBaseManager;
|
||||
|
||||
private readonly IMemoryCache _memCache;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="DbLinkService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public DbLinkService(
|
||||
ISqlSugarRepository<DbLinkEntity> repository,
|
||||
IDictionaryDataService dictionaryDataService,
|
||||
IDataBaseManager dataBaseManager,
|
||||
IMemoryCache memCache)
|
||||
IDataBaseManager dataBaseManager)
|
||||
{
|
||||
_repository = repository;
|
||||
_dictionaryDataService = dictionaryDataService;
|
||||
_dataBaseManager = dataBaseManager;
|
||||
_memCache = memCache;
|
||||
}
|
||||
|
||||
#region GET
|
||||
@@ -318,7 +313,7 @@ public class DbLinkService : IDbLinkService, IDynamicApiController, ITransient
|
||||
[NonAction]
|
||||
public async Task<DbLinkEntity> GetInfo(string id)
|
||||
{
|
||||
return await _repository.AsSugarClient().CopyNew().Queryable<DbLinkEntity>().FirstAsync(m => m.Id == id && m.DeleteMark == null);
|
||||
return await _repository.GetFirstAsync(m => m.Id == id && m.DeleteMark == null);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -16,220 +16,221 @@ using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
|
||||
namespace JNPF.Systems.System
|
||||
namespace JNPF.Systems.System;
|
||||
|
||||
/// <summary>
|
||||
/// 接口认证
|
||||
/// 版 本:V3.2
|
||||
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
|
||||
/// 日 期:2021-06-01.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "System", Name = "InterfaceOauth", Order = 202)]
|
||||
[Route("api/system/[controller]")]
|
||||
public class InterfaceOauthService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 接口认证
|
||||
/// 版 本:V3.2
|
||||
/// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com)
|
||||
/// 日 期:2021-06-01.
|
||||
/// 服务基本仓储.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "System", Name = "InterfaceOauth", Order = 202)]
|
||||
[Route("api/system/[controller]")]
|
||||
public class InterfaceOauthService : IDynamicApiController, ITransient
|
||||
private readonly ISqlSugarRepository<InterfaceOauthEntity> _repository;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="DictionaryTypeService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public InterfaceOauthService(
|
||||
ISqlSugarRepository<InterfaceOauthEntity> repository,
|
||||
IUserManager userManager)
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基本仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<InterfaceOauthEntity> _repository;
|
||||
_repository = repository;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="DictionaryTypeService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public InterfaceOauthService(
|
||||
ISqlSugarRepository<InterfaceOauthEntity> repository,
|
||||
IUserManager userManager)
|
||||
/// <summary>
|
||||
/// 信息.
|
||||
/// </summary>
|
||||
/// <param name="id">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
var info = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var output = info.Adapt<InterfaceOauthOutput>();
|
||||
if (info.IsNotEmptyOrNull() && info.DataInterfaceIds.IsNotEmptyOrNull())
|
||||
{
|
||||
_repository = repository;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
|
||||
/// <summary>
|
||||
/// 信息.
|
||||
/// </summary>
|
||||
/// <param name="id">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<dynamic> GetInfo(string id)
|
||||
{
|
||||
var info = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var output = info.Adapt<InterfaceOauthOutput>();
|
||||
if (info.IsNotEmptyOrNull() && info.DataInterfaceIds.IsNotEmptyOrNull())
|
||||
{
|
||||
var ids = info.DataInterfaceIds.Split(",");
|
||||
output.list = await _repository.AsSugarClient().Queryable<DataInterfaceEntity>()
|
||||
.Where(a => ids.Contains(a.Id))
|
||||
.Select(a => new DataInterfaceListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
path = a.Path,
|
||||
requestParameters = a.RequestParameters,
|
||||
dataType = a.DataType,
|
||||
requestMethod = SqlFunc.IF(a.RequestMethod.Equals("1")).Return("新增").ElseIF(a.RequestMethod.Equals("2")).Return("修改")
|
||||
.ElseIF(a.RequestMethod.Equals("3")).Return("查询").ElseIF(a.RequestMethod.Equals("4")).Return("删除")
|
||||
.ElseIF(a.RequestMethod.Equals("5")).Return("存储过程").ElseIF(a.RequestMethod.Equals("6")).Return("Get")
|
||||
.End("Post")
|
||||
}).ToListAsync();
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 列表.
|
||||
/// </summary>
|
||||
[HttpGet("")]
|
||||
public async Task<dynamic> GetList([FromQuery] PageInputBase input)
|
||||
{
|
||||
var list = await _repository.AsSugarClient().Queryable<InterfaceOauthEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.CreatorUserId))
|
||||
.Where(a => a.DeleteMark == null)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.AppId.Contains(input.keyword) || a.AppName.Contains(input.keyword))
|
||||
.OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||||
.Select((a, b) => new InterfaceOauthListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
lastModifyTime = a.LastModifyTime,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
|
||||
appId = a.AppId,
|
||||
appName = a.AppName,
|
||||
usefulLife = a.UsefulLife,
|
||||
sortCode = a.SortCode,
|
||||
creatorTime = a.CreatorTime
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<InterfaceOauthListOutput>.SqlSugarPageResult(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取秘钥.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("getAppSecret")]
|
||||
public async Task<dynamic> GetAppSecret()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("dataInterfaceLog/{id}")]
|
||||
public async Task<dynamic> GetList(string id, [FromQuery] DataInterfaceLogListQuery input)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var whereLambda = LinqExpression.And<DataInterfaceLogListOutput>();
|
||||
if (!input.startTime.IsNullOrEmpty() && !input.endTime.IsNullOrEmpty())
|
||||
{
|
||||
var startTime = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
|
||||
var endTime = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
|
||||
whereLambda = whereLambda.And(a => SqlFunc.Between(a.invokTime, startTime, endTime));
|
||||
}
|
||||
var list = await _repository.AsSugarClient().Queryable<DataInterfaceLogEntity, UserEntity, DataInterfaceEntity>((a, b, c) =>
|
||||
new JoinQueryInfos(JoinType.Left, b.Id == a.UserId, JoinType.Left, a.InvokId == c.Id))
|
||||
.Where(a => a.OauthAppId == entity.AppId)
|
||||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.UserId.Contains(input.keyword) || a.InvokIp.Contains(input.keyword))
|
||||
.Select((a, b, c) => new DataInterfaceLogListOutput
|
||||
var ids = info.DataInterfaceIds.Split(",");
|
||||
output.list = await _repository.AsSugarClient().Queryable<DataInterfaceEntity>()
|
||||
.Where(a => ids.Contains(a.Id))
|
||||
.Select(a => new DataInterfaceListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = c.FullName,
|
||||
enCode = c.EnCode,
|
||||
invokDevice = a.InvokDevice,
|
||||
invokIp = a.InvokIp,
|
||||
userId = SqlFunc.MergeString(b.RealName, "/", b.Account),
|
||||
invokTime = a.InvokTime,
|
||||
invokType = a.InvokType,
|
||||
invokWasteTime = a.InvokWasteTime
|
||||
}).MergeTable().Where(whereLambda).OrderBy(a => a.invokTime).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<DataInterfaceLogListOutput>.SqlSugarPageResult(list);
|
||||
fullName = a.FullName,
|
||||
enCode = a.EnCode,
|
||||
path = a.Path,
|
||||
requestParameters = a.RequestParameters,
|
||||
dataType = a.DataType,
|
||||
requestMethod = SqlFunc.IF(a.RequestMethod.Equals("1")).Return("新增").ElseIF(a.RequestMethod.Equals("2")).Return("修改")
|
||||
.ElseIF(a.RequestMethod.Equals("3")).Return("查询").ElseIF(a.RequestMethod.Equals("4")).Return("删除")
|
||||
.ElseIF(a.RequestMethod.Equals("5")).Return("存储过程").ElseIF(a.RequestMethod.Equals("6")).Return("Get")
|
||||
.End("Post")
|
||||
}).ToListAsync();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("")]
|
||||
public async Task Create_Api([FromBody] InterfaceOauthInput input)
|
||||
{
|
||||
if (await _repository.IsAnyAsync(x => (x.AppId == input.appId || x.AppName == input.appName) && x.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.D3001);
|
||||
var entity = input.Adapt<InterfaceOauthEntity>();
|
||||
if (input.usefulLife.IsNullOrEmpty() || input.usefulLife == "0")
|
||||
{
|
||||
entity.UsefulLife = null;
|
||||
}
|
||||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
if (isOk < 1)
|
||||
throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <param name="id">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task Delete(string id)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <param name="id">id.</param>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
public async Task Update(string id, [FromBody] InterfaceOauthInput input)
|
||||
{
|
||||
if (await _repository.IsAnyAsync(x => x.Id != id && (x.AppId == input.appId || x.AppName == input.appName) && x.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.COM1004);
|
||||
var entity = input.Adapt<InterfaceOauthEntity>();
|
||||
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
|
||||
if (input.usefulLife.IsNullOrEmpty() || input.usefulLife == "0")
|
||||
{
|
||||
await _repository.AsUpdateable().SetColumns(it => new InterfaceOauthEntity()
|
||||
{
|
||||
UsefulLife = null
|
||||
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
|
||||
}
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 授权接口.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("saveInterfaceList")]
|
||||
public async Task SaveInterFaceList([FromBody] InterfaceOauthSaveInput input)
|
||||
{
|
||||
var isOk = await _repository.AsSugarClient().Updateable<InterfaceOauthEntity>()
|
||||
.SetColumns(it => it.DataInterfaceIds == input.dataInterfaceIds).Where(x => x.Id == input.interfaceIdentId).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
#endregion
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 列表.
|
||||
/// </summary>
|
||||
[HttpGet("")]
|
||||
public async Task<dynamic> GetList([FromQuery] PageInputBase input)
|
||||
{
|
||||
var list = await _repository.AsSugarClient().Queryable<InterfaceOauthEntity, UserEntity>((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.CreatorUserId))
|
||||
.Where(a => a.DeleteMark == null)
|
||||
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.AppId.Contains(input.keyword) || a.AppName.Contains(input.keyword))
|
||||
.OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc)
|
||||
.Select((a, b) => new InterfaceOauthListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
lastModifyTime = a.LastModifyTime,
|
||||
enabledMark = a.EnabledMark,
|
||||
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
|
||||
appId = a.AppId,
|
||||
appName = a.AppName,
|
||||
usefulLife = a.UsefulLife,
|
||||
sortCode = a.SortCode,
|
||||
creatorTime = a.CreatorTime
|
||||
}).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<InterfaceOauthListOutput>.SqlSugarPageResult(list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取秘钥.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet("getAppSecret")]
|
||||
public async Task<dynamic> GetAppSecret()
|
||||
{
|
||||
return Guid.NewGuid().ToString().Replace("-", string.Empty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 日志.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("dataInterfaceLog/{id}")]
|
||||
public async Task<dynamic> GetList(string id, [FromQuery] DataInterfaceLogListQuery input)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
var whereLambda = LinqExpression.And<DataInterfaceLogListOutput>();
|
||||
if (!input.startTime.IsNullOrEmpty() && !input.endTime.IsNullOrEmpty())
|
||||
{
|
||||
var startTime = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
|
||||
var endTime = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
|
||||
whereLambda = whereLambda.And(a => SqlFunc.Between(a.invokTime, startTime, endTime));
|
||||
}
|
||||
var list = await _repository.AsSugarClient().Queryable<DataInterfaceLogEntity, UserEntity, DataInterfaceEntity>((a, b, c) =>
|
||||
new JoinQueryInfos(JoinType.Left, b.Id == a.UserId, JoinType.Left, a.InvokId == c.Id))
|
||||
.Where(a => a.OauthAppId == entity.AppId)
|
||||
.WhereIF(input.keyword.IsNotEmptyOrNull(), a => a.UserId.Contains(input.keyword) || a.InvokIp.Contains(input.keyword))
|
||||
.Select((a, b, c) => new DataInterfaceLogListOutput
|
||||
{
|
||||
id = a.Id,
|
||||
fullName = c.FullName,
|
||||
enCode = c.EnCode,
|
||||
invokDevice = a.InvokDevice,
|
||||
invokIp = a.InvokIp,
|
||||
userId = SqlFunc.MergeString(b.RealName, "/", b.Account),
|
||||
invokTime = a.InvokTime,
|
||||
invokType = a.InvokType,
|
||||
invokWasteTime = a.InvokWasteTime
|
||||
}).MergeTable().Where(whereLambda).OrderBy(a => a.invokTime).ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<DataInterfaceLogListOutput>.SqlSugarPageResult(list);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("")]
|
||||
public async Task Create_Api([FromBody] InterfaceOauthInput input)
|
||||
{
|
||||
if (await _repository.IsAnyAsync(x => (x.AppId == input.appId || x.AppName == input.appName) && x.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.D3001);
|
||||
var entity = input.Adapt<InterfaceOauthEntity>();
|
||||
if (input.usefulLife.IsNullOrEmpty() || input.usefulLife == "0")
|
||||
{
|
||||
entity.UsefulLife = null;
|
||||
}
|
||||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
if (isOk < 1)
|
||||
throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除.
|
||||
/// </summary>
|
||||
/// <param name="id">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpDelete("{id}")]
|
||||
public async Task Delete(string id)
|
||||
{
|
||||
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改.
|
||||
/// </summary>
|
||||
/// <param name="id">id.</param>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPut("{id}")]
|
||||
public async Task Update(string id, [FromBody] InterfaceOauthInput input)
|
||||
{
|
||||
if (await _repository.IsAnyAsync(x => x.Id != id && (x.AppId == input.appId || x.AppName == input.appName) && x.DeleteMark == null))
|
||||
throw Oops.Oh(ErrorCode.COM1004);
|
||||
var entity = input.Adapt<InterfaceOauthEntity>();
|
||||
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
|
||||
if (input.usefulLife.IsNullOrEmpty() || input.usefulLife == "0")
|
||||
{
|
||||
await _repository.AsUpdateable().SetColumns(it => new InterfaceOauthEntity()
|
||||
{
|
||||
UsefulLife = null
|
||||
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
|
||||
}
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1001);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 授权接口.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("saveInterfaceList")]
|
||||
public async Task SaveInterFaceList([FromBody] InterfaceOauthSaveInput input)
|
||||
{
|
||||
var isOk = await _repository.AsSugarClient().Updateable<InterfaceOauthEntity>()
|
||||
.SetColumns(it => it.DataInterfaceIds == input.dataInterfaceIds).Where(x => x.Id == input.interfaceIdentId).ExecuteCommandHasChangeAsync();
|
||||
if (!isOk)
|
||||
throw Oops.Oh(ErrorCode.COM1002);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
@@ -375,7 +375,8 @@ public class MessageTemplateService : IMessageTemplateService, IDynamicApiContro
|
||||
Account = sysconfig.emailAccount,
|
||||
Password = sysconfig.emailPassword,
|
||||
SMTPHost = sysconfig.emailSmtpHost,
|
||||
SMTPPort = sysconfig.emailSmtpPort.ParseToInt()
|
||||
SMTPPort = sysconfig.emailSmtpPort.ParseToInt(),
|
||||
Ssl = sysconfig.emailSsl,
|
||||
}, mailModel);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Const;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Extension;
|
||||
using JNPF.Common.Filter;
|
||||
@@ -120,7 +121,7 @@ public class ModuleColumnService : IModuleColumnService, IDynamicApiController,
|
||||
var visualDevId = moduleEntity.PropertyJson.ToObject<JObject>()["moduleId"].ToString();
|
||||
var visualDevEntity = await _repository.AsSugarClient().Queryable<VisualDevEntity>().FirstAsync(x => x.Id == visualDevId && x.DeleteMark == null);
|
||||
var defaultColumnList = visualDevEntity.ColumnData.ToObject<ColumnDesignModel>().defaultColumnList;
|
||||
var uelessList = new List<string>() { "PsdInput", "colorPicker", "rate", "slider", "divider", "uploadImg", "uploadFz", "editor", "JNPFText", "relationFormAttr", "popupAttr", "groupTitle" };
|
||||
var uelessList = new List<string>() { "PsdInput", JnpfKeyConst.COLORPICKER, JnpfKeyConst.RATE, JnpfKeyConst.SLIDER, JnpfKeyConst.DIVIDER, JnpfKeyConst.UPLOADIMG, JnpfKeyConst.UPLOADFZ, JnpfKeyConst.EDITOR, JnpfKeyConst.JNPFTEXT, JnpfKeyConst.RELATIONFORMATTR, JnpfKeyConst.POPUPATTR, JnpfKeyConst.GROUPTITLE };
|
||||
return defaultColumnList?.Where(x => !uelessList.Contains(x.jnpfKey)).Select(x => new { field = x.prop, fieldName = x.label }).ToList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -73,7 +73,7 @@ public class ModuleDataAuthorizeService : IModuleDataAuthorizeService, IDynamicA
|
||||
type = a.Type,
|
||||
conditionSymbol = a.ConditionSymbol,
|
||||
conditionText = a.ConditionText,
|
||||
conditionSymbolName = a.ConditionSymbol.Replace("Equal", "等于").Replace("Included", "包含").Replace("GreaterThan", "大于").Replace("LessThan", "小于").Replace("Not", "不").Replace("Or", ""),
|
||||
conditionSymbolName = SqlFunc.ToString(a.ConditionSymbol).Replace("Equal", "等于").Replace("Included", "包含").Replace("GreaterThan", "大于").Replace("LessThan", "小于").Replace("Not", "不").Replace("Or", ""),
|
||||
bindTable = a.BindTable,
|
||||
fieldRule = a.FieldRule,
|
||||
enCode = SqlFunc.IF(b.Type == 2 && a.FieldRule == 1 && !SqlFunc.IsNullOrEmpty(a.BindTable)).Return(a.EnCode.Replace("jnpf_" + a.BindTable + "_jnpf_", ""))
|
||||
|
||||
@@ -142,7 +142,7 @@ public class OnlineUserService : IDynamicApiController, ITransient
|
||||
/// <returns></returns>
|
||||
public async Task<bool> DelUserInfo(string tenantId, string userId)
|
||||
{
|
||||
var cacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, tenantId, userId);
|
||||
var cacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, userId);
|
||||
return await _cacheManager.DelAsync(cacheKey);
|
||||
}
|
||||
}
|
||||
@@ -209,7 +209,7 @@ public class PrintDevService : IDynamicApiController, ITransient
|
||||
|
||||
var fieldModel = new PrintDevFieldModel()
|
||||
{
|
||||
id = index == 0 ? "headTable" : "childrenDataTable" + (index-1),
|
||||
id = index == 0 ? "headTable" : "childrenDataTable" + (index - 1),
|
||||
parentId = "struct",
|
||||
fullName = index == 0 ? "主表" : "子表" + (index - 1),
|
||||
};
|
||||
@@ -228,51 +228,37 @@ public class PrintDevService : IDynamicApiController, ITransient
|
||||
[HttpGet("Data")]
|
||||
public async Task<dynamic> GetData([FromQuery] PrintDevSqlDataQuery input)
|
||||
{
|
||||
var output = new PrintDevDataOutput();
|
||||
var entity = await GetInfo(input.id);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var link = await _dbLinkService.GetInfo(entity.DbLinkId);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var parameter = new List<SugarParameter>()
|
||||
{
|
||||
new SugarParameter("@formId", input.formId)
|
||||
};
|
||||
var sqlList = entity.SqlTemplate.ToList<PrintDevSqlModel>();
|
||||
var dataTable = _dataBaseManager.GetInterFaceData(tenantLink, sqlList.FirstOrDefault().sql, parameter.ToArray());
|
||||
var dic = DateConver(DataTableToDicList(dataTable)).FirstOrDefault();
|
||||
for (int i = 1; i < sqlList.Count; i++)
|
||||
{
|
||||
if (sqlList[i].sql.IsNullOrEmpty())
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var childDataTable = _dataBaseManager.GetInterFaceData(tenantLink, sqlList[i].sql, parameter.ToArray());
|
||||
if (childDataTable.Rows.Count > 0)
|
||||
dic.Add("childrenDataTable" + (i - 1), DateConver(DataTableToDicList(childDataTable)));
|
||||
}
|
||||
|
||||
output.printData = dic;
|
||||
output.printTemplate = entity.PrintTemplate;
|
||||
output.operatorRecordList = await _repository.AsSugarClient().Queryable<FlowTaskOperatorRecordEntity>()
|
||||
.Where(a => a.TaskId == input.formId)
|
||||
.Select(a => new PrintDevDataModel()
|
||||
{
|
||||
id = a.Id,
|
||||
handleId = a.HandleId,
|
||||
handleOpinion = a.HandleOpinion,
|
||||
handleStatus = a.HandleStatus,
|
||||
nodeCode = a.NodeCode,
|
||||
handleTime = a.HandleTime,
|
||||
nodeName = a.NodeName,
|
||||
signImg = a.SignImg,
|
||||
taskId = a.TaskId,
|
||||
operatorId = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.OperatorId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||||
userName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.HandleId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||||
status = a.Status,
|
||||
taskNodeId = a.TaskNodeId,
|
||||
taskOperatorId = a.TaskOperatorId,
|
||||
}).ToListAsync();
|
||||
var output = await GetPrintDevDataOutput(input.id, input.formId);
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模板数据.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("BatchData")]
|
||||
public async Task<dynamic> GetBatchData([FromQuery] PrintDevSqlDataQuery input)
|
||||
{
|
||||
var output = new List<PrintDevDataOutput>();
|
||||
foreach (var formId in input.formId.Split(','))
|
||||
{
|
||||
var data = await GetPrintDevDataOutput(input.id, formId);
|
||||
output.Add(data);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 模板列表.
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("getListOptions")]
|
||||
public async Task<dynamic> GetListOptions([FromBody] PrintDevSqlDataQuery input)
|
||||
{
|
||||
return _repository.GetList(x => input.ids.Contains(x.Id)).Select(x => new { id = x.Id, fullName = x.FullName }).ToList();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
@@ -362,6 +348,8 @@ public class PrintDevService : IDynamicApiController, ITransient
|
||||
entity.FullName = entity.FullName + "副本" + random;
|
||||
entity.EnabledMark = 0;
|
||||
entity.EnCode += random;
|
||||
entity.LastModifyTime = null;
|
||||
entity.LastModifyUserId = null;
|
||||
if (entity.FullName.Length >= 50 || entity.EnCode.Length >= 50)
|
||||
throw Oops.Oh(ErrorCode.COM1009);
|
||||
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
|
||||
@@ -407,6 +395,60 @@ public class PrintDevService : IDynamicApiController, ITransient
|
||||
|
||||
#region PrivateMethod
|
||||
|
||||
/// <summary>
|
||||
/// 模板数据.
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="formId"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<PrintDevDataOutput> GetPrintDevDataOutput(string id, string formId)
|
||||
{
|
||||
var output = new PrintDevDataOutput();
|
||||
var entity = await GetInfo(id);
|
||||
if (entity == null)
|
||||
throw Oops.Oh(ErrorCode.D9010);
|
||||
var link = await _dbLinkService.GetInfo(entity.DbLinkId);
|
||||
var tenantLink = link ?? _dataBaseManager.GetTenantDbLink(_userManager.TenantId, _userManager.TenantDbName);
|
||||
var parameter = new List<SugarParameter>()
|
||||
{
|
||||
new SugarParameter("@formId", formId)
|
||||
};
|
||||
var sqlList = entity.SqlTemplate.ToList<PrintDevSqlModel>();
|
||||
var dataTable = _dataBaseManager.GetInterFaceData(tenantLink, sqlList.FirstOrDefault().sql, parameter.ToArray());
|
||||
var dic = DateConver(DataTableToDicList(dataTable)).FirstOrDefault();
|
||||
for (int i = 1; i < sqlList.Count; i++)
|
||||
{
|
||||
if (sqlList[i].sql.IsNullOrEmpty())
|
||||
throw Oops.Oh(ErrorCode.COM1005);
|
||||
var childDataTable = _dataBaseManager.GetInterFaceData(tenantLink, sqlList[i].sql, parameter.ToArray());
|
||||
if (childDataTable.Rows.Count > 0)
|
||||
dic.Add("childrenDataTable" + (i - 1), DateConver(DataTableToDicList(childDataTable)));
|
||||
}
|
||||
|
||||
output.printData = dic;
|
||||
output.printTemplate = entity.PrintTemplate;
|
||||
output.operatorRecordList = await _repository.AsSugarClient().Queryable<FlowTaskOperatorRecordEntity>()
|
||||
.Where(a => a.TaskId == formId)
|
||||
.Select(a => new PrintDevDataModel()
|
||||
{
|
||||
id = a.Id,
|
||||
handleId = a.HandleId,
|
||||
handleOpinion = a.HandleOpinion,
|
||||
handleStatus = a.HandleStatus,
|
||||
nodeCode = a.NodeCode,
|
||||
handleTime = a.HandleTime,
|
||||
nodeName = a.NodeName,
|
||||
signImg = a.SignImg,
|
||||
taskId = a.TaskId,
|
||||
operatorId = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.OperatorId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||||
userName = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.HandleId).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||||
status = a.Status,
|
||||
taskNodeId = a.TaskNodeId,
|
||||
taskOperatorId = a.TaskOperatorId,
|
||||
}).ToListAsync();
|
||||
return output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取字段模型.
|
||||
/// </summary>
|
||||
|
||||
105
system/Tnb.Systems/System/PrintLogService.cs
Normal file
105
system/Tnb.Systems/System/PrintLogService.cs
Normal file
@@ -0,0 +1,105 @@
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
using JNPF.Common.Filter;
|
||||
using JNPF.Common.Security;
|
||||
using JNPF.DependencyInjection;
|
||||
using JNPF.DynamicApiController;
|
||||
using JNPF.FriendlyException;
|
||||
using JNPF.LinqBuilder;
|
||||
using JNPF.Systems.Entitys.Dto.System.PrintLog;
|
||||
using JNPF.Systems.Entitys.Entity.System;
|
||||
using JNPF.Systems.Entitys.Permission;
|
||||
using Mapster;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SqlSugar;
|
||||
using JNPF.Common.Extension;
|
||||
|
||||
namespace JNPF.Systems.System;
|
||||
|
||||
/// <summary>
|
||||
/// 打印模板日志
|
||||
/// 版 本:V3.2
|
||||
/// 版 权:引迈信息技术有限公司(https://www.jnpfsoft.com)
|
||||
/// 作 者:JNPF开发平台组
|
||||
/// 日 期:2021-06-01.
|
||||
/// </summary>
|
||||
[ApiDescriptionSettings(Tag = "System", Name = "PrintLog", Order = 200)]
|
||||
[Route("api/system/[controller]")]
|
||||
public class PrintLogService : IDynamicApiController, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务基础仓储.
|
||||
/// </summary>
|
||||
private readonly ISqlSugarRepository<PrintLogEntity> _repository;
|
||||
|
||||
/// <summary>
|
||||
/// 用户管理.
|
||||
/// </summary>
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// 初始化一个<see cref="PrintDevService"/>类型的新实例.
|
||||
/// </summary>
|
||||
public PrintLogService(
|
||||
ISqlSugarRepository<PrintLogEntity> repository,
|
||||
IUserManager userManager)
|
||||
{
|
||||
_repository = repository;
|
||||
_userManager = userManager;
|
||||
}
|
||||
|
||||
#region Get
|
||||
/// <summary>
|
||||
/// 列表(分页).
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("{id}")]
|
||||
public async Task<dynamic> GetList(string id, [FromQuery] PrintLogQuery input)
|
||||
{
|
||||
var whereLambda = LinqExpression.And<PrintLogEntity>();
|
||||
whereLambda = whereLambda.And(x => x.PrintId == id);
|
||||
var start = new DateTime();
|
||||
var end = new DateTime();
|
||||
if (input.endTime != null && input.startTime != null)
|
||||
{
|
||||
start = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 00:00:00}", input.startTime?.TimeStampToDateTime()));
|
||||
end = Convert.ToDateTime(string.Format("{0:yyyy-MM-dd 23:59:59}", input.endTime?.TimeStampToDateTime()));
|
||||
whereLambda = whereLambda.And(x => SqlFunc.Between(x.PrintTime, start, end));
|
||||
}
|
||||
if (!string.IsNullOrEmpty(input.keyword))
|
||||
whereLambda = whereLambda.And(m => m.PrintTitle.Contains(input.keyword));
|
||||
var list = await _repository.AsQueryable().Where(whereLambda).OrderBy(x => x.PrintTime, OrderByType.Desc)
|
||||
.Select(a => new PrintLogOutuut
|
||||
{
|
||||
id = a.Id,
|
||||
printId = a.PrintId,
|
||||
printMan = SqlFunc.Subqueryable<UserEntity>().Where(u => u.Id == a.PrintMan).Select(u => SqlFunc.MergeString(u.RealName, "/", u.Account)),
|
||||
printNum = a.PrintNum,
|
||||
printTime = a.PrintTime,
|
||||
printTitle = a.PrintTitle
|
||||
})
|
||||
.ToPagedListAsync(input.currentPage, input.pageSize);
|
||||
return PageResult<PrintLogOutuut>.SqlSugarPageResult(list);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Post
|
||||
/// <summary>
|
||||
/// 新增.
|
||||
/// </summary>
|
||||
/// <param name="input">请求参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("save")]
|
||||
public async Task Delete([FromBody] PrintLogOutuut input)
|
||||
{
|
||||
var entity = input.Adapt<PrintLogEntity>();
|
||||
entity.Id= SnowflakeIdHelper.NextId();
|
||||
entity.PrintMan = _userManager.UserId;
|
||||
entity.PrintTime = DateTime.Now;
|
||||
var isOk = await _repository.AsInsertable(entity).ExecuteCommandAsync();
|
||||
if (isOk < 1)
|
||||
throw Oops.Oh(ErrorCode.COM1000);
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -178,7 +178,7 @@ public class SysCacheService : IDynamicApiController, ITransient
|
||||
/// <returns></returns>
|
||||
private async Task<bool> DelUserInfo(string tenantId, string userId)
|
||||
{
|
||||
var cacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, tenantId, userId);
|
||||
var cacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, userId);
|
||||
return await _cacheManager.DelAsync(cacheKey);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ public class SysConfigService : ISysConfigService, IDynamicApiController, ITrans
|
||||
[UnitOfWork]
|
||||
public async Task SetAdminList([FromBody] SetAdminInput input)
|
||||
{
|
||||
await _repository.AsSugarClient().Updateable<UserEntity>().SetColumns(x => x.IsAdministrator == 0).Where(x => x.IsAdministrator == 1 && !x.Id.Equals("admin")).ExecuteCommandAsync();
|
||||
await _repository.AsSugarClient().Updateable<UserEntity>().SetColumns(x => x.IsAdministrator == 0).Where(x => x.IsAdministrator == 1 && !x.Account.Equals("admin")).ExecuteCommandAsync();
|
||||
await _repository.AsSugarClient().Updateable<UserEntity>().SetColumns(x => x.IsAdministrator == 1).Where(x => input.adminIds.Contains(x.Id)).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using JNPF.Common.Const;
|
||||
using Aop.Api.Domain;
|
||||
using JNPF.Common.Const;
|
||||
using JNPF.Common.Core.Handlers;
|
||||
using JNPF.Common.Core.Manager;
|
||||
using JNPF.Common.Enums;
|
||||
@@ -70,7 +71,7 @@ public class SystemService : IDynamicApiController, ITransient
|
||||
/// <param name="input">参数.</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("")]
|
||||
public async Task<dynamic> GetList([FromQuery] KeywordInput input)
|
||||
public async Task<dynamic> GetList([FromQuery] SystemQuery input)
|
||||
{
|
||||
var authorIds = await _repository.AsSugarClient().Queryable<AuthorizeEntity>()
|
||||
.Where(x => x.ItemType.Equals("system") && x.ObjectType.Equals("Role") && _userManager.Roles.Contains(x.ObjectId)).Select(x => x.ItemId).ToListAsync();
|
||||
@@ -81,6 +82,8 @@ public class SystemService : IDynamicApiController, ITransient
|
||||
whereLambda = whereLambda.And(x => authorIds.Contains(x.Id));
|
||||
if (input.keyword.IsNotEmptyOrNull())
|
||||
whereLambda = whereLambda.And(x => x.FullName.Contains(input.keyword) || x.EnCode.Contains(input.keyword));
|
||||
if (input.enableMark.IsNotEmptyOrNull())
|
||||
whereLambda = whereLambda.And(x => x.EnabledMark == SqlFunc.ToInt32(input.enableMark));
|
||||
var output = (await _repository.AsQueryable().Where(whereLambda).OrderBy(a => a.SortCode).OrderByDescending(a => a.CreatorTime).ToListAsync()).Adapt<List<SystemListOutput>>();
|
||||
return new { list = output };
|
||||
}
|
||||
@@ -215,7 +218,7 @@ public class SystemService : IDynamicApiController, ITransient
|
||||
allUserOnlineList.RemoveAll((x) => x.connectionId == item.connectionId);
|
||||
|
||||
// 删除用户登录信息缓存.
|
||||
var mCacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYUSER, tenantId, item.userId);
|
||||
var mCacheKey = string.Format("{0}:{1}:{2}", tenantId, CommonConst.CACHEKEYUSER, item.userId);
|
||||
await _cacheManager.DelAsync(mCacheKey);
|
||||
});
|
||||
await _cacheManager.SetAsync(cacheKey, allUserOnlineList);
|
||||
|
||||
Reference in New Issue
Block a user