From 742936e26017578bebb8996c084217aaf03d8f63 Mon Sep 17 00:00:00 2001 From: milimoe Date: Wed, 23 Jul 2025 01:09:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=A8=E5=B1=80=E5=BA=93?= =?UTF-8?q?=E5=AD=98=E5=95=86=E5=BA=97=E3=80=81=E5=95=86=E5=93=81=E9=99=90?= =?UTF-8?q?=E8=B4=AD=E6=95=B0=E9=87=8F=E3=80=81=E8=BF=87=E6=9C=9F=E6=97=B6?= =?UTF-8?q?=E9=97=B4=EF=BC=9B=E5=8C=BA=E5=88=86=E5=95=86=E5=BA=97=E5=BC=80?= =?UTF-8?q?=E6=94=BE=E6=97=B6=E9=97=B4=E5=92=8C=E8=90=A5=E4=B8=9A=E6=97=B6?= =?UTF-8?q?=E9=97=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Entity/Trade/Goods.cs | 13 +++-- Entity/Trade/Store.cs | 46 +++++++++++++--- .../Common/JsonConverter/GoodsConverter.cs | 22 ++++++++ .../Common/JsonConverter/StoreConverter.cs | 53 +++++++++++++++++++ Library/Constant/General.cs | 5 ++ 5 files changed, 129 insertions(+), 10 deletions(-) diff --git a/Entity/Trade/Goods.cs b/Entity/Trade/Goods.cs index e00d886..355bac7 100644 --- a/Entity/Trade/Goods.cs +++ b/Entity/Trade/Goods.cs @@ -11,24 +11,29 @@ namespace Milimoe.FunGame.Core.Entity public string Description { get; set; } = ""; public Dictionary Prices { get; } = []; public int Stock { get; set; } + public int Quota { get; set; } + public Dictionary UsersBuyCount { get; } = []; + public DateTime? ExpireTime { get; set; } = null; public Goods() { } - public Goods(long id, Item item, int stock, string name, string description, Dictionary? prices = null) + public Goods(long id, Item item, int stock, string name, string description, Dictionary? prices = null, int quota = 0) { Id = id; Items.Add(item); Stock = stock; + Quota = quota; Name = name; Description = description; if (prices != null) Prices = prices; } - public Goods(long id, List items, int stock, string name, string description, Dictionary? prices = null) + public Goods(long id, List items, int stock, string name, string description, Dictionary? prices = null, int quota = 0) { Id = id; Items = items; Stock = stock; + Quota = quota; Name = name; Description = description; if (prices != null) Prices = prices; @@ -38,10 +43,12 @@ namespace Milimoe.FunGame.Core.Entity { StringBuilder builder = new(); builder.AppendLine($"{Id}. {Name}"); + if (ExpireTime.HasValue) builder.AppendLine($"限时购买:{ExpireTime.Value.ToString(General.GeneralDateTimeFormatChinese)} 截止"); builder.AppendLine($"商品描述:{Description}"); builder.AppendLine($"商品售价:{(Prices.Count > 0 ? string.Join("、", Prices.Select(kv => $"{kv.Value} {kv.Key}")) : "免费")}"); builder.AppendLine($"包含物品:{string.Join("、", Items.Select(i => $"[{ItemSet.GetQualityTypeName(i.QualityType)}|{ItemSet.GetItemTypeName(i.ItemType)}] {i.Name}"))}"); - builder.AppendLine($"剩余库存:{(Stock == -1 ? "不限量提供" : Stock)}"); + builder.AppendLine($"剩余库存:{(Stock == -1 ? "不限" : Stock)}"); + if (Quota > 0) builder.AppendLine($"限购数量:{Quota}"); return builder.ToString().Trim(); } diff --git a/Entity/Trade/Store.cs b/Entity/Trade/Store.cs index 62a8bfd..c941432 100644 --- a/Entity/Trade/Store.cs +++ b/Entity/Trade/Store.cs @@ -7,12 +7,19 @@ namespace Milimoe.FunGame.Core.Entity public class Store : BaseEntity { public User User { get; set; } = General.UnknownUserInstance; + public string Description { get; set; } = ""; public DateTime? StartTime { get; set; } = null; public DateTime? EndTime { get; set; } = null; + public DateTime? StartTimeOfDay { get; set; } = null; + public DateTime? EndTimeOfDay { get; set; } = null; public Dictionary Goods { get; } = []; public bool AutoRefresh { get; set; } = false; public DateTime NextRefreshDate { get; set; } = DateTime.MinValue; + public Dictionary NextRefreshGoods { get; } = []; public int RefreshInterval { get; set; } = 1; // Days + public bool GetNewerGoodsOnVisiting { get; set; } = false; + public bool GlobalStock { get; set; } = false; + public DateTime? ExpireTime { get; set; } = null; public Store(string name, User? user = null) { @@ -28,24 +35,36 @@ namespace Milimoe.FunGame.Core.Entity StringBuilder builder = new(); builder.AppendLine($"☆★☆ {Name} ☆★☆"); + if (Description != "") builder.AppendLine($"{Description}"); if (StartTime.HasValue && EndTime.HasValue) { - builder.AppendLine($"营业时间:{StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)} 至 {EndTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"开放时间:{StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)} 至 {EndTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); } else if (StartTime.HasValue && !EndTime.HasValue) { - builder.AppendLine($"开始营业时间:{StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"开始开放时间:{StartTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); } else if (!StartTime.HasValue && EndTime.HasValue) { - builder.AppendLine($"停止营业时间:{EndTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); + builder.AppendLine($"停止开放时间:{EndTime.Value.ToString(General.GeneralDateTimeFormatChinese)}"); } else { - builder.AppendLine($"[ 24H ] 全年无休,永久开放"); + builder.AppendLine($"开放时间:全年无休,永久开放"); + } + if (StartTimeOfDay.HasValue && EndTimeOfDay.HasValue) + { + builder.AppendLine($"每日营业时间:{StartTimeOfDay.Value.ToString(General.GeneralDateTimeFormatTimeOnly)} 至 {EndTimeOfDay.Value.ToString(General.GeneralDateTimeFormatTimeOnly)}"); + DateTime now = DateTime.Now; + if (StartTimeOfDay.Value > now || EndTimeOfDay.Value < now) builder.AppendLine($"商店现在还未开始营业。"); + } + else + { + builder.AppendLine($"[ 24H ] 全天营业"); } builder.AppendLine($"☆--- 商品列表 ---☆"); - foreach (Goods goods in Goods.Values) + Goods[] goodsValid = [.. Goods.Values.Where(g => !g.ExpireTime.HasValue || g.ExpireTime.Value > DateTime.Now)]; + foreach (Goods goods in goodsValid) { builder.AppendLine(goods.ToString()); } @@ -114,8 +133,12 @@ namespace Milimoe.FunGame.Core.Entity { if (AutoRefresh) { - time ??= DateTime.Now; - NextRefreshDate = time.Value.AddDays(RefreshInterval); + DateTime now = DateTime.Now; + time ??= NextRefreshDate; + if (now > time) + { + NextRefreshDate = time.Value.AddDays(RefreshInterval); + } } else { @@ -123,6 +146,15 @@ namespace Milimoe.FunGame.Core.Entity } } + public void CopyGoodsToNextRefreshGoods() + { + NextRefreshGoods.Clear(); + foreach (long goodsId in Goods.Keys) + { + NextRefreshGoods.Add(goodsId, Goods[goodsId]); + } + } + public override bool Equals(IBaseEntity? other) { return other is Store && other.GetIdName() == GetIdName(); diff --git a/Library/Common/JsonConverter/GoodsConverter.cs b/Library/Common/JsonConverter/GoodsConverter.cs index 6666c64..fa4efa1 100644 --- a/Library/Common/JsonConverter/GoodsConverter.cs +++ b/Library/Common/JsonConverter/GoodsConverter.cs @@ -2,6 +2,7 @@ using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; using Milimoe.FunGame.Core.Library.Common.Architecture; +using Milimoe.FunGame.Core.Library.Constant; namespace Milimoe.FunGame.Core.Library.Common.JsonConverter { @@ -29,6 +30,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Goods.Stock): result.Stock = reader.GetInt32(); break; + case nameof(Goods.Quota): + result.Quota = reader.GetInt32(); + break; case nameof(Goods.Name): result.Name = reader.GetString() ?? ""; break; @@ -42,6 +46,20 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter result.Prices[needy] = prices[needy]; } break; + case nameof(Goods.UsersBuyCount): + Dictionary buyCount = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; + foreach (long uid in buyCount.Keys) + { + result.UsersBuyCount[uid] = buyCount[uid]; + } + break; + case nameof(Store.ExpireTime): + string dateString = reader.GetString() ?? ""; + if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out DateTime time)) + { + result.ExpireTime = time; + } + break; } } @@ -53,10 +71,14 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WritePropertyName(nameof(Goods.Items)); JsonSerializer.Serialize(writer, value.Items, options); writer.WriteNumber(nameof(Goods.Stock), value.Stock); + writer.WriteNumber(nameof(Goods.Quota), value.Quota); writer.WriteString(nameof(Goods.Name), value.Name); writer.WriteString(nameof(Goods.Description), value.Description); writer.WritePropertyName(nameof(Goods.Prices)); JsonSerializer.Serialize(writer, value.Prices, options); + writer.WritePropertyName(nameof(Goods.UsersBuyCount)); + JsonSerializer.Serialize(writer, value.UsersBuyCount, options); + if (value.ExpireTime.HasValue) writer.WriteString(nameof(Goods.ExpireTime), value.ExpireTime.Value.ToString(General.GeneralDateTimeFormat)); writer.WriteEndObject(); } diff --git a/Library/Common/JsonConverter/StoreConverter.cs b/Library/Common/JsonConverter/StoreConverter.cs index bf0bf29..c214e96 100644 --- a/Library/Common/JsonConverter/StoreConverter.cs +++ b/Library/Common/JsonConverter/StoreConverter.cs @@ -20,6 +20,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Store.Name): result.Name = reader.GetString() ?? ""; break; + case nameof(Store.Description): + result.Description = reader.GetString() ?? ""; + break; case nameof(Store.StartTime): string dateString = reader.GetString() ?? ""; if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out DateTime time)) @@ -42,6 +45,28 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter result.EndTime = DateTime.MinValue; } break; + case nameof(Store.StartTimeOfDay): + dateString = reader.GetString() ?? ""; + if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out time)) + { + result.StartTimeOfDay = time; + } + else + { + result.StartTimeOfDay = DateTime.MinValue; + } + break; + case nameof(Store.EndTimeOfDay): + dateString = reader.GetString() ?? ""; + if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out time)) + { + result.EndTimeOfDay = time; + } + else + { + result.EndTimeOfDay = DateTime.MinValue; + } + break; case nameof(Store.Goods): Dictionary goods = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; foreach (long id in goods.Keys) @@ -63,9 +88,29 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter result.NextRefreshDate = DateTime.MinValue; } break; + case nameof(Store.NextRefreshGoods): + Dictionary goods2 = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; + foreach (long id in goods2.Keys) + { + result.NextRefreshGoods[id] = goods2[id]; + } + break; case nameof(Store.RefreshInterval): result.RefreshInterval = Convert.ToInt32(reader.GetInt64()); break; + case nameof(Store.GetNewerGoodsOnVisiting): + result.GetNewerGoodsOnVisiting = reader.GetBoolean(); + break; + case nameof(Store.GlobalStock): + result.GlobalStock = reader.GetBoolean(); + break; + case nameof(Store.ExpireTime): + dateString = reader.GetString() ?? ""; + if (DateTime.TryParseExact(dateString, General.GeneralDateTimeFormat, null, System.Globalization.DateTimeStyles.None, out time)) + { + result.ExpireTime = time; + } + break; } } @@ -74,13 +119,21 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WriteStartObject(); writer.WriteString(nameof(Store.Name), value.Name); + writer.WriteString(nameof(Store.Description), value.Description); if (value.StartTime.HasValue) writer.WriteString(nameof(Store.StartTime), value.StartTime.Value.ToString(General.GeneralDateTimeFormat)); if (value.EndTime.HasValue) writer.WriteString(nameof(Store.EndTime), value.EndTime.Value.ToString(General.GeneralDateTimeFormat)); + if (value.StartTimeOfDay.HasValue) writer.WriteString(nameof(Store.StartTimeOfDay), value.StartTimeOfDay.Value.ToString(General.GeneralDateTimeFormat)); + if (value.EndTimeOfDay.HasValue) writer.WriteString(nameof(Store.EndTimeOfDay), value.EndTimeOfDay.Value.ToString(General.GeneralDateTimeFormat)); writer.WritePropertyName(nameof(Store.Goods)); JsonSerializer.Serialize(writer, value.Goods, options); writer.WriteBoolean(nameof(Store.AutoRefresh), value.AutoRefresh); writer.WriteString(nameof(Store.NextRefreshDate), value.NextRefreshDate.ToString(General.GeneralDateTimeFormat)); + writer.WritePropertyName(nameof(Store.NextRefreshGoods)); + JsonSerializer.Serialize(writer, value.NextRefreshGoods, options); writer.WriteNumber(nameof(Store.RefreshInterval), value.RefreshInterval); + writer.WriteBoolean(nameof(Store.GetNewerGoodsOnVisiting), value.GetNewerGoodsOnVisiting); + writer.WriteBoolean(nameof(Store.GlobalStock), value.GlobalStock); + if (value.ExpireTime.HasValue) writer.WriteString(nameof(Store.ExpireTime), value.ExpireTime.Value.ToString(General.GeneralDateTimeFormat)); writer.WriteEndObject(); } diff --git a/Library/Constant/General.cs b/Library/Constant/General.cs index b573d3c..afd3213 100644 --- a/Library/Constant/General.cs +++ b/Library/Constant/General.cs @@ -56,6 +56,11 @@ namespace Milimoe.FunGame.Core.Library.Constant /// yyyy年MM月dd日 HH:mm:ss /// public static string GeneralDateTimeFormatChinese => "yyyy年MM月dd日 HH:mm:ss"; + + /// + /// HH:mm:ss + /// + public static string GeneralDateTimeFormatTimeOnly => "HH:mm:ss"; /// /// 默认的时间值(1970年8月1日8点0分0秒)