添加全局库存商店、商品限购数量、过期时间;区分商店开放时间和营业时间

This commit is contained in:
milimoe 2025-07-23 01:09:32 +08:00
parent b1bfcc5577
commit 742936e260
Signed by: milimoe
GPG Key ID: 9554D37E4B8991D0
5 changed files with 129 additions and 10 deletions

View File

@ -11,24 +11,29 @@ namespace Milimoe.FunGame.Core.Entity
public string Description { get; set; } = "";
public Dictionary<string, double> Prices { get; } = [];
public int Stock { get; set; }
public int Quota { get; set; }
public Dictionary<long, int> UsersBuyCount { get; } = [];
public DateTime? ExpireTime { get; set; } = null;
public Goods() { }
public Goods(long id, Item item, int stock, string name, string description, Dictionary<string, double>? prices = null)
public Goods(long id, Item item, int stock, string name, string description, Dictionary<string, double>? 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<Item> items, int stock, string name, string description, Dictionary<string, double>? prices = null)
public Goods(long id, List<Item> items, int stock, string name, string description, Dictionary<string, double>? 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();
}

View File

@ -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<long, Goods> Goods { get; } = [];
public bool AutoRefresh { get; set; } = false;
public DateTime NextRefreshDate { get; set; } = DateTime.MinValue;
public Dictionary<long, Goods> 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();

View File

@ -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<long, int> buyCount = NetworkUtility.JsonDeserialize<Dictionary<long, int>>(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();
}

View File

@ -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<long, Goods> goods = NetworkUtility.JsonDeserialize<Dictionary<long, Goods>>(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<long, Goods> goods2 = NetworkUtility.JsonDeserialize<Dictionary<long, Goods>>(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();
}

View File

@ -57,6 +57,11 @@ namespace Milimoe.FunGame.Core.Library.Constant
/// </summary>
public static string GeneralDateTimeFormatChinese => "yyyy年MM月dd日 HH:mm:ss";
/// <summary>
/// HH:mm:ss
/// </summary>
public static string GeneralDateTimeFormatTimeOnly => "HH:mm:ss";
/// <summary>
/// 默认的时间值1970年8月1日8点0分0秒
/// </summary>