😎1、优化钉钉接口服务 2、优化行政区划接口服务 3、增加token黑名单 4、事件消费增加重试 5、优化租户接口服务 6、升级依赖
This commit is contained in:
parent
f3c49e1f42
commit
50f024644b
@ -27,7 +27,7 @@
|
||||
//],
|
||||
"DbSettings": {
|
||||
"EnableInitDb": true, // 启用库初始化(若实体没有变化建议关闭)
|
||||
"EnableInitView": true, // 启用视图初始化
|
||||
"EnableInitView": true, // 启用视图初始化(若实体和视图没有变化建议关闭)
|
||||
"EnableDiffLog": false, // 启用库表差异日志
|
||||
"EnableUnderLine": false, // 启用驼峰转下划线
|
||||
"EnableConnEncrypt": false // 启用数据库连接串加密(国密SM2加解密)
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.7.76" />
|
||||
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster" Version="4.9.7.76" />
|
||||
<PackageReference Include="Furion.Pure" Version="4.9.7.76" />
|
||||
<PackageReference Include="Hardware.Info" Version="101.0.1" />
|
||||
<PackageReference Include="Hardware.Info" Version="101.0.1.1" />
|
||||
<PackageReference Include="Hashids.net" Version="1.7.0" />
|
||||
<PackageReference Include="IPTools.China" Version="1.6.0" />
|
||||
<PackageReference Include="IPTools.International" Version="1.6.0" />
|
||||
@ -54,9 +54,9 @@
|
||||
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.12.0" />
|
||||
<PackageReference Include="SqlSugarCore" Version="5.1.4.193" />
|
||||
<PackageReference Include="SSH.NET" Version="2025.0.0" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.4" />
|
||||
<PackageReference Include="System.Linq.Dynamic.Core" Version="1.6.5" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1249" />
|
||||
<PackageReference Include="TencentCloudSDK.Sms" Version="3.0.1250" />
|
||||
<PackageReference Include="UAParser" Version="3.1.47" />
|
||||
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
|
||||
</ItemGroup>
|
||||
|
||||
@ -16,6 +16,11 @@ public class CacheConst
|
||||
/// </summary>
|
||||
public const string KeyUserToken = "sys_user_token:";
|
||||
|
||||
/// <summary>
|
||||
/// Token黑名单
|
||||
/// </summary>
|
||||
public const string KeyTokenBlacklist = "sys_token_blacklist:";
|
||||
|
||||
/// <summary>
|
||||
/// 用户接口缓存(接口集合)
|
||||
/// </summary>
|
||||
|
||||
@ -12,7 +12,7 @@ namespace Admin.NET.Core;
|
||||
[SugarTable(null, "系统行政地区表")]
|
||||
[SysTable]
|
||||
[SugarIndex("index_{table}_N", nameof(Name), OrderByType.Asc)]
|
||||
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc)]
|
||||
[SugarIndex("index_{table}_C", nameof(Code), OrderByType.Asc, IsUnique = true)]
|
||||
public partial class SysRegion : EntityBaseId
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@ -54,13 +54,21 @@ public class EventConsumer<T> : IDisposable
|
||||
}
|
||||
_consumerCts = new CancellationTokenSource();
|
||||
var ct = _consumerCts.Token;
|
||||
_consumerTask = Task.Factory.StartNew(() =>
|
||||
_consumerTask = Task.Factory.StartNew(async () =>
|
||||
{
|
||||
while (!ct.IsCancellationRequested)
|
||||
{
|
||||
var cr = Consumer.TakeOne(10);
|
||||
if (cr == null) continue;
|
||||
Received?.Invoke(this, cr);
|
||||
try
|
||||
{
|
||||
var cr = Consumer.TakeOne(10);
|
||||
if (cr == null) continue;
|
||||
Received?.Invoke(this, cr);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"消息消费异常: {ex.Message}");
|
||||
await Task.Delay(1000);
|
||||
}
|
||||
}
|
||||
}, ct, TaskCreationOptions.LongRunning, TaskScheduler.Default);
|
||||
}
|
||||
|
||||
@ -343,10 +343,17 @@ public class SysAuthService : IDynamicApiController, ITransient
|
||||
[DisplayName("退出系统")]
|
||||
public async void Logout()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_userManager.Account))
|
||||
var httpContext = _httpContextAccessor.HttpContext ?? throw Oops.Oh(ErrorCodeEnum.D1016);
|
||||
|
||||
var accessToken = httpContext.Request.Headers.Authorization.ToString();
|
||||
if (string.IsNullOrWhiteSpace(accessToken) || string.IsNullOrWhiteSpace(_userManager.Account))
|
||||
throw Oops.Oh(ErrorCodeEnum.D1011);
|
||||
|
||||
// 发布系统退出事件
|
||||
// 写入Token黑名单
|
||||
var tokenExpire = await _sysConfigService.GetTokenExpire();
|
||||
_sysCacheService.Set($"{CacheConst.KeyTokenBlacklist}:{accessToken}", _userManager.Account, TimeSpan.FromMinutes(tokenExpire));
|
||||
|
||||
// 发布系统退出事件
|
||||
await _eventPublisher.PublishAsync(UserEventTypeEnum.Logout, _userManager);
|
||||
|
||||
// 退出Swagger/设置无效Token响应头
|
||||
|
||||
@ -203,7 +203,7 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
Level = 1,
|
||||
Pid = 0,
|
||||
};
|
||||
if (municipalityList.Any(m => province.Name.StartsWith(m))) province.Name += "(省)";
|
||||
//if (municipalityList.Any(u => province.Name.StartsWith(u))) province.Name += "(省)";
|
||||
list.Add(province);
|
||||
|
||||
if (input.Level <= 1) continue;
|
||||
@ -221,7 +221,11 @@ public class SysRegionService : IDynamicApiController, ITransient
|
||||
Name = cityName,
|
||||
Level = 2
|
||||
};
|
||||
if (municipalityList.Any(m => city.Name.StartsWith(m))) city.Name += "(地)";
|
||||
if (municipalityList.Any(u => city.Name.StartsWith(u)))
|
||||
{
|
||||
city.Name = "市辖区";
|
||||
if (province.Code == city.Code) city.Code = province.Code.Substring(0, 2) + "0100";
|
||||
}
|
||||
list.Add(city);
|
||||
|
||||
if (input.Level <= 2) continue;
|
||||
|
||||
@ -76,8 +76,8 @@ public class SysTenantService : IDynamicApiController, ITransient
|
||||
public async Task<SqlSugarPagedList<TenantOutput>> Page(PageTenantInput input)
|
||||
{
|
||||
return await _sysTenantRep.AsQueryable()
|
||||
.LeftJoin<SysUser>((u, a) => u.UserId == a.Id)
|
||||
.LeftJoin<SysOrg>((u, a, b) => u.OrgId == b.Id)
|
||||
.LeftJoin<SysUser>((u, a) => u.UserId == a.Id).ClearFilter()
|
||||
.LeftJoin<SysOrg>((u, a, b) => u.OrgId == b.Id).ClearFilter()
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Phone), (u, a) => a.Phone.Contains(input.Phone.Trim()))
|
||||
.WhereIF(!string.IsNullOrWhiteSpace(input.Name), (u, a, b) => b.Name.Contains(input.Name.Trim()))
|
||||
.WhereIF(!input.IncludeDefault, u => u.Id.ToString() != SqlSugarConst.MainConfigId) // 排除默认主库/主租户
|
||||
|
||||
@ -57,6 +57,15 @@ namespace Admin.NET.Web.Core
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证Token黑名单
|
||||
var accessToken = httpContext.Request.Headers.Authorization.ToString();
|
||||
if (sysCacheService.ExistKey($"{CacheConst.KeyTokenBlacklist}:{accessToken}"))
|
||||
{
|
||||
context.Fail(new AuthorizationFailureReason(this, "令牌已失效,请重新登录。"));
|
||||
context.GetCurrentHttpContext().SignoutToSwagger();
|
||||
return;
|
||||
}
|
||||
|
||||
// 验证Token版本号
|
||||
var userId = httpContext.User.FindFirst(ClaimConst.UserId)?.Value;
|
||||
var tokenVersion1 = httpContext.User.FindFirst(ClaimConst.TokenVersion)?.Value;
|
||||
|
||||
@ -72,4 +72,16 @@ public class DingTalkService : IDynamicApiController, IScoped
|
||||
{
|
||||
return await _dingTalkApi.DingTalkSendInteractiveCards(token, input);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建并投放钉钉消息卡片 🔖
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[DisplayName("给指定用户发送钉钉消息卡片")]
|
||||
public async Task<DingTalkCreateAndDeliverOutput> DingTalkCreateAndDeliver(string token, DingTalkCreateAndDeliverInput input)
|
||||
{
|
||||
return await _dingTalkApi.DingTalkCreateAndDeliver(token, input);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,316 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkCreateAndDeliverInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 卡片创建者的userId
|
||||
/// </summary>
|
||||
public string? userId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片内容模板ID
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string cardTemplateId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 外部卡片实例Id
|
||||
/// </summary>
|
||||
[Required]
|
||||
public string outTrackId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片回调的类型:STREAM:stream模式 HTTP:http模式
|
||||
/// </summary>
|
||||
public string? callbackType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片回调HTTP模式时的路由 Key,用于查询注册的 callbackUrl。
|
||||
/// </summary>
|
||||
public string? callbackRouteKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片数据
|
||||
/// </summary>
|
||||
[Required]
|
||||
public DingTalk_CardData cardData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户的私有数据
|
||||
/// </summary>
|
||||
public PrivateData? crivateData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 动态数据源配置
|
||||
/// </summary>
|
||||
public OpenDynamicDataConfig? openDynamicDataConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IM单聊酷应用场域信息
|
||||
/// </summary>
|
||||
public OpenSpaceModel? imSingleOpenSpaceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IM群聊场域信息。
|
||||
/// </summary>
|
||||
public OpenSpaceModel? imGroupOpenSpaceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IM机器人单聊场域信息。
|
||||
/// </summary>
|
||||
public OpenSpaceModel? imRobotOpenSpaceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 协作场域信息
|
||||
/// </summary>
|
||||
public OpenSpaceModel? coFeedOpenSpaceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吊顶场域信息
|
||||
/// </summary>
|
||||
public OpenSpaceModel? topOpenSpaceModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 表示场域及其场域id
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 其格式为dtv1.card//spaceType1.spaceId1;spaceType2.spaceId2_1;spaceType2.spaceId2_2;spaceType3.spaceId3
|
||||
/// </remarks>
|
||||
[Required]
|
||||
public string openSpaceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 单聊酷应用场域投放参数。
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? imSingleOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 群聊投放参数。
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? imGroupOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IM机器人单聊投放参数。
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? imRobotOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 吊顶投放参数。
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? topOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 协作投放参数。
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? coFeedOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 文档投放参数
|
||||
/// </summary>
|
||||
public DingTalkOpenDeliverModel? docOpenDeliverModel { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户userId类型:1(默认):userId模式 2:unionId模式
|
||||
/// </summary>
|
||||
public int UserIdType { get; set; }
|
||||
}
|
||||
|
||||
public class DingTalk_CardData
|
||||
{
|
||||
public DingTalk_CardParamMap cardParamMap { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 卡片模板内容替换参数
|
||||
/// </summary>
|
||||
public class DingTalk_CardParamMap
|
||||
{
|
||||
/// <summary>
|
||||
/// 片模板内容替换参数
|
||||
/// </summary>
|
||||
[Newtonsoft.Json.JsonProperty("sys_full_json_obj")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("sys_full_json_obj")]
|
||||
public string sysFullJsonObj { get; set; }
|
||||
}
|
||||
|
||||
public class PrivateData
|
||||
{
|
||||
public Dictionary<string, DingTalk_CardParamMap> key { get; set; } = new Dictionary<string, DingTalk_CardParamMap>();
|
||||
}
|
||||
|
||||
public class OpenDynamicDataConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 动态数据源配置列表。
|
||||
/// </summary>
|
||||
public List<DynamicDataSourceConfig>? dynamicDataSourceConfigs { get; set; }
|
||||
}
|
||||
|
||||
public class DynamicDataSourceConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据源的唯一 ID, 调用方指定。
|
||||
/// </summary>
|
||||
public string? dynamicDataSourceId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 回调数据源时回传的固定参数。 示例
|
||||
/// </summary>
|
||||
public Dictionary<string, string>? constParams { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据源拉取配置。
|
||||
/// </summary>
|
||||
public PullConfig? pullConfig { get; set; }
|
||||
}
|
||||
|
||||
public class PullConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 拉取策略,可选值:NONE:不拉取,无动态数据 INTERVAL:间隔拉取ONCE:只拉取一次
|
||||
/// </summary>
|
||||
public string pullStrategy { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 拉取的间隔时间。
|
||||
/// </summary>
|
||||
public int interval { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 拉取的间隔时间的单位, 可选值:SECONDS:秒 MINUTES:分钟 HOURS:小时 DAYS:天
|
||||
/// </summary>
|
||||
public string timeUnit { get; set; }
|
||||
}
|
||||
|
||||
public class OpenSpaceModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 吊顶场域属性,通过增加spaeType使卡片支持吊顶场域。
|
||||
/// </summary>
|
||||
public string? spaceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片标题。
|
||||
/// </summary>
|
||||
public string? title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 酷应用编码。
|
||||
/// </summary>
|
||||
public string? coolAppCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否支持转发, 默认false。
|
||||
/// </summary>
|
||||
public bool? supportForward { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持国际化的LastMessage。
|
||||
/// </summary>
|
||||
public Dictionary<string, string>? lastMessageI18n { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 支持卡片消息可被搜索字段。
|
||||
/// </summary>
|
||||
public SearchSupport? searchSupport { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 通知信息。
|
||||
/// </summary>
|
||||
public Notification? notification { get; set; }
|
||||
}
|
||||
|
||||
public class SearchSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// 类型的icon,供搜索展示使用。
|
||||
/// </summary>
|
||||
public string searchIcon { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 卡片类型名。
|
||||
/// </summary>
|
||||
public string searchTypeName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 供消息展示与搜索的字段。
|
||||
/// </summary>
|
||||
public string searchDesc { get; set; }
|
||||
}
|
||||
|
||||
public class Notification
|
||||
{
|
||||
/// <summary>
|
||||
/// 供消息展示与搜索的字段。
|
||||
/// </summary>
|
||||
public string alertContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否关闭推送通知:true:关闭 false:不关闭
|
||||
/// </summary>
|
||||
public bool notificationOff { get; set; }
|
||||
}
|
||||
|
||||
public class DingTalkOpenDeliverModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于发送卡片的机器人编码。
|
||||
/// </summary>
|
||||
public string robotCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息@人。格式:{"key":"value"}。key:用户的userId value:用户名
|
||||
/// </summary>
|
||||
public Dictionary<string, string> atUserIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 指定接收人的userId。
|
||||
/// </summary>
|
||||
public List<string> recipients { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 扩展字段,示例如下:{"key":"value"}
|
||||
/// </summary>
|
||||
public Dictionary<string, string> extension { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// IM机器人单聊若未设置其他投放属性,需设置spaeType为IM_ROBOT。
|
||||
/// </summary>
|
||||
public string spaceType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期时间戳。若使用topOpenDeliverModel对象,则该字段必填。
|
||||
/// </summary>
|
||||
public long expiredTimeMillis { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可以查看该吊顶卡片的userId。
|
||||
/// </summary>
|
||||
public List<string> userIds { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可以查看该吊顶卡片的设备:android|ios|win|mac。
|
||||
/// </summary>
|
||||
public List<string> platforms { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 业务标识。
|
||||
/// </summary>
|
||||
public string bizTag { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 协作场域下的排序时间。
|
||||
/// </summary>
|
||||
public long gmtTimeLine { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 员工userId信息
|
||||
/// </summary>
|
||||
public string userId { get; set; }
|
||||
}
|
||||
@ -0,0 +1,32 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkCreateAndDeliverOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 返回结果
|
||||
/// </summary>
|
||||
public bool success { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建卡片结果
|
||||
/// </summary>
|
||||
public DingTalkCreateAndDeliverResult result { get; set; }
|
||||
|
||||
public string code { get; set; }
|
||||
public string requestid { get; set; }
|
||||
public string message { get; set; }
|
||||
}
|
||||
|
||||
public class DingTalkCreateAndDeliverResult
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于业务方后续查看已读列表的查询key
|
||||
/// </summary>
|
||||
public string processQueryKey { get; set; }
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkRoleListOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否还有更多数据
|
||||
/// </summary>
|
||||
[JsonProperty("hasMore")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("hasMore")]
|
||||
public bool hasMore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色组列表
|
||||
/// </summary>
|
||||
[JsonProperty("list")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("list")]
|
||||
public List<DingTalkRoleListResult> list { get; set; }
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkRoleListResult
|
||||
{
|
||||
[JsonProperty("groupId")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("groupId")]
|
||||
public long groupId { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("name")]
|
||||
public string name { get; set; }
|
||||
|
||||
[JsonProperty("roles")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("roles")]
|
||||
public List<DingTalkRoleResult> roles { get; set; }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkRoleResult
|
||||
{
|
||||
[JsonProperty("id")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("id")]
|
||||
public long id { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("name")]
|
||||
public string name { get; set; }
|
||||
}
|
||||
@ -0,0 +1,24 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkRoleSimplelistOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 是否还有更多数据
|
||||
/// </summary>
|
||||
[JsonProperty("hasMore")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("hasMore")]
|
||||
public bool hasMore { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色组列表
|
||||
/// </summary>
|
||||
[JsonProperty("list")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("list")]
|
||||
public List<DingTalkRoleSimplelistResult> list { get; set; }
|
||||
}
|
||||
@ -0,0 +1,18 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class DingTalkRoleSimplelistResult
|
||||
{
|
||||
[JsonProperty("userid")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("userid")]
|
||||
public string userid { get; set; }
|
||||
|
||||
[JsonProperty("name")]
|
||||
[System.Text.Json.Serialization.JsonPropertyName("name")]
|
||||
public string name { get; set; }
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class GetDingTalkCurrentRoleListInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值。
|
||||
/// </summary>
|
||||
public int? Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分页大小,最大50。
|
||||
/// </summary>
|
||||
public int? Size { get; set; }
|
||||
}
|
||||
@ -0,0 +1,25 @@
|
||||
// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
|
||||
//
|
||||
// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
|
||||
//
|
||||
// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
|
||||
|
||||
namespace Admin.NET.Plugin.DingTalk;
|
||||
|
||||
public class GetDingTalkCurrentRoleSimplelistInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色id
|
||||
/// </summary>
|
||||
public long role_id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值。
|
||||
/// </summary>
|
||||
public int? Offset { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 分页大小,最大50。
|
||||
/// </summary>
|
||||
public int? Size { get; set; }
|
||||
}
|
||||
@ -25,7 +25,7 @@ public interface IDingTalkApi : IHttpDeclarative
|
||||
/// <returns></returns>
|
||||
[Post("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob")]
|
||||
Task<DingTalkBaseResponse<GetDingTalkCurrentEmployeesListOutput>> GetDingTalkCurrentEmployeesList([Query] string access_token,
|
||||
[Body, Required] GetDingTalkCurrentEmployeesListInput input);
|
||||
[Body(ContentType = "application/json", UseStringContent = true), Required] GetDingTalkCurrentEmployeesListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取员工花名册字段信息
|
||||
@ -35,7 +35,7 @@ public interface IDingTalkApi : IHttpDeclarative
|
||||
/// <returns></returns>
|
||||
[Post("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/v2/list")]
|
||||
Task<DingTalkBaseResponse<List<DingTalkEmpRosterFieldVo>>> GetDingTalkCurrentEmployeesRosterList([Query] string access_token,
|
||||
[Body, Required] GetDingTalkCurrentEmployeesRosterListInput input);
|
||||
[Body(ContentType = "application/json", UseStringContent = true), Required] GetDingTalkCurrentEmployeesRosterListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 发送钉钉互动卡片
|
||||
@ -43,10 +43,15 @@ public interface IDingTalkApi : IHttpDeclarative
|
||||
/// <param name="token">调用该接口的访问凭证</param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// 钉钉官方文档显示接口不再支持新应用接入, 已接入的应用可继续调用
|
||||
/// 推荐更新接口https://open.dingtalk.com/document/orgapp/create-and-deliver-cards?spm=ding_open_doc.document.0.0.67fc50988Pf0mc
|
||||
/// </remarks>
|
||||
[Post("https://api.dingtalk.com/v1.0/im/interactiveCards/send")]
|
||||
[Obsolete]
|
||||
Task<DingTalkSendInteractiveCardsOutput> DingTalkSendInteractiveCards(
|
||||
[Header("x-acs-dingtalk-access-token")] string token,
|
||||
[Body] DingTalkSendInteractiveCardsInput input);
|
||||
[Body(ContentType = "application/json", UseStringContent = true)] DingTalkSendInteractiveCardsInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取钉钉卡片消息读取状态
|
||||
@ -58,4 +63,35 @@ public interface IDingTalkApi : IHttpDeclarative
|
||||
Task<GetDingTalkCardMessageReadStatusOutput> GetDingTalkCardMessageReadStatus(
|
||||
[Header("x-acs-dingtalk-access-token")] string token,
|
||||
[Query] GetDingTalkCardMessageReadStatusInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取角色列表
|
||||
/// </summary>
|
||||
/// <param name="access_token">调用该接口的应用凭证</param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[Post("https://oapi.dingtalk.com/topapi/role/list")]
|
||||
Task<DingTalkBaseResponse<DingTalkRoleListOutput>> GetDingTalkRoleList([Query] string access_token,
|
||||
[Body(ContentType = "application/json", UseStringContent = true), Required] GetDingTalkCurrentRoleListInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 获取指定角色的员工列表
|
||||
/// </summary>
|
||||
/// <param name="access_token">调用该接口的应用凭证</param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[Post("https://oapi.dingtalk.com/topapi/role/simplelist")]
|
||||
Task<DingTalkBaseResponse<DingTalkRoleSimplelistOutput>> GetDingTalkRoleSimplelist([Query] string access_token,
|
||||
[Body(ContentType = "application/json", UseStringContent = true), Required] GetDingTalkCurrentRoleSimplelistInput input);
|
||||
|
||||
/// <summary>
|
||||
/// 创建并投放钉钉消息卡片
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[Post("https://api.dingtalk.com/v1.0/card/instances/createAndDeliver")]
|
||||
Task<DingTalkCreateAndDeliverOutput> DingTalkCreateAndDeliver(
|
||||
[Header("x-acs-dingtalk-access-token")] string token,
|
||||
[Body(ContentType = "application/json", UseStringContent = true)] DingTalkCreateAndDeliverInput input);
|
||||
}
|
||||
@ -89,6 +89,7 @@
|
||||
23. ES 日志:通过 NEST 组件实现日志存取到 Elasticsearch 日志系统。
|
||||
24. 开放授权:支持OAuth 2.0开放标准授权登录,比如微信。
|
||||
25. APIJSON:适配腾讯APIJSON协议,支持后端0代码,[使用文档](https://github.com/liaozb/APIJSON.NET)。
|
||||
26. 数据库视图:基于SqlSugar生成查询SQL + 表实体维护视图,可维护性更强。
|
||||
|
||||
## 🎀捐赠支持
|
||||
```
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
"name": "admin.net.pro",
|
||||
"type": "module",
|
||||
"version": "2.4.33",
|
||||
"lastBuildTime": "2025.05.28",
|
||||
"lastBuildTime": "2025.05.29",
|
||||
"description": "Admin.NET 站在巨人肩膀上的 .NET 通用权限开发框架",
|
||||
"author": "zuohuaijun",
|
||||
"license": "MIT",
|
||||
@ -68,7 +68,7 @@
|
||||
"splitpanes": "^4.0.4",
|
||||
"vcrontab-3": "^3.3.22",
|
||||
"vform3-builds": "^3.0.10",
|
||||
"vue": "^3.5.15",
|
||||
"vue": "^3.5.16",
|
||||
"vue-clipboard3": "^2.0.0",
|
||||
"vue-demi": "0.14.10",
|
||||
"vue-draggable-plus": "^0.6.0",
|
||||
@ -89,14 +89,14 @@
|
||||
"@iconify/vue": "^5.0.0",
|
||||
"@plugin-web-update-notification/vite": "^2.0.0",
|
||||
"@types/lodash-es": "^4.17.12",
|
||||
"@types/node": "^22.15.23",
|
||||
"@types/node": "^22.15.24",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/sortablejs": "^1.15.8",
|
||||
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
||||
"@typescript-eslint/parser": "^8.33.0",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vitejs/plugin-vue-jsx": "^4.2.0",
|
||||
"@vue/compiler-sfc": "^3.5.15",
|
||||
"@vue/compiler-sfc": "^3.5.16",
|
||||
"code-inspector-plugin": "^0.20.11",
|
||||
"eslint": "^9.27.0",
|
||||
"eslint-plugin-vue": "^10.1.0",
|
||||
@ -104,7 +104,7 @@
|
||||
"less": "^4.3.0",
|
||||
"openapi-ts-request": "^1.5.0",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-visualizer": "^6.0.0",
|
||||
"rollup-plugin-visualizer": "^6.0.1",
|
||||
"sass": "^1.89.0",
|
||||
"terser": "^5.40.0",
|
||||
"typescript": "^5.8.3",
|
||||
|
||||
@ -199,7 +199,7 @@ const resetQuery = async () => {
|
||||
// 打开新增页面
|
||||
const handleAdd = () => {
|
||||
state.title = '添加租户';
|
||||
editTenantRef.value?.openDialog({ tenantType: 0, orderNo: 100 });
|
||||
editTenantRef.value?.openDialog({ tenantType: 0, orderNo: 100, host: '' });
|
||||
};
|
||||
|
||||
// 打开编辑页面
|
||||
|
||||
Loading…
Reference in New Issue
Block a user