Skip to content

Commit 1087a5d

Browse files
committed
feat 命令迁移
1 parent c7552a1 commit 1087a5d

37 files changed

+1661
-313
lines changed

XinjingdailyBot.Command/Command/AdminCommand.cs

+960
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,228 @@
1-
using Microsoft.Extensions.Logging;
1+
using System.Text;
2+
using Microsoft.Extensions.Logging;
23
using Telegram.Bot;
34
using Telegram.Bot.Types;
5+
using Telegram.Bot.Types.Enums;
46
using XinjingdailyBot.Infrastructure.Attribute;
57
using XinjingdailyBot.Infrastructure.Enums;
68
using XinjingdailyBot.Infrastructure.Extensions;
79
using XinjingdailyBot.Interface.Data;
810
using XinjingdailyBot.Model.Models;
11+
using XinjingdailyBot.Repository;
912

1013
namespace XinjingdailyBot.Command.Command
1114
{
12-
[AppService(ServiceLifetime = LifeTime.Scoped)]
15+
[AppService(ServiceLifetime = LifeTime.Transient)]
1316
public class NormalCommand
1417
{
1518
private readonly ILogger<NormalCommand> _logger;
1619
private readonly ITelegramBotClient _botClient;
1720
private readonly IUserService _userService;
21+
private readonly LevelRepository _levelRepository;
22+
private readonly GroupRepository _groupRepository;
1823

1924
public NormalCommand(
2025
ILogger<NormalCommand> logger,
2126
ITelegramBotClient botClient,
22-
IUserService userService)
27+
IUserService userService,
28+
LevelRepository levelRepository,
29+
GroupRepository groupRepository)
2330
{
2431
_logger = logger;
2532
_botClient = botClient;
2633
_userService = userService;
34+
_levelRepository = levelRepository;
35+
_groupRepository = groupRepository;
2736
}
2837

29-
[TextCmd("ECHO", Alias = "E")]
30-
public async Task Echo(Users users, Message message)
38+
/// <summary>
39+
/// 检测机器人是否存活
40+
/// </summary>
41+
/// <param name="message"></param>
42+
/// <returns></returns>
43+
[TextCmd("PING", UserRights.NormalCmd, Description = "检测机器人是否存活")]
44+
public async Task ResponsePing(Message message)
3145
{
32-
await _botClient.SendCommandReply("test", message);
46+
await _botClient.SendCommandReply("PONG!", message);
3347
}
3448

49+
/// <summary>
50+
/// 设置是否匿名
51+
/// </summary>
52+
/// <param name="dbUser"></param>
53+
/// <param name="message"></param>
54+
/// <returns></returns>
55+
[TextCmd("ANONYMOUS", UserRights.NormalCmd, Alias = "ANYMOUSE", Description = "设置是否匿名")]
56+
public async Task ResponseAnonymous(Users dbUser, Message message)
57+
{
58+
bool anymouse = !dbUser.PreferAnonymous;
59+
dbUser.PreferAnonymous = anymouse;
60+
dbUser.ModifyAt = DateTime.Now;
61+
await _userService.Updateable(dbUser).UpdateColumns(x => new { x.PreferAnonymous, x.ModifyAt }).ExecuteCommandAsync();
62+
63+
string mode = anymouse ? "匿名投稿" : "保留来源";
64+
string text = $"后续投稿将默认使用【{mode}】";
65+
await _botClient.SendCommandReply(text, message);
66+
}
3567

36-
[TextCmd("TEST")]
37-
public async Task Test(Users users, Message message)
68+
/// <summary>
69+
/// 设置稿件审核后是否通知
70+
/// </summary>
71+
/// <param name="dbUser"></param>
72+
/// <param name="message"></param>
73+
/// <returns></returns>
74+
[TextCmd("NOTIFICATION", UserRights.NormalCmd, Description = "设置稿件审核后是否通知")]
75+
public async Task ResponseNotification(Users dbUser, Message message)
3876
{
39-
await _botClient.SendCommandReply("test", message);
77+
bool notificationg = !dbUser.Notification;
78+
dbUser.Notification = notificationg;
79+
dbUser.ModifyAt = DateTime.Now;
80+
await _userService.Updateable(dbUser).UpdateColumns(x => new { x.Notification, x.ModifyAt }).ExecuteCommandAsync();
81+
82+
string mode = notificationg ? "接收通知" : "静默模式";
83+
string text = $"稿件被审核或者过期时将会尝试通知用户\n当前通知设置: {mode}";
84+
await _botClient.SendCommandReply(text, message);
85+
}
86+
87+
/// <summary>
88+
/// 获取自己的信息
89+
/// </summary>
90+
/// <param name="dbUser"></param>
91+
/// <param name="message"></param>
92+
/// <returns></returns>
93+
[TextCmd("MYINFO", UserRights.NormalCmd, Description = "获取自己的信息")]
94+
public async Task ResponseMyInfo(Users dbUser, Message message)
95+
{
96+
string userNick = message.From!.EscapedNickName();
97+
string level = _levelRepository.GetLevelName(dbUser.Level);
98+
string group = _groupRepository.GetGroupName(dbUser.GroupID);
99+
100+
int totalPost = dbUser.PostCount - dbUser.ExpiredPostCount;
101+
102+
StringBuilder sb = new();
103+
104+
sb.AppendLine("-- 基础信息 --");
105+
sb.AppendLine($"用户名: <code>{userNick}</code>");
106+
sb.AppendLine($"用户ID: <code>{dbUser.UserID}</code>");
107+
sb.AppendLine($"用户组: <code>{group}</code>");
108+
sb.AppendLine($"等级: <code>{level}</code>");
109+
sb.AppendLine($"投稿数量: <code>{totalPost}</code>");
110+
sb.AppendLine($"投稿通过率: <code>{(100.0 * dbUser.AcceptCount / totalPost).ToString("0.00")}%</code>");
111+
sb.AppendLine($"通过数量: <code>{dbUser.AcceptCount}</code>");
112+
sb.AppendLine($"拒绝数量: <code>{dbUser.RejetCount}</code>");
113+
sb.AppendLine($"审核数量: <code>{dbUser.ReviewCount}</code>");
114+
sb.AppendLine();
115+
sb.AppendLine("-- 用户排名 --");
116+
117+
DateTime now = DateTime.Now;
118+
DateTime prev30Days = now.AddDays(-30).AddHours(-now.Hour).AddMinutes(-now.Minute).AddSeconds(-now.Second);
119+
120+
if (dbUser.GroupID == 1)
121+
{
122+
if (dbUser.AcceptCount >= 1)
123+
{
124+
const int miniumPost = 10;
125+
126+
int acceptCountRank = await _userService.Queryable().Where(x => !x.IsBan && !x.IsBot && x.GroupID == 1 && x.AcceptCount > dbUser.AcceptCount && x.ModifyAt >= prev30Days).CountAsync() + 1;
127+
128+
double ratio = 1.0 * dbUser.AcceptCount / dbUser.PostCount;
129+
int acceptRatioRank = await _userService.Queryable().Where(x => !x.IsBan && !x.IsBot && x.GroupID == 1 && x.AcceptCount > miniumPost && x.ModifyAt >= prev30Days)
130+
.Select(y => 100.0 * y.AcceptCount / y.PostCount).Where(x => x > ratio).CountAsync() + 1;
131+
132+
sb.AppendLine($"通过数排名: <code>{acceptCountRank}</code>");
133+
sb.AppendLine($"通过率排名: <code>{acceptRatioRank}</code>");
134+
}
135+
else
136+
{
137+
sb.AppendLine("稿件数量太少, 未进入排行榜");
138+
}
139+
}
140+
else
141+
{
142+
int activeUser = await _userService.Queryable().Where(x => !x.IsBan && !x.IsBot && x.ModifyAt >= prev30Days).CountAsync();
143+
sb.AppendLine($"活跃用户数: <code>{activeUser}</code>");
144+
145+
sb.AppendLine($"管理员不参与用户排名");
146+
sb.AppendLine($"可以使用命令 /userrank 查看总排名");
147+
}
148+
149+
await _botClient.SendCommandReply(sb.ToString(), message, parsemode: ParseMode.Html);
40150
}
151+
152+
153+
/// <summary>
154+
/// 获取自己的权限
155+
/// </summary>
156+
/// <param name="botClient"></param>
157+
/// <param name="dbUser"></param>
158+
/// <param name="message"></param>
159+
/// <returns></returns>
160+
[TextCmd("MYRIGHT", UserRights.NormalCmd, Description = "获取自己的权限")]
161+
public async Task ResponseMyRight(ITelegramBotClient botClient, Users dbUser, Message message)
162+
{
163+
var right = dbUser.Right;
164+
bool superCmd = right.HasFlag(UserRights.SuperCmd);
165+
bool adminCmd = right.HasFlag(UserRights.AdminCmd);
166+
bool normalCmd = right.HasFlag(UserRights.NormalCmd);
167+
bool sendPost = right.HasFlag(UserRights.SendPost);
168+
bool reviewPost = right.HasFlag(UserRights.ReviewPost);
169+
bool directPost = right.HasFlag(UserRights.DirectPost);
170+
string userNick = message.From!.EscapedNickName();
171+
172+
string group = _groupRepository.GetGroupName(dbUser.GroupID);
173+
174+
List<string> functions = new();
175+
if (sendPost) { functions.Add("投递稿件"); }
176+
if (reviewPost) { functions.Add("审核稿件"); }
177+
if (directPost) { functions.Add("直接发布稿件"); }
178+
if (functions.Count == 0) { functions.Add("无"); }
179+
180+
List<string> commands = new();
181+
if (superCmd) { commands.Add("所有命令"); }
182+
if (adminCmd) { commands.Add("管理员命令"); }
183+
if (normalCmd) { commands.Add("普通命令"); }
184+
if (functions.Count == 0) { commands.Add("无"); }
185+
186+
StringBuilder sb = new();
187+
sb.AppendLine($"用户名: <code>{userNick}</code>");
188+
sb.AppendLine($"用户组: <code>{group}</code>");
189+
sb.AppendLine($"功能: <code>{string.Join(", ", functions)}</code>");
190+
sb.AppendLine($"命令: <code>{string.Join(", ", commands)}</code>");
191+
192+
await botClient.SendCommandReply(sb.ToString(), message, parsemode: ParseMode.Html);
193+
}
194+
195+
/// <summary>
196+
/// 艾特群管理
197+
/// </summary>
198+
/// <param name="botClient"></param>
199+
/// <param name="message"></param>
200+
/// <returns></returns>
201+
[TextCmd("ADMIN", UserRights.NormalCmd, Description = "艾特群管理")]
202+
public async Task ResponseCallAdmins(Message message)
203+
{
204+
StringBuilder sb = new();
205+
206+
if (message.Chat.Type != ChatType.Group && message.Chat.Type != ChatType.Supergroup)
207+
{
208+
sb.AppendLine("该命令仅在群组内有效");
209+
}
210+
else
211+
{
212+
ChatMember[] admins = await _botClient.GetChatAdministratorsAsync(message.Chat.Id);
213+
214+
foreach (var menber in admins)
215+
{
216+
var admin = menber.User;
217+
if (!(admin.IsBot || string.IsNullOrEmpty(admin.Username)))
218+
{
219+
sb.AppendLine($"@{admin.Username}");
220+
}
221+
}
222+
}
223+
224+
await _botClient.SendCommandReply(sb.ToString(), message);
225+
}
226+
41227
}
42228
}

XinjingdailyBot.Infrastructure/Extensions/ChatExtension.cs

+10
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,15 @@ public static string ChatProfile(this Chat chat)
1313
{
1414
return $"{chat.Title} {chat.ChatID()}";
1515
}
16+
17+
/// <summary>
18+
/// HTML转义后的聊天名
19+
/// </summary>
20+
/// <param name="user"></param>
21+
/// <returns></returns>
22+
public static string EscapedChatName(this Chat chat)
23+
{
24+
return chat.Title?.EscapeHtml() ?? "";
25+
}
1626
}
1727
}

XinjingdailyBot.Infrastructure/Extensions/StringExtension.cs

+21-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,26 @@ namespace XinjingdailyBot.Infrastructure.Extensions
55
{
66
public static class StringExtension
77
{
8+
/// <summary>
9+
/// HTML转义
10+
/// </summary>
11+
/// <param name="text"></param>
12+
/// <returns></returns>
13+
public static string EscapeHtml(this string text)
14+
{
15+
if (string.IsNullOrEmpty(text))
16+
{
17+
return "";
18+
}
19+
else
20+
{
21+
var escapedText = text
22+
.Replace("<", "<")
23+
.Replace(">", ">")
24+
.Replace("&", "&");
25+
return escapedText;
26+
}
27+
}
828

929
/// <summary>
1030
/// SQL条件拼接
@@ -36,7 +56,7 @@ public static bool IfNotEmpty(this string str)
3656
public static string ReplaceFirst(this string input, string oldValue, string newValue)
3757
{
3858
Regex regEx = new Regex(oldValue, RegexOptions.Multiline);
39-
return regEx.Replace(input, newValue == null ? "" : newValue, 1);
59+
return regEx.Replace(input, newValue ?? "", 1);
4060
}
4161

4262
/// <summary>

XinjingdailyBot.Infrastructure/Extensions/UserExtension.cs

+16-28
Original file line numberDiff line numberDiff line change
@@ -16,48 +16,36 @@ public static string UserID(this User user)
1616

1717
public static string UserProfile(this User user)
1818
{
19-
return $"{user.EscapedUserName()} {user.UserID()}";
19+
return $"{user.EscapedNickName()} {user.UserID()}";
2020
}
2121

2222
/// <summary>
23-
/// HTML转义
24-
/// </summary>
25-
/// <param name="text"></param>
26-
/// <returns></returns>
27-
public static string EscapeHtml(string? text)
28-
{
29-
if (string.IsNullOrEmpty(text))
30-
{
31-
return "";
32-
}
33-
else
34-
{
35-
var escapedText = text
36-
.Replace("<", "<")
37-
.Replace(">", ">")
38-
.Replace("&", "&");
39-
return escapedText;
40-
}
41-
}
42-
43-
/// <summary>
44-
/// HTML转义后的聊天名
23+
/// HTML转义后的用户名
4524
/// </summary>
4625
/// <param name="user"></param>
4726
/// <returns></returns>
48-
public static string EscapedChatName(this Chat chat)
27+
public static string EscapedNickName(this User user)
4928
{
50-
return EscapeHtml(chat.Title);
29+
return user.NickName().EscapeHtml();
5130
}
5231

5332
/// <summary>
54-
/// HTML转义后的用户名
33+
/// Html格式的用户链接
5534
/// </summary>
5635
/// <param name="user"></param>
5736
/// <returns></returns>
58-
public static string EscapedUserName(this User user)
37+
public static string HtmlUserLink(this User user)
5938
{
60-
return EscapeHtml(user.NickName());
39+
string nick = user.EscapedNickName();
40+
41+
if (string.IsNullOrEmpty(user.Username))
42+
{
43+
return $"<a href=\"tg://user?id={user.UserID}\">{nick}</a>";
44+
}
45+
else
46+
{
47+
return $"<a href=\"https://t.me/{user.Username}\">{nick}</a>";
48+
}
6149
}
6250

6351
}

XinjingdailyBot.Interface/Bot/Handler/ICommandHandler.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace XinjingdailyBot.Interface.Bot.Handler
55
{
66
public interface ICommandHandler
77
{
8-
Task InitCommands();
8+
void InitCommands();
99
Task OnCommandReceived(Users dbUser, Message message);
1010
}
1111
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Telegram.Bot.Types;
2+
using Telegram.Bot.Types.ReplyMarkups;
3+
using XinjingdailyBot.Model.Models;
4+
5+
namespace XinjingdailyBot.Interface.Data
6+
{
7+
public interface IAttachmentService : IBaseService<Attachments>
8+
{
9+
}
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using Telegram.Bot.Types;
2+
using Telegram.Bot.Types.ReplyMarkups;
3+
using XinjingdailyBot.Model.Models;
4+
5+
namespace XinjingdailyBot.Interface.Data
6+
{
7+
public interface IBanRecordService : IBaseService<BanRecords>
8+
{
9+
}
10+
}

XinjingdailyBot.Interface/IBaseService.cs XinjingdailyBot.Interface/Data/IBaseService.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
using XinjingdailyBot.Model.Base;
22
using XinjingdailyBot.Repository.Base;
33

4-
namespace XinjingdailyBot.Interface
4+
namespace XinjingdailyBot.Interface.Data
55
{
66
/// <summary>
77
/// 基础服务定义

0 commit comments

Comments
 (0)