Browse Source

add custom business module: tui-juhe push service.

pull/697/head
cKey 3 years ago
parent
commit
3034700eab
  1. 38
      aspnet-core/LINGYUN.MicroService.Common.sln
  2. 3
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/FodyWeavers.xml
  3. 30
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/FodyWeavers.xsd
  4. 16
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN.Abp.Notifications.TuiJuhe.csproj
  5. 57
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs
  6. 18
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheModule.cs
  7. 115
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/TuiJuhe/TuiJuheNotificationPublishProvider.cs
  8. 15
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/README.md
  9. 3
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/FodyWeavers.xml
  10. 30
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/FodyWeavers.xsd
  11. 30
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN.Abp.TuiJuhe.SettingManagement.csproj
  12. 48
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/AbpTuiJuheSettingManagementModule.cs
  13. 8
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/ITuiJuheSettingAppService.cs
  14. 7
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/Localization/Resources/en.json
  15. 7
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/Localization/Resources/zh-Hans.json
  16. 61
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingAppService.cs
  17. 36
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingController.cs
  18. 24
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingPermissionDefinitionProvider.cs
  19. 9
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingPermissionNames.cs
  20. 3
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/FodyWeavers.xml
  21. 30
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/FodyWeavers.xsd
  22. 29
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN.Abp.TuiJuhe.csproj
  23. 42
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/AbpTuiJuheModule.cs
  24. 51
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Features/TuiJuheFeatureDefinitionProvider.cs
  25. 28
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Features/TuiJuheFeatureNames.cs
  26. 20
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/Resources/en.json
  27. 20
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/Resources/zh-Hans.json
  28. 8
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/TuiJuheResource.cs
  29. 15
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/ITuiJuheMessageSender.cs
  30. 9
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/MessageContentType.cs
  31. 38
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/MessageHttpClientExtensions.cs
  32. 76
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/TuiJuheMessageSender.cs
  33. 30
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Settings/TuiJuheSettingDefinitionProvider.cs
  34. 13
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Settings/TuiJuheSettingNames.cs
  35. 9
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Token/ITuiJuheTokenProvider.cs
  36. 23
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Token/TuiJuheTokenProvider.cs
  37. 15
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/TuiJuheRemoteCallException.cs
  38. 64
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/TuiJuheResult.cs
  39. 19
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/Microsoft/Extensions/DependencyInjection/IServiceCollectionExtensions.cs
  40. 31
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/README.md
  41. 10
      aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/System/Net/Http/IHttpClientFactoryExtensions.cs
  42. 2
      aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Messages/WxPusherMessageProvider.cs
  43. 2
      aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Messages/WxPusherMessageSender.cs
  44. 4
      aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/QrCode/WxPusherQrCodeProvider.cs
  45. 6
      aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/WxPusherUserProvider.cs
  46. 2
      aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/System/Net/Http/IHttpClientFactoryExtensions.cs
  47. 7
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider.cs
  48. 2
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider_Tests.cs
  49. 4
      aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs
  50. 7
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheTestBase.cs
  51. 11
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheTestModule.cs
  52. 94
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/NotificationSenderTests.cs
  53. 27
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/NotificationsWxPusherTestsDefinitionProvider.cs
  54. 20
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests.csproj
  55. 4
      aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Usings.cs
  56. 20
      aspnet-core/tests/LINGYUN.Abp.PushPlus.Tests/LINGYUN/Abp/PushPlus/AbpPushPlusTestModule.cs
  57. 18
      aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN.Abp.TuiJuhe.Tests.csproj
  58. 7
      aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/AbpTuiJuheTestBase.cs
  59. 37
      aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/AbpTuiJuheTestModule.cs
  60. 100
      aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/Messages/TuiJuheMessageSenderTests.cs
  61. 3
      aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/Usings.cs
  62. 13
      aspnet-core/tests/LINGYUN.Abp.WxPusher.Tests/LINGYUN/Abp/WxPusher/AbpWxPusherTestModule.cs

38
aspnet-core/LINGYUN.MicroService.Common.sln

@ -272,6 +272,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Notifications.C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Http.Client.Wrapper", "modules\common\LINGYUN.Abp.Http.Client.Wrapper\LINGYUN.Abp.Http.Client.Wrapper.csproj", "{2C5C57FB-70F5-4C20-92FC-39ACD260CEE3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tui-juhe", "tui-juhe", "{A1C75C3E-67D1-4BCE-89BF-44A735909BD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TuiJuhe", "modules\tui-juhe\LINGYUN.Abp.TuiJuhe\LINGYUN.Abp.TuiJuhe.csproj", "{60143C9C-E539-498A-9DBE-B95E6A8301A5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.TuiJuhe", "modules\tui-juhe\LINGYUN.Abp.Notifications.TuiJuhe\LINGYUN.Abp.Notifications.TuiJuhe.csproj", "{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Notifications.TuiJuhe.Tests", "tests\LINGYUN.Abp.Notifications.TuiJuhe.Tests\LINGYUN.Abp.Notifications.TuiJuhe.Tests.csproj", "{641DF0BA-0E79-441D-B328-FDA288A35CDE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TuiJuhe.Tests", "tests\LINGYUN.Abp.TuiJuhe.Tests\LINGYUN.Abp.TuiJuhe.Tests.csproj", "{2020EA8D-F276-498D-92D1-94D1E25F8E1A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TuiJuhe.SettingManagement", "modules\tui-juhe\LINGYUN.Abp.TuiJuhe.SettingManagement\LINGYUN.Abp.TuiJuhe.SettingManagement.csproj", "{2A3DF8B2-4760-41C4-9337-44FEE29B17CD}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -702,6 +714,26 @@ Global
{2C5C57FB-70F5-4C20-92FC-39ACD260CEE3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2C5C57FB-70F5-4C20-92FC-39ACD260CEE3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2C5C57FB-70F5-4C20-92FC-39ACD260CEE3}.Release|Any CPU.Build.0 = Release|Any CPU
{60143C9C-E539-498A-9DBE-B95E6A8301A5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{60143C9C-E539-498A-9DBE-B95E6A8301A5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{60143C9C-E539-498A-9DBE-B95E6A8301A5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{60143C9C-E539-498A-9DBE-B95E6A8301A5}.Release|Any CPU.Build.0 = Release|Any CPU
{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F}.Release|Any CPU.Build.0 = Release|Any CPU
{641DF0BA-0E79-441D-B328-FDA288A35CDE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{641DF0BA-0E79-441D-B328-FDA288A35CDE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{641DF0BA-0E79-441D-B328-FDA288A35CDE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{641DF0BA-0E79-441D-B328-FDA288A35CDE}.Release|Any CPU.Build.0 = Release|Any CPU
{2020EA8D-F276-498D-92D1-94D1E25F8E1A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2020EA8D-F276-498D-92D1-94D1E25F8E1A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2020EA8D-F276-498D-92D1-94D1E25F8E1A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2020EA8D-F276-498D-92D1-94D1E25F8E1A}.Release|Any CPU.Build.0 = Release|Any CPU
{2A3DF8B2-4760-41C4-9337-44FEE29B17CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2A3DF8B2-4760-41C4-9337-44FEE29B17CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2A3DF8B2-4760-41C4-9337-44FEE29B17CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2A3DF8B2-4760-41C4-9337-44FEE29B17CD}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -837,6 +869,12 @@ Global
{B78E53AC-6BB8-402D-90CF-BEF1BD9558EB} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{AA039B4E-CE12-43AC-8340-3D52463E971E} = {B91F26C5-B148-4094-B5F1-71E5F945DBED}
{2C5C57FB-70F5-4C20-92FC-39ACD260CEE3} = {086BE5BE-8594-4DA7-8819-935FEF76DABD}
{A1C75C3E-67D1-4BCE-89BF-44A735909BD5} = {02EA4E78-5891-43BC-944F-3E52FEE032E4}
{60143C9C-E539-498A-9DBE-B95E6A8301A5} = {A1C75C3E-67D1-4BCE-89BF-44A735909BD5}
{C55D9BA0-4AFD-4D18-958B-B53FD3F2FF4F} = {A1C75C3E-67D1-4BCE-89BF-44A735909BD5}
{641DF0BA-0E79-441D-B328-FDA288A35CDE} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{2020EA8D-F276-498D-92D1-94D1E25F8E1A} = {B86C21A4-73B7-471E-B73A-B4B905EC9435}
{2A3DF8B2-4760-41C4-9337-44FEE29B17CD} = {A1C75C3E-67D1-4BCE-89BF-44A735909BD5}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {06C707C6-02C0-411A-AD3B-2D0E13787CB8}

3
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

16
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN.Abp.Notifications.TuiJuhe.csproj

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\LINGYUN.Abp.Notifications\LINGYUN.Abp.Notifications.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TuiJuhe\LINGYUN.Abp.TuiJuhe.csproj" />
</ItemGroup>
</Project>

57
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/NotificationDefinitionExtensions.cs

@ -0,0 +1,57 @@
using LINGYUN.Abp.TuiJuhe.Messages;
namespace LINGYUN.Abp.Notifications;
public static class NotificationDefinitionExtensions
{
private const string Prefix = "tui-juhe:";
private const string ServiceIdKey = Prefix + "serviceId";
/// <summary>
/// 获取消息内容类型
/// </summary>
/// <param name="notification"></param>
/// <param name="defaultContentType"></param>
/// <returns></returns>
public static MessageContentType GetContentTypeOrDefault(
this NotificationDefinition notification,
MessageContentType defaultContentType = MessageContentType.Text)
{
return notification.ContentType switch
{
NotificationContentType.Text => MessageContentType.Text,
NotificationContentType.Html => MessageContentType.Html,
NotificationContentType.Markdown => MessageContentType.Markdown,
NotificationContentType.Json => MessageContentType.Text,
_ => defaultContentType,
};
}
/// <summary>
/// 指定服务编号
/// </summary>
/// <param name="notification">群组编码</param>
/// <param name="serviceId">服务编号,在服务创建后自动生成ServiceID,是服务的唯一标识,可在每个服务的详情页中查看</param>
/// <returns>
/// <see cref="NotificationDefinition"/>
/// </returns>
public static NotificationDefinition WithServiceId(
this NotificationDefinition notification,
string serviceId)
{
return notification.WithProperty(ServiceIdKey, serviceId);
}
/// <summary>
/// 获取服务编号
/// </summary>
/// <param name="notification"></param>
public static string GetServiceIdOrNull(
this NotificationDefinition notification)
{
if (notification.Properties.TryGetValue(ServiceIdKey, out var serviceIdDefine))
{
return serviceIdDefine.ToString();
}
return null;
}
}

18
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheModule.cs

@ -0,0 +1,18 @@
using LINGYUN.Abp.TuiJuhe;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
[DependsOn(
typeof(AbpNotificationsModule),
typeof(AbpTuiJuheModule))]
public class AbpNotificationsTuiJuheModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpNotificationsPublishOptions>(options =>
{
options.PublishProviders.Add<TuiJuheNotificationPublishProvider>();
});
}
}

115
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/LINGYUN/Abp/Notifications/TuiJuhe/TuiJuheNotificationPublishProvider.cs

@ -0,0 +1,115 @@
using LINGYUN.Abp.RealTime.Localization;
using LINGYUN.Abp.TuiJuhe.Features;
using LINGYUN.Abp.TuiJuhe.Messages;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.Features;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
public class TuiJuheNotificationPublishProvider : NotificationPublishProvider
{
public const string ProviderName = "TuiJuhe";
public override string Name => ProviderName;
protected IFeatureChecker FeatureChecker { get; }
protected ITuiJuheMessageSender TuiJuheMessageSender { get; }
protected IStringLocalizerFactory LocalizerFactory { get; }
protected AbpLocalizationOptions LocalizationOptions { get; }
protected INotificationDefinitionManager NotificationDefinitionManager { get; }
public TuiJuheNotificationPublishProvider(
IFeatureChecker featureChecker,
ITuiJuheMessageSender tuiJuheMessageSender,
IStringLocalizerFactory localizerFactory,
IOptions<AbpLocalizationOptions> localizationOptions,
INotificationDefinitionManager notificationDefinitionManager)
{
FeatureChecker = featureChecker;
TuiJuheMessageSender = tuiJuheMessageSender;
LocalizerFactory = localizerFactory;
LocalizationOptions = localizationOptions.Value;
NotificationDefinitionManager = notificationDefinitionManager;
}
protected async override Task<bool> CanPublishAsync(NotificationInfo notification, CancellationToken cancellationToken = default)
{
if (!await FeatureChecker.IsEnabledAsync(TuiJuheFeatureNames.Message.Enable))
{
Logger.LogWarning(
"{0} cannot push messages because the feature {1} is not enabled",
Name,
TuiJuheFeatureNames.Message.Enable);
return false;
}
return true;
}
protected async override Task PublishAsync(
NotificationInfo notification,
IEnumerable<UserIdentifier> identifiers,
CancellationToken cancellationToken = default)
{
var notificationDefine = await NotificationDefinitionManager.GetOrNullAsync(notification.Name);
var contentType = notificationDefine?.GetContentTypeOrDefault(MessageContentType.Text)
?? MessageContentType.Text;
var serviceId = notificationDefine?.GetServiceIdOrNull();
if (serviceId.IsNullOrWhiteSpace())
{
Logger.LogWarning(
"{0} cannot push messages because the notification {1} service id is not specified",
Name,
notification.Name);
return;
}
if (!notification.Data.NeedLocalizer())
{
var title = notification.Data.TryGetData("title").ToString();
var message = notification.Data.TryGetData("message").ToString();
await TuiJuheMessageSender.SendAsync(
title: title,
content: message,
serviceId: serviceId,
contentType: contentType,
cancellationToken: cancellationToken);
}
else
{
var titleInfo = notification.Data.TryGetData("title").As<LocalizableStringInfo>();
var titleResource = GetResource(titleInfo.ResourceName);
var title = LocalizerFactory.Create(titleResource.ResourceType)[titleInfo.Name, titleInfo.Values].Value;
var messageInfo = notification.Data.TryGetData("message").As<LocalizableStringInfo>();
var messageResource = GetResource(messageInfo.ResourceName);
var message = LocalizerFactory.Create(messageResource.ResourceType)[messageInfo.Name, messageInfo.Values].Value;
await TuiJuheMessageSender.SendAsync(
title: title,
content: message,
serviceId: serviceId,
contentType: contentType,
cancellationToken: cancellationToken);
}
}
private LocalizationResource GetResource(string resourceName)
{
return LocalizationOptions.Resources.Values
.First(x => x.ResourceName.Equals(resourceName));
}
}

15
aspnet-core/modules/tui-juhe/LINGYUN.Abp.Notifications.TuiJuhe/README.md

@ -0,0 +1,15 @@
# LINGYUN.Abp.Notifications.TuiJuhe
通知模块的TuiJuhe实现
使应用可通过TuiJuhe发布实时通知
## 模块引用
```csharp
[DependsOn(typeof(AbpNotificationsTuiJuheModule))]
public class YouProjectModule : AbpModule
{
// other
}
```

3
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

30
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN.Abp.TuiJuhe.SettingManagement.csproj

@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\en.json" />
<None Remove="LINGYUN\Abp\TuiJuhe\SettingManagement\Localization\Resources\zh-Hans.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.AspNetCore.Mvc" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.SettingManagement.Domain" Version="$(VoloAbpPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\settings\LINGYUN.Abp.SettingManagement.Application.Contracts\LINGYUN.Abp.SettingManagement.Application.Contracts.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TuiJuhe\LINGYUN.Abp.TuiJuhe.csproj" />
</ItemGroup>
</Project>

48
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/AbpTuiJuheSettingManagementModule.cs

@ -0,0 +1,48 @@
using LINGYUN.Abp.TuiJuhe.Localization;
using Localization.Resources.AbpUi;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
[DependsOn(
typeof(AbpTuiJuheModule),
typeof(AbpAspNetCoreMvcModule))]
public class AbpWxPusherSettingManagementModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IMvcBuilder>(mvcBuilder =>
{
mvcBuilder.AddApplicationPartIfNotExists(typeof(AbpWxPusherSettingManagementModule).Assembly);
});
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpWxPusherSettingManagementModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<TuiJuheResource>()
.AddVirtualJson("/LINGYUN/Abp/TuiJuhe/SettingManagement/Localization/Resources");
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<TuiJuheResource>()
.AddBaseTypes(
typeof(AbpUiResource)
);
});
}
}
}

8
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/ITuiJuheSettingAppService.cs

@ -0,0 +1,8 @@
using LINGYUN.Abp.SettingManagement;
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
public interface ITuiJuheSettingAppService : IReadonlySettingAppService
{
}
}

7
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/Localization/Resources/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"Permission:TuiJuhe": "TuiJuhe",
"Permission:ManageSetting": "Manage Setting"
}
}

7
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/Localization/Resources/zh-Hans.json

@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"Permission:TuiJuhe": "聚合云推",
"Permission:ManageSetting": "管理设置"
}
}

61
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingAppService.cs

@ -0,0 +1,61 @@
using LINGYUN.Abp.SettingManagement;
using LINGYUN.Abp.TuiJuhe.Localization;
using LINGYUN.Abp.TuiJuhe.Settings;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.MultiTenancy;
using Volo.Abp.SettingManagement;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
public class TuiJuheSettingAppService : ApplicationService, ITuiJuheSettingAppService
{
protected ISettingManager SettingManager { get; }
protected IPermissionChecker PermissionChecker { get; }
protected ISettingDefinitionManager SettingDefinitionManager { get; }
public TuiJuheSettingAppService(
ISettingManager settingManager,
IPermissionChecker permissionChecker,
ISettingDefinitionManager settingDefinitionManager)
{
SettingManager = settingManager;
PermissionChecker = permissionChecker;
SettingDefinitionManager = settingDefinitionManager;
LocalizationResource = typeof(TuiJuheResource);
}
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await GetAllForProviderAsync(TenantSettingValueProvider.ProviderName, CurrentTenant.GetId().ToString());
}
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await GetAllForProviderAsync(GlobalSettingValueProvider.ProviderName, null);
}
protected async virtual Task<SettingGroupResult> GetAllForProviderAsync(string providerName, string providerKey)
{
var settingGroups = new SettingGroupResult();
var wxPusherSettingGroup = new SettingGroupDto(L["DisplayName:TuiJuhe"], L["Description:TuiJuhe"]);
if (await PermissionChecker.IsGrantedAsync(TuiJuheSettingPermissionNames.ManageSetting))
{
var securitySetting = wxPusherSettingGroup.AddSetting(L["Security"], L["Security"]);
securitySetting.AddDetail(
SettingDefinitionManager.Get(TuiJuheSettingNames.Security.Token),
StringLocalizerFactory,
await SettingManager.GetOrNullAsync(TuiJuheSettingNames.Security.Token, providerName, providerKey),
ValueType.String,
providerName);
}
settingGroups.AddGroup(wxPusherSettingGroup);
return settingGroups;
}
}
}

36
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingController.cs

@ -0,0 +1,36 @@
using LINGYUN.Abp.SettingManagement;
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.AspNetCore.Mvc;
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
[RemoteService(Name = AbpSettingManagementRemoteServiceConsts.RemoteServiceName)]
[Area(AbpSettingManagementRemoteServiceConsts.ModuleName)]
[Route($"api/{AbpSettingManagementRemoteServiceConsts.ModuleName}/tui-juhe")]
public class TuiJuheSettingController : AbpController, ITuiJuheSettingAppService
{
protected ITuiJuheSettingAppService Service { get; }
public TuiJuheSettingController(
ITuiJuheSettingAppService service)
{
Service = service;
}
[HttpGet]
[Route("by-current-tenant")]
public async virtual Task<SettingGroupResult> GetAllForCurrentTenantAsync()
{
return await Service.GetAllForCurrentTenantAsync();
}
[HttpGet]
[Route("by-global")]
public async virtual Task<SettingGroupResult> GetAllForGlobalAsync()
{
return await Service.GetAllForGlobalAsync();
}
}
}

24
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingPermissionDefinitionProvider.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.TuiJuhe.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
public class WxPusherSettingPermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var tuiJuheGroup = context.AddGroup(
TuiJuheSettingPermissionNames.GroupName,
L("Permission:TuiJuhe"));
tuiJuheGroup.AddPermission(
TuiJuheSettingPermissionNames.ManageSetting, L("Permission:ManageSetting"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<TuiJuheResource>(name);
}
}
}

9
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe.SettingManagement/LINGYUN/Abp/TuiJuhe/SettingManagement/TuiJuheSettingPermissionNames.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.TuiJuhe.SettingManagement
{
public class TuiJuheSettingPermissionNames
{
public const string GroupName = "Abp.TuiJuhe";
public const string ManageSetting = GroupName + ".ManageSetting";
}
}

3
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/FodyWeavers.xml

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ConfigureAwait ContinueOnCapturedContext="false" />
</Weavers>

30
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/FodyWeavers.xsd

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="ConfigureAwait" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="ContinueOnCapturedContext" type="xs:boolean" />
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

29
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN.Abp.TuiJuhe.csproj

@ -0,0 +1,29 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\configureawait.props" />
<Import Project="..\..\..\common.props" />
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<EmbeddedResource Include="LINGYUN\Abp\TuiJuhe\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\TuiJuhe\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Volo.Abp.Caching" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Volo.Abp.Json" Version="$(VoloAbpPackageVersion)" />
<PackageReference Include="Microsoft.Extensions.Http" Version="$(MicrosoftPackageVersion)" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\common\LINGYUN.Abp.Features.LimitValidation\LINGYUN.Abp.Features.LimitValidation.csproj" />
</ItemGroup>
</Project>

42
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/AbpTuiJuheModule.cs

@ -0,0 +1,42 @@
using LINGYUN.Abp.Features.LimitValidation;
using LINGYUN.Abp.TuiJuhe.Localization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Caching;
using Volo.Abp.Json;
using Volo.Abp.Json.SystemTextJson;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Settings;
using Volo.Abp.VirtualFileSystem;
namespace LINGYUN.Abp.TuiJuhe;
[DependsOn(
typeof(AbpJsonModule),
typeof(AbpSettingsModule),
typeof(AbpCachingModule),
typeof(AbpFeaturesLimitValidationModule))]
public class AbpTuiJuheModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
context.Services.AddTuiJuheClient();
Configure<AbpSystemTextJsonSerializerOptions>(options =>
{
});
Configure<AbpVirtualFileSystemOptions>(options =>
{
options.FileSets.AddEmbedded<AbpTuiJuheModule>();
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Add<TuiJuheResource>()
.AddVirtualJson("/LINGYUN/Abp/TuiJuhe/Localization/Resources");
});
}
}

51
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Features/TuiJuheFeatureDefinitionProvider.cs

@ -0,0 +1,51 @@
using LINGYUN.Abp.TuiJuhe.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;
namespace LINGYUN.Abp.TuiJuhe.Features;
public class TuiJuheFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
var group = context.AddGroup(
name: TuiJuheFeatureNames.GroupName,
displayName: L("Features:TuiJuhe"));
group.AddFeature(
name: TuiJuheFeatureNames.Enable,
defaultValue: "false",
displayName: L("Features:TuiJuheEnable"),
description: L("Features:TuiJuheEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
var message = group.AddFeature(
name: TuiJuheFeatureNames.Message.GroupName,
displayName: L("Features:Message"),
description: L("Features:Message"));
message.CreateChild(
name: TuiJuheFeatureNames.Message.Enable,
defaultValue: "false",
displayName: L("Features:MessageEnable"),
description: L("Features:MessageEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
message.CreateChild(
name: TuiJuheFeatureNames.Message.SendLimit,
defaultValue: "50",
displayName: L("Features:Message.SendLimit"),
description: L("Features:Message.SendLimitDesc"),
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 50)));
message.CreateChild(
name: TuiJuheFeatureNames.Message.SendLimitInterval,
defaultValue: "1",
displayName: L("Features:Message.SendLimitInterval"),
description: L("Features:Message.SendLimitIntervalDesc"),
valueType: new FreeTextStringValueType(new NumericValueValidator(1, 1)));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<TuiJuheResource>(name);
}
}

28
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Features/TuiJuheFeatureNames.cs

@ -0,0 +1,28 @@
namespace LINGYUN.Abp.TuiJuhe.Features;
public static class TuiJuheFeatureNames
{
public const string GroupName = "TuiJuhe";
/// <summary>
/// 启用TuiJuhe
/// </summary>
public const string Enable = GroupName + ".Enable";
public static class Message
{
public const string GroupName = TuiJuheFeatureNames.GroupName + ".Message";
/// <summary>
/// 启用消息推送
/// </summary>
public const string Enable = GroupName + ".Enable";
/// <summary>
/// 发送次数上限
/// </summary>
public const string SendLimit = GroupName + ".SendLimit";
/// <summary>
/// 发送次数上限时长
/// </summary>
public const string SendLimitInterval = GroupName + ".SendLimitInterval";
}
}

20
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/Resources/en.json

@ -0,0 +1,20 @@
{
"culture": "en",
"texts": {
"DisplayName:TuiJuhe": "TuiJuhe",
"Description:TuiJuhe": "TuiJuhe",
"Settings:Security.Token": "Token",
"Settings:Security.TokenDesc": "The user token, (https://tui.juhe.cn/setup) in the center of the personal page views.",
"Features:TuiJuhe": "TuiJuhe push service",
"Features:TuiJuheEnable": "Enable TuiJuhe",
"Features:TuiJuheEnableDesc": "Enable to enable the application to have TuiJuhe capabilities.",
"Features:Message": "TuiJuhe message push",
"Features:MessageEnable": "Enable TuiJuhe Message Push",
"Features:MessageEnableDesc": "Enable so that apps will have the ability to be pushed notification via TuiJuhe.",
"Features:Message.SendLimit": "Amount of TuiJuhe push",
"Features:Message.SendLimitDesc": "Set to limit the amount of TuiJuhe message push.",
"Features:Message.SendLimitInterval": "TuiJuhe message limit interval",
"Features:Message.SendLimitIntervalDesc": "Set the TuiJuhe message limit period (time scale: hours). Message sending frequency (request limit) : The rate does not exceed 50 times per unit hour.",
"Security": "Security"
}
}

20
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/Resources/zh-Hans.json

@ -0,0 +1,20 @@
{
"culture": "zh-Hans",
"texts": {
"DisplayName:TuiJuhe": "聚合云推",
"Description:TuiJuhe": "聚合云推(TuiJuhe)",
"Settings:Security.Token": "用户令牌",
"Settings:Security.TokenDesc": "用户令牌,在个人中心(https://tui.juhe.cn/setup)页面查看获取.",
"Features:TuiJuhe": "聚合云推服务",
"Features:TuiJuheEnable": "启用聚合云推",
"Features:TuiJuheEnableDesc": "启用以使应用拥有聚合云推的能力.",
"Features:Message": "聚合云推消息推送",
"Features:MessageEnable": "启用聚合云推消息推送",
"Features:MessageEnableDesc": "启用以使应用将拥有通过聚合云推推送到实时消息的能力.",
"Features:Message.SendLimit": "聚合云推推送量",
"Features:Message.SendLimitDesc": "设置以限制聚合云推推送量.",
"Features:Message.SendLimitInterval": "聚合云推消息限制周期",
"Features:Message.SendLimitIntervalDesc": "设置聚合云推消息限制周期(时间刻度: 时).消息发送频率(请求限制): 单位小时内不超过50次率.",
"Security": "安全选项"
}
}

8
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Localization/TuiJuheResource.cs

@ -0,0 +1,8 @@
using Volo.Abp.Localization;
namespace LINGYUN.Abp.TuiJuhe.Localization;
[LocalizationResourceName("TuiJuhe")]
public class TuiJuheResource
{
}

15
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/ITuiJuheMessageSender.cs

@ -0,0 +1,15 @@
using JetBrains.Annotations;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.TuiJuhe.Messages;
public interface ITuiJuheMessageSender
{
Task<TuiJuheResult<object, object>> SendAsync(
[NotNull] string title,
[NotNull] string content,
[NotNull] string serviceId,
MessageContentType contentType = MessageContentType.Text,
CancellationToken cancellationToken = default);
}

9
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/MessageContentType.cs

@ -0,0 +1,9 @@
namespace LINGYUN.Abp.TuiJuhe.Messages;
public enum MessageContentType
{
Text = 0,
Html = 1,
Markdown = 2,
Json = 3
}

38
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/MessageHttpClientExtensions.cs

@ -0,0 +1,38 @@
using System.Collections.Generic;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.TuiJuhe.Messages;
internal static class MessageHttpClientExtensions
{
public async static Task<string> SendMessageAsync(
this HttpClient httpClient,
string token,
string title,
string content,
string serviceId,
string docType = "txt",
CancellationToken cancellationToken = default)
{
var requestMessage = new HttpRequestMessage(
HttpMethod.Post,
"/api/plus/pushApi");
var requestData = new Dictionary<string, string>
{
{ "token", token },
{ "title", title },
{ "content", content },
{ "service_id", serviceId },
{ "doc_type", docType ?? "txt" },
};
var formData = new FormUrlEncodedContent(requestData);
requestMessage.Content = formData;
var httpResponse = await httpClient.SendAsync(requestMessage, cancellationToken);
return await httpResponse.Content.ReadAsStringAsync();
}
}

76
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Messages/TuiJuheMessageSender.cs

@ -0,0 +1,76 @@
using JetBrains.Annotations;
using LINGYUN.Abp.Features.LimitValidation;
using LINGYUN.Abp.TuiJuhe.Features;
using LINGYUN.Abp.TuiJuhe.Token;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
using Volo.Abp.Json;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.TuiJuhe.Messages;
[RequiresFeature(TuiJuheFeatureNames.Enable)]
public class TuiJuheMessageSender : ITuiJuheMessageSender, ITransientDependency
{
protected IJsonSerializer JsonSerializer { get; }
protected ISettingProvider SettingProvider { get; }
protected IHttpClientFactory HttpClientFactory { get; }
protected ITuiJuheTokenProvider TokenProvider { get; }
public TuiJuheMessageSender(
IJsonSerializer jsonSerializer,
ISettingProvider settingProvider,
IHttpClientFactory httpClientFactory,
ITuiJuheTokenProvider tokenProvider)
{
JsonSerializer = jsonSerializer;
SettingProvider = settingProvider;
HttpClientFactory = httpClientFactory;
TokenProvider = tokenProvider;
}
// 消息发送频率(请求限制):单位小时内不超过50次
[RequiresFeature(TuiJuheFeatureNames.Message.Enable)]
[RequiresLimitFeature(
TuiJuheFeatureNames.Message.SendLimit,
TuiJuheFeatureNames.Message.SendLimitInterval,
LimitPolicy.Hours)]
public async virtual Task<TuiJuheResult<object, object>> SendAsync(
[NotNull] string title,
[NotNull] string content,
[NotNull] string serviceId,
MessageContentType contentType = MessageContentType.Text,
CancellationToken cancellationToken = default)
{
var token = await TokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetTuiJuheClient();
var resultContent = await client.SendMessageAsync(
token,
title,
content,
serviceId,
GetDocType(contentType),
cancellationToken);
var response = JsonSerializer
.Deserialize<TuiJuheResult<object, object>>(resultContent);
return response;
}
private static string GetDocType(MessageContentType contentType)
{
return contentType switch
{
MessageContentType.Html => "html",
MessageContentType.Text => "txt",
MessageContentType.Json => "json",
MessageContentType.Markdown => "markdown",
_ => "html",
};
}
}

30
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Settings/TuiJuheSettingDefinitionProvider.cs

@ -0,0 +1,30 @@
using LINGYUN.Abp.TuiJuhe.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.TuiJuhe.Settings;
public class TuiJuheSettingDefinitionProvider : SettingDefinitionProvider
{
public override void Define(ISettingDefinitionContext context)
{
context.Add(new[]
{
new SettingDefinition(
name: TuiJuheSettingNames.Security.Token,
displayName: L("Settings:Security.Token"),
description: L("Settings:Security.TokenDesc"),
isEncrypted: true)
.WithProviders(
DefaultValueSettingValueProvider.ProviderName,
ConfigurationSettingValueProvider.ProviderName,
GlobalSettingValueProvider.ProviderName,
TenantSettingValueProvider.ProviderName),
});
}
public static ILocalizableString L(string name)
{
return LocalizableString.Create<TuiJuheResource>(name);
}
}

13
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Settings/TuiJuheSettingNames.cs

@ -0,0 +1,13 @@
namespace LINGYUN.Abp.TuiJuhe.Settings;
public static class TuiJuheSettingNames
{
public const string Prefix = "TuiJuhe";
public static class Security
{
public const string Prefix = TuiJuheSettingNames.Prefix + ".Security";
public const string Token = Prefix + ".Token";
}
}

9
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Token/ITuiJuheTokenProvider.cs

@ -0,0 +1,9 @@
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.TuiJuhe.Token;
public interface ITuiJuheTokenProvider
{
Task<string> GetTokenAsync(CancellationToken cancellationToken = default);
}

23
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/Token/TuiJuheTokenProvider.cs

@ -0,0 +1,23 @@
using LINGYUN.Abp.TuiJuhe.Settings;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Settings;
namespace LINGYUN.Abp.TuiJuhe.Token;
public class TuiJuheTokenProvider : ITuiJuheTokenProvider, ITransientDependency
{
protected ISettingProvider SettingProvider { get; }
public TuiJuheTokenProvider(ISettingProvider settingProvider)
{
SettingProvider = settingProvider;
}
public async virtual Task<string> GetTokenAsync(CancellationToken cancellationToken = default)
{
return await SettingProvider.GetOrNullAsync(
TuiJuheSettingNames.Security.Token);
}
}

15
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/TuiJuheRemoteCallException.cs

@ -0,0 +1,15 @@
using Volo.Abp;
using Volo.Abp.ExceptionHandling;
namespace LINGYUN.Abp.TuiJuhe;
public class TuiJuheRemoteCallException : AbpException, IHasErrorCode
{
public string Code { get; }
public TuiJuheRemoteCallException(string code, string message)
: base($"The TuiJuhe api returns an error: {code} - {message}")
{
Code = code;
}
}

64
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/LINGYUN/Abp/TuiJuhe/TuiJuheResult.cs

@ -0,0 +1,64 @@
using Newtonsoft.Json;
using System;
namespace LINGYUN.Abp.TuiJuhe;
[Serializable]
public class TuiJuheResult<TParam, TResult>
{
/// <summary>
/// 状态码
/// </summary>
[JsonProperty("code")]
public int Code { get; set; }
/// <summary>
/// 错误消息
/// </summary>
[JsonProperty("reason")]
public string Reason { get; set; }
/// <summary>
/// 响应数据
/// </summary>
[JsonProperty("result")]
public TResult Result { get; set; }
/// <summary>
/// 响应参数
/// </summary>
[JsonProperty("params")]
public TParam Params { get; set; }
[JsonIgnore]
public bool Success => 200 == Code;
public TuiJuheResult()
{
}
public TuiJuheResult(int code, string reason)
{
Code = code;
Reason = reason;
}
public TuiJuheResult(int code, string reason, TResult result)
{
Code = code;
Reason = reason;
Result = result;
}
public TResult GetData()
{
ThrowOfFailed();
return Result;
}
public void ThrowOfFailed()
{
if (!Success)
{
throw new TuiJuheRemoteCallException(Code.ToString(), Reason);
}
}
}

19
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/Microsoft/Extensions/DependencyInjection/IServiceCollectionExtensions.cs

@ -0,0 +1,19 @@
using System;
namespace Microsoft.Extensions.DependencyInjection;
internal static class IServiceCollectionExtensions
{
public static IServiceCollection AddTuiJuheClient(
this IServiceCollection services)
{
services.AddHttpClient(
"_Abp_TuiJuhe_Client",
(httpClient) =>
{
httpClient.BaseAddress = new Uri("https://tui.juhe.cn");
});
return services;
}
}

31
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/README.md

@ -0,0 +1,31 @@
# LINGYUN.Abp.TuiJuhe
集成TuiJuhe(仅适用于特定消息与人员通知, 不支持群发)
实现TuiJuhe相关Api文档,拥有TuiJuhe开放能力
详情见TuiJuhe文档: https://tui.juhe.cn/docs
## 模块引用
```csharp
[DependsOn(typeof(AbpTuiJuheModule))]
public class YouProjectModule : AbpModule
{
// other
}
```
## Features
* TuiJuhe TuiJuhe特性分组
* TuiJuhe.Enable 全局启用TuiJuhe
* TuiJuhe.Message.Enable 全局启用TuiJuhe消息通道
* TuiJuhe.Message TuiJuhe消息推送
* TuiJuhe.Message.Enable 启用TuiJuhe消息推送
* TuiJuhe.Message.SendLimit TuiJuhe消息推送限制次数
* TuiJuhe.Message.SendLimitInterval TuiJuhe消息推送限制周期(时)
## Settings
* TuiJuhe.Security.Token 用户令牌.

10
aspnet-core/modules/tui-juhe/LINGYUN.Abp.TuiJuhe/System/Net/Http/IHttpClientFactoryExtensions.cs

@ -0,0 +1,10 @@
namespace System.Net.Http;
internal static class IHttpClientFactoryExtensions
{
public static HttpClient GetTuiJuheClient(
this IHttpClientFactory httpClientFactory)
{
return httpClientFactory.CreateClient("_Abp_TuiJuhe_Client");
}
}

2
aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Messages/WxPusherMessageProvider.cs

@ -13,7 +13,7 @@ public class WxPusherMessageProvider : WxPusherRequestProvider, IWxPusherMessage
int messageId,
CancellationToken cancellationToken = default)
{
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var content = await client.QueryMessageAsync(
messageId,

2
aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/Messages/WxPusherMessageSender.cs

@ -34,7 +34,7 @@ public class WxPusherMessageSender : WxPusherRequestProvider, IWxPusherMessageSe
CancellationToken cancellationToken = default)
{
var token = await WxPusherTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var sendMessage = new SendMessage(
token,
content,

4
aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/QrCode/WxPusherQrCodeProvider.cs

@ -25,7 +25,7 @@ public class WxPusherQrCodeProvider : WxPusherRequestProvider, IWxPusherQrCodePr
CancellationToken cancellationToken = default)
{
var token = await WxPusherTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var request = new CreateQrcodeRequest(token, extra, validTime);
var content = await client.CreateQrcodeAsync(
@ -43,7 +43,7 @@ public class WxPusherQrCodeProvider : WxPusherRequestProvider, IWxPusherQrCodePr
{
Check.NotNullOrWhiteSpace(code, nameof(code));
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var content = await client.GetScanQrCodeUidAsync(
code,

6
aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/LINGYUN/Abp/WxPusher/User/WxPusherUserProvider.cs

@ -23,7 +23,7 @@ public class WxPusherUserProvider : WxPusherRequestProvider, IWxPusherUserProvid
CancellationToken cancellationToken = default)
{
var token = await WxPusherTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var content = await client.DeleteUserAsync(
token,
@ -49,7 +49,7 @@ public class WxPusherUserProvider : WxPusherRequestProvider, IWxPusherUserProvid
}
var token = await WxPusherTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var content = await client.GetUserListAsync(
token,
@ -72,7 +72,7 @@ public class WxPusherUserProvider : WxPusherRequestProvider, IWxPusherUserProvid
CancellationToken cancellationToken = default)
{
var token = await WxPusherTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.GetPushPlusClient();
var client = HttpClientFactory.GetWxPusherClient();
var content = await client.RejectUserAsync(
token,

2
aspnet-core/modules/wx-pusher/LINGYUN.Abp.WxPusher/System/Net/Http/IHttpClientFactoryExtensions.cs

@ -2,7 +2,7 @@
internal static class IHttpClientFactoryExtensions
{
public static HttpClient GetPushPlusClient(
public static HttpClient GetWxPusherClient(
this IHttpClientFactory httpClientFactory)
{
return httpClientFactory.CreateClient("_Abp_WxPusher_Client");

7
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider.cs

@ -8,16 +8,23 @@
group.AddNotification(NotificationsTestsNames.Test1,
notificationType: NotificationType.Application,
contentType: NotificationContentType.Text,
lifetime: NotificationLifetime.OnlyOne);
group.AddNotification(NotificationsTestsNames.Test2,
notificationType: NotificationType.Application,
contentType: NotificationContentType.Html,
lifetime: NotificationLifetime.Persistent);
group.AddNotification(NotificationsTestsNames.Test3,
notificationType: NotificationType.User,
contentType: NotificationContentType.Markdown,
lifetime: NotificationLifetime.OnlyOne);
group.AddNotification(NotificationsTestsNames.Test4,
notificationType: NotificationType.System,
contentType: NotificationContentType.Json,
lifetime: NotificationLifetime.OnlyOne);
}
}
}

2
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsDefinitionProvider_Tests.cs

@ -25,7 +25,7 @@ namespace LINGYUN.Abp.Notifications
public async Task GetNotifications_Test()
{
var notifications = await NotificationDefinitionManager.GetNotificationsAsync();
notifications.Count.ShouldBe(6);
notifications.Count.ShouldBe(7);
}
[Fact]

4
aspnet-core/tests/LINGYUN.Abp.Notifications.Tests/LINGYUN/Abp/Notifications/NotificationsTestsNames.cs

@ -8,6 +8,8 @@
public const string Test2 = GroupName + ".Test2";
public const string Test3 = GroupName + ".Test3";
public const string Test3 = GroupName + ".Test3";
public const string Test4 = GroupName + ".Test4";
}
}

7
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheTestBase.cs

@ -0,0 +1,7 @@
using LINGYUN.Abp.Tests;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
public abstract class AbpNotificationsTuiJuheTestBase : AbpTestsBase<AbpNotificationsTuiJuheTestModule>
{
}

11
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/AbpNotificationsTuiJuheTestModule.cs

@ -0,0 +1,11 @@
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
[DependsOn(
typeof(AbpNotificationsTuiJuheModule),
typeof(AbpTuiJuheTestModule),
typeof(AbpNotificationsTestsModule))]
public class AbpNotificationsTuiJuheTestModule : AbpModule
{
}

94
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/NotificationSenderTests.cs

@ -0,0 +1,94 @@
using System;
using System.Threading.Tasks;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
public class NotificationSenderTests : AbpNotificationsTuiJuheTestBase
{
protected INotificationSender NotificationSender { get; }
public NotificationSenderTests()
{
NotificationSender = GetRequiredService<INotificationSender>();
}
[Theory]
[InlineData(
"Form nTest Text",
"Text content from the Xunit unit test. \r\n Click the link https://www.baidu.com/ at the top to redirect baidu site.")]
public async Task Send_Text_Test(
string title,
string message)
{
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title,
message,
DateTime.Now,
"xUnit Test");
await NotificationSender.SendNofiterAsync(
NotificationsTestsNames.Test1,
notificationData);
}
[Theory]
[InlineData(
"Form nTest Html",
"<h>Html content from the Xunit unit test.</h> <br /> <a href=\"https://www.baidu.com/\">Click to redirect baidu site.</a>")]
public async Task Send_Html_Test(
string title,
string message)
{
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title,
message,
DateTime.Now,
"xUnit Test");
await NotificationSender.SendNofiterAsync(
NotificationsTestsNames.Test2,
notificationData);
}
[Theory]
[InlineData(
"Form nTest Markdown",
"**Markdown content from the Xunit unit test.** <br /> <a href=\"https://www.baidu.com/\">Click to redirect baidu site.</a>")]
public async Task Send_Markdown_Test(
string title,
string message)
{
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title,
message,
DateTime.Now,
"xUnit Test");
await NotificationSender.SendNofiterAsync(
NotificationsTestsNames.Test3,
notificationData);
}
[Theory]
[InlineData(
"Form nTest Json",
"{\"content\":\"Content from the Xunit unit test.\",\"url\":{\"component\":{\"name\":\"a\",\"value\":\"Click to redirect baidu site.\",\"options\":{\"href\":\"https://www.baidu.com/\"}}}}")]
public async Task Send_Json_Test(
string title,
string message)
{
var notificationData = new NotificationData();
notificationData.WriteStandardData(
title,
message,
DateTime.Now,
"xUnit Test");
await NotificationSender.SendNofiterAsync(
NotificationsTestsNames.Test4,
notificationData);
}
}

27
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Abp/Notifications/TuiJuhe/NotificationsWxPusherTestsDefinitionProvider.cs

@ -0,0 +1,27 @@
using System.Linq;
namespace LINGYUN.Abp.Notifications.TuiJuhe;
public class NotificationsWxPusherTestsDefinitionProvider : NotificationDefinitionProvider
{
public override void Define(INotificationDefinitionContext context)
{
var group = context.GetGroupOrNull(NotificationsTestsNames.GroupName);
var nt1 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test1));
nt1.WithProviders(TuiJuheNotificationPublishProvider.ProviderName)
.WithServiceId("1d5v5GuH");
var nt2 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test2));
nt2.WithProviders(TuiJuheNotificationPublishProvider.ProviderName)
.WithServiceId("1d5v5GuH");
var nt3 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test3));
nt3.WithProviders(TuiJuheNotificationPublishProvider.ProviderName)
.WithServiceId("1d5v5GuH");
var nt4 = group.Notifications.FirstOrDefault(n => n.Name.Equals(NotificationsTestsNames.Test4));
nt4.WithProviders(TuiJuheNotificationPublishProvider.ProviderName)
.WithServiceId("1d5v5GuH");
}
}

20
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests.csproj

@ -0,0 +1,20 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\tui-juhe\LINGYUN.Abp.Notifications.TuiJuhe\LINGYUN.Abp.Notifications.TuiJuhe.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TuiJuhe.Tests\LINGYUN.Abp.TuiJuhe.Tests.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.Notifications.Tests\LINGYUN.Abp.Notifications.Tests.csproj" />
</ItemGroup>
</Project>

4
aspnet-core/tests/LINGYUN.Abp.Notifications.TuiJuhe.Tests/Usings.cs

@ -0,0 +1,4 @@
global using Xunit;
global using Shouldly;
global using LINGYUN.Abp.TuiJuhe;
global using LINGYUN.Abp.Notifications.TuiJuhe;

20
aspnet-core/tests/LINGYUN.Abp.PushPlus.Tests/LINGYUN/Abp/PushPlus/AbpPushPlusTestModule.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.Tests;
using LINGYUN.Abp.PushPlus.Features;
using LINGYUN.Abp.Tests;
using LINGYUN.Abp.Tests.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
@ -21,4 +23,20 @@ public class AbpPushPlusTestModule : AbpModule
context.Services.ReplaceConfiguration(configuration);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<FakeFeatureOptions>(options =>
{
options.Map(PushPlusFeatureNames.Message.Enable, (_) => "true");
options.Map(PushPlusFeatureNames.Channel.Email.Enable, (_) => "true");
options.Map(PushPlusFeatureNames.Channel.Email.SendLimit, (_) => "500");
options.Map(PushPlusFeatureNames.Channel.Email.SendLimitInterval, (_) => "1");
options.Map(PushPlusFeatureNames.Channel.WeChat.Enable, (_) => "true");
options.Map(PushPlusFeatureNames.Channel.WeChat.SendLimit, (_) => "500");
options.Map(PushPlusFeatureNames.Channel.WeChat.SendLimitInterval, (_) => "1");
});
}
}

18
aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN.Abp.TuiJuhe.Tests.csproj

@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace />
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\modules\tui-juhe\LINGYUN.Abp.TuiJuhe\LINGYUN.Abp.TuiJuhe.csproj" />
<ProjectReference Include="..\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj" />
</ItemGroup>
</Project>

7
aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/AbpTuiJuheTestBase.cs

@ -0,0 +1,7 @@
using LINGYUN.Abp.Tests;
namespace LINGYUN.Abp.TuiJuhe;
public class AbpTuiJuheTestBase : AbpTestsBase<AbpTuiJuheTestModule>
{
}

37
aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/AbpTuiJuheTestModule.cs

@ -0,0 +1,37 @@
using LINGYUN.Abp.Tests;
using LINGYUN.Abp.Tests.Features;
using LINGYUN.Abp.TuiJuhe.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.TuiJuhe;
[DependsOn(
typeof(AbpTuiJuheModule),
typeof(AbpTestsBaseModule))]
public class AbpTuiJuheTestModule : AbpModule
{
public override void PreConfigureServices(ServiceConfigurationContext context)
{
var configurationOptions = new AbpConfigurationBuilderOptions
{
BasePath = @"D:\Projects\Development\Abp\TuiJuhe",
EnvironmentName = "Test"
};
var configuration = ConfigurationHelper.BuildConfiguration(configurationOptions);
context.Services.ReplaceConfiguration(configuration);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<FakeFeatureOptions>(options =>
{
options.Map(TuiJuheFeatureNames.Enable, (_) => "true");
options.Map(TuiJuheFeatureNames.Message.Enable, (_) => "true");
options.Map(TuiJuheFeatureNames.Message.SendLimit, (_) => "50");
options.Map(TuiJuheFeatureNames.Message.SendLimitInterval, (_) => "1");
});
}
}

100
aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/LINGYUN/Abp/TuiJuhe/Messages/TuiJuheMessageSenderTests.cs

@ -0,0 +1,100 @@
using System.Threading.Tasks;
namespace LINGYUN.Abp.TuiJuhe.Messages;
public class TuiJuheMessageSenderTests : AbpTuiJuheTestBase
{
protected ITuiJuheMessageSender MessageSender { get; }
public TuiJuheMessageSenderTests()
{
MessageSender = GetRequiredService<ITuiJuheMessageSender>();
}
[Theory]
[InlineData(
"Form Test Text",
"Content from the xUnit unit test. \r\n Click the link https://www.baidu.com/ at the top to redirect baidu site.",
"1d5v5GuH")]
public async virtual Task Send_Text_Test(string title, string content, string serviceId)
{
var result = await MessageSender
.SendAsync(
title,
content,
serviceId,
MessageContentType.Text);
result.ShouldNotBeNull();
result.Code.ShouldBe(200);
result.Reason.ShouldBe("success");
result.Success.ShouldBeTrue();
result.Params.ShouldBeNull();
result.Result.ShouldBeNull();
}
[Theory]
[InlineData(
"Form Test Html",
"<h>Content from the xUnit unit test.</h> <br /> <a href=\"https://www.baidu.com/\">Click to redirect baidu site.</a>",
"1d5v5GuH")]
public async virtual Task Send_Html_Test(string title, string content, string serviceId)
{
var result = await MessageSender
.SendAsync(
title,
content,
serviceId,
MessageContentType.Html);
result.ShouldNotBeNull();
result.Code.ShouldBe(200);
result.Reason.ShouldBe("success");
result.Success.ShouldBeTrue();
result.Params.ShouldBeNull();
result.Result.ShouldBeNull();
}
[Theory]
[InlineData(
"Form Test Markdown",
"**Content from the Xunit unit test.** <br /> <a href=\"https://www.baidu.com/\">Click to redirect baidu site.</a>",
"1d5v5GuH")]
public async virtual Task Send_Markdown_Test(string title, string content, string serviceId)
{
var result = await MessageSender
.SendAsync(
title,
content,
serviceId,
MessageContentType.Markdown);
result.ShouldNotBeNull();
result.Code.ShouldBe(200);
result.Reason.ShouldBe("success");
result.Success.ShouldBeTrue();
result.Params.ShouldBeNull();
result.Result.ShouldBeNull();
}
[Theory]
[InlineData(
"Form Test Json",
"{\"content\":\"Content from the Xunit unit test.\",\"url\":{\"component\":{\"name\":\"a\",\"value\":\"Click to redirect baidu site.\",\"options\":{\"href\":\"https://www.baidu.com/\"}}}}",
"1d5v5GuH")]
public async virtual Task Send_Json_Test(string title, string content, string serviceId)
{
var result = await MessageSender
.SendAsync(
title,
content,
serviceId,
MessageContentType.Json);
result.ShouldNotBeNull();
result.Code.ShouldBe(200);
result.Reason.ShouldBe("success");
result.Success.ShouldBeTrue();
result.Params.ShouldBeNull();
result.Result.ShouldBeNull();
}
}

3
aspnet-core/tests/LINGYUN.Abp.TuiJuhe.Tests/Usings.cs

@ -0,0 +1,3 @@
global using Xunit;
global using Shouldly;
global using LINGYUN.Abp.TuiJuhe;

13
aspnet-core/tests/LINGYUN.Abp.WxPusher.Tests/LINGYUN/Abp/WxPusher/AbpWxPusherTestModule.cs

@ -1,4 +1,6 @@
using LINGYUN.Abp.Tests;
using LINGYUN.Abp.Tests.Features;
using LINGYUN.Abp.WxPusher.Features;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Modularity;
@ -21,4 +23,15 @@ public class AbpWxPusherTestModule : AbpModule
context.Services.ReplaceConfiguration(configuration);
}
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<FakeFeatureOptions>(options =>
{
options.Map(WxPusherFeatureNames.Enable, (_) => "true");
options.Map(WxPusherFeatureNames.Message.Enable, (_) => "true");
options.Map(WxPusherFeatureNames.Message.SendLimit, (_) => "500");
options.Map(WxPusherFeatureNames.Message.SendLimitInterval, (_) => "1");
});
}
}

Loading…
Cancel
Save