添加描述功能

This commit is contained in:
milimoe 2026-05-10 13:47:22 +08:00
parent c1bf8b843f
commit c40a2b095f
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
4 changed files with 136 additions and 15 deletions

View File

@ -127,6 +127,67 @@ namespace Oshima.FunGame.WebAPI.Services
return (header.ToString() + matches.ToString(), totalPages);
}
/// <summary>
/// 获取所有比赛列表(赛程),按开始时间排序,支持分页
/// </summary>
public static (string, int) GetAllMatches(int page, int pageSize)
{
using SQLHelper? sql = Factory.OpenFactory.GetSQLHelper();
if (sql == null) return ("数据库连接失败。", 0);
UpdateStatuses(sql);
// 总数
sql.ExecuteDataSet("SELECT COUNT(*) FROM csbetting_matches");
int total = sql.Success ? Convert.ToInt32(sql.DataSet.Tables[0].Rows[0][0]) : 0;
int totalPages = (int)Math.Ceiling(total / (double)pageSize);
if (page > totalPages) page = totalPages;
if (page < 1) page = 1;
if (total == 0)
return ("暂无比赛赛程。", 1);
int offset = (page - 1) * pageSize;
sql.Parameters["@offset"] = offset;
sql.Parameters["@limit"] = pageSize;
sql.ExecuteDataSet($@"
SELECT m.id, m.team1_name, m.team2_name, m.status, m.start_time, m.stage,
e.name AS event_name, e.id AS event_id
FROM csbetting_matches m
LEFT JOIN csbetting_events e ON m.event_id = e.id
ORDER BY
CASE m.status WHEN 1 THEN 0 WHEN 0 THEN 1 ELSE 2 END,
m.start_time ASC
LIMIT @limit OFFSET @offset");
if (!sql.Success || sql.DataSet.Tables.Count == 0 || sql.DataSet.Tables[0].Rows.Count == 0)
return ("暂无比赛赛程。", 1);
StringBuilder sb = new();
sb.AppendLine($"📅 比赛赛程{(totalPages > 1 ? $" {page}/{totalPages} " : "")}");
foreach (DataRow row in sql.DataSet.Tables[0].Rows)
{
int id = Convert.ToInt32(row["id"]);
string t1 = row["team1_name"].ToString() ?? "";
string t2 = row["team2_name"].ToString() ?? "";
int status = Convert.ToInt32(row["status"]);
DateTime start = Convert.ToDateTime(row["start_time"]);
string stage = row["stage"]?.ToString() ?? "";
string eventName = row["event_name"]?.ToString() ?? "";
long eventId = Convert.ToInt64(row["event_id"]);
string statusStr = status switch { 0 => "未开始", 1 => "进行中", 2 => "已结束", _ => "未知" };
string matchLabel = $"{t1} vs {t2}".CreateCmdInput($"比赛详情 {id}");
sb.Append($"[{id}] {matchLabel}");
if (!string.IsNullOrWhiteSpace(eventName)) sb.Append($" ({eventName.CreateCmdInput($" {eventId}")}{(!string.IsNullOrWhiteSpace(stage) ? $" - {stage}" : "")})");
sb.AppendLine($" | {statusStr} | {start:MM-dd HH:mm}");
}
return (sb.ToString().TrimEnd(), totalPages);
}
public static string GetMatchDetail(int matchId, out int status)
{
status = 0;
@ -147,6 +208,7 @@ namespace Oshima.FunGame.WebAPI.Services
DateTime deadline = Convert.ToDateTime(row["bet_deadline"]);
string stage = row["stage"].ToString() ?? "";
string available = row["available_options"]?.ToString() ?? "[]";
string description = row["description"].ToString() ?? "";
string result = row["result"] != DBNull.Value ? row["result"].ToString() ?? "" : "";
long winner = row["winner"] != DBNull.Value ? Convert.ToInt64(row["winner"]) : 0;
decimal team1Odds = Convert.ToDecimal(row["team1_win_odds"]);
@ -176,8 +238,8 @@ namespace Oshima.FunGame.WebAPI.Services
if (status == 0)
{
sb.AppendLine($"可用选项:");
if (available.Contains("team1_win")) sb.AppendLine($" - {t1}胜 (x {team1Odds})");
if (available.Contains("team2_win")) sb.AppendLine($" - {t2}胜 (x {team2Odds})");
if (available.Contains("team1_win")) sb.AppendLine($" - 队伍1 {t1} 胜 (x {team1Odds})");
if (available.Contains("team2_win")) sb.AppendLine($" - 队伍2 {t2} 胜 (x {team2Odds})");
if (available.Contains("score")) sb.AppendLine($" - 精确比分 (x 4)");
if (available.Contains("mvp")) sb.AppendLine($" - 赛事MVP (x 3.5)");
}
@ -188,7 +250,12 @@ namespace Oshima.FunGame.WebAPI.Services
if (winner != 3) sb.AppendLine($"结果:{result}");
}
return sb.ToString().Trim();
if (!string.IsNullOrWhiteSpace(description))
{
sb.AppendLine($"> 📝 {description}\r\n");
}
return sb.ToString();
}
return "数据库连接失败。";
}
@ -420,7 +487,8 @@ namespace Oshima.FunGame.WebAPI.Services
return ("你还没有任何竞猜记录。", 1);
StringBuilder sb = new();
sb.AppendLine($"我的竞猜{(paged && totalPages > 1 ? $" {page}/{totalPages} " : "")}");
if (mid > 0) sb.Append("你的本场竞猜记录:\r\n> ");
else sb.Append($"我的竞猜{(paged && totalPages > 1 ? $" {page}/{totalPages} " : "")}\r\n> ");
foreach (DataRow row in sql.DataSet.Tables[0].Rows)
{
int matchId = Convert.ToInt32(row["match_id"]);

View File

@ -67,3 +67,7 @@ CREATE TABLE IF NOT EXISTS `csbetting_matches` (
ALTER TABLE `csbetting_matches`
ADD COLUMN `team1_win_odds` DECIMAL(5,2) NOT NULL DEFAULT 2.50 COMMENT '队伍1胜赔率' AFTER `available_options`,
ADD COLUMN `team2_win_odds` DECIMAL(5,2) NOT NULL DEFAULT 2.50 COMMENT '队伍2胜赔率' AFTER `team1_win_odds`;
-- 为比赛表添加描述字段
ALTER TABLE `csbetting_matches`
ADD COLUMN `description` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '比赛描述信息' AFTER `team2_win_odds`;

View File

@ -44,11 +44,24 @@ namespace Oshima.FunGame.WebAPI.Controllers
return new BotReply { Markdown = new MarkdownMessage { Content = content }, Keyboard = kb };
}
/// <summary>
/// 获取所有比赛赛程
/// </summary>
[AllowAnonymous]
[HttpGet("matches")]
public BotReply GetAllMatches([FromQuery] int page = 1, [FromQuery] int pageSize = 10)
{
var (content, totalPages) = CSBettingService.GetAllMatches(page, pageSize);
KeyboardMessage kb = new();
if (totalPages > 1) kb = new KeyboardMessage().AddPaginationRow("赛程 ", page, totalPages);
return new BotReply { Markdown = new MarkdownMessage { Content = content }, Keyboard = kb };
}
[AllowAnonymous]
[HttpGet("match/{matchId:int}")]
public BotReply GetMatchDetail(int matchId)
{
return new BotReply { Markdown = new MarkdownMessage { Content = CSBettingService.GetMatchDetail(matchId, out int status) + (status == 0 ? $"\r\n竞猜指令{"".CreateCmdInput()} <比赛ID> <选项> <{General.GameplayEquilibriumConstant.InGameCurrency}数>\r\n👇🏻 点击下方按钮快速竞猜" : "")} };
return new BotReply { Markdown = new MarkdownMessage { Content = CSBettingService.GetMatchDetail(matchId, out int status) + (status == 0 ? $"竞猜指令:{"".CreateCmdInput()} <比赛ID> <选项> <{General.GameplayEquilibriumConstant.InGameCurrency}数>\r\n👇🏻 点击下方按钮快速竞猜" : "")} };
}
[AllowAnonymous]

View File

@ -19,6 +19,8 @@ namespace Oshima.FunGame.WebAPI.Services
{
Content = "🎮 CS赛事竞猜帮助\r\n"
+ $"✨ {"".CreateCmdInput()} - 查看所有赛事\r\n"
+ $"✨ {"".CreateCmdInput()} - 查看所有比赛\r\n"
+ $"✨ {"".CreateCmdInput()} - 创建存档后可竞猜\r\n"
+ $"✨ {"".CreateCmdInput()} - 查看我的投注记录\r\n"
+ $"✨ {"".CreateCmdInput()} - 领取竞猜奖励\r\n"
+ $"✨ {"".CreateCmdInput()} - 查看单场比赛并投注"
@ -26,6 +28,8 @@ namespace Oshima.FunGame.WebAPI.Services
Keyboard = new KeyboardMessage()
.AppendButtons(2,
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("⚙️ 创建存档", "创建存档"),
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
Button.CreateCmdButton("💰 竞猜领奖", "竞猜领奖"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"))
@ -38,13 +42,33 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail.StartsWith("赛事列表"))
{
int page = 1;
string[] parts = e.Detail.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length > 1 && int.TryParse(parts[1], out int p)) page = p;
BotReply reply = BettingController.GetEventsOverview(page); // 需要Controller增加page参数的方法
string detail = e.Detail.Replace("赛事列表", "").Trim();
System.Text.RegularExpressions.Match match = GetFirstNumber().Match(detail);
if (match.Success && int.TryParse(match.Value, out int p)) page = p;
BotReply reply = BettingController.GetEventsOverview(page);
await SendAsync(e, "CS赛事竞猜", reply);
return true;
}
// 赛程:显示所有比赛
if (e.Detail.StartsWith("赛程") || e.Detail.StartsWith("比赛列表"))
{
int page = 1;
string detail = e.Detail.Replace("赛程", "").Replace("比赛列表", "").Trim();
System.Text.RegularExpressions.Match match = GetFirstNumber().Match(detail);
if (match.Success && int.TryParse(match.Value, out int p)) page = p;
BotReply reply = BettingController.GetAllMatches(page);
reply.Keyboard ??= new KeyboardMessage();
reply.Keyboard.AppendButtonsWithNewRow(2,
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"));
await SendAsync(e, "比赛赛程", reply);
return true;
}
if (e.Detail.StartsWith("比赛详情"))
{
string detail = e.Detail.Replace("比赛详情", "").Trim();
@ -63,12 +87,14 @@ namespace Oshima.FunGame.WebAPI.Services
}
kb.AppendButtonsWithNewRow(2,
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("💰 竞猜领奖", "竞猜领奖"));
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("💰 竞猜领奖", "竞猜领奖"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"));
reply.Keyboard = kb;
BotReply reply2 = BettingController.GetMyBets(uid, mid: matchId);
if (reply.Markdown != null && reply.Markdown.Content != null && !(reply2.Markdown?.Content?.Equals("你还没有任何竞猜记录。") ?? true))
{
reply.Markdown.Content = $"{reply.Markdown.Content.Trim()}\r\n你的本场竞猜记录:\r\n{reply2.Markdown.Content}";
reply.Markdown.Content = $"{reply.Markdown.Content.Trim()}\r\n{reply2.Markdown.Content}";
}
await SendAsync(e, "CS赛事竞猜", reply);
}
@ -93,8 +119,8 @@ namespace Oshima.FunGame.WebAPI.Services
BotReply reply = BettingController.GetEventDetail(eventId, page);
reply.Keyboard ??= new KeyboardMessage();
reply.Keyboard.AppendButtonsWithNewRow(2,
Button.CreateCmdButton("🔍 比赛详情 ", "比赛详情 ", enter: false),
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
Button.CreateCmdButton("💰 竞猜领奖", "竞猜领奖"));
await SendAsync(e, "CS赛事竞猜", reply);
@ -110,7 +136,9 @@ namespace Oshima.FunGame.WebAPI.Services
Keyboard = new KeyboardMessage()
.AppendButtons(2,
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"))
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"),
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"))
};
await SendAsync(e, "CS赛事竞猜", reply);
}
@ -120,13 +148,15 @@ namespace Oshima.FunGame.WebAPI.Services
if (e.Detail.StartsWith("我的竞猜"))
{
int page = 1;
string[] parts = e.Detail.Split(' ', StringSplitOptions.RemoveEmptyEntries);
if (parts.Length > 1 && int.TryParse(parts[1], out int p)) page = p;
string detail = e.Detail.Replace("我的竞猜", "").Trim();
System.Text.RegularExpressions.Match match = GetFirstNumber().Match(detail);
if (match.Success && int.TryParse(match.Value, out int p)) page = p;
BotReply reply = BettingController.GetMyBets(uid, page);
reply.Keyboard ??= new KeyboardMessage();
reply.Keyboard.AppendButtonsWithNewRow(2,
Button.CreateCmdButton("💰 竞猜领奖", "竞猜领奖", enter: true),
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"));
if (reply.Markdown?.Content?.Contains("创建存档") ?? false)
{
@ -142,7 +172,8 @@ namespace Oshima.FunGame.WebAPI.Services
reply.Keyboard = new KeyboardMessage()
.AppendButtons(2,
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
Button.CreateCmdButton("📋 赛事列表", "赛事列表"));
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"));
if (reply.Markdown?.Content?.Contains("创建存档") ?? false)
{
reply.Keyboard.AppendButtons(2, Button.CreateCmdButton("⚙️ 创建存档", "创建存档"));
@ -172,6 +203,7 @@ namespace Oshima.FunGame.WebAPI.Services
kb.AppendButtons(2,
Button.CreateCmdButton("📜 我的竞猜", "我的竞猜"),
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("❓ 竞猜帮助", "竞猜帮助"));
if (reply.Markdown?.Content?.Contains("创建存档") ?? false)
@ -209,6 +241,7 @@ namespace Oshima.FunGame.WebAPI.Services
reply.Keyboard = new KeyboardMessage()
.AppendButtons(2,
Button.CreateCmdButton("📋 赛事列表", "赛事列表"),
Button.CreateCmdButton("📅 比赛列表", "比赛列表"),
Button.CreateCmdButton("⚙️ 继续结算", "结算比赛 ", enter: false));
await SendAsync(e, "CS赛事竞猜", reply);
}
@ -396,5 +429,8 @@ namespace Oshima.FunGame.WebAPI.Services
return false;
}
[System.Text.RegularExpressions.GeneratedRegex(@"\d+")]
private static partial System.Text.RegularExpressions.Regex GetFirstNumber();
}
}