Browse Source

Merge pull request #1374 from colinin/enhance-integration-of-wechat-work

Enhance integration of wechat work
pull/1377/head
yx lin 3 months ago
committed by GitHub
parent
commit
296940e404
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 44
      aspnet-core/LINGYUN.MicroService.WechatManagement.sln
  2. 3
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/FodyWeavers.xml
  3. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/FodyWeavers.xsd
  4. 27
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN.Abp.WeChat.Work.ExternalContact.csproj
  5. 78
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/AbpWeChatWorkExternalContactModule.cs
  6. 24
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/IWeChatWorkAttachmentProvider.cs
  7. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Models/AttachmentType.cs
  8. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Models/MediaType.cs
  9. 41
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Request/WeChatWorkUploadAttachmentRequest.cs
  10. 35
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Response/WeChatWorkUploadAttachmentResponse.cs
  11. 41
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/WeChatWorkAttachmentProvider.cs
  12. 24
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/IWeChatWorkExternalContactProvider.cs
  13. 73
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Models/ExternalContactInfo.cs
  14. 36
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Request/WeChatWorkGetExternalContactListRequest.cs
  15. 29
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Response/WeChatWorkGetExternalContactListResponse.cs
  16. 44
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/WeChatWorkExternalContactProvider.cs
  17. 62
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/IWeChatWorkCustomerProvider.cs
  18. 87
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/IWeChatWorkCustomerStrategyProvider.cs
  19. 18
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategy.cs
  20. 46
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyInfo.cs
  21. 183
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyPrivilege.cs
  22. 61
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyRange.cs
  23. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyRangeType.cs
  24. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactGender.cs
  25. 88
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactInfo.cs
  26. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactList.cs
  27. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactType.cs
  28. 92
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUser.cs
  29. 125
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserAddWay.cs
  30. 39
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserTag.cs
  31. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserTagType.cs
  32. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserWechatChannel.cs
  33. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserWechatChannelSource.cs
  34. 55
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkBulkGetCustomerRequest.cs
  35. 74
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkCreateCustomerStrategyRequest.cs
  36. 28
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkDeleteCustomerStrategyRequest.cs
  37. 39
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyListRequest.cs
  38. 47
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyRangeRequest.cs
  39. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyRequest.cs
  40. 86
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkUpdateCustomerRemarkRequest.cs
  41. 75
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkUpdateCustomerStrategyRequest.cs
  42. 48
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkBulkGetCustomerResponse.cs
  43. 21
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkCreateCustomerStrategyResponse.cs
  44. 22
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerListResponse.cs
  45. 37
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerResponse.cs
  46. 29
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyListResponse.cs
  47. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyRangeResponse.cs
  48. 22
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyResponse.cs
  49. 93
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/WeChatWorkCustomerProvider.cs
  50. 111
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/WeChatWorkCustomerStrategyProvider.cs
  51. 31
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Features/WeChatWorkExternalContactFeatureDefinitionProvider.cs
  52. 14
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Features/WeChatWorkExternalContactFeatureNames.cs
  53. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/IWeChatWorkFollowUserProvider.cs
  54. 22
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/Response/WeChatWorkGetFollowUserListResponse.cs
  55. 38
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/WeChatWorkFollowUserProvider.cs
  56. 48
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/IWeChatWorkGroupChatProvider.cs
  57. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChat.cs
  58. 67
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatInfo.cs
  59. 18
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatInvitor.cs
  60. 18
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatManager.cs
  61. 70
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMember.cs
  62. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMemberJoinScene.cs
  63. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMemberType.cs
  64. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatStatus.cs
  65. 31
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/OwnerFilter.cs
  66. 30
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/StatusFilter.cs
  67. 50
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkGetGroupChatListRequest.cs
  68. 36
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkGetGroupChatRequest.cs
  69. 28
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkOpengIdToChatIdRequest.cs
  70. 29
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkGetGroupChatListResponse.cs
  71. 22
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkGetGroupChatResponse.cs
  72. 21
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkOpengIdToChatIdResponse.cs
  73. 76
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/WeChatWorkGroupChatProvider.cs
  74. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources/en.json
  75. 7
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources/zh-Hans.json
  76. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChaDelMemberEvent.cs
  77. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatAddMemberEvent.cs
  78. 21
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeEvent.cs
  79. 39
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeMemberEvent.cs
  80. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeNameEvent.cs
  81. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeNoticeEvent.cs
  82. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeOwnerEvent.cs
  83. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatCreateEvent.cs
  84. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatDismissEvent.cs
  85. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatMemberJoinScene.cs
  86. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatMemberQuitScene.cs
  87. 19
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatUpdateEvent.cs
  88. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactChangeEvent.cs
  89. 28
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactCreateEvent.cs
  90. 28
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactCreateHalfEvent.cs
  91. 23
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactDeleteEvent.cs
  92. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactDeleteFollowUserEvent.cs
  93. 23
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactTransferFailEvent.cs
  94. 17
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactUpdateEvent.cs
  95. 20
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagChangeEvent.cs
  96. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagCreateEvent.cs
  97. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagDeleteEvent.cs
  98. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagShuffleEvent.cs
  99. 16
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagUpdateEvent.cs
  100. 25
      aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Models/ExternalAttribute.cs

44
aspnet-core/LINGYUN.MicroService.WechatManagement.sln

@ -111,6 +111,20 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LINGYUN.Abp.Identity.Sessio
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Telemetry.SkyWalking", "framework\telemetry\LINGYUN.Abp.Telemetry.SkyWalking\LINGYUN.Abp.Telemetry.SkyWalking.csproj", "{7CF83493-6AF5-9C6D-01A7-AC7FC11BC2CE}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Telemetry.OpenTelemetry", "framework\telemetry\LINGYUN.Abp.Telemetry.OpenTelemetry\LINGYUN.Abp.Telemetry.OpenTelemetry.csproj", "{164E4514-4E84-F13A-E24E-2A743753CDB3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.Identity.WeChat.Work", "framework\wechat\LINGYUN.Abp.Identity.WeChat.Work\LINGYUN.Abp.Identity.WeChat.Work.csproj", "{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.ExternalContact", "framework\wechat\LINGYUN.Abp.WeChat.Work.ExternalContact\LINGYUN.Abp.WeChat.Work.ExternalContact.csproj", "{3A6D0EA9-FA3F-4252-87D9-31845D57180D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{02EA681E-C7D8-13C7-8484-4AC65E1B71E8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.TestsBase", "tests\LINGYUN.Abp.TestBase\LINGYUN.Abp.TestsBase.csproj", "{757279EC-708D-D1AD-5E9E-7B757F3F7785}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.Tests", "tests\LINGYUN.Abp.WeChat.Work.Tests\LINGYUN.Abp.WeChat.Work.Tests.csproj", "{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.ExternalContact.Tests", "tests\LINGYUN.Abp.WeChat.Work.ExternalContact.Tests\LINGYUN.Abp.WeChat.Work.ExternalContact.Tests.csproj", "{6628FB84-66C0-4023-9AA0-AAC4C0CC5917}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINGYUN.Abp.WeChat.Work.Handlers", "framework\wechat\LINGYUN.Abp.WeChat.Work.Handlers\LINGYUN.Abp.WeChat.Work.Handlers.csproj", "{E0DFCAD9-8AFE-A816-10F7-B4CA6691E910}"
EndProject
Global
@ -283,6 +297,30 @@ Global
{7CF83493-6AF5-9C6D-01A7-AC7FC11BC2CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7CF83493-6AF5-9C6D-01A7-AC7FC11BC2CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7CF83493-6AF5-9C6D-01A7-AC7FC11BC2CE}.Release|Any CPU.Build.0 = Release|Any CPU
{164E4514-4E84-F13A-E24E-2A743753CDB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{164E4514-4E84-F13A-E24E-2A743753CDB3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{164E4514-4E84-F13A-E24E-2A743753CDB3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{164E4514-4E84-F13A-E24E-2A743753CDB3}.Release|Any CPU.Build.0 = Release|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5}.Release|Any CPU.Build.0 = Release|Any CPU
{3A6D0EA9-FA3F-4252-87D9-31845D57180D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A6D0EA9-FA3F-4252-87D9-31845D57180D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A6D0EA9-FA3F-4252-87D9-31845D57180D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A6D0EA9-FA3F-4252-87D9-31845D57180D}.Release|Any CPU.Build.0 = Release|Any CPU
{757279EC-708D-D1AD-5E9E-7B757F3F7785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{757279EC-708D-D1AD-5E9E-7B757F3F7785}.Debug|Any CPU.Build.0 = Debug|Any CPU
{757279EC-708D-D1AD-5E9E-7B757F3F7785}.Release|Any CPU.ActiveCfg = Release|Any CPU
{757279EC-708D-D1AD-5E9E-7B757F3F7785}.Release|Any CPU.Build.0 = Release|Any CPU
{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39}.Release|Any CPU.Build.0 = Release|Any CPU
{6628FB84-66C0-4023-9AA0-AAC4C0CC5917}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6628FB84-66C0-4023-9AA0-AAC4C0CC5917}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6628FB84-66C0-4023-9AA0-AAC4C0CC5917}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6628FB84-66C0-4023-9AA0-AAC4C0CC5917}.Release|Any CPU.Build.0 = Release|Any CPU
{E0DFCAD9-8AFE-A816-10F7-B4CA6691E910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0DFCAD9-8AFE-A816-10F7-B4CA6691E910}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0DFCAD9-8AFE-A816-10F7-B4CA6691E910}.Release|Any CPU.ActiveCfg = Release|Any CPU
@ -343,6 +381,12 @@ Global
{CC8DDC8C-CC0C-4534-8D9F-2C345E065869} = {52701ECE-3EBD-45EC-AD2C-0AAB15322311}
{80EBBECC-EF11-4E5E-91DA-EEECED832F21} = {73ED64BB-7C39-42EA-B821-3DD697B9C36A}
{7CF83493-6AF5-9C6D-01A7-AC7FC11BC2CE} = {FFACB4F0-33E0-4F8B-A97E-8FFFA10C12E6}
{164E4514-4E84-F13A-E24E-2A743753CDB3} = {FFACB4F0-33E0-4F8B-A97E-8FFFA10C12E6}
{CCC8A29C-1FC1-044F-895A-EC6894CDC8E5} = {EDBB7BC1-46F0-4803-A572-7F8FEF433BE2}
{3A6D0EA9-FA3F-4252-87D9-31845D57180D} = {EDBB7BC1-46F0-4803-A572-7F8FEF433BE2}
{757279EC-708D-D1AD-5E9E-7B757F3F7785} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{9DC2A982-8FA2-93BE-5FE1-3D7F7C105C39} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{6628FB84-66C0-4023-9AA0-AAC4C0CC5917} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{E0DFCAD9-8AFE-A816-10F7-B4CA6691E910} = {EDBB7BC1-46F0-4803-A572-7F8FEF433BE2}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution

3
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/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/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/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>

27
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN.Abp.WeChat.Work.ExternalContact.csproj

@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\configureawait.props" />
<Import Project="..\..\..\..\common.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;netstandard2.1;net8.0;net9.0</TargetFrameworks>
<AssemblyName>LINGYUN.Abp.WeChat.Work.ExternalContact</AssemblyName>
<PackageId>LINGYUN.Abp.WeChat.Work.ExternalContact</PackageId>
<GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
<GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<GenerateDocumentationFile>True</GenerateDocumentationFile>
<Nullable>enable</Nullable>
<RootNamespace />
</PropertyGroup>
<ItemGroup>
<None Remove="LINGYUN\Abp\WeChat\Work\ExternalContact\Localization\Resources\*.json" />
<EmbeddedResource Include="LINGYUN\Abp\WeChat\Work\ExternalContact\Localization\Resources\*.json" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LINGYUN.Abp.WeChat.Work\LINGYUN.Abp.WeChat.Work.csproj" />
</ItemGroup>
</Project>

78
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/AbpWeChatWorkExternalContactModule.cs

@ -0,0 +1,78 @@
using LINGYUN.Abp.WeChat.Common;
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
using LINGYUN.Abp.WeChat.Work.Localization;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact;
[DependsOn(typeof(AbpWeChatWorkModule))]
public class AbpWeChatWorkExternalContactModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpWeChatWorkMessageResolveOptions>(options =>
{
// 企业客户变更事件
options.MapEvent("change_external_contact", context =>
{
var changeType = context.GetMessageData("ChangeType");
return changeType switch
{
"add_external_contact" => context.GetWeChatMessage<ExternalContactCreateEvent>(),
"edit_external_contact" => context.GetWeChatMessage<ExternalContactUpdateEvent>(),
"add_half_external_contact" => context.GetWeChatMessage<ExternalContactCreateHalfEvent>(),
"del_external_contact" => context.GetWeChatMessage<ExternalContactDeleteEvent>(),
"del_follow_user" => context.GetWeChatMessage<ExternalContactDeleteFollowUserEvent>(),
"transfer_fail" => context.GetWeChatMessage<ExternalContactTransferFailEvent>(),
_ => throw new AbpWeChatException($"Contact change event change_external_contact:{changeType} is not mounted!"),
};
});
// 客户群变更事件
options.MapEvent("change_external_chat", context =>
{
var changeType = context.GetMessageData("ChangeType");
switch (changeType)
{
case "create": return context.GetWeChatMessage<ExternalChatCreateEvent>();
case "update":
// 客户群变更事件
var updateDetail = context.GetMessageData("UpdateDetail");
return updateDetail switch
{
"add_member" => context.GetWeChatMessage<ExternalChatAddMemberEvent>(),
"del_member" => context.GetWeChatMessage<ExternalChaDelMemberEvent>(),
"change_owner" => context.GetWeChatMessage<ExternalChatChangeOwnerEvent>(),
"change_name" => context.GetWeChatMessage<ExternalChatChangeNameEvent>(),
"change_notice" => context.GetWeChatMessage<ExternalChatChangeNoticeEvent>(),
_ => throw new AbpWeChatException($"Contact change event change_external_chat:{changeType}:{updateDetail} is not mounted!"),
};
case "dismiss": return context.GetWeChatMessage<ExternalChatDismissEvent>();
default: throw new AbpWeChatException($"Contact change event change_external_chat:{changeType} is not mounted!");
}
});
// 企业客户标签事件
options.MapEvent("change_external_tag", context =>
{
var changeType = context.GetMessageData("ChangeType");
return changeType switch
{
"create" => context.GetWeChatMessage<ExternalTagCreateEvent>(),
"update" => context.GetWeChatMessage<ExternalTagUpdateEvent>(),
"delete" => context.GetWeChatMessage<ExternalTagDeleteEvent>(),
"shuffle" => context.GetWeChatMessage<ExternalTagShuffleEvent>(),
_ => throw new AbpWeChatException($"Contact change event change_external_tag:{changeType} is not mounted!"),
};
});
});
Configure<AbpLocalizationOptions>(options =>
{
options.Resources
.Get<WeChatWorkResource>()
.AddVirtualJson("/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources");
});
}
}

24
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/IWeChatWorkAttachmentProvider.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments;
/// <summary>
/// 附件资源接口
/// </summary>
public interface IWeChatWorkAttachmentProvider
{
/// <summary>
/// 上传附件资源
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/90253"/>
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkUploadAttachmentResponse> UploadAsync(
WeChatWorkUploadAttachmentRequest request,
CancellationToken cancellationToken = default);
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Models/AttachmentType.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models;
/// <summary>
/// 附件类型
/// </summary>
[Description("附件类型")]
public enum AttachmentType
{
/// <summary>
/// 朋友圈
/// </summary>
[Description("朋友圈")]
Moments = 1,
/// <summary>
/// 商品图册
/// </summary>
[Description("商品图册")]
ProductCatalogue = 2,
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Models/MediaType.cs

@ -0,0 +1,25 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models;
/// <summary>
/// 媒体文件类型
/// </summary>
[Description("媒体文件类型")]
public enum MediaType
{
/// <summary>
/// 图片
/// </summary>
[Description("图片")]
Image = 1,
/// <summary>
/// 视频
/// </summary>
[Description("视频")]
Video = 2,
/// <summary>
/// 普通文件
/// </summary>
[Description("普通文件")]
File = 3,
}

41
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Request/WeChatWorkUploadAttachmentRequest.cs

@ -0,0 +1,41 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Models;
using Volo.Abp;
using Volo.Abp.Content;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request;
/// <summary>
/// 上传附件资源请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/95098" />
/// </remarks>
public class WeChatWorkUploadAttachmentRequest : WeChatWorkRequest
{
/// <summary>
/// 媒体文件类型
/// </summary>
[NotNull]
public MediaType MediaType { get; }
/// <summary>
/// 附件类型
/// </summary>
[NotNull]
public AttachmentType AttachmentType { get; }
/// <summary>
/// 媒体文件
/// </summary>
[NotNull]
public IRemoteStreamContent Content { get; }
public WeChatWorkUploadAttachmentRequest(
MediaType mediaType,
AttachmentType attachmentType,
IRemoteStreamContent content)
{
Check.NotNull(content, nameof(content));
MediaType = mediaType;
AttachmentType = attachmentType;
Content = content;
}
}

35
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/Response/WeChatWorkUploadAttachmentResponse.cs

@ -0,0 +1,35 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response;
/// <summary>
/// 上传附件资源响应结果
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/95098" />
/// </remarks>
public class WeChatWorkUploadAttachmentResponse : WeChatWorkResponse
{
/// <summary>
/// 媒体文件类型,分别有图片(image)、语音(voice)、视频(video),普通文件(file)
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public string MediaType { get; set; }
/// <summary>
/// 媒体文件上传后获取的唯一标识,三天有效,可使用获取临时素材接口获取
/// </summary>
[NotNull]
[JsonProperty("media_id")]
[JsonPropertyName("media_id")]
public string MediaId { get; set; }
/// <summary>
/// 媒体文件上传时间戳
/// </summary>
[NotNull]
[JsonProperty("created_at")]
[JsonPropertyName("created_at")]
public long CreatedAt { get; set; }
}

41
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Attachments/WeChatWorkAttachmentProvider.cs

@ -0,0 +1,41 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments.Response;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Attachments;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkAttachmentProvider : IWeChatWorkAttachmentProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkAttachmentProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkUploadAttachmentResponse> UploadAsync(
WeChatWorkUploadAttachmentRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.UploadAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkUploadAttachmentResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

24
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/IWeChatWorkExternalContactProvider.cs

@ -0,0 +1,24 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts;
/// <summary>
/// 外部联系人接口
/// </summary>
public interface IWeChatWorkExternalContactProvider
{
/// <summary>
/// 获取已服务的外部联系人
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/99434" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetExternalContactListResponse> GetExternalContactListAsync(
WeChatWorkGetExternalContactListRequest request,
CancellationToken cancellationToken = default);
}

73
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Models/ExternalContactInfo.cs

@ -0,0 +1,73 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Models;
/// <summary>
/// 外部联系人
/// </summary>
public class ExternalContactInfo
{
/// <summary>
/// 是否被成员标记为客户
/// </summary>
[NotNull]
[JsonProperty("is_customer")]
[JsonPropertyName("is_customer")]
public bool IsCustomer { get; set; }
/// <summary>
/// 外部联系人临时ID
/// </summary>
/// <remarks>
///
/// 外部联系人临时id是一个外部联系人的唯一标识,企业可根据此id对外部联系人进行去重统计。<br />
/// 但外部联系人临时id仅在一轮遍历查询(从首个分页查询开始到最后一个分页查询完毕)中唯一;<br />
/// 每次请求首个数据分页(cursor为空)时,返回的外部联系人临时id和next_cursor将发生变化。
/// </remarks>
[NotNull]
[JsonProperty("tmp_openid")]
[JsonPropertyName("tmp_openid")]
public string TmpOpenId { get; set; }
/// <summary>
/// 外部联系人的externaluserid(如果是客户才返回)
/// </summary>
[CanBeNull]
[JsonProperty("external_userid")]
[JsonPropertyName("external_userid")]
public string? ExternalUserId { get; set; }
/// <summary>
/// 脱敏后的外部联系人昵称(如果是其他外部联系人才返回)
/// </summary>
[CanBeNull]
[JsonProperty("name")]
[JsonPropertyName("name")]
public string? Name { get; set; }
/// <summary>
/// 添加此外部联系人的企业成员或外部联系人所在群聊的群主userid
/// </summary>
[CanBeNull]
[JsonProperty("follow_userid")]
[JsonPropertyName("follow_userid")]
public string? FollowUserId { get; set; }
/// <summary>
/// 外部联系人所在的群聊ID(如果群聊被成员标记为客户群才返回)
/// </summary>
[CanBeNull]
[JsonProperty("chat_id")]
[JsonPropertyName("chat_id")]
public string? ChatId { get; set; }
/// <summary>
/// 外部联系人所在群聊的群名(如果群聊未被成员标记为客户群才返回)
/// </summary>
[CanBeNull]
[JsonProperty("chat_name")]
[JsonPropertyName("chat_name")]
public string? ChatName { get; set; }
/// <summary>
/// 外部联系人首次添加/进群的时间
/// </summary>
[NotNull]
[JsonProperty("add_time")]
[JsonPropertyName("add_time")]
public long AddTime { get; set; }
}

36
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Request/WeChatWorkGetExternalContactListRequest.cs

@ -0,0 +1,36 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request;
/// <summary>
/// 获取已服务的外部联系人请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/99434" />
/// </remarks>
public class WeChatWorkGetExternalContactListRequest : WeChatWorkRequest
{
/// <summary>
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用可不填
/// </summary>
/// <remarks>
/// cursor具有有效期,请勿缓存后使用
/// </remarks>
[CanBeNull]
[JsonProperty("cursor")]
[JsonPropertyName("cursor")]
public string? Cursor { get; }
/// <summary>
/// 返回的最大记录数,整型,默认为1000
/// </summary>
[CanBeNull]
[JsonProperty("limit")]
[JsonPropertyName("limit")]
public int? Limit { get; }
public WeChatWorkGetExternalContactListRequest(string? cursor = null, int? limit = 1000)
{
Cursor = cursor;
Limit = limit;
}
}

29
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/Response/WeChatWorkGetExternalContactListResponse.cs

@ -0,0 +1,29 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response;
/// <summary>
/// 获取已服务的外部联系人响应结果
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
/// </remarks>
public class WeChatWorkGetExternalContactListResponse : WeChatWorkResponse
{
/// <summary>
/// 外部联系人列表
/// </summary>
[NotNull]
[JsonProperty("info_list")]
[JsonPropertyName("info_list")]
public ExternalContactInfo[] InfoList { get; set; }
/// <summary>
/// 分页游标,再下次请求时填写以获取之后分页的记录,如果已经没有更多的数据则返回空,有效期为4小时
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
}

44
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Contacts/WeChatWorkExternalContactProvider.cs

@ -0,0 +1,44 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts.Response;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Contacts;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkExternalContactProvider : IWeChatWorkExternalContactProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkExternalContactProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkGetExternalContactListResponse> GetExternalContactListAsync(
WeChatWorkGetExternalContactListRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetExternalContactListAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetExternalContactListResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

62
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/IWeChatWorkCustomerProvider.cs

@ -0,0 +1,62 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers;
/// <summary>
/// 客户管理接口
/// </summary>
public interface IWeChatWorkCustomerProvider
{
/// <summary>
/// 获取客户列表
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92113" />
/// </remarks>
/// <param name="userId">企业成员的userid</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetCustomerListResponse> GetCustomerListAsync(
string userId,
CancellationToken cancellationToken = default);
/// <summary>
/// 批量获取客户详情
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkBulkGetCustomerResponse> BulkGetCustomerAsync(
WeChatWorkBulkGetCustomerRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取客户详情
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92114" />
/// </remarks>
/// <param name="externalUserid">外部联系人的userid,注意不是企业成员的账号</param>
/// <param name="cursor">上次请求返回的next_cursor</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetCustomerResponse> GetCustomerAsync(
string externalUserid,
string? cursor = null,
CancellationToken cancellationToken = default);
/// <summary>
/// 修改客户备注信息
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92115" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkResponse> UpdateCustomerRemarkAsync(
WeChatWorkUpdateCustomerRemarkRequest request,
CancellationToken cancellationToken = default);
}

87
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/IWeChatWorkCustomerStrategyProvider.cs

@ -0,0 +1,87 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers;
/// <summary>
/// 客户联系规则组管理
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
/// </remarks>
public interface IWeChatWorkCustomerStrategyProvider
{
/// <summary>
/// 获取规则组列表
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetCustomerStrategyListResponse> GetCustomerStrategyListAsync(
WeChatWorkGetCustomerStrategyListRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取规则组
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetCustomerStrategyResponse> GetCustomerStrategyAsync(
WeChatWorkGetCustomerStrategyRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取规则组管理范围
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetCustomerStrategyRangeResponse> GetCustomerStrategyRangeAsync(
WeChatWorkGetCustomerStrategyRangeRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 创建新的规则组
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkCreateCustomerStrategyResponse> CreateCustomerStrategyAsync(
WeChatWorkCreateCustomerStrategyRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 编辑规则组及其管理范围
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkResponse> UpdateCustomerStrategyAsync(
WeChatWorkUpdateCustomerStrategyRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 删除规则组
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkResponse> DeleteCustomerStrategyAsync(
WeChatWorkDeleteCustomerStrategyRequest request,
CancellationToken cancellationToken = default);
}

18
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategy.cs

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 规则组
/// </summary>
public class CustomerStrategy
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; set; }
}

46
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyInfo.cs

@ -0,0 +1,46 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 规则组详情
/// </summary>
public class CustomerStrategyInfo : CustomerStrategy
{
/// <summary>
/// 父规则组id, 如果当前规则组没父规则组,则为0
/// </summary>
[NotNull]
[JsonProperty("parent_id")]
[JsonPropertyName("parent_id")]
public int ParentId { get; set; }
/// <summary>
/// 规则组名称
/// </summary>
[NotNull]
[JsonProperty("strategy_name")]
[JsonPropertyName("strategy_name")]
public string StrategyName { get; set; }
/// <summary>
/// 规则组创建时间戳
/// </summary>
[NotNull]
[JsonProperty("create_time")]
[JsonPropertyName("create_time")]
public long CreateTime { get; set; }
/// <summary>
/// 规则组管理员userid列表
/// </summary>
[NotNull]
[JsonProperty("admin_list")]
[JsonPropertyName("admin_list")]
public string[] AdminList { get; set; }
/// <summary>
/// 规则组权限
/// </summary>
[NotNull]
[JsonProperty("privilege")]
[JsonPropertyName("privilege")]
public CustomerStrategyPrivilege Privilege { get; set; }
}

183
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyPrivilege.cs

@ -0,0 +1,183 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 规则组权限
/// </summary>
public class CustomerStrategyPrivilege
{
/// <summary>
/// 查看客户列表,基础权限,不可取消
/// </summary>
[NotNull]
[JsonProperty("view_customer_list")]
[JsonPropertyName("view_customer_list")]
public bool ViewCustomerList { get; set; }
/// <summary>
/// 查看客户统计数据,基础权限,不可取消
/// </summary>
[NotNull]
[JsonProperty("view_customer_data")]
[JsonPropertyName("view_customer_data")]
public bool ViewCustomerData { get; set; }
/// <summary>
/// 查看群聊列表,基础权限,不可取消
/// </summary>
[NotNull]
[JsonProperty("view_room_list")]
[JsonPropertyName("view_room_list")]
public bool ViewRoomList { get; set; }
/// <summary>
/// 可使用联系我,基础权限,不可取消
/// </summary>
[NotNull]
[JsonProperty("contact_me")]
[JsonPropertyName("contact_me")]
public bool ContactMe { get; set; }
/// <summary>
/// 可加入群聊,基础权限,不可取消
/// </summary>
[NotNull]
[JsonProperty("join_room")]
[JsonPropertyName("join_room")]
public bool JoinRoom { get; set; }
/// <summary>
/// 允许分享客户给其他成员,默认为true
/// </summary>
[NotNull]
[JsonProperty("share_customer")]
[JsonPropertyName("share_customer")]
public bool ShareCustomer { get; set; }
/// <summary>
/// 允许分配离职成员客户,默认为true
/// </summary>
[NotNull]
[JsonProperty("oper_resign_customer")]
[JsonPropertyName("oper_resign_customer")]
public bool OperResignCustomer { get; set; }
/// <summary>
/// 允许分配离职成员客户群,默认为true
/// </summary>
[NotNull]
[JsonProperty("oper_resign_group")]
[JsonPropertyName("oper_resign_group")]
public bool OperResignGroup { get; set; }
/// <summary>
/// 允许给企业客户发送消息,默认为true
/// </summary>
[NotNull]
[JsonProperty("send_customer_msg")]
[JsonPropertyName("send_customer_msg")]
public bool SendCustomerMsg { get; set; }
/// <summary>
/// 允许配置欢迎语,默认为true
/// </summary>
[NotNull]
[JsonProperty("edit_welcome_msg")]
[JsonPropertyName("edit_welcome_msg")]
public bool EditWelcomeMsg { get; set; }
/// <summary>
/// 允许查看成员联系客户统计,默认为true
/// </summary>
[NotNull]
[JsonProperty("view_behavior_data")]
[JsonPropertyName("view_behavior_data")]
public bool ViewBehaviorData { get; set; }
/// <summary>
/// 允许查看群聊数据统计,默认为true
/// </summary>
[NotNull]
[JsonProperty("view_room_data")]
[JsonPropertyName("view_room_data")]
public bool ViewRoomData { get; set; }
/// <summary>
/// 允许发送消息到企业的客户群,默认为true
/// </summary>
[NotNull]
[JsonProperty("send_group_msg")]
[JsonPropertyName("send_group_msg")]
public bool SendGroupMsg { get; set; }
/// <summary>
/// 允许对企业客户群进行去重,默认为true
/// </summary>
[NotNull]
[JsonProperty("room_deduplication")]
[JsonPropertyName("room_deduplication")]
public bool RoomDeduplication { get; set; }
/// <summary>
/// 配置快捷回复,默认为true
/// </summary>
[NotNull]
[JsonProperty("rapid_reply")]
[JsonPropertyName("rapid_reply")]
public bool RapidReply { get; set; }
/// <summary>
/// 转接在职成员的客户,默认为true
/// </summary>
[NotNull]
[JsonProperty("onjob_customer_transfer")]
[JsonPropertyName("onjob_customer_transfer")]
public bool OnjobCustomerTransfer { get; set; }
/// <summary>
/// 编辑企业成员防骚扰规则,默认为true
/// </summary>
[NotNull]
[JsonProperty("edit_anti_spam_rule")]
[JsonPropertyName("edit_anti_spam_rule")]
public bool EditAntiSpamRule { get; set; }
/// <summary>
/// 导出客户列表,默认为true
/// </summary>
[NotNull]
[JsonProperty("export_customer_list")]
[JsonPropertyName("export_customer_list")]
public bool ExportCustomerList { get; set; }
/// <summary>
/// 导出成员客户统计,默认为true
/// </summary>
[NotNull]
[JsonProperty("export_customer_data")]
[JsonPropertyName("export_customer_data")]
public bool ExportCustomerData { get; set; }
/// <summary>
/// 导出客户群列表,默认为true
/// </summary>
[NotNull]
[JsonProperty("export_customer_group_list")]
[JsonPropertyName("export_customer_group_list")]
public bool ExportCustomerGroupList { get; set; }
/// <summary>
/// 配置企业客户标签,默认为true
/// </summary>
[NotNull]
[JsonProperty("manage_customer_tag")]
[JsonPropertyName("manage_customer_tag")]
public bool ManageCustomerTag { get; set; }
public static CustomerStrategyPrivilege Default()
{
return new CustomerStrategyPrivilege
{
ViewCustomerList = true,
ViewCustomerData = true,
ViewRoomList = true,
ContactMe = true,
JoinRoom = true,
ShareCustomer = true,
EditWelcomeMsg = true,
ViewBehaviorData = true,
ViewRoomData = true,
SendGroupMsg = true,
RoomDeduplication = true,
RapidReply = true,
OnjobCustomerTransfer = true,
EditAntiSpamRule = true,
ExportCustomerList = true,
ExportCustomerData = true,
ExportCustomerGroupList = true,
ManageCustomerTag = true,
};
}
}

61
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyRange.cs

@ -0,0 +1,61 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 规则组管理范围
/// </summary>
public class CustomerStrategyRange
{
/// <summary>
/// 节点类型
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public CustomerStrategyRangeType Type { get; set; }
/// <summary>
/// 管理范围内配置的成员userid,仅 Type为<see cref="CustomerStrategyRangeType.Member"/> 时返回
/// </summary>
[CanBeNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string? UserId { get; set; }
/// <summary>
/// 管理范围内配置的部门partyid,仅 Type为<see cref="CustomerStrategyRangeType.Part"/> 时返回
/// </summary>
[CanBeNull]
[JsonProperty("partyid")]
[JsonPropertyName("partyid")]
public int? PartyId { get; set; }
public CustomerStrategyRange()
{
}
private CustomerStrategyRange(
CustomerStrategyRangeType type,
string? userId = null,
int? partyId = null)
{
Type = type;
UserId = userId;
PartyId = partyId;
}
public static CustomerStrategyRange Member(string userId)
{
Check.NotNullOrWhiteSpace(userId, nameof(userId));
return new CustomerStrategyRange(CustomerStrategyRangeType.Member, userId);
}
public static CustomerStrategyRange Party(int partyId)
{
Check.NotDefaultOrNull<int>(partyId, nameof(partyId));
return new CustomerStrategyRange(CustomerStrategyRangeType.Part, partyId: partyId);
}
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/CustomerStrategyRangeType.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 节点类型
/// </summary>
[Description("节点类型")]
public enum CustomerStrategyRangeType
{
/// <summary>
/// 成员
/// </summary>
[Description("成员")]
Member = 1,
/// <summary>
/// 部门
/// </summary>
[Description("部门")]
Part = 2
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactGender.cs

@ -0,0 +1,25 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 外部联系人性别
/// </summary>
[Description("外部联系人性别")]
public enum ExternalContactGender
{
/// <summary>
/// 未知
/// </summary>
[Description("未知")]
None = 0,
/// <summary>
/// 男性
/// </summary>
[Description("男性")]
Male = 1,
/// <summary>
/// 女性
/// </summary>
[Description("女性")]
FeMale = 2,
}

88
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactInfo.cs

@ -0,0 +1,88 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 外部联系人信息
/// </summary>
public class ExternalContactInfo
{
/// <summary>
/// 外部联系人的userid
/// </summary>
[NotNull]
[JsonProperty("external_userid")]
[JsonPropertyName("external_userid")]
public string ExternalUserId { get; set; }
/// <summary>
/// 外部联系人的名称
/// </summary>
/// <remarks>
/// 如果是微信用户,则返回其微信昵称。<br />
/// 如果是企业微信联系人,则返回其设置对外展示的别名或实名
/// </remarks>
[NotNull]
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 外部联系人头像
/// </summary>
[CanBeNull]
[JsonProperty("avatar")]
[JsonPropertyName("avatar")]
public string? Avatar { get; set; }
/// <summary>
/// 外部联系人的类型
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public ExternalContactType Type { get; set; }
/// <summary>
/// 外部联系人性别
/// </summary>
[NotNull]
[JsonProperty("gender")]
[JsonPropertyName("gender")]
public ExternalContactGender Gender { get; set; }
/// <summary>
/// 外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。<br />
/// 仅当联系人类型是微信用户,且企业绑定了微信开发者ID有此字段
/// </summary>
[CanBeNull]
[JsonProperty("unionid")]
[JsonPropertyName("unionid")]
public string? UnionId { get; set; }
/// <summary>
/// 外部联系人的职位,如果外部企业或用户选择隐藏职位,则不返回,仅当联系人类型是企业微信用户时有此字段
/// </summary>
[CanBeNull]
[JsonProperty("position")]
[JsonPropertyName("position")]
public string? Position { get; set; }
/// <summary>
/// 外部联系人所在企业的简称,仅当联系人类型是企业微信用户时有此字段
/// </summary>
[CanBeNull]
[JsonProperty("corp_name")]
[JsonPropertyName("corp_name")]
public string? CorpName { get; set; }
/// <summary>
/// 外部联系人所在企业的主体名称,仅当联系人类型是企业微信用户时有此字段<br />
/// 仅企业自建应用可获取
/// </summary>
[CanBeNull]
[JsonProperty("corp_full_name")]
[JsonPropertyName("corp_full_name")]
public string? CorpFullName { get; set; }
/// <summary>
/// 外部联系人的自定义展示信息
/// </summary>
[CanBeNull]
[JsonProperty("external_profile")]
[JsonPropertyName("external_profile")]
public ExternalProfile? ExternalProfile { get; set; }
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactList.cs

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 外部联系人列表
/// </summary>
public class ExternalContactList
{
/// <summary>
/// 客户的基本信息
/// </summary>
[NotNull]
[JsonProperty("external_contact")]
[JsonPropertyName("external_contact")]
public ExternalContactInfo ExternalContact { get; set; }
/// <summary>
/// 企业成员客户跟进信息
/// </summary>
[NotNull]
[JsonProperty("follow_info")]
[JsonPropertyName("follow_info")]
public FollowUser FollowUser { get; set; }
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/ExternalContactType.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 外部联系人类型
/// </summary>
[Description("外部联系人类型")]
public enum ExternalContactType
{
/// <summary>
/// 微信用户
/// </summary>
[Description("微信用户")]
WeChat = 1,
/// <summary>
/// 企业微信用户
/// </summary>
[Description("企业微信用户")]
WeChatWork = 2,
}

92
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUser.cs

@ -0,0 +1,92 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 添加了外部联系人的企业成员
/// </summary>
public class FollowUser
{
/// <summary>
/// 添加了此外部联系人的企业成员userid
/// </summary>
[NotNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string UserId { get; set; }
/// <summary>
/// 发起添加的userid<br />
/// 如果成员主动添加,为成员的userid;<br />
/// 如果是客户主动添加,则为客户的外部联系人userid;<br />
/// 如果是内部成员共享/管理员分配,则为对应的成员/管理员userid
/// </summary>
[NotNull]
[JsonProperty("oper_userid")]
[JsonPropertyName("oper_userid")]
public string OperUserId { get; set; }
/// <summary>
/// 企业自定义的state参数,用于区分客户具体是通过哪个「联系我」或获客链接添加
/// </summary>
[CanBeNull]
[JsonProperty("state")]
[JsonPropertyName("state")]
public string? State { get; set; }
/// <summary>
/// 该成员对此外部联系人的备注
/// </summary>
[CanBeNull]
[JsonProperty("remark")]
[JsonPropertyName("remark")]
public string? Remark { get; set; }
/// <summary>
/// 该成员对此外部联系人的描述
/// </summary>
[CanBeNull]
[JsonProperty("description")]
[JsonPropertyName("description")]
public string? Description { get; set; }
/// <summary>
/// 该成员添加此外部联系人的时间
/// </summary>
[NotNull]
[JsonProperty("createtime")]
[JsonPropertyName("createtime")]
public long Createtime { get; set; }
/// <summary>
/// 外部联系人所打标签列表
/// </summary>
[CanBeNull]
[JsonProperty("tags")]
[JsonPropertyName("tags")]
public List<FollowUserTag>? Tags { get; set; }
/// <summary>
/// 该成员对此微信客户备注的企业名称(仅微信客户有该字段)
/// </summary>
[CanBeNull]
[JsonProperty("remark_corp_name")]
[JsonPropertyName("remark_corp_name")]
public string? RemarkCorpName { get; set; }
/// <summary>
/// 该成员对此客户备注的手机号码,代开发自建应用需要管理员授权才可以获取
/// </summary>
[CanBeNull]
[JsonProperty("remark_mobiles")]
[JsonPropertyName("remark_mobiles")]
public List<string>? RemarkMobiles { get; set; }
/// <summary>
/// 该成员添加此客户的来源
/// </summary>
[NotNull]
[JsonProperty("add_way")]
[JsonPropertyName("add_way")]
public FollowUserAddWay AddWay { get; set; }
/// <summary>
/// 该成员添加此客户的来源add_way为10时,对应的视频号信息
/// </summary>
[CanBeNull]
[JsonProperty("wechat_channels")]
[JsonPropertyName("wechat_channels")]
public FollowUserWechatChannel? WechatChannel { get; set; }
}

125
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserAddWay.cs

@ -0,0 +1,125 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 客户来源
/// </summary>
[Description("客户来源")]
public enum FollowUserAddWay
{
/// <summary>
/// 未知来源
/// </summary>
[Description("未知来源")]
None = 0,
/// <summary>
/// 扫描二维码
/// </summary>
[Description("扫描二维码")]
ScanQrCode = 1,
/// <summary>
/// 搜索手机号
/// </summary>
[Description("搜索手机号")]
SearchPhoneNumber = 2,
/// <summary>
/// 名片分享
/// </summary>
[Description("名片分享")]
SharedCard = 3,
/// <summary>
/// 群聊
/// </summary>
[Description("群聊")]
GroupChat = 4,
/// <summary>
/// 手机通讯录
/// </summary>
[Description("手机通讯录")]
PhoneBook = 5,
/// <summary>
/// 微信联系人
/// </summary>
[Description("微信联系人")]
WeChatContact = 6,
/// <summary>
/// 安装第三方应用时自动添加的客服人员
/// </summary>
[Description("安装第三方应用时自动添加的客服人员")]
InstallThirdPartyApp = 8,
/// <summary>
/// 搜索邮箱
/// </summary>
[Description("搜索邮箱")]
SearchEmail = 9,
/// <summary>
/// 视频号添加
/// </summary>
[Description("视频号添加")]
WechatChannel = 10,
/// <summary>
/// 通过日程参与人添加
/// </summary>
[Description("通过日程参与人添加")]
SchedulePart = 11,
/// <summary>
/// 通过会议参与人添加
/// </summary>
[Description("通过会议参与人添加")]
MeetPart = 12,
/// <summary>
/// 添加微信好友对应的企业微信
/// </summary>
[Description("添加微信好友对应的企业微信")]
WeChatFriend = 13,
/// <summary>
/// 通过智慧硬件专属客服添加
/// </summary>
[Description("通过智慧硬件专属客服添加")]
SmartHardware = 14,
/// <summary>
/// 通过上门服务客服添加
/// </summary>
[Description("通过上门服务客服添加")]
DoorService = 15,
/// <summary>
/// 通过获客链接添加
/// </summary>
[Description("通过获客链接添加")]
CustomerAcqLink = 16,
/// <summary>
/// 通过定制开发添加
/// </summary>
[Description("通过定制开发添加")]
CustomDevelopment = 17,
/// <summary>
/// 通过需求回复添加
/// </summary>
[Description("通过需求回复添加")]
DemandResponse = 18,
/// <summary>
/// 通过第三方售前客服添加
/// </summary>
[Description("通过第三方售前客服添加")]
ThirdPartyPreSales = 21,
/// <summary>
/// 通过可能的商务伙伴添加
/// </summary>
[Description("通过可能的商务伙伴添加")]
PotentialBusPart = 22,
/// <summary>
/// 通过接受微信账号收到的好友申请添加
/// </summary>
[Description("通过接受微信账号收到的好友申请添加")]
WeChatFriendRequest = 24,
/// <summary>
/// 内部成员共享
/// </summary>
[Description("内部成员共享")]
SharedByInternalMembers = 201,
/// <summary>
/// 管理员/负责人分配
/// </summary>
[Description("管理员/负责人分配")]
AllocationByAdmin = 202
}

39
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserTag.cs

@ -0,0 +1,39 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 外部联系人所打标签
/// </summary>
public class FollowUserTag
{
/// <summary>
/// 该成员添加此外部联系人所打标签的分组名称
/// </summary>
[CanBeNull]
[JsonProperty("group_name")]
[JsonPropertyName("group_name")]
public string? GroupName { get; set; }
/// <summary>
/// 该成员添加此外部联系人所打标签名称
/// </summary>
[NotNull]
[JsonProperty("tag_name")]
[JsonPropertyName("tag_name")]
public string TagName { get; set; }
/// <summary>
/// 该成员添加此外部联系人所打标签类型
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public FollowUserTagType Type { get; set; }
/// <summary>
/// 该成员添加此外部联系人所打企业标签的id,用户自定义类型标签(type=2)不返回
/// </summary>
[CanBeNull]
[JsonProperty("tag_id")]
[JsonPropertyName("tag_id")]
public string? TagId { get; set; }
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserTagType.cs

@ -0,0 +1,25 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 标签类型
/// </summary>
[Description("标签类型")]
public enum FollowUserTagType
{
/// <summary>
/// 企业设置
/// </summary>
[Description("企业设置")]
EnterpriseSettings = 1,
/// <summary>
/// 用户自定义
/// </summary>
[Description("用户自定义")]
UserCustom = 2,
/// <summary>
/// 规则组标签
/// </summary>
[Description("规则组标签")]
RuleGroupTags = 3,
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserWechatChannel.cs

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 视频号信息
/// </summary>
public class FollowUserWechatChannel
{
/// <summary>
/// 视频号名称
/// </summary>
[NotNull]
[JsonProperty("nickname")]
[JsonPropertyName("nickname")]
public string NickName { get; set; }
/// <summary>
/// 视频号添加场景
/// </summary>
[NotNull]
[JsonProperty("source")]
[JsonPropertyName("source")]
public FollowUserWechatChannelSource Source { get; set; }
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Models/FollowUserWechatChannelSource.cs

@ -0,0 +1,30 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
/// <summary>
/// 视频号添加场景
/// </summary>
[Description("视频号添加场景")]
public enum FollowUserWechatChannelSource
{
/// <summary>
/// 未知
/// </summary>
[Description("未知")]
None = 0,
/// <summary>
/// 视频号主页
/// </summary>
[Description("视频号主页")]
Home = 1,
/// <summary>
/// 视频号直播间
/// </summary>
[Description("视频号直播间")]
LiveRoom = 2,
/// <summary>
/// 视频号留资服务
/// </summary>
[Description("视频号留资服务")]
RetentionService = 3
}

55
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkBulkGetCustomerRequest.cs

@ -0,0 +1,55 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 创建新的规则组请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%9B%E5%BB%BA%E6%96%B0%E7%9A%84%E8%A7%84%E5%88%99%E7%BB%84" />
/// </remarks>
public class WeChatWorkBulkGetCustomerRequest : WeChatWorkRequest
{
/// <summary>
/// 企业成员的userid列表,字符串类型,最多支持100个
/// </summary>
[NotNull]
[JsonProperty("userid_list")]
[JsonPropertyName("userid_list")]
public List<string> UserIds { get; }
/// <summary>
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用可不填
/// </summary>
[CanBeNull]
[JsonProperty("cursor")]
[JsonPropertyName("cursor")]
public string? Cursor { get; }
/// <summary>
/// 返回的最大记录数,整型,最大值100,默认值50,超过最大值时取最大值
/// </summary>
[CanBeNull]
[JsonProperty("limit")]
[JsonPropertyName("limit")]
public int Limit { get; }
public WeChatWorkBulkGetCustomerRequest(
List<string> userIds,
string? cursor = null,
int limit = 50)
{
Check.NotNullOrEmpty(userIds, nameof(userIds));
Check.Range(limit, nameof(limit), 1, 100);
if (userIds.Count > 100)
{
throw new ArgumentException("The maximum number of userIds allowed in the list is only 100!");
}
UserIds = userIds;
Cursor = cursor;
Limit = limit;
}
}

74
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkCreateCustomerStrategyRequest.cs

@ -0,0 +1,74 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 批量获取客户详情请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
/// </remarks>
public class WeChatWorkCreateCustomerStrategyRequest : WeChatWorkRequest
{
/// <summary>
/// 父规则组id
/// </summary>
[CanBeNull]
[JsonProperty("parent_id")]
[JsonPropertyName("parent_id")]
public int? ParentId { get; set; }
/// <summary>
/// 规则组名称
/// </summary>
[NotNull]
[JsonProperty("strategy_name")]
[JsonPropertyName("strategy_name")]
public string StrategyName { get; }
/// <summary>
/// 规则组管理员userid列表
/// </summary>
[NotNull]
[JsonProperty("admin_list")]
[JsonPropertyName("admin_list")]
public string[] AdminList { get; }
/// <summary>
/// 规则组权限
/// </summary>
[NotNull]
[JsonProperty("privilege")]
[JsonPropertyName("privilege")]
public CustomerStrategyPrivilege Privilege { get; }
/// <summary>
/// 规则组管理范围
/// </summary>
[NotNull]
[JsonProperty("range")]
[JsonPropertyName("range")]
public CustomerStrategyRange[] Range { get; }
public WeChatWorkCreateCustomerStrategyRequest(
string strategyName,
string[] adminList,
CustomerStrategyPrivilege? privilege = null,
CustomerStrategyRange[]? range = null)
{
Check.NotNullOrWhiteSpace(strategyName, nameof(strategyName));
Check.NotNullOrEmpty(adminList, nameof(adminList));
if (adminList.Length > 20)
{
throw new ArgumentException("Up to 20 admin list can be configured at a time!");
}
if (range != null && range.Length > 100)
{
throw new ArgumentException("Up to 100 management range can be configured at a time!");
}
StrategyName = strategyName;
AdminList = adminList;
Privilege = privilege ?? CustomerStrategyPrivilege.Default();
}
}

28
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkDeleteCustomerStrategyRequest.cs

@ -0,0 +1,28 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 删除规则组请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E5%88%A0%E9%99%A4%E8%A7%84%E5%88%99%E7%BB%84" />
/// </remarks>
public class WeChatWorkDeleteCustomerStrategyRequest : WeChatWorkRequest
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; }
public WeChatWorkDeleteCustomerStrategyRequest(int strategyId)
{
Check.NotDefaultOrNull<int>(strategyId, nameof(strategyId));
StrategyId = strategyId;
}
}

39
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyListRequest.cs

@ -0,0 +1,39 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 获取规则组列表请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E5%88%97%E8%A1%A8" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyListRequest : WeChatWorkRequest
{
/// <summary>
/// 分页查询游标,首次调用可不填
/// </summary>
[CanBeNull]
[JsonProperty("cursor")]
[JsonPropertyName("cursor")]
public string? Cursor { get; }
/// <summary>
/// 分页大小,默认为1000,最大不超过1000
/// </summary>
[CanBeNull]
[JsonProperty("limit")]
[JsonPropertyName("limit")]
public int? Limit { get; }
public WeChatWorkGetCustomerStrategyListRequest(string? cursor = null, int? limit = 1000)
{
if (limit.HasValue)
{
Check.Range(limit.Value, nameof(limit), 1, 1000);
}
Cursor = cursor;
Limit = limit;
}
}

47
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyRangeRequest.cs

@ -0,0 +1,47 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 获取规则组管理范围请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyRangeRequest : WeChatWorkRequest
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; }
/// <summary>
/// 分页查询游标,首次调用可不填
/// </summary>
[CanBeNull]
[JsonProperty("cursor")]
[JsonPropertyName("cursor")]
public string? Cursor { get; }
/// <summary>
/// 每个分页的成员/部门节点数,默认为1000,最大为1000
/// </summary>
[CanBeNull]
[JsonProperty("limit")]
[JsonPropertyName("limit")]
public int? Limit { get; }
public WeChatWorkGetCustomerStrategyRangeRequest(int strategyId, string? cursor = null, int? limit = 1000)
{
if (limit.HasValue)
{
Check.Range(limit.Value, nameof(limit), 1, 1000);
}
StrategyId = strategyId;
Cursor = cursor;
Limit = limit;
}
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkGetCustomerStrategyRequest.cs

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 获取规则组请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E8%8E%B7%E5%8F%96%E8%A7%84%E5%88%99%E7%BB%84%E8%AF%A6%E6%83%85" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyRequest : WeChatWorkRequest
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; }
public WeChatWorkGetCustomerStrategyRequest(int strategyId)
{
StrategyId = strategyId;
}
}

86
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkUpdateCustomerRemarkRequest.cs

@ -0,0 +1,86 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 修改客户备注信息请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92115" />
/// </remarks>
public class WeChatWorkUpdateCustomerRemarkRequest : WeChatWorkRequest
{
/// <summary>
/// 企业成员的userid
/// </summary>
[NotNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string UserId { get; }
/// <summary>
/// 外部联系人userid
/// </summary>
[NotNull]
[JsonProperty("external_userid")]
[JsonPropertyName("external_userid")]
public string ExternalUserId { get; }
/// <summary>
/// 此用户对外部联系人的备注,最多20个字符
/// </summary>
[CanBeNull]
[StringLength(20)]
[JsonProperty("remark")]
[JsonPropertyName("remark")]
public string? Remark { get; }
/// <summary>
/// 此用户对外部联系人的描述,最多150个字符
/// </summary>
[CanBeNull]
[StringLength(150)]
[JsonProperty("description")]
[JsonPropertyName("description")]
public string? Description { get; }
/// <summary>
/// 此用户对外部联系人备注的所属公司名称,最多20个字符
/// </summary>
[CanBeNull]
[StringLength(20)]
[JsonProperty("remark_company")]
[JsonPropertyName("remark_company")]
public string? RemarkCompany { get; }
/// <summary>
/// 此用户对外部联系人备注的手机号
/// </summary>
[CanBeNull]
[JsonProperty("remark_mobiles")]
[JsonPropertyName("remark_mobiles")]
public List<string>? RemarkMobiles { get; }
/// <summary>
/// 备注图片的mediaid
/// </summary>
[CanBeNull]
[JsonProperty("remark_pic_mediaid")]
[JsonPropertyName("remark_pic_mediaid")]
public string? RemarkPictureMediaId { get; }
public WeChatWorkUpdateCustomerRemarkRequest(
string userId,
string externalUserId,
string? remark = null,
string? description = null,
string? remarkCompany = null,
List<string>? remarkMobiles = null,
string? remarkPictureMediaId = null)
{
UserId = Check.NotNullOrWhiteSpace(userId, nameof(userId));
ExternalUserId = Check.NotNullOrWhiteSpace(externalUserId, nameof(externalUserId));
Remark = Check.Length(remark, nameof(remark), 20);
Description = Check.Length(description, nameof(description), 150);
RemarkCompany = Check.Length(remarkCompany, nameof(remarkCompany), 20);
RemarkMobiles = remarkMobiles;
RemarkPictureMediaId = remarkPictureMediaId;
}
}

75
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Request/WeChatWorkUpdateCustomerStrategyRequest.cs

@ -0,0 +1,75 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
/// <summary>
/// 编辑规则组及其管理范围请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883#%E7%BC%96%E8%BE%91%E8%A7%84%E5%88%99%E7%BB%84%E5%8F%8A%E5%85%B6%E7%AE%A1%E7%90%86%E8%8C%83%E5%9B%B4" />
/// </remarks>
public class WeChatWorkUpdateCustomerStrategyRequest : WeChatWorkRequest
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; }
/// <summary>
/// 规则组名称
/// </summary>
[CanBeNull]
[JsonProperty("strategy_name")]
[JsonPropertyName("strategy_name")]
public string? StrategyName { get; set; }
/// <summary>
/// 规则组管理员userid列表
/// </summary>
[CanBeNull]
[JsonProperty("admin_list")]
[JsonPropertyName("admin_list")]
public string[]? AdminList { get; set; }
/// <summary>
/// 规则组权限
/// </summary>
[CanBeNull]
[JsonProperty("privilege")]
[JsonPropertyName("privilege")]
public CustomerStrategyPrivilege? Privilege { get; set; }
/// <summary>
/// 新增管理范围
/// </summary>
[NotNull]
[JsonProperty("range_add")]
[JsonPropertyName("range_add")]
public List<CustomerStrategyRange> CreateRange { get; private set; }
/// <summary>
/// 删除管理范围
/// </summary>
[NotNull]
[JsonProperty("range_del")]
[JsonPropertyName("range_del")]
public List<CustomerStrategyRange> DeleteRange { get; private set; }
public WeChatWorkUpdateCustomerStrategyRequest(
int strategyId,
string? strategyName = null,
string[]? adminList = null,
CustomerStrategyPrivilege? privilege = null)
{
Check.NotDefaultOrNull<int>(strategyId, nameof(strategyId));
StrategyId = strategyId;
StrategyName = strategyName;
AdminList = adminList;
Privilege = privilege;
CreateRange = new List<CustomerStrategyRange>();
DeleteRange = new List<CustomerStrategyRange>();
}
}

48
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkBulkGetCustomerResponse.cs

@ -0,0 +1,48 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 批量获取客户详情响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92994" />
/// </remarks>
public class WeChatWorkBulkGetCustomerResponse : WeChatWorkResponse
{
/// <summary>
/// 外部联系人的userid列表
/// </summary>
[NotNull]
[JsonProperty("external_contact_list")]
[JsonPropertyName("external_contact_list")]
public List<ExternalContactList> ExternalUserId { get; set; } = new List<ExternalContactList>();
/// <summary>
/// 分页游标,再下次请求时填写以获取之后分页的记录,如果已经没有更多的数据则返回空
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
/// <summary>
/// 若请求中所有userid都无有效互通许可,接口直接报错701008。如果部分userid无有效互通许可,接口返回成功
/// </summary>
[CanBeNull]
[JsonProperty("fail_info")]
[JsonPropertyName("fail_info")]
public WeChatWorkBulkGetCustomerFailInfo? FailInfo { get; set; }
}
public class WeChatWorkBulkGetCustomerFailInfo
{
/// <summary>
/// 无许可的userid列表
/// </summary>
[NotNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public List<string> UnlicensedUseridList { get; set; } = new List<string>();
}

21
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkCreateCustomerStrategyResponse.cs

@ -0,0 +1,21 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 创建新的规则组响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
/// </remarks>
public class WeChatWorkCreateCustomerStrategyResponse : WeChatWorkResponse
{
/// <summary>
/// 规则组id
/// </summary>
[NotNull]
[JsonProperty("strategy_id")]
[JsonPropertyName("strategy_id")]
public int StrategyId { get; set; }
}

22
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerListResponse.cs

@ -0,0 +1,22 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 获取客户列表响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92113" />
/// </remarks>
public class WeChatWorkGetCustomerListResponse : WeChatWorkResponse
{
/// <summary>
/// 外部联系人的userid列表
/// </summary>
[NotNull]
[JsonProperty("external_userid")]
[JsonPropertyName("external_userid")]
public List<string> ExternalUserId { get; set; } = new List<string>();
}

37
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerResponse.cs

@ -0,0 +1,37 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 获取客户详情响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92114" />
/// </remarks>
public class WeChatWorkGetCustomerResponse : WeChatWorkResponse
{
/// <summary>
/// 外部联系人信息
/// </summary>
[NotNull]
[JsonProperty("external_contact")]
[JsonPropertyName("external_contact")]
public ExternalContactInfo ExternalContact { get; set; }
/// <summary>
/// 添加了此外部联系人的企业成员
/// </summary>
[NotNull]
[JsonProperty("follow_user")]
[JsonPropertyName("follow_user")]
public List<FollowUser> FollowUser { get; set; }
/// <summary>
/// 分页的cursor,当跟进人多于500人时返回
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
}

29
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyListResponse.cs

@ -0,0 +1,29 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 获取规则组列表响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyListResponse : WeChatWorkResponse
{
/// <summary>
/// 规则组列表
/// </summary>
[NotNull]
[JsonProperty("strategy")]
[JsonPropertyName("strategy")]
public CustomerStrategy[] Strategy { get; set; }
/// <summary>
/// 分页游标,用于查询下一个分页的数据,无更多数据时不返回
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyRangeResponse.cs

@ -0,0 +1,30 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 获取规则组管理范围响应参数
/// </summary>
/// <remarks>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyRangeResponse : WeChatWorkResponse
{
/// <summary>
/// 规则组管理范围
/// </summary>
[NotNull]
[JsonProperty("range")]
[JsonPropertyName("range")]
public CustomerStrategyRange[] Range { get; set; }
/// <summary>
/// 分页游标,用于查询下一个分页的数据,无更多数据时不返回
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
}

22
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/Response/WeChatWorkGetCustomerStrategyResponse.cs

@ -0,0 +1,22 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
/// <summary>
/// 获取规则组详情响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94883" />
/// </remarks>
public class WeChatWorkGetCustomerStrategyResponse : WeChatWorkResponse
{
/// <summary>
/// 规则组详情
/// </summary>
[NotNull]
[JsonProperty("strategy")]
[JsonPropertyName("strategy")]
public CustomerStrategyInfo Strategy { get; set; }
}

93
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/WeChatWorkCustomerProvider.cs

@ -0,0 +1,93 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkCustomerProvider : IWeChatWorkCustomerProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkCustomerProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkGetCustomerListResponse> GetCustomerListAsync(
string userId,
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(userId, nameof(userId));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetCustomerListAsync(token.AccessToken, userId, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerListResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkBulkGetCustomerResponse> BulkGetCustomerAsync(
WeChatWorkBulkGetCustomerRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.BulkGetCustomerAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkBulkGetCustomerResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkGetCustomerResponse> GetCustomerAsync(
string externalUserid,
string? cursor = null,
CancellationToken cancellationToken = default)
{
Check.NotNullOrWhiteSpace(externalUserid, nameof(externalUserid));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetCustomerAsync(token.AccessToken, externalUserid, cursor, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkResponse> UpdateCustomerRemarkAsync(
WeChatWorkUpdateCustomerRemarkRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.UpdateCustomerRemarkAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

111
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Customers/WeChatWorkCustomerStrategyProvider.cs

@ -0,0 +1,111 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Customers.Response;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Customers;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkCustomerStrategyProvider : IWeChatWorkCustomerStrategyProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkCustomerStrategyProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkGetCustomerStrategyListResponse> GetCustomerStrategyListAsync(
WeChatWorkGetCustomerStrategyListRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetCustomerStrategyListAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyListResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkGetCustomerStrategyResponse> GetCustomerStrategyAsync(
WeChatWorkGetCustomerStrategyRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetCustomerStrategyAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkGetCustomerStrategyRangeResponse> GetCustomerStrategyRangeAsync(
WeChatWorkGetCustomerStrategyRangeRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetCustomerStrategyRangeAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetCustomerStrategyRangeResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkCreateCustomerStrategyResponse> CreateCustomerStrategyAsync(
WeChatWorkCreateCustomerStrategyRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.CreateCustomerStrategyAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkCreateCustomerStrategyResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkResponse> UpdateCustomerStrategyAsync(
WeChatWorkUpdateCustomerStrategyRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.UpdateCustomerStrategyAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkResponse> DeleteCustomerStrategyAsync(
WeChatWorkDeleteCustomerStrategyRequest request,
CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.DeleteCustomerStrategyAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

31
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Features/WeChatWorkExternalContactFeatureDefinitionProvider.cs

@ -0,0 +1,31 @@
using LINGYUN.Abp.WeChat.Work.Features;
using LINGYUN.Abp.WeChat.Work.Localization;
using Volo.Abp.Features;
using Volo.Abp.Localization;
using Volo.Abp.Validation.StringValues;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
public class WeChatWorkExternalContactFeatureDefinitionProvider : FeatureDefinitionProvider
{
public override void Define(IFeatureDefinitionContext context)
{
var weChatFeature = context.GetGroupOrNull(WeChatWorkFeatureNames.GroupName);
if (weChatFeature == null)
{
return;
}
var group = weChatFeature.AddFeature(WeChatWorkExternalContactFeatureNames.GroupName);
group.CreateChild(
WeChatWorkExternalContactFeatureNames.Enable,
defaultValue: "false",
displayName: L("Features:ExternalContactEnable"),
description: L("Features:ExternalContactEnableDesc"),
valueType: new ToggleStringValueType(new BooleanValueValidator()));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<WeChatWorkResource>(name);
}
}

14
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Features/WeChatWorkExternalContactFeatureNames.cs

@ -0,0 +1,14 @@
using LINGYUN.Abp.WeChat.Work.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
/// <summary>
/// 企业微信客户联系模块功能
/// </summary>
public static class WeChatWorkExternalContactFeatureNames
{
public const string GroupName = WeChatWorkFeatureNames.GroupName + ".ExternalContact";
/// <summary>
/// 启用企业微信客户联系
/// </summary>
public const string Enable = GroupName + ".Enable";
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/IWeChatWorkFollowUserProvider.cs

@ -0,0 +1,20 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows;
/// <summary>
/// 企业服务人员管理接口
/// </summary>
public interface IWeChatWorkFollowUserProvider
{
/// <summary>
/// 获取配置了客户联系功能的成员列表
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92571" />
/// </remarks>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetFollowUserListResponse> GetFollowUserListAsync(CancellationToken cancellationToken = default);
}

22
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/Response/WeChatWorkGetFollowUserListResponse.cs

@ -0,0 +1,22 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response;
/// <summary>
/// 获取配置了客户联系功能的成员列表响应参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/91853" />
/// </remarks>
public class WeChatWorkGetFollowUserListResponse : WeChatWorkResponse
{
/// <summary>
/// 配置了客户联系功能的成员userid列表
/// </summary>
[NotNull]
[JsonProperty("follow_user")]
[JsonPropertyName("follow_user")]
public List<string> FollowUser { get; set; } = new List<string>();
}

38
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Follows/WeChatWorkFollowUserProvider.cs

@ -0,0 +1,38 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.ExternalContact.Follows.Response;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Follows;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkFollowUserProvider : IWeChatWorkFollowUserProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkFollowUserProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkGetFollowUserListResponse> GetFollowUserListAsync(CancellationToken cancellationToken = default)
{
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetFollowUserListAsync(token.AccessToken, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetFollowUserListResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

48
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/IWeChatWorkGroupChatProvider.cs

@ -0,0 +1,48 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response;
using System.Threading;
using System.Threading.Tasks;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats;
/// <summary>
/// 客户群管理接口
/// </summary>
public interface IWeChatWorkGroupChatProvider
{
/// <summary>
/// 获取客户群列表
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetGroupChatListResponse> GetGroupChatListAsync(
WeChatWorkGetGroupChatListRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 获取客户群详情
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkGetGroupChatResponse> GetGroupChatAsync(
WeChatWorkGetGroupChatRequest request,
CancellationToken cancellationToken = default);
/// <summary>
/// 客户群opengid转换
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
/// </remarks>
/// <param name="request">请求参数</param>
/// <param name="cancellationToken"></param>
/// <returns></returns>
Task<WeChatWorkOpengIdToChatIdResponse> OpengIdToChatIdAsync(
WeChatWorkOpengIdToChatIdRequest request,
CancellationToken cancellationToken = default);
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChat.cs

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 客户群
/// </summary>
public class GroupChat
{
/// <summary>
/// 客户群ID
/// </summary>
[NotNull]
[JsonProperty("chat_id")]
[JsonPropertyName("chat_id")]
public string ChatId { get; set; }
/// <summary>
/// 客户群跟进状态
/// </summary>
[NotNull]
[JsonProperty("status")]
[JsonPropertyName("status")]
public GroupChatStatus Status { get; set; }
}

67
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatInfo.cs

@ -0,0 +1,67 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 客户群详情
/// </summary>
public class GroupChatInfo
{
/// <summary>
/// 客户群ID
/// </summary>
[NotNull]
[JsonProperty("chat_id")]
[JsonPropertyName("chat_id")]
public string ChatId { get; set; }
/// <summary>
/// 群名
/// </summary>
[NotNull]
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 群主ID
/// </summary>
[NotNull]
[JsonProperty("owner")]
[JsonPropertyName("owner")]
public string Owner { get; set; }
/// <summary>
/// 群的创建时间
/// </summary>
[NotNull]
[JsonProperty("create_time")]
[JsonPropertyName("create_time")]
public long CreateTime { get; set; }
/// <summary>
/// 群公告
/// </summary>
[CanBeNull]
[JsonProperty("notice")]
[JsonPropertyName("notice")]
public string Notice { get; set; }
/// <summary>
/// 群成员列表
/// </summary>
[NotNull]
[JsonProperty("member_list")]
[JsonPropertyName("member_list")]
public GroupChatMember[] MemberList { get; set; }
/// <summary>
/// 群管理员列表
/// </summary>
[NotNull]
[JsonProperty("admin_list")]
[JsonPropertyName("admin_list")]
public GroupChatManager[] AdminList { get; set; }
/// <summary>
/// 当前群成员版本号。可以配合客户群变更事件减少主动调用本接口的次数
/// </summary>
[NotNull]
[JsonProperty("member_version")]
[JsonPropertyName("member_version")]
public string MemberVersion { get; set; }
}

18
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatInvitor.cs

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 邀请者
/// </summary>
public class GroupChatInvitor
{
/// <summary>
/// 邀请者的userid
/// </summary>
[NotNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string UserId { get; set; }
}

18
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatManager.cs

@ -0,0 +1,18 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 群管理员
/// </summary>
public class GroupChatManager
{
/// <summary>
/// 群管理员userid
/// </summary>
[NotNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string UserId { get; set; }
}

70
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMember.cs

@ -0,0 +1,70 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 群成员
/// </summary>
public class GroupChatMember
{
/// <summary>
/// 群成员id
/// </summary>
[NotNull]
[JsonProperty("userid")]
[JsonPropertyName("userid")]
public string UserId { get; set; }
/// <summary>
/// 成员类型
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public GroupChatMemberType Type { get; set; }
/// <summary>
/// 外部联系人在微信开放平台的唯一身份标识(微信unionid),通过此字段企业可将外部联系人与公众号/小程序用户关联起来。<br />
/// 仅当群成员类型是微信用户(包括企业成员未添加好友),且企业绑定了微信开发者ID有此字段
/// </summary>
[CanBeNull]
[JsonProperty("unionid")]
[JsonPropertyName("unionid")]
public string? UnionId { get; set; }
/// <summary>
/// 入群时间
/// </summary>
[NotNull]
[JsonProperty("join_time")]
[JsonPropertyName("join_time")]
public long JoinTime { get; set; }
/// <summary>
/// 入群方式
/// </summary>
[NotNull]
[JsonProperty("join_scene")]
[JsonPropertyName("join_scene")]
public GroupChatMemberJoinScene JoinScene { get; set; }
/// <summary>
/// 邀请者。目前仅当是由本企业内部成员邀请入群时会返回该值
/// </summary>
[CanBeNull]
[JsonProperty("invitor")]
[JsonPropertyName("invitor")]
public GroupChatInvitor? Invitor { get; set; }
/// <summary>
/// 在群里的昵称
/// </summary>
[CanBeNull]
[JsonProperty("group_nickname")]
[JsonPropertyName("group_nickname")]
public string? GroupNickname { get; set; }
/// <summary>
/// 名字。仅当 need_name = 1 时返回<br />
/// 如果是微信用户,则返回其在微信中设置的名字<br />
/// 如果是企业微信联系人,则返回其设置对外展示的别名或实名
/// </summary>
[CanBeNull]
[JsonProperty("name")]
[JsonPropertyName("name")]
public string? Name { get; set; }
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMemberJoinScene.cs

@ -0,0 +1,25 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 入群方式
/// </summary>
[Description("入群方式")]
public enum GroupChatMemberJoinScene
{
/// <summary>
/// 由群成员邀请入群(直接邀请入群)
/// </summary>
[Description("直接邀请入群")]
DirectInvitation = 1,
/// <summary>
/// 由群成员邀请入群(通过邀请链接入群)
/// </summary>
[Description("通过邀请链接入群")]
InvitationLink = 2,
/// <summary>
/// 通过扫描群二维码入群
/// </summary>
[Description("通过扫描群二维码入群")]
ScanQrCode = 3,
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatMemberType.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 成员类型
/// </summary>
[Description("成员类型")]
public enum GroupChatMemberType
{
/// <summary>
/// 企业成员
/// </summary>
[Description("企业成员")]
Internal = 1,
/// <summary>
/// 外部联系人
/// </summary>
[Description("外部联系人")]
External = 2
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/GroupChatStatus.cs

@ -0,0 +1,30 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 客户群跟进状态
/// </summary>
[Description("客户群跟进状态")]
public enum GroupChatStatus
{
/// <summary>
/// 跟进人正常
/// </summary>
[Description("跟进人正常")]
Normal = 0,
/// <summary>
/// 跟进人离职
/// </summary>
[Description("跟进人离职")]
Leaves = 1,
/// <summary>
/// 离职继承中
/// </summary>
[Description("离职继承中")]
Resiging = 2,
/// <summary>
/// 离职继承完成
/// </summary>
[Description(" 离职继承完成")]
ResignCompleted = 3,
}

31
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/OwnerFilter.cs

@ -0,0 +1,31 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 群主过滤
/// </summary>
public class OwnerFilter
{
/// <summary>
/// 用户ID列表。最多100个
/// </summary>
[NotNull]
[JsonProperty("userid_list")]
[JsonPropertyName("userid_list")]
public string[] UserIdList { get; }
public OwnerFilter(string[] userIdList)
{
Check.NotNullOrEmpty(userIdList, nameof(userIdList));
if (userIdList.Length > 100)
{
throw new ArgumentException("The maximum number of parameters allowed for group owner filtering is only 100!");
}
UserIdList = userIdList;
}
}

30
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Models/StatusFilter.cs

@ -0,0 +1,30 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
/// <summary>
/// 客户群跟进状态过滤
/// </summary>
[Description("客户群跟进状态过滤")]
public enum StatusFilter
{
/// <summary>
/// 所有列表
/// </summary>
[Description("所有列表")]
All = 0,
/// <summary>
/// 跟进人离职
/// </summary>
[Description("跟进人离职")]
Leaves = 1,
/// <summary>
/// 离职继承中
/// </summary>
[Description("离职继承中")]
Resiging = 2,
/// <summary>
/// 离职继承完成
/// </summary>
[Description(" 离职继承完成")]
ResignCompleted = 3,
}

50
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkGetGroupChatListRequest.cs

@ -0,0 +1,50 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request;
/// <summary>
/// 获取客户群列表请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
/// </remarks>
public class WeChatWorkGetGroupChatListRequest : WeChatWorkRequest
{
/// <summary>
/// 客户群跟进状态过滤
/// </summary>
[CanBeNull]
[JsonProperty("status_filter")]
[JsonPropertyName("status_filter")]
public StatusFilter? StatusFilter { get; set; }
/// <summary>
/// 客户群跟进状态过滤
/// </summary>
[CanBeNull]
[JsonProperty("owner_filter")]
[JsonPropertyName("owner_filter")]
public OwnerFilter[]? OwnerFilter { get; set; }
/// <summary>
/// 用于分页查询的游标,字符串类型,由上一次调用返回,首次调用不填
/// </summary>
[CanBeNull]
[JsonProperty("cursor")]
[JsonPropertyName("cursor")]
public string? Cursor { get; set; }
/// <summary>
/// 分页,预期请求的数据量,取值范围 1 ~ 1000
/// </summary>
[CanBeNull]
[JsonProperty("limit")]
[JsonPropertyName("limit")]
public int Limit { get; }
public WeChatWorkGetGroupChatListRequest(int limit = 1000)
{
Check.Range(limit, nameof(limit), 1, 1000);
Limit = limit;
}
}

36
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkGetGroupChatRequest.cs

@ -0,0 +1,36 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request;
/// <summary>
/// 获取客户群详情
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
/// </remarks>
public class WeChatWorkGetGroupChatRequest : WeChatWorkRequest
{
/// <summary>
/// 客户群ID
/// </summary>
[NotNull]
[JsonProperty("chat_id")]
[JsonPropertyName("chat_id")]
public string ChatId { get; }
/// <summary>
/// 是否需要返回群成员的名字group_chat.member_list.name。0-不返回;1-返回。默认不返回
/// </summary>
[CanBeNull]
[JsonProperty("need_name")]
[JsonPropertyName("need_name")]
public int? NeedName { get; }
public WeChatWorkGetGroupChatRequest(string chatId, bool needName = false)
{
Check.NotNullOrWhiteSpace(chatId, nameof(chatId));
ChatId = chatId;
NeedName = needName ? 1 : 0;
}
}

28
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Request/WeChatWorkOpengIdToChatIdRequest.cs

@ -0,0 +1,28 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
using Volo.Abp;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request;
/// <summary>
/// 客户群opengid转换请求参数
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
/// </remarks>
public class WeChatWorkOpengIdToChatIdRequest : WeChatWorkRequest
{
/// <summary>
/// 小程序在微信获取到的群ID
/// </summary>
[NotNull]
[JsonProperty("opengid")]
[JsonPropertyName("opengid")]
public string OpengId { get; }
public WeChatWorkOpengIdToChatIdRequest(string opengId)
{
Check.NotNullOrWhiteSpace(opengId, nameof(opengId));
OpengId = opengId;
}
}

29
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkGetGroupChatListResponse.cs

@ -0,0 +1,29 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response;
/// <summary>
/// 获取客户群列表响应结果
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92120" />
/// </remarks>
public class WeChatWorkGetGroupChatListResponse : WeChatWorkResponse
{
/// <summary>
/// 客户群列表
/// </summary>
[NotNull]
[JsonProperty("group_chat_list")]
[JsonPropertyName("group_chat_list")]
public GroupChat[] GroupChatList { get; set; }
/// <summary>
/// 分页游标,下次请求时填写以获取之后分页的记录。如果该字段返回空则表示已没有更多数据
/// </summary>
[CanBeNull]
[JsonProperty("next_cursor")]
[JsonPropertyName("next_cursor")]
public string? NextCursor { get; set; }
}

22
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkGetGroupChatResponse.cs

@ -0,0 +1,22 @@
using JetBrains.Annotations;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Models;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response;
/// <summary>
/// 获取客户群详情响应结果
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/92122" />
/// </remarks>
public class WeChatWorkGetGroupChatResponse : WeChatWorkResponse
{
/// <summary>
/// 客户群详情
/// </summary>
[NotNull]
[JsonProperty("group_chat")]
[JsonPropertyName("group_chat")]
public GroupChatInfo GroupChat { get; set; }
}

21
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/Response/WeChatWorkOpengIdToChatIdResponse.cs

@ -0,0 +1,21 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response;
/// <summary>
/// 客户群opengid转换响应结果
/// </summary>
/// <remarks>
/// 详情见: <see href="https://developer.work.weixin.qq.com/document/path/94822" />
/// </remarks>
public class WeChatWorkOpengIdToChatIdResponse : WeChatWorkResponse
{
/// <summary>
/// 客户群ID,可以用来调用获取客户群详情
/// </summary>
[NotNull]
[JsonProperty("chat_id")]
[JsonPropertyName("chat_id")]
public string ChatId { get; set; }
}

76
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/GroupChats/WeChatWorkGroupChatProvider.cs

@ -0,0 +1,76 @@
using LINGYUN.Abp.WeChat.Work.ExternalContact.Features;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Request;
using LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats.Response;
using LINGYUN.Abp.WeChat.Work.Token;
using Microsoft.Extensions.DependencyInjection;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Features;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.GroupChats;
[RequiresFeature(WeChatWorkExternalContactFeatureNames.Enable)]
public class WeChatWorkGroupChatProvider : IWeChatWorkGroupChatProvider, ISingletonDependency
{
protected IHttpClientFactory HttpClientFactory { get; }
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; }
public WeChatWorkGroupChatProvider(
IHttpClientFactory httpClientFactory,
IWeChatWorkTokenProvider weChatWorkTokenProvider)
{
HttpClientFactory = httpClientFactory;
WeChatWorkTokenProvider = weChatWorkTokenProvider;
}
public async virtual Task<WeChatWorkGetGroupChatListResponse> GetGroupChatListAsync(
WeChatWorkGetGroupChatListRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetGroupChatListAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetGroupChatListResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkGetGroupChatResponse> GetGroupChatAsync(
WeChatWorkGetGroupChatRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.GetGroupChatAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkGetGroupChatResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
public async virtual Task<WeChatWorkOpengIdToChatIdResponse> OpengIdToChatIdAsync(
WeChatWorkOpengIdToChatIdRequest request,
CancellationToken cancellationToken = default)
{
Check.NotNull(request, nameof(request));
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken);
var client = HttpClientFactory.CreateWeChatWorkApiClient();
using var response = await client.OpengIdToChatIdAsync(token.AccessToken, request, cancellationToken);
var wechatResponse = await response.DeserializeObjectAsync<WeChatWorkOpengIdToChatIdResponse>();
wechatResponse.ThrowIfNotSuccess();
return wechatResponse;
}
}

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources/en.json

@ -0,0 +1,7 @@
{
"culture": "en",
"texts": {
"Features:ExternalContactEnable": "Enable External Contact",
"Features:ExternalContactEnableDesc": "Enable the ability to provide the application with an Enterprise wechat customer contact interface."
}
}

7
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Localization/Resources/zh-Hans.json

@ -0,0 +1,7 @@
{
"culture": "zh-Hans",
"texts": {
"Features:ExternalContactEnable": "启用客户联系",
"Features:ExternalContactEnableDesc": "启用以使应用拥有企业微信客户联系接口的能力."
}
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChaDelMemberEvent.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群成员退群事件推送
/// </summary>
[EventName("external_chat_del_member")]
public class ExternalChaDelMemberEvent : ExternalChatChangeMemberEvent
{
/// <summary>
/// 当是成员退群时有值。表示成员的退群方式<br />
/// 0 - 自己退群<br />
/// 1 - 群主/群管理员移出<br />
/// </summary>
[XmlElement("QuitScene")]
public ExternalChatMemberQuitScene QuitScene { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChaDelMemberEvent>(this);
}
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatAddMemberEvent.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群成员入群事件推送
/// </summary>
[EventName("external_chat_add_member")]
public class ExternalChatAddMemberEvent : ExternalChatChangeMemberEvent
{
/// <summary>
/// 当是成员入群时有值。表示成员的入群方式<br />
/// 0 - 由成员邀请入群(包括直接邀请入群和通过邀请链接入群)<br />
/// 3 - 通过扫描群二维码入群<br />
/// </summary>
[XmlElement("JoinScene")]
public ExternalChatMemberJoinScene JoinScene { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatAddMemberEvent>(this);
}
}

21
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeEvent.cs

@ -0,0 +1,21 @@
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群变更事件推送
/// </summary>
public abstract class ExternalChatChangeEvent : WeChatWorkEventMessage
{
/// <summary>
/// 变更类型
/// </summary>
[XmlElement("ChangeType")]
public string ChangeType { get; set; }
/// <summary>
/// 群ID
/// </summary>
[XmlElement("ChatId")]
public string ChatId { get; set; }
}

39
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeMemberEvent.cs

@ -0,0 +1,39 @@
using System.Collections.Generic;
using System.Xml.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群成员变更事件推送
/// </summary>
public abstract class ExternalChatChangeMemberEvent : ExternalChatUpdateEvent
{
/// <summary>
/// 成员变更数量
/// </summary>
[XmlElement("MemChangeCnt")]
public int MemChangeCnt { get; set; }
/// <summary>
/// 变更的成员列表
/// </summary>
[XmlElement("MemChangeList")]
public List<ExternalChatChangeMember> MemChangeList { get; set; } = new List<ExternalChatChangeMember>();
/// <summary>
/// 变更前的群成员版本号
/// </summary>
[XmlElement("LastMemVer")]
public string LastMemVer { get; set; }
/// <summary>
/// 变更后的群成员版本号
/// </summary>
[XmlElement("CurMemVer")]
public string CurMemVer { get; set; }
}
public class ExternalChatChangeMember
{
/// <summary>
/// 成员Id
/// </summary>
[XmlElement("Item")]
public string UserId { get; set; }
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeNameEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群群名变更事件推送
/// </summary>
[EventName("external_chat_change_name")]
public class ExternalChatChangeNameEvent : ExternalChatUpdateEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatChangeNameEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeNoticeEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群群公告变更事件推送
/// </summary>
[EventName("external_chat_change_notice")]
public class ExternalChatChangeNoticeEvent : ExternalChatUpdateEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatChangeNoticeEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatChangeOwnerEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群群主变更事件推送
/// </summary>
[EventName("external_chat_change_owner")]
public class ExternalChatChangeOwnerEvent : ExternalChatUpdateEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatChangeOwnerEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatCreateEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群创建事件推送
/// </summary>
[EventName("external_chat_create")]
public class ExternalChatCreateEvent : ExternalChatChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatCreateEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatDismissEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群解散事件推送
/// </summary>
[EventName("external_chat_dismiss")]
public class ExternalChatDismissEvent : ExternalChatChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalChatDismissEvent>(this);
}
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatMemberJoinScene.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 成员的入群方式
/// </summary>
[Description("成员的入群方式")]
public enum ExternalChatMemberJoinScene
{
/// <summary>
/// 由成员邀请入群
/// </summary>
[Description("由成员邀请入群")]
MemberInvitation = 0,
/// <summary>
/// 通过扫描群二维码入群
/// </summary>
[Description("通过扫描群二维码入群")]
ScanQrCode = 3
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatMemberQuitScene.cs

@ -0,0 +1,20 @@
using System.ComponentModel;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 成员的退群方式
/// </summary>
[Description("成员的退群方式")]
public enum ExternalChatMemberQuitScene
{
/// <summary>
/// 自己退群
/// </summary>
[Description("自己退群")]
UserSelf = 0,
/// <summary>
/// 群主/群管理员移出
/// </summary>
[Description("群主/群管理员移出")]
Admin = 1
}

19
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalChatUpdateEvent.cs

@ -0,0 +1,19 @@
using System.Xml.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户群变更事件推送
/// </summary>
public abstract class ExternalChatUpdateEvent : ExternalChatChangeEvent
{
/// <summary>
/// 变更详情。目前有以下几种:<br />
/// add_member : 成员入群<br />
/// del_member : 成员退群<br />
/// change_owner : 群主变更<br />
/// change_name : 群名变更<br />
/// change_notice : 群公告变更
/// </summary>
[XmlElement("UpdateDetail")]
public string UpdateDetail { get; set; }
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactChangeEvent.cs

@ -0,0 +1,25 @@
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户变更事件推送
/// </summary>
public abstract class ExternalContactChangeEvent : WeChatWorkEventMessage
{
/// <summary>
/// 变更类型
/// </summary>
[XmlElement("ChangeType")]
public string ChangeType { get; set; }
/// <summary>
/// 企业服务人员的UserID
/// </summary>
[XmlElement("UserID")]
public string UserId { get; set; }
/// <summary>
/// 外部联系人的userid,注意不是企业成员的账号
/// </summary>
[XmlElement("ExternalUserID")]
public string ExternalUserId { get; set; }
}

28
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactCreateEvent.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 添加企业客户事件推送
/// </summary>
[EventName("external_contact_create")]
public class ExternalContactCreateEvent : ExternalContactChangeEvent
{
/// <summary>
/// 添加此用户的「联系我」方式配置的state参数,或在获客链接中指定的customer_channel参数,可用于识别添加此用户的渠道
/// </summary>
[XmlElement("State")]
public string State { get; set; }
/// <summary>
/// 欢迎语code,可用于发送欢迎语
/// </summary>
[XmlElement("WelcomeCode")]
public string WelcomeCode { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactCreateEvent>(this);
}
}

28
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactCreateHalfEvent.cs

@ -0,0 +1,28 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 外部联系人免验证添加成员事件
/// </summary>
[EventName("external_contact_create_half")]
public class ExternalContactCreateHalfEvent : ExternalContactChangeEvent
{
/// <summary>
/// 添加此用户的「联系我」方式配置的state参数,或在获客链接中指定的customer_channel参数,可用于识别添加此用户的渠道
/// </summary>
[XmlElement("State")]
public string State { get; set; }
/// <summary>
/// 欢迎语code,可用于发送欢迎语
/// </summary>
[XmlElement("WelcomeCode")]
public string WelcomeCode { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactCreateHalfEvent>(this);
}
}

23
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactDeleteEvent.cs

@ -0,0 +1,23 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 删除企业客户事件
/// </summary>
[EventName("external_contact_delete")]
public class ExternalContactDeleteEvent : ExternalContactChangeEvent
{
/// <summary>
/// 删除客户的操作来源,DELETE_BY_TRANSFER表示此客户是因在职继承自动被转接成员删除
/// </summary>
[XmlElement("Source")]
public string Source { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactDeleteEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactDeleteFollowUserEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 删除跟进成员事件
/// </summary>
[EventName("external_contact_del_follow_user")]
public class ExternalContactDeleteFollowUserEvent : ExternalContactChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactDeleteFollowUserEvent>(this);
}
}

23
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactTransferFailEvent.cs

@ -0,0 +1,23 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 客户接替失败事件
/// </summary>
[EventName("external_contact_transfer_fail")]
public class ExternalContactTransferFailEvent : ExternalContactChangeEvent
{
/// <summary>
/// 接替失败的原因, customer_refused-客户拒绝, customer_limit_exceed-接替成员的客户数达到上限
/// </summary>
[XmlElement("FailReason")]
public string FailReason { get; set; }
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactTransferFailEvent>(this);
}
}

17
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalContactUpdateEvent.cs

@ -0,0 +1,17 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 编辑企业客户事件推送
/// </summary>
[EventName("external_contact_update")]
public class ExternalContactUpdateEvent : ExternalContactChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalContactUpdateEvent>(this);
}
}

20
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagChangeEvent.cs

@ -0,0 +1,20 @@
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using System.Xml.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户标签变更事件推送
/// </summary>
public abstract class ExternalTagChangeEvent : WeChatWorkEventMessage
{
/// <summary>
/// 变更类型
/// </summary>
[XmlElement("ChangeType")]
public string ChangeType { get; set; }
/// <summary>
/// 标签或标签组所属的规则组id,只回调给“客户联系”应用
/// </summary>
[XmlElement("StrategyId")]
public string StrategyId { get; set; }
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagCreateEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户标签创建事件推送
/// </summary>
[EventName("change_external_tag_create")]
public class ExternalTagCreateEvent : ExternalTagChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalTagCreateEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagDeleteEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户标签删除事件推送
/// </summary>
[EventName("change_external_tag_delete")]
public class ExternalTagDeleteEvent : ExternalTagChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalTagDeleteEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagShuffleEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户标签重排事件推送
/// </summary>
[EventName("change_external_tag_shuffle")]
public class ExternalTagShuffleEvent : ExternalTagChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalTagShuffleEvent>(this);
}
}

16
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Messages/Models/ExternalTagUpdateEvent.cs

@ -0,0 +1,16 @@
using LINGYUN.Abp.WeChat.Common.Messages;
using LINGYUN.Abp.WeChat.Work.Common.Messages;
using Volo.Abp.EventBus;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Messages.Models;
/// <summary>
/// 企业客户标签变更事件推送
/// </summary>
[EventName("change_external_tag_update")]
public class ExternalTagUpdateEvent : ExternalTagChangeEvent
{
public override WeChatMessageEto ToEto()
{
return new WeChatWorkEventMessageEto<ExternalTagUpdateEvent>(this);
}
}

25
aspnet-core/framework/wechat/LINGYUN.Abp.WeChat.Work.ExternalContact/LINGYUN/Abp/WeChat/Work/ExternalContact/Models/ExternalAttribute.cs

@ -0,0 +1,25 @@
using JetBrains.Annotations;
using Newtonsoft.Json;
using System.Text.Json.Serialization;
namespace LINGYUN.Abp.WeChat.Work.ExternalContact.Models;
/// <summary>
/// 成员对外属性
/// </summary>
public abstract class ExternalAttribute
{
/// <summary>
/// 属性名称: 需要先确保在管理端有创建该属性,否则会忽略
/// </summary>
[NotNull]
[JsonProperty("name")]
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 属性类型
/// </summary>
[NotNull]
[JsonProperty("type")]
[JsonPropertyName("type")]
public ExternalAttributeType Type { get; set; }
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save