From 0afbf6e39aa49cb93ed76082c498049e6fe462da Mon Sep 17 00:00:00 2001 From: Putoo <290555932@qq.com> Date: Mon, 25 May 2026 18:41:27 +0800 Subject: [PATCH] 1111 --- Kx.SeaTime.sln.DotSettings.user | 1 + .../game/user/unit_user_equ.cs | 56 +- .../game/user/unit_user_goods.cs | 10 +- .../model/AttrItem.cs | 36 + .../model/EquAwaken.cs | 37 + .../Application.Domain.Entity/model/EquGem.cs | 50 ++ .../model/EquMent.cs | 45 ++ .../resource/game/game_equ.cs | 171 +++++ .../resource/game/game_goods.cs | 2 +- Service/Application.Domain/Enum/EquEnum.cs | 6 + Service/Application.Domain/Enum/GoodsEnum.cs | 7 + .../Services/Interface/Equ/IGameEquService.cs | 17 + .../Interface/Goods/IGameGoodsService.cs | 2 +- .../Services/Interface/Map/IGameMapService.cs | 15 +- .../Interface/User/IUnitUserAttrService.cs | 7 + .../Services/Service/Equ/GameEquService.cs | 233 ++++++ .../Service/Goods/GameGoodsService.cs | 3 +- .../Services/Service/Map/GameMapService.cs | 377 +++++++++- .../Service/User/UnitUserAttrService.cs | 62 ++ .../Tool/MapPath/MapLine.cs | 8 + .../Tool/MapPath/MapRunTool.cs | 692 ++++++++++++++++++ .../Controllers/Map/MapController.cs | 85 ++- .../Controllers/User/BagController.cs | 92 ++- Web/src/components/Business/GamePopup.vue | 1 - Web/src/components/Page/Footer.vue | 1 + Web/src/extends/PageExtend.ts | 4 + Web/src/extends/TimeExtend.ts | 14 +- Web/src/pages/bag/index.vue | 48 +- Web/src/pages/map/index.vue | 101 ++- Web/src/pages/treasure/index.vue | 31 + Web/src/services/map/MapService.ts | 16 + Web/src/services/user/BagService.ts | 8 + 32 files changed, 2137 insertions(+), 101 deletions(-) create mode 100644 Service/Application.Domain.Entity/model/AttrItem.cs create mode 100644 Service/Application.Domain.Entity/model/EquAwaken.cs create mode 100644 Service/Application.Domain.Entity/model/EquGem.cs create mode 100644 Service/Application.Domain.Entity/model/EquMent.cs create mode 100644 Service/Application.Domain.Entity/resource/game/game_equ.cs create mode 100644 Service/Application.Domain/Enum/EquEnum.cs create mode 100644 Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs create mode 100644 Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs create mode 100644 Service/Application.Domain/Tool/MapPath/MapLine.cs create mode 100644 Service/Application.Domain/Tool/MapPath/MapRunTool.cs create mode 100644 Web/src/pages/treasure/index.vue diff --git a/Kx.SeaTime.sln.DotSettings.user b/Kx.SeaTime.sln.DotSettings.user index 7ee2977..5f75113 100644 --- a/Kx.SeaTime.sln.DotSettings.user +++ b/Kx.SeaTime.sln.DotSettings.user @@ -1,5 +1,6 @@  ForceIncluded + ForceIncluded ForceIncluded ForceIncluded ForceIncluded diff --git a/Service/Application.Domain.Entity/game/user/unit_user_equ.cs b/Service/Application.Domain.Entity/game/user/unit_user_equ.cs index 805a411..b6b7e51 100644 --- a/Service/Application.Domain.Entity/game/user/unit_user_equ.cs +++ b/Service/Application.Domain.Entity/game/user/unit_user_equ.cs @@ -63,8 +63,8 @@ namespace Application.Domain.Entity /// /// qualityAttr /// - [SugarColumn(Length = 2000, IsNullable = true)] - public string? qualityAttr { get; set; } + [SugarColumn( IsNullable = true,IsJson = true)] + public List? qualityAttr { get; set; } /// /// sex @@ -172,7 +172,7 @@ namespace Application.Domain.Entity /// useEndTime /// [SugarColumn(IsNullable = true)] - public DateTime? useEndTime { get; set; } + public long? useEndTime { get; set; } /// /// weight @@ -189,8 +189,8 @@ namespace Application.Domain.Entity /// /// sysPrice /// - [SugarColumn(Length = 10, IsNullable = true)] - public decimal? sysPrice { get; set; } + [SugarColumn(IsNullable = true)] + public int? sysPrice { get; set; } /// /// canEqualUp @@ -199,28 +199,28 @@ namespace Application.Domain.Entity public int? canEqualUp { get; set; } /// - /// EquAttr + /// 装备属性 /// - [SugarColumn(IsNullable = true)] - public string? EquAttr { get; set; } + [SugarColumn(IsNullable = true,IsJson = true)] + public List? EquAttr { get; set; } /// - /// EquMent + /// 附魔属性 /// - [SugarColumn(IsNullable = true)] - public string? EquMent { get; set; } + [SugarColumn(IsNullable = true,IsJson = true)] + public EquMent? EquMent { get; set; } /// - /// EquAwaken + /// 觉醒属性 /// - [SugarColumn(IsNullable = true)] - public string? EquAwaken { get; set; } + [SugarColumn(IsNullable = true,IsJson = true)] + public List? EquAwaken { get; set; } /// - /// GemMent + /// 宝石属性 /// - [SugarColumn(IsNullable = true)] - public string? GemMent { get; set; } + [SugarColumn(IsNullable = true,IsJson = true)] + public List? GemMent { get; set; } /// /// isDeal @@ -235,33 +235,21 @@ namespace Application.Domain.Entity public int? isGive { get; set; } /// - /// score - /// - [SugarColumn(IsNullable = true)] - public int? score { get; set; } - - /// - /// start + /// 星级 /// [SugarColumn(IsNullable = true)] public int? start { get; set; } /// - /// exp + /// 0不需要鉴定 1需要鉴定 /// [SugarColumn(IsNullable = true)] - public int? exp { get; set; } + public int? isAppr { get; set; } /// - /// startAttr + /// 是否穿戴 /// [SugarColumn(IsNullable = true)] - public string? startAttr { get; set; } - - /// - /// swallow - /// - [SugarColumn(IsNullable = true)] - public string? swallow { get; set; } + public int? isOn { get; set; } } } diff --git a/Service/Application.Domain.Entity/game/user/unit_user_goods.cs b/Service/Application.Domain.Entity/game/user/unit_user_goods.cs index 55b2775..4f5f8f4 100644 --- a/Service/Application.Domain.Entity/game/user/unit_user_goods.cs +++ b/Service/Application.Domain.Entity/game/user/unit_user_goods.cs @@ -45,8 +45,8 @@ namespace Application.Domain.Entity /// /// count /// - [SugarColumn(Length = 65, IsNullable = true)] - public decimal? count { get; set; } + [SugarColumn(IsNullable = true)] + public long? count { get; set; } /// /// weight @@ -57,8 +57,8 @@ namespace Application.Domain.Entity /// /// sysPrice /// - [SugarColumn(Length = 18, IsNullable = true)] - public decimal? sysPrice { get; set; } + [SugarColumn(IsNullable = true)] + public int? sysPrice { get; set; } /// /// 0不可交易1可交易 @@ -72,4 +72,4 @@ namespace Application.Domain.Entity [SugarColumn(IsNullable = true)] public int? isGive { get; set; } } -} +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/AttrItem.cs b/Service/Application.Domain.Entity/model/AttrItem.cs new file mode 100644 index 0000000..d6d04ce --- /dev/null +++ b/Service/Application.Domain.Entity/model/AttrItem.cs @@ -0,0 +1,36 @@ +namespace Application.Domain.Entity; + +public class AttrItem +{ + private System.String _code; + + /// + /// + /// + public System.String code + { get { return this._code; } set { this._code = value; } } + + private System.String _compute; + + /// + /// + /// + public System.String compute + { get { return this._compute; } set { this._compute = value; } } + + private System.Decimal _parameter; + + /// + /// + /// + public System.Decimal parameter + { get { return this._parameter; } set { this._parameter = value; } } + + private System.String _tip; + + /// + /// + /// + public System.String tip + { get { return this._tip; } set { this._tip = value; } } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/EquAwaken.cs b/Service/Application.Domain.Entity/model/EquAwaken.cs new file mode 100644 index 0000000..f21bf14 --- /dev/null +++ b/Service/Application.Domain.Entity/model/EquAwaken.cs @@ -0,0 +1,37 @@ +namespace Application.Domain.Entity; + +public class EquAwaken +{ + private System.String _atId; + + /// + /// + /// + public System.String atId + { get { return this._atId; } set { this._atId = value; } } + + private System.Int32 _lev; + + /// + /// + /// + public System.Int32 lev + { get { return this._lev; } set { this._lev = value; } } + + private System.String _name; + + /// + /// + /// + public System.String name + { get { return this._name; } set { this._name = value; } } + + private List _awaken; + + /// + /// + /// + [SqlSugar.SugarColumn(ColumnDataType = "varchar(max)", IsJson = true)] + public List awaken + { get { return this._awaken; } set { this._awaken = value; } } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/EquGem.cs b/Service/Application.Domain.Entity/model/EquGem.cs new file mode 100644 index 0000000..6c0f2d4 --- /dev/null +++ b/Service/Application.Domain.Entity/model/EquGem.cs @@ -0,0 +1,50 @@ +namespace Application.Domain.Entity; + +public class EquGem +{ + private System.String _Id; + + /// + /// + /// + public System.String Id + { get { return this._Id; } set { this._Id = value; } } + + private System.Int32 _goodsId; + + /// + /// + /// + public System.Int32 goodsId + { get { return this._goodsId; } set { this._goodsId = value; } } + + private System.String _goodsName; + + /// + /// + /// + public System.String goodsName + { get { return this._goodsName; } set { this._goodsName = value; } } + + private System.Int32? _isDeal; + + /// + /// + /// + public System.Int32? isDeal + { get { return this._isDeal; } set { this._isDeal = value; } } + + public EquGemItem gemItem { get; set; } +} +public class EquGemItem +{ + private System.String _place; + + /// + /// + /// + public System.String place + { get { return this._place; } set { this._place = value; } } + + public List GemAttr { get; set; } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/model/EquMent.cs b/Service/Application.Domain.Entity/model/EquMent.cs new file mode 100644 index 0000000..ee2cf7c --- /dev/null +++ b/Service/Application.Domain.Entity/model/EquMent.cs @@ -0,0 +1,45 @@ +namespace Application.Domain.Entity; + +public class EquMent +{ + private System.String _name; + + /// + /// + /// + public System.String name + { get { return this._name; } set { this._name = value; } } + + private System.Int32 _goodsId; + + /// + /// + /// + public System.Int32 goodsId + { get { return this._goodsId; } set { this._goodsId = value; } } + + private System.Int32? _isDeal; + + /// + /// + /// + public System.Int32? isDeal + { get { return this._isDeal; } set { this._isDeal = value; } } + + private System.Int32? _isGive; + + /// + /// + /// + public System.Int32? isGive + { get { return this._isGive; } set { this._isGive = value; } } + + private List _EquAttr; + + /// + /// + /// + [SqlSugar.SugarColumn(ColumnDataType = "varchar(max)", IsJson = true)] + public List EquAttr + { get { return this._EquAttr; } set { this._EquAttr = value; } } +} \ No newline at end of file diff --git a/Service/Application.Domain.Entity/resource/game/game_equ.cs b/Service/Application.Domain.Entity/resource/game/game_equ.cs new file mode 100644 index 0000000..11590c9 --- /dev/null +++ b/Service/Application.Domain.Entity/resource/game/game_equ.cs @@ -0,0 +1,171 @@ +using SqlSugar; +using System; + +namespace Application.Domain.Entity +{ + [Tenant("Kg.SeaTime.Resource")] + public class game_equ + { + /// + /// equId + /// + [SugarColumn(IsPrimaryKey = true)] + public int equId { get; set; } + + /// + /// equName + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? equName { get; set; } + + /// + /// lev + /// + [SugarColumn(IsNullable = true)] + public int? lev { get; set; } + + /// + /// quality + /// + [SugarColumn(IsNullable = true)] + public int? quality { get; set; } + + /// + /// code + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? code { get; set; } + + /// + /// sex + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? sex { get; set; } + + /// + /// img + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? img { get; set; } + + /// + /// minAtk + /// + [SugarColumn(IsNullable = true)] + public int? minAtk { get; set; } + + /// + /// maxAtk + /// + [SugarColumn(IsNullable = true)] + public int? maxAtk { get; set; } + + /// + /// defense + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? defense { get; set; } + + /// + /// agility + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? agility { get; set; } + + /// + /// blood + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? blood { get; set; } + + /// + /// morale + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? morale { get; set; } + + /// + /// 0非套装 + /// + [SugarColumn(Length = 50, IsNullable = true)] + public string? suitCode { get; set; } + + /// + /// durability + /// + [SugarColumn(IsNullable = true)] + public int? durability { get; set; } + + /// + /// 是否可强化 + /// + [SugarColumn(IsNullable = true)] + public int? isIntensify { get; set; } + + /// + /// holeCount + /// + [SugarColumn(IsNullable = true)] + public int? holeCount { get; set; } + + /// + /// 0永久 其他为小时 + /// + [SugarColumn(IsNullable = true)] + public int? useTime { get; set; } + + /// + /// weight + /// + [SugarColumn(IsNullable = true)] + public int? weight { get; set; } + + /// + /// remark + /// + [SugarColumn(IsNullable = true)] + public string? remark { get; set; } + + /// + /// source + /// + [SugarColumn(Length = 255, IsNullable = true)] + public string? source { get; set; } + + /// + /// sysPrice + /// + [SugarColumn(IsNullable = true)] + public int? sysPrice { get; set; } + + /// + /// equAttr + /// + [SugarColumn(IsNullable = true,IsJson = true)] + public List? equAttr { get; set; } + + /// + /// 可穿戴数量 + /// + [SugarColumn(IsNullable = true)] + public int? canEqualUp { get; set; } + + /// + /// 0不可交易1可交易 + /// + [SugarColumn(IsNullable = true)] + public int? isDeal { get; set; } + + /// + /// 0不可赠送 1可赠送 + /// + [SugarColumn(IsNullable = true)] + public int? isGive { get; set; } + + /// + /// 0不需要鉴定 1需要鉴定 + /// + [SugarColumn(IsNullable = true)] + public int? isAppr { get; set; } + } +} diff --git a/Service/Application.Domain.Entity/resource/game/game_goods.cs b/Service/Application.Domain.Entity/resource/game/game_goods.cs index ebc738c..f57bdf0 100644 --- a/Service/Application.Domain.Entity/resource/game/game_goods.cs +++ b/Service/Application.Domain.Entity/resource/game/game_goods.cs @@ -58,7 +58,7 @@ namespace Application.Domain.Entity /// sysPrice /// [SugarColumn(Length = 18, IsNullable = true)] - public decimal? sysPrice { get; set; } + public int? sysPrice { get; set; } /// /// content diff --git a/Service/Application.Domain/Enum/EquEnum.cs b/Service/Application.Domain/Enum/EquEnum.cs new file mode 100644 index 0000000..b460deb --- /dev/null +++ b/Service/Application.Domain/Enum/EquEnum.cs @@ -0,0 +1,6 @@ +namespace Application.Domain; + +public static class EquEnum +{ + +} \ No newline at end of file diff --git a/Service/Application.Domain/Enum/GoodsEnum.cs b/Service/Application.Domain/Enum/GoodsEnum.cs index ad3d0b4..29130f3 100644 --- a/Service/Application.Domain/Enum/GoodsEnum.cs +++ b/Service/Application.Domain/Enum/GoodsEnum.cs @@ -7,5 +7,12 @@ public static class GoodsEnum Drug,//药品 Prop,//物品 Cargo,//货物 + Gem,//宝石 + Mak,//材料 + Palace,//九宫 + Paper,//图纸 + Card,//附魔卡片 + Mark,//圣痕 + Pack,//宝箱 } } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs b/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs index 31f2ad1..820c66d 100644 --- a/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs +++ b/Service/Application.Domain/Services/Interface/Equ/IGameEquService.cs @@ -2,5 +2,22 @@ public interface IGameEquService { + #region 装备资源 + + Task GetEquInfo(int equId); + + #endregion + #region 用户装备 + + Task> GetUserEquData(string userId, int type, string equName, int PageIndex, int PageSize, + RefAsync Total); + + Task> GetUserEquData(string userId, int equId); + Task AddUserEqu(string userId, int equId, int count, string remark); + Task DeductUserEqu(string userId, List equData, string remark); + Task DeductUserEqu(string userId, int equId, int count, string remark); + + #endregion + } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/Goods/IGameGoodsService.cs b/Service/Application.Domain/Services/Interface/Goods/IGameGoodsService.cs index 5fec967..3684165 100644 --- a/Service/Application.Domain/Services/Interface/Goods/IGameGoodsService.cs +++ b/Service/Application.Domain/Services/Interface/Goods/IGameGoodsService.cs @@ -15,7 +15,7 @@ public interface IGameGoodsService Task GetUserGoodsInfo(string userId, int goodsId); Task GetUserGoodsCount(string userId, int goodsId); - Task> GetUserGoodsData(string userId, List code, string search, int page, + Task> GetUserGoodsData(string userId, List code, List noCode, string search, int page, int limit, RefAsync total); Task UpdateUserGoods(string userId, int op, int goodsId, int count, string remark = ""); diff --git a/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs b/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs index 1e56fdd..e8c474b 100644 --- a/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs +++ b/Service/Application.Domain/Services/Interface/Map/IGameMapService.cs @@ -5,8 +5,10 @@ public interface IGameMapService #region 城市地图数据 Task GetCityInfo(int cityId); + Task> GetCityData(); + Task> GetCityMap(int cityId); + Task> GetCityShowMap(int cityId); Task GetMapInfo(string mapId); - Task> GetMapCity(int cityId); Task GetMapCityByMapId(string mapId); Task> GetMapNpc(string mapId); Task GetNpcInfo(int npcId); @@ -17,7 +19,9 @@ public interface IGameMapService Task GetUserOnMapId(string userId); Task GetUserOnMap(string userId); Task UpdateUserOnMap(string userId, string ip, string mapId); - + Task UpdateUserOnMap(unit_user_online data, string mapId); + Task SetUserMapDefult(string userId); + Task GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, bool isChangeCity = false); #endregion #region 其他相关 @@ -27,5 +31,12 @@ public interface IGameMapService Task> GetMapUser(string mapId, int area, int showArea, List noUser, int page, int limit, RefAsync total); + #endregion + + #region 自动寻路 + + Task> CreateAutoMap(string start, string end); + + #endregion } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs b/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs new file mode 100644 index 0000000..713f363 --- /dev/null +++ b/Service/Application.Domain/Services/Interface/User/IUnitUserAttrService.cs @@ -0,0 +1,7 @@ +namespace Application.Domain; + +public interface IUnitUserAttrService +{ + Task GetUserBlood(string userId); + Task UpdateUserBlood(string userId, int op, int count, bool mustUp = false); +} \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/Equ/GameEquService.cs b/Service/Application.Domain/Services/Service/Equ/GameEquService.cs index c1ad506..406fed9 100644 --- a/Service/Application.Domain/Services/Service/Equ/GameEquService.cs +++ b/Service/Application.Domain/Services/Service/Equ/GameEquService.cs @@ -2,4 +2,237 @@ public class GameEquService(ISqlSugarClient DbClient, IRedisCache redis) : IGameEquService, ITransient { + #region 装备资源 + + public async Task GetEquInfo(int equId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "EquData", "EquInfo"); + var data = await redis.GetHashAsync(key, equId.ToString()); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().Where(it => it.equId == equId).SingleAsync(); + await redis.AddHashAsync(key, equId.ToString(), data); + } + + return data; + } + + #endregion + + #region 用户装备 + + public async Task> GetUserEquData(string userId, int type, string equName, int PageIndex, + int PageSize, RefAsync Total) + { + long onTime = TimeExtend.GetTimeStampSeconds; + var db = DbClient.AsTenant().GetConnectionWithAttr(); + return await db.Queryable().Where(it => it.userId == userId) + .WhereIF(type == 2, it => it.useEndTime < onTime) + .WhereIF(type == 1, it => it.isOn == 1) + .WhereIF(type == 3, it => it.isAppr == 0) + .WhereIF(!string.IsNullOrEmpty(equName), + it => it.equName.Contains(equName) || it.unitEquName.Contains(equName)) + .OrderByDescending(it => it.lev) + .OrderByDescending(it => it.ueId).ToPageListAsync(PageIndex, PageSize, Total); + } + + public async Task> GetUserEquData(string userId, int equId) + { + long onTime = TimeExtend.GetTimeStampSeconds; + var db = DbClient.AsTenant().GetConnectionWithAttr(); + return await db.Queryable().Where(it => it.userId == userId && it.equId == equId).ToListAsync(); + } + + public async Task AddUserEqu(string userId, int equId, int count, string remark) + { + bool result = false; + var equ = await GetEquInfo(equId); + if (equ != null) + { + List adds = new List(); + for (int i = 0; i < count; i++) + { + unit_user_equ ue = new unit_user_equ(); + string ueId = StringAssist.NewGuid; + ue.ueId = ueId; + ue.userId = userId; + ue.owerId = userId; + ue.equId = equ.equId; + ue.equName = equ.equName; + ue.unitEquName = equ.equName; + ue.img = equ.img; + ue.sign = ""; + if (equ.isAppr == 0) + { + ue.minAtk = equ.minAtk; + ue.maxAtk = equ.maxAtk; + ue.Defense = Convert.ToInt32(equ.defense); + ue.Agility = Convert.ToInt32(equ.agility); + ue.Morale = Convert.ToInt32(equ.morale); + ue.Blood = Convert.ToInt32(equ.blood); + ue.isAppr = 1; + } + else + { + ue.minAtk = 0; + ue.maxAtk = 0; + ue.Defense = 0; + ue.Agility = 0; + ue.Morale = 0; + ue.Blood = 0; + ue.isAppr = 0; + } + + ue.code = equ.code; + ue.suitCode = equ.suitCode; + ue.lev = equ.lev; + ue.durability = equ.durability; + ue.maxdurability = equ.durability; + ue.isIntensify = equ.isIntensify; + ue.intensifyLev = 0; + ue.isLock = 0; + ue.holeCount = equ.holeCount; + ue.sex = equ.sex; + ue.quality = 0; + ue.qualityName = "普通"; + ue.qualityAttr = new List(); + ue.weight = equ.weight; + ue.sysPrice = equ.sysPrice; + ue.EquAttr = equ.equAttr; + ue.canEqualUp = equ.canEqualUp; + ue.isDeal = equ.isDeal; + ue.isGive = equ.isGive; + ue.opTime = 0; + ue.start = 0; + ue.EquMent = new EquMent(); + ue.EquAwaken = new List(); + ue.GemMent = new List(); + ue.useEndTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddYears(20)); + adds.Add(ue); + } + + if (adds.Count > 0) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + result = await db.Insertable(adds).ExecuteCommandAsync() > 0; + } + + if (result) + { + //添加日志 + await AddEquLog(adds, 1, remark, userId, true); + //更新负重 + int weightCount = Convert.ToInt32(equ.weight) * count; + if (weightCount > 0) + { + var attrService = App.GetService(); + await attrService.UpdateUserWeight(userId, 1, weightCount); + } + } + } + + return result; + } + + public async Task DeductUserEqu(string userId, List equData, string remark) + { + bool result = false; + List DelEqu = new List(); + List logs = new List(); + int weightCount = 0; + foreach (var item in equData) + { + weightCount += (int)item.weight; + DelEqu.Add(item.ueId); + //生成日志集合 + unit_user_equ_log log = new unit_user_equ_log(); + log.logId = StringAssist.NewGuid; + log.ueId = item.ueId; + log.userId = item.userId; + log.code = nameof(GameEnum.LogCode.减少); + log.equData = item; + log.remark = remark; + log.addTime = DateTime.Now; + logs.Add(log); + } + + if (DelEqu.Count > 0) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + result = await db.Deleteable().Where(i => DelEqu.Contains(i.ueId)).ExecuteCommandAsync() > 0; + if (result) //生成成功 + { + //更新负重 + if (weightCount > 0) + { + var attrService = App.GetService(); + await attrService.UpdateUserWeight(userId, 0, weightCount); + } + + if (logs.Count > 0) + { + await AddEquLog(logs); + } + } + } + + return result; + } + + public async Task DeductUserEqu(string userId, int equId, int count, string remark) + { + var userEqu = await GetUserEquData(userId, equId); + if (userEqu.Count < 1) + { + return false; + } + + userEqu = userEqu.FindAll(it => it.isLock == 0); + if (userEqu.Count < count) + { + return false; + } + + userEqu = userEqu.OrderBy(it => (int)it.intensifyLev) + .OrderBy(it => it.quality) + .ToList(); + var opData = userEqu.Take(count).ToList(); + return await DeductUserEqu(userId, opData, remark); + } + + private async Task AddEquLog(List ues, int code, string remark, string userId, + bool isAddAttr = false) + { + List adds = new List(); + foreach (var item in ues) + { + unit_user_equ_log bagLog = new unit_user_equ_log(); + bagLog.logId = StringAssist.NewGuid; + bagLog.userId = userId; + bagLog.ueId = item.ueId; + bagLog.code = code == 0 + ? bagLog.code = nameof(GameEnum.LogCode.减少) + : bagLog.code = nameof(GameEnum.LogCode.增加); + if (isAddAttr) + { + bagLog.equData = item; + } + + bagLog.addTime = DateTime.Now; + bagLog.remark = remark; + adds.Add(bagLog); + } + + var db = DbClient.AsTenant().GetConnectionWithAttr(); + await db.Insertable(adds).ExecuteCommandAsync(); + } + + private async Task AddEquLog(List logs) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + await db.Insertable(logs).ExecuteCommandAsync(); + } + + #endregion } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/Goods/GameGoodsService.cs b/Service/Application.Domain/Services/Service/Goods/GameGoodsService.cs index 27c4a5c..a67d739 100644 --- a/Service/Application.Domain/Services/Service/Goods/GameGoodsService.cs +++ b/Service/Application.Domain/Services/Service/Goods/GameGoodsService.cs @@ -55,12 +55,13 @@ public class GameGoodsService(ISqlSugarClient DbClient, IRedisCache redis) : IGa return info == null ? 0 : (int)info.count; } - public async Task> GetUserGoodsData(string userId, List code, string search, int page, + public async Task> GetUserGoodsData(string userId, List code, List noCode, string search, int page, int limit, RefAsync total) { var db = DbClient.AsTenant().GetConnectionWithAttr(); return await db.Queryable().Where(it => it.userId == userId && it.count > 0) .WhereIF(code.Count > 0, it => code.Contains(it.code)) + .WhereIF(noCode.Count > 0, it => !noCode.Contains(it.code)) .WhereIF(!string.IsNullOrEmpty(search), it => it.goodsName.Contains(search)) .OrderBy(it => it.lev, OrderByType.Desc) .OrderBy(it => it.count, OrderByType.Desc) diff --git a/Service/Application.Domain/Services/Service/Map/GameMapService.cs b/Service/Application.Domain/Services/Service/Map/GameMapService.cs index 0777c21..e4e884a 100644 --- a/Service/Application.Domain/Services/Service/Map/GameMapService.cs +++ b/Service/Application.Domain/Services/Service/Map/GameMapService.cs @@ -6,7 +6,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame public async Task GetCityInfo(int cityId) { - string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "CityData"); + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInfo"); var data = await redis.GetHashAsync(key, cityId.ToString()); if (data == null) { @@ -18,9 +18,53 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame return data; } + public async Task> GetCityData() + { + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityData"); + var data = await redis.GetAsync>(key); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().ToListAsync(); + await redis.SetAsync(key, data); + } + + return data; + } + + + + public async Task> GetCityMap(int cityId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityMap"); + var data = await redis.GetHashAsync>(key, cityId.ToString()); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().Where(it => it.cityId == cityId).ToListAsync(); + await redis.AddHashAsync(key, cityId.ToString(), data); + } + + return data; + } + + public async Task> GetCityShowMap(int cityId) + { + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityShowMap"); + var data = await redis.GetHashAsync>(key, cityId.ToString()); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().Where(it => it.cityId == cityId && it.show == 1).ToListAsync(); + await redis.AddHashAsync(key, cityId.ToString(), data); + } + + return data; + } + public async Task GetMapInfo(string mapId) { - string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "MapData"); + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapData"); var data = await redis.GetHashAsync(key, mapId); if (data == null) { @@ -32,19 +76,6 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame return data; } - public async Task> GetMapCity(int cityId) - { - string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "CityShowMap"); - var data = await redis.GetHashAsync>(key, cityId.ToString()); - if (data == null) - { - var db = DbClient.AsTenant().GetConnectionWithAttr(); - data = await db.Queryable().Where(it => it.cityId == cityId && it.show == 1).ToListAsync(); - await redis.AddHashAsync(key, cityId.ToString(), data); - } - - return data; - } public async Task GetMapCityByMapId(string mapId) { @@ -61,7 +92,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame public async Task> GetMapNpc(string mapId) { - string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "NpcData"); + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcData"); var data = await redis.GetHashAsync>(key, mapId); if (data == null) { @@ -75,7 +106,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame public async Task GetNpcInfo(int npcId) { - string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "NpcInfo"); + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcInfo"); var data = await redis.GetHashAsync(key, npcId.ToString()); if (data == null) { @@ -131,6 +162,119 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame } } + public async Task UpdateUserOnMap(unit_user_online data, string mapId) + { + data.mapId = mapId; + data.upTime = TimeAssist.GetTimeStampNum; + string key = string.Format(UserCache.BaseCacheKey, "UserOnline"); + if (await redis.AddHashAsync(key, data.userId, data)) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + await db.Updateable(data).ExecuteCommandAsync(); + } + + return true; + } + + public async Task SetUserMapDefult(string userId) + { + var userMap = await GetUserOnMap(userId); + var MapInfo = await GetMapInfo(userMap.mapId); + if (MapInfo != null) + { + await UpdateUserOnMap(userMap, MapInfo.retMap); + } + } + + public async Task GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, + bool isChangeCity = false) + { + bool result = false; + var onMapUser = await GetUserOnMap(userId); + var onMap = onMapUser.mapId; + var onMapInfo = await GetMapInfo(onMap); + var mapInfo = await GetMapInfo(toMap); + if (onMap == toMap) //相同地图不更新 + { + if (isUpUserMap) + { + await UpdateUserOnMap(onMapUser, toMap); + } + + return mapInfo; + } + else + { + //更新挂机,结束挂机 + } + + if (mapInfo == null) + { + var myOnMap = await GetMapInfo(onMap); + return myOnMap; + } + + if (isChangeCity) + { + result = true; + } + else + { + if (mapInfo.show == 1) + { + result = true; + } + else + { + string[] onMaps = onMap.Split('_'); + int onMapX = Convert.ToInt32(onMaps[0]); + int onMapY = Convert.ToInt32(onMaps[1]); + if (onMapX == mapInfo.x) + { + if (onMapY == (mapInfo.y - 1) || onMapY == (mapInfo.y + 1)) + { + result = true; + } + } + else + { + if (onMapY == mapInfo.y) + { + if (onMapX == (mapInfo.x - 1) || onMapX == (mapInfo.x + 1)) + { + result = true; + } + } + } + } + + //当传送有效时,此处判断是否跨城市 + if (result) + { + result = onMapInfo.cityId == mapInfo.cityId; + } + } + + if (isUpUserMap && result) + { + result = await UpdateUserOnMap(onMapUser, toMap); + } + + if (result) + { + if (mapInfo.lockTime > 0) + { + // await SetUserMapLock(userId, (int)mapInfo.lockTime); //增加地图锁定 + } + + return mapInfo; + } + else + { + return onMapInfo; + } + } + #endregion #region 其他相关 @@ -141,7 +285,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame long time = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime)); var data = await db.Queryable().Where(it => it.upTime > time && it.mapId == mapId) .WhereIF(noUser.Count > 0, it => !noUser.Contains(it.userId)) - .OrderByDescending(it=>it.upTime) + .OrderByDescending(it => it.upTime) .ToListAsync(); List result = new List(); @@ -168,11 +312,204 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame { var data = await GetMapUser(mapId, area, showArea, noUser); total = data.Count; - return data.Skip((page - 1) * limit) // 跳过前面的页 - .Take(limit) // 取当前页 + return data.Skip((page - 1) * limit) // 跳过前面的页 + .Take(limit) // 取当前页 .ToList(); } + #endregion + + #region 自动寻路 + + private async Task> GetCityDataExcludeParent() + { + string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityParent"); + var data = await redis.GetAsync>(key); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().Where(it => it.parent != 0).ToListAsync(); + + await redis.SetAsync(key, data); + } + return data; + } + private async Task> GetAllMaoToData() + { + string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityInterCityPortal"); + if (await redis.ExistsAsync(key)) + { + return await redis.GetAsync>(key); + } + + List result = new List(); + + var cityData = await GetCityDataExcludeParent(); + foreach (var item in cityData) + { + if (!string.IsNullOrEmpty(item.toMap)) + { + var map = await GetMapInfo(item.toMap); + if (map != null) + { + result.Add(map); + } + } + } + await redis.SetAsync(key, result); + return result; + } + /// + /// 城市信息 + /// + /// + private async Task> GetCityNode() + { + string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityNode"); + var data = await redis.GetAsync>(key); + if (data == null) + { + data = new List(); + var cityData = await GetCityDataExcludeParent(); //获取所有城市 + foreach (var city in cityData) + { + var mdMap = await GetMapInfo(city.toMap); + if (mdMap != null) + { + var cityTemp = new CityNode(city.cityId, city.cityName, new Point((int)mdMap.x, (int)mdMap.y), + mdMap.mapName, (int)city.x_s, (int)city.x_e, (int)city.y_s, (int)city.y_e); + data.Add(cityTemp); + } + } + + await redis.SetAsync(key, data); + } + + return data; + } + + /// + /// 城市网络 + /// + /// + private async Task>> GetCityRoadNetwork() + { + string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityRoadNetwork"); + var data = await redis.GetAsync>>(key); + if (data == null) + { + data = new Dictionary>(); + var cityData = await GetCityDataExcludeParent(); //获取所有城市 + foreach (var city in cityData) + { + //添加地图 + var mapData = await GetCityMap(city.cityId); + data.Add(city.cityId, mapData); + } + + await redis.SetAsync(key, data); + } + + return data; + } + + + + /// + /// 传送点信息 + /// + /// + private async Task> GetCityInterCityPortal() + { + string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInterCityPortal"); + var data = await redis.GetAsync>(key); + if (data == null) + { + data = new List(); + var toAddr = await GetAllMaoToData(); //获取所有传送点 + var cityData = await GetCityDataExcludeParent(); //获取所有城市 + foreach (var item in toAddr) + { + var toMapInfo = await GetMapInfo(item.retMap); + //获取反向传送点 + var retAddr = cityData.Find(it => it.cityId == (int)item.cityId); + + data.Add(new InterCityPortal(item.mapId, (int)item.cityId, new Point((int)item.x, (int)item.y), + (int)toMapInfo.cityId, item.mapName, 1, retAddr.toMap)); + } + + await redis.SetAsync(key, data); + } + + return data; + } + + private async Task> FinderMapLine(Point start, Point end) + { + //初始化 + var globalNetwork = new GlobalRoadNetwork(); + //注册城市 + var NodeData = await GetCityNode(); + NodeData.ForEach(item => { globalNetwork.AddCity(item); }); + //注册传送点 + var CityInterCityPortal = await GetCityInterCityPortal(); + CityInterCityPortal.ForEach(item => { globalNetwork.AddPortal(item); }); + var pathFinder = new CrossCityPathFinder(globalNetwork); //初始化寻找器 + //注册城市网络 + List NetworkData = new List(); + var NetworkCityData = await GetCityRoadNetwork(); + foreach (var cityNet in NetworkCityData) + { + var cityNetwork = new CityRoadNetwork(cityNet.Key); + foreach (var map in cityNet.Value) + { + cityNetwork.AddWalkablePoint((int)map.x, (int)map.y); + } + + NetworkData.Add(cityNetwork); + } + + NetworkData.ForEach(item => { pathFinder.AddCityRoadNetwork(item); }); + + //获取所有城市ID + var cityData = await GetCityDataExcludeParent(); + List cityRoute = cityData.Select(it => it.cityId).ToList(); + var path = pathFinder.FindCrossCityPath(start, end); + List result = new List(); + if (path != null) + { + foreach (var item in path) + { + if (item.StepType == PathStepType.Move) + { + MapLine line = new MapLine(); + line.x = item.Position.X; + line.y = item.Position.Y; + line.mapId = $"{line.x}_{line.y}"; + result.Add(line); + } + } + } + + return result; + } + + + public async Task> CreateAutoMap(string start, string end) + { + //获取所有起始点 + var startMap = await GetMapInfo(start); + var endMap = await GetMapInfo(end); + Point startPoint = new Point((int)startMap.x, (int)startMap.y); + Point endPoint = new Point((int)endMap.x, (int)endMap.y); + var result = await FinderMapLine(startPoint, endPoint); + if (result.Count > 0) + { + result.RemoveAt(0); + } + + return result; + } #endregion } \ No newline at end of file diff --git a/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs b/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs new file mode 100644 index 0000000..3021c3f --- /dev/null +++ b/Service/Application.Domain/Services/Service/User/UnitUserAttrService.cs @@ -0,0 +1,62 @@ +namespace Application.Domain; + +public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) : IUnitUserAttrService, ITransient +{ + + #region 体力操作 + public async Task GetUserBlood(string userId) + { + string key = string.Format(UserCache.BaseCacheKeys, "AttrData","Blood"); + var data = await redis.GetHashAsync(key, userId); + if (data == null) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + data = await db.Queryable().Where(it => it.userId == userId).SingleAsync(); + await redis.AddHashAsync(key, userId, data); + } + return data; + } + + public async Task UpdateUserBlood(string userId, int op, int count, bool mustUp = false) + { + bool result = false; + unit_user_blood data = new unit_user_blood(); + string key = string.Format(UserCache.BaseCacheKeys, "AttrData","Blood"); + if (op == 2) + { + data.userId = userId; + data.blood = count; + } + else + { + data = await GetUserBlood(userId); + if (op == 0) + { + data.blood -= count; + } + else if (op == 1) + { + data.blood += count; + } + } + + data.blood = data.blood < 0 ? 0 : data.blood; + result = await redis.AddHashAsync(key, userId, data); + + if (mustUp) + { + var db = DbClient.AsTenant().GetConnectionWithAttr(); + result = await db.Updateable() + .SetColumnsIF(op == 0, it => it.blood == it.blood - count) + .SetColumnsIF(op == 1, it => it.blood == it.blood + count) + .SetColumnsIF(op == 2, it => it.blood == count) + .Where(it => it.userId == userId).ExecuteCommandAsync() > 0; + } + + return result; + } + + + #endregion + +} \ No newline at end of file diff --git a/Service/Application.Domain/Tool/MapPath/MapLine.cs b/Service/Application.Domain/Tool/MapPath/MapLine.cs new file mode 100644 index 0000000..997ed3e --- /dev/null +++ b/Service/Application.Domain/Tool/MapPath/MapLine.cs @@ -0,0 +1,8 @@ +namespace Application.Domain; + +public class MapLine +{ + public string mapId { get; set; } + public int x { get; set; } + public int y { get; set; } +} \ No newline at end of file diff --git a/Service/Application.Domain/Tool/MapPath/MapRunTool.cs b/Service/Application.Domain/Tool/MapPath/MapRunTool.cs new file mode 100644 index 0000000..b60196a --- /dev/null +++ b/Service/Application.Domain/Tool/MapPath/MapRunTool.cs @@ -0,0 +1,692 @@ +namespace Application.Domain; + +// ===================== 核心定义:全局坐标体系 ===================== +/// +/// 全局坐标结构体(所有城市共享唯一坐标) +/// +public struct Point +{ + public int X; // 全局X坐标 + public int Y; // 全局Y坐标 + + public Point(int x, int y) + { + X = x; + Y = y; + } + + public override bool Equals(object obj) + { + return obj is Point point && X == point.X && Y == point.Y; + } + + public override int GetHashCode() + { + return HashCode.Combine(X, Y); + } + + public static bool operator ==(Point a, Point b) => a.X == b.X && a.Y == b.Y; + public static bool operator !=(Point a, Point b) => !(a == b); + + public override string ToString() => $"({X},{Y})"; +} + +/// +/// 城市节点(全局坐标管辖范围) +/// +public class CityNode +{ + public int CityId { get; set; } // 城市ID + public string CityName { get; set; } // 城市名称 + public Point CoreAnchor { get; set; } // 核心锚点(全局坐标) + public string CoreAnchorName { get; set; } // 核心锚点名称 + public int MinX { get; set; } // 城市管辖范围-最小X(全局) + public int MaxX { get; set; } // 城市管辖范围-最大X(全局) + public int MinY { get; set; } // 城市管辖范围-最小Y(全局) + public int MaxY { get; set; } // 城市管辖范围-最大Y(全局) + public List Portals { get; set; } // 所属传送点(全局坐标) + + public CityNode(int cityId, string cityName, Point coreAnchor, string coreAnchorName, + int minX, int maxX, int minY, int maxY) + { + CityId = cityId; + CityName = cityName; + CoreAnchor = coreAnchor; + CoreAnchorName = coreAnchorName; + MinX = minX; + MaxX = maxX; + MinY = minY; + MaxY = maxY; + Portals = new List(); + } + + /// + /// 校验全局坐标是否属于当前城市管辖范围 + /// + public bool IsPointInCity(Point point) + { + return point.X >= MinX && point.X <= MaxX && point.Y >= MinY && point.Y <= MaxY; + } + + public void AddPortal(InterCityPortal portal) + { + if (!Portals.Any(p => p.PortalId == portal.PortalId)) + Portals.Add(portal); + } +} + +/// +/// 城际传送点(全局坐标,PortalId改为字符串) +/// +public class InterCityPortal +{ + public string PortalId { get; set; } // 1. 改为字符串类型 + public int BelongCityId { get; set; } // 所属城市ID + public Point Position { get; set; } // 传送点全局坐标 + public int TargetCityId { get; set; } // 目标城市ID + public string PortalName { get; set; } // 传送点名称 + public int Priority { get; set; } = 1; // 优先级 + public string? ReversePortalId { get; set; } // 反向传送点ID(字符串) + + public InterCityPortal(string portalId, int belongCityId, Point pos, int targetCityId, string name, + int priority = 1, string? reversePortalId = null) + { + PortalId = portalId; + BelongCityId = belongCityId; + Position = pos; + TargetCityId = targetCityId; + PortalName = name; + Priority = priority; + ReversePortalId = reversePortalId; + } +} + +/// +/// 全局路网(基于全局坐标管理城市+传送点) +/// +public class GlobalRoadNetwork +{ + public Dictionary CityDict { get; private set; } + public Dictionary PortalDict { get; private set; } // 适配字符串PortalId + + public GlobalRoadNetwork() + { + CityDict = new Dictionary(); + PortalDict = new Dictionary(); // 改为字符串Key + } + + public void AddCity(CityNode city) + { + if (!CityDict.ContainsKey(city.CityId)) + CityDict.Add(city.CityId, city); + } + + public void AddPortal(InterCityPortal portal) + { + if (!PortalDict.ContainsKey(portal.PortalId)) + { + PortalDict.Add(portal.PortalId, portal); + if (CityDict.ContainsKey(portal.BelongCityId)) + CityDict[portal.BelongCityId].AddPortal(portal); + } + } + + /// + /// 根据全局坐标获取所属城市 + /// + public CityNode GetCityByGlobalPoint(Point point) + { + return CityDict.Values.FirstOrDefault(city => city.IsPointInCity(point)); + } + + /// + /// 获取最优传送点(修复反向寻路筛选逻辑) + /// + public InterCityPortal GetOptimalPortal(int startCityId, int targetCityId, Point startPos, + Dictionary cityNetworks, bool isReverse = false) + { + if (!CityDict.ContainsKey(startCityId) || !cityNetworks.ContainsKey(startCityId)) + return null; + + var startCity = CityDict[startCityId]; + var startCityNetwork = cityNetworks[startCityId]; + + // 修复反向寻路筛选逻辑: + // - 正向:当前城市传送点 → 目标城市 + // - 反向:目标城市传送点 → 当前城市(但从当前城市视角找) + var candidatePortals = isReverse + ? CityDict.Values + .Where(c => c.CityId == targetCityId) + .SelectMany(c => c.Portals) + .Where(p => p.TargetCityId == startCityId) + .Where(p => startCityNetwork.IsPointWalkable(p.Position)) + .Where(p => startCityNetwork.FindPathInCity(startPos, p.Position) != null) + : startCity.Portals + .Where(p => p.TargetCityId == targetCityId) + .Where(p => startCityNetwork.IsPointWalkable(p.Position)) + .Where(p => startCityNetwork.FindPathInCity(startPos, p.Position) != null); + + // 计算距离并排序 + var sortedPortals = candidatePortals + .Select(p => new + { + Portal = p, + Distance = GetManhattanDistance(startPos, p.Position) + }) + .OrderBy(p => p.Portal.Priority) + .ThenBy(p => p.Distance); + + return sortedPortals.FirstOrDefault()?.Portal; + } + + /// + /// 获取反向传送点(适配字符串PortalId) + /// + public InterCityPortal GetReversePortal(InterCityPortal portal) + { + if (!string.IsNullOrEmpty(portal.ReversePortalId) && PortalDict.ContainsKey(portal.ReversePortalId)) + return PortalDict[portal.ReversePortalId]; + return null; + } + + /// + /// 校验全局坐标合法性(属于某城市+该城市内可通行) + /// + public bool IsPointValid(Point point, Dictionary cityNetworks) + { + var city = GetCityByGlobalPoint(point); + if (city == null || !cityNetworks.ContainsKey(city.CityId)) + return false; + return cityNetworks[city.CityId].IsPointWalkable(point); + } + + /// + /// 修复:使用BFS获取所有连通的城市链(支持多中转) + /// + public List GetConnectedCityChain(int startCityId, int endCityId) + { + if (startCityId == endCityId) + return new List { startCityId }; + + // BFS队列:存储(当前城市ID, 路径) + var queue = new Queue>>(); + var visited = new HashSet(); + + queue.Enqueue(Tuple.Create(startCityId, new List { startCityId })); + visited.Add(startCityId); + + while (queue.Count > 0) + { + var current = queue.Dequeue(); + int currCityId = current.Item1; + List path = current.Item2; + + // 获取当前城市所有可达的传送点目标城市 + var reachableCities = CityDict[currCityId].Portals + .Select(p => p.TargetCityId) + .Distinct() + .Where(c => !visited.Contains(c)); + + foreach (int nextCityId in reachableCities) + { + var newPath = new List(path) { nextCityId }; + + // 找到终点,返回路径 + if (nextCityId == endCityId) + return newPath; + + visited.Add(nextCityId); + queue.Enqueue(Tuple.Create(nextCityId, newPath)); + } + } + + return null; // 无可达路线 + } + + private int GetManhattanDistance(Point a, Point b) + { + return Math.Abs(a.X - b.X) + Math.Abs(a.Y - b.Y); + } +} + +public class AStarNode : IComparable +{ + public Point Position { get; set; } + public AStarNode Parent { get; set; } + public int G { get; set; } // 起点到当前节点的代价 + public int H { get; set; } // 当前节点到终点的预估代价 + public int F => G + H; // 总代价 + + // 实现IComparable接口,解决SortedSet重复元素问题 + public int CompareTo(AStarNode other) + { + if (other == null) return 1; + + // 先按F值排序,再按H值,最后按坐标(避免重复) + int fCompare = F.CompareTo(other.F); + if (fCompare != 0) return fCompare; + + int hCompare = H.CompareTo(other.H); + if (hCompare != 0) return hCompare; + + int xCompare = Position.X.CompareTo(other.Position.X); + return xCompare != 0 ? xCompare : Position.Y.CompareTo(other.Position.Y); + } +} + +/// +/// 单城市路网(基于全局坐标管理可通行区域) +/// +public class CityRoadNetwork +{ + public int CityId { get; set; } + public Dictionary WalkablePoints { get; private set; } // 全局坐标可通行列表 + + public CityRoadNetwork(int cityId) + { + CityId = cityId; + WalkablePoints = new Dictionary(); + } + + /// + /// 添加全局坐标可通行点 + /// + public void AddWalkablePoint(int x, int y, bool walkable = true) + { + var point = new Point(x, y); + WalkablePoints[point] = walkable; + } + + /// + /// 批量添加全局坐标可通行区域 + /// + public void AddWalkableRect(int minX, int maxX, int minY, int maxY, bool walkable = true) + { + if (minX > maxX || minY > maxY) + throw new ArgumentException("矩形范围不合法:min不能大于max"); + + for (int x = minX; x <= maxX; x++) + for (int y = minY; y <= maxY; y++) + AddWalkablePoint(x, y, walkable); + } + + /// + /// 校验全局坐标是否可走 + /// + public bool IsPointWalkable(Point point) + { + return WalkablePoints.TryGetValue(point, out bool walkable) && walkable; + } + + /// + /// 修复后的A*寻路(基于全局坐标) + /// + public List FindPathInCity(Point start, Point end) + { + // 基础校验 + if (!WalkablePoints.ContainsKey(start) || !WalkablePoints.ContainsKey(end)) + return null; + if (!IsPointWalkable(start) || !IsPointWalkable(end)) + return null; + if (start == end) + return new List { start }; + + // 开放列表(排序集合)和关闭列表 + var openSet = new SortedSet(); + var openDict = new Dictionary(); // 快速查找 + var closeDict = new Dictionary(); + + // 初始化起点 + var startNode = new AStarNode + { + Position = start, + Parent = null, + G = 0, + H = GetManhattanDistance(start, end) + }; + openSet.Add(startNode); + openDict[start] = startNode; + + // 四方向移动 + var dirs = new[] { new Point(0, 1), new Point(0, -1), new Point(1, 0), new Point(-1, 0) }; + + while (openSet.Count > 0) + { + // 获取F值最小的节点 + var currentNode = openSet.Min; + openSet.Remove(currentNode); + openDict.Remove(currentNode.Position); + closeDict[currentNode.Position] = currentNode; + + // 到达终点,回溯路径 + if (currentNode.Position == end) + { + var path = new List(); + var node = currentNode; + while (node != null) + { + path.Add(node.Position); + node = node.Parent; + } + + path.Reverse(); + return path; + } + + // 遍历邻接节点 + foreach (var dir in dirs) + { + var neighborPos = new Point(currentNode.Position.X + dir.X, currentNode.Position.Y + dir.Y); + + // 跳过不可通行或已关闭的节点 + if (!IsPointWalkable(neighborPos) || closeDict.ContainsKey(neighborPos)) + continue; + + // 计算新的G值 + int newG = currentNode.G + 1; + + // 邻接节点不存在或找到更优路径 + if (!openDict.TryGetValue(neighborPos, out var neighborNode) || newG < neighborNode.G) + { + // 如果节点已存在,先移除 + if (neighborNode != null) + { + openSet.Remove(neighborNode); + openDict.Remove(neighborPos); + } + + // 创建/更新节点 + neighborNode = new AStarNode + { + Position = neighborPos, + Parent = currentNode, + G = newG, + H = GetManhattanDistance(neighborPos, end) + }; + + openSet.Add(neighborNode); + openDict[neighborPos] = neighborNode; + } + } + } + + // 无路径 + return null; + } + + private int GetManhattanDistance(Point a, Point b) + { + return Math.Abs(a.X - b.X) + Math.Abs(a.Y - b.Y); + } +} + +// ===================== 路径步骤定义 ===================== +public enum PathStepType +{ + Move, + Teleport +} + +public class PathStep +{ + public int CityId { get; set; } + public Point Position { get; set; } // 全局坐标 + public PathStepType StepType { get; set; } + public int? TargetCityId { get; set; } + public Point? TargetAnchor { get; set; } // 目标锚点全局坐标 + public string? TargetAnchorName { get; set; } + + public string ToWapDesc(GlobalRoadNetwork globalNetwork) + { + var cityName = globalNetwork?.CityDict?.ContainsKey(CityId) == true + ? globalNetwork.CityDict[CityId].CityName + : "未知城市"; + + return StepType switch + { + PathStepType.Move => $"【{cityName}】移动到全局坐标{Position}", + PathStepType.Teleport => GetTeleportDesc(globalNetwork, cityName), + _ => string.Empty + }; + } + + private string GetTeleportDesc(GlobalRoadNetwork globalNetwork, string currentCityName) + { + if (globalNetwork == null || !TargetCityId.HasValue) + return $"【{currentCityName}】通过传送阵→【未知城市】未知锚点"; + + var targetCityName = globalNetwork.CityDict.ContainsKey(TargetCityId.Value) + ? globalNetwork.CityDict[TargetCityId.Value].CityName + : "未知城市"; + + var anchorName = string.IsNullOrEmpty(TargetAnchorName) ? "未知锚点" : TargetAnchorName; + var anchorPos = TargetAnchor.HasValue ? $"(全局坐标{TargetAnchor})" : ""; + + return $"【{currentCityName}】通过传送阵→【{targetCityName}】{anchorName}{anchorPos}"; + } +} + +// ===================== 跨城寻路核心服务(全自动适配) ===================== +public class CrossCityPathFinder +{ + private readonly GlobalRoadNetwork _globalNetwork; + private readonly Dictionary _cityNetworks; + + public CrossCityPathFinder(GlobalRoadNetwork globalNetwork) + { + _globalNetwork = globalNetwork; + _cityNetworks = new Dictionary(); + } + + public void AddCityRoadNetwork(CityRoadNetwork cityNetwork) + { + if (!_cityNetworks.ContainsKey(cityNetwork.CityId)) + _cityNetworks.Add(cityNetwork.CityId, cityNetwork); + } + + /// + /// 核心方法:输入起止点,全自动判定同城/跨城/多城市,自动适配正向/反向 + /// + public List FindCrossCityPath(Point startPos, Point endPos) + { + // 1. 基础校验:识别起止点所属城市 + var startCity = _globalNetwork.GetCityByGlobalPoint(startPos); + var endCity = _globalNetwork.GetCityByGlobalPoint(endPos); + + if (startCity == null || endCity == null) + { + return null; + } + + // 2. 同城寻路 + if (startCity.CityId == endCity.CityId) + { + return FindSameCityPath(startCity.CityId, startPos, endPos); + } + + // 3. 跨城/多城市寻路(使用修复后的BFS路径链) + var cityChain = _globalNetwork.GetConnectedCityChain(startCity.CityId, endCity.CityId); + if (cityChain == null || cityChain.Count < 2) + { + return null; + } + + // 自动适配正向/反向 + var cityStartPoints = new Dictionary + { + { startCity.CityId, startPos }, + { endCity.CityId, endPos } + }; + + // 自动判断是否需要反向寻路 + var isReverse = IsNeedReverseRoute(startCity.CityId, endCity.CityId); + + return FindMultiCityPath(cityChain, cityStartPoints, isReverse); + } + + /// + /// 同城寻路 + /// + private List FindSameCityPath(int cityId, Point startPos, Point endPos) + { + if (!_globalNetwork.IsPointValid(startPos, _cityNetworks) || + !_globalNetwork.IsPointValid(endPos, _cityNetworks)) + { + return null; + } + + var cityPath = _cityNetworks[cityId].FindPathInCity(startPos, endPos); + return cityPath?.Select(p => new PathStep + { + CityId = cityId, + Position = p, + StepType = PathStepType.Move + }).ToList(); + } + + /// + /// 多城市寻路(自动适配正向/反向) + /// + private List FindMultiCityPath(List cityChain, Dictionary cityStartPoints, + bool isReverse) + { + var finalPath = new List(); + var actualChain = isReverse ? cityChain.AsEnumerable().Reverse().ToList() : cityChain; + + for (int i = 0; i < actualChain.Count - 1; i++) + { + int currCityId = actualChain[i]; + int nextCityId = actualChain[i + 1]; + Point currStartPoint = cityStartPoints.ContainsKey(currCityId) + ? cityStartPoints[currCityId] + : _globalNetwork.CityDict[currCityId].CoreAnchor; + + // 校验起点坐标归属 + var currCity = _globalNetwork.CityDict[currCityId]; + if (!currCity.IsPointInCity(currStartPoint)) + { + return null; + } + + if (!_globalNetwork.IsPointValid(currStartPoint, _cityNetworks)) + return null; + + // 获取最优传送点(自动传入反向标识) + var optimalPortal = + _globalNetwork.GetOptimalPortal(currCityId, nextCityId, currStartPoint, _cityNetworks, isReverse); + if (optimalPortal == null) + { + return null; + } + + // 当前城市内:起点 → 传送点 + var currToPortal = _cityNetworks[currCityId].FindPathInCity(currStartPoint, optimalPortal.Position); + if (currToPortal == null) + return null; + finalPath.AddRange(currToPortal.Select(p => new PathStep + { + CityId = currCityId, + Position = p, + StepType = PathStepType.Move + })); + + // 跨城传送 + var nextCity = _globalNetwork.CityDict[nextCityId]; + finalPath.Add(new PathStep + { + CityId = currCityId, + Position = optimalPortal.Position, + StepType = PathStepType.Teleport, + TargetCityId = nextCityId, + TargetAnchor = nextCity.CoreAnchor, + TargetAnchorName = nextCity.CoreAnchorName + }); + + // 更新下一个城市的起点 + if (!cityStartPoints.ContainsKey(nextCityId)) + cityStartPoints.Add(nextCityId, nextCity.CoreAnchor); + + // 最后一段:核心锚点→终点 + if (i == actualChain.Count - 2) + { + Point nextEndPoint = cityStartPoints[nextCityId]; + var anchorToEnd = _cityNetworks[nextCityId].FindPathInCity(nextCity.CoreAnchor, nextEndPoint); + if (anchorToEnd == null) + return null; + finalPath.AddRange(anchorToEnd.Select(p => new PathStep + { + CityId = nextCityId, + Position = p, + StepType = PathStepType.Move + })); + } + } + + return finalPath; + } + + /// + /// 自动判断是否需要反向寻路 + /// + private bool IsNeedReverseRoute(int startCityId, int endCityId) + { + // 检查正向传送点 + var startCity = _globalNetwork.CityDict[startCityId]; + var hasForward = startCity.Portals.Any(p => p.TargetCityId == endCityId); + + // 正向无则反向 + if (!hasForward) + { + var endCity = _globalNetwork.CityDict[endCityId]; + var hasReverse = endCity.Portals.Any(p => p.TargetCityId == startCityId); + return hasReverse; + } + + return false; + } + + /// + /// 辅助方法:获取城市名称 + /// + private string GetCityName(CityNode city) + { + return city?.CityName ?? "未知城市"; + } + + /// + /// 简化路径描述(用于展示) + /// + public List SimplifyPathForWap(List fullPath) + { + if (fullPath == null || fullPath.Count == 0) + return new List(); + + var simplified = new List(); + PathStep? lastTeleport = null; + + foreach (var step in fullPath) + { + if (step.StepType == PathStepType.Teleport) + { + simplified.Add(step.ToWapDesc(_globalNetwork)); + lastTeleport = step; + } + else if (lastTeleport == null && step == fullPath.First()) + { + var cityName = _globalNetwork.CityDict.ContainsKey(step.CityId) + ? _globalNetwork.CityDict[step.CityId].CityName + : "未知城市"; + simplified.Add($"【{cityName}】从起点(全局坐标{step.Position})出发"); + } + else if (step == fullPath.Last()) + { + var cityName = _globalNetwork.CityDict.ContainsKey(step.CityId) + ? _globalNetwork.CityDict[step.CityId].CityName + : "未知城市"; + simplified.Add($"【{cityName}】到达终点(全局坐标{step.Position})"); + } + } + + return simplified; + } +} \ No newline at end of file diff --git a/Service/Application.Web/Controllers/Map/MapController.cs b/Service/Application.Web/Controllers/Map/MapController.cs index 20bff4b..67f6c2d 100644 --- a/Service/Application.Web/Controllers/Map/MapController.cs +++ b/Service/Application.Web/Controllers/Map/MapController.cs @@ -14,12 +14,15 @@ public class MapController : ControllerBase private readonly IUnitUserService _userService; private readonly IGameMapService _mapService; private readonly IGameChatService _chatService; + private readonly IUnitUserAttrService _attrService; - public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService) + public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService, + IUnitUserAttrService attrService) { _userService = userService; _mapService = mapService; _chatService = chatService; + _attrService = attrService; } /// @@ -32,17 +35,35 @@ public class MapController : ControllerBase { string userId = StateHelper.userId; int area = StateHelper.areaId; - var onMap = await _mapService.GetUserOnMap(userId); game_city_map mapInfo = new game_city_map(); - if (string.IsNullOrEmpty(map)) + + #region 地图导向处理 + + bool isSelfMap = false; + if (!isSelfMap) { + //血量为0得时候地图点为本身 + var myBlood = await _attrService.GetUserBlood(userId); + if (myBlood.blood < 1) + { + //设置默认地图点 + await _mapService.SetUserMapDefult(userId); + isSelfMap = true; + } + } + + if (isSelfMap) + { + var onMap = await _mapService.GetUserOnMap(userId); mapInfo = await _mapService.GetMapInfo(onMap.mapId); } else { - mapInfo = await _mapService.GetMapInfo(map); + mapInfo = await _mapService.GetToMapInfo(userId, map, false); } + #endregion + //公聊信息 string teamId = ""; string groupId = ""; @@ -56,7 +77,7 @@ public class MapController : ControllerBase 3); //获取附近的人 var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId); //城市信息 - var cityShow = await _mapService.GetMapCity(cityInfo.cityId); //城内地图 + var cityShow = await _mapService.GetCityShowMap(cityInfo.cityId); //城内地图 #region 更新在线 @@ -83,16 +104,62 @@ public class MapController : ControllerBase string userId = StateHelper.userId; int areaId = StateHelper.areaId; var onMap = await _mapService.GetUserOnMap(userId); - + var mapInfo = await _mapService.GetMapInfo(onMap.mapId); if (mapInfo == null) { return PoAction.Message("地图不存在!"); } - var data = await _mapService.GetMapUser(onMap.mapId, areaId, (int)mapInfo.lookArea, new List { userId }, page, + var data = await _mapService.GetMapUser(onMap.mapId, areaId, (int)mapInfo.lookArea, new List { userId }, + page, 10, Total); - - return PoAction.Ok(new { data, total = Total.Value}); + + return PoAction.Ok(new { data, total = Total.Value }); + } + + /// + /// 获取当前城市所有地图 + /// + /// + [HttpGet] + public async Task GetUserOnCityMap(string? search) + { + string userId = StateHelper.userId; + var onMap = await _mapService.GetUserOnMap(userId); + var mapInfo = await _mapService.GetMapInfo(onMap.mapId); + var data = await _mapService.GetCityMap((int)mapInfo.cityId); + if (!string.IsNullOrEmpty(search)) + { + data = data.FindAll(it => it.mapName.Contains(search)); + } + + return PoAction.Ok(data); + } + + /// + /// 获取自动寻路路径 + /// + /// + /// + [HttpGet] + public async Task GetAutoMapPath(string? toMap) + { + if (string.IsNullOrEmpty(toMap)) + { + return PoAction.Message("目标地点不能为空!"); + } + + string userId = StateHelper.userId; + var onMap = await _mapService.GetUserOnMap(userId); + var result = await _mapService.CreateAutoMap(onMap.mapId, toMap); + if (result.Count > 0) + { + return PoAction.Ok(result); + } + else + { + return PoAction.Message("无法自动寻路!"); + } } } \ No newline at end of file diff --git a/Service/Application.Web/Controllers/User/BagController.cs b/Service/Application.Web/Controllers/User/BagController.cs index fd7e322..2aeadab 100644 --- a/Service/Application.Web/Controllers/User/BagController.cs +++ b/Service/Application.Web/Controllers/User/BagController.cs @@ -10,10 +10,14 @@ public class BagController : ControllerBase { private readonly IUnitUserWeight _weightService; + private readonly IGameGoodsService _goodsService; + private readonly IGameEquService _equService; - public BagController(IUnitUserWeight weightService) + public BagController(IUnitUserWeight weightService, IGameGoodsService goodsService, IGameEquService equService) { _weightService = weightService; + _goodsService = goodsService; + _equService = equService; } /// @@ -32,7 +36,89 @@ public class BagController : ControllerBase var userWeight = await _weightService.GetUserWeightInfo(userId); onWeight = (int)userWeight.onWeight; maxWeight = (int)userWeight.maxWeight; - - return PoAction.Ok(new { onWeight, maxWeight,cowry, gold, copper }); + + return PoAction.Ok(new { onWeight, maxWeight, cowry, gold, copper }); + } + + /// + /// 获取用户道具数据 + /// + /// + /// + /// + /// + /// + [HttpGet] + public async Task GetUserBagProp(int type, int ch, string? query, int page) + { + RefAsync total = 0; + string userId = StateHelper.userId; + if (type == 0) + { + int _t = 0; + switch (ch) + { + case 1: + _t = 1; + break; + case 2: + _t = 2; + break; + case 3: + _t = 3; + break; + } + + var data = await _equService.GetUserEquData(userId, _t, query, page, 10, total); + return PoAction.Ok(new { data, total.Value }); + } + else if (type == 1) + { + List code = new List() { nameof(GoodsEnum.Code.Drug) }; + var data = await _goodsService.GetUserGoodsData(userId, code, new List(), query, page, 10, total); + return PoAction.Ok(new { data, total.Value }); + } + else if (type == 2) + { + List code = new List(); + List noCode = new List() { nameof(GoodsEnum.Code.Drug) }; + switch (ch) + { + case 1: + code.Add(nameof(GoodsEnum.Code.Gem)); + break; + case 2: + code.Add(nameof(GoodsEnum.Code.Palace)); + break; + case 3: + code.Add(nameof(GoodsEnum.Code.Mark)); + break; + case 4: + code.Add(nameof(GoodsEnum.Code.Pack)); + break; + case 5: + code.Add(nameof(GoodsEnum.Code.Mak)); + break; + case 6: + code.Add(nameof(GoodsEnum.Code.Paper)); + break; + case 7: + code.Add(nameof(GoodsEnum.Code.Card)); + break; + case 8: + code.Add(nameof(GoodsEnum.Code.Cargo)); + break; + case 9: + code.Add(nameof(GoodsEnum.Code.Prop)); + break; + } + + var data = await _goodsService.GetUserGoodsData(userId, code, noCode, query, page, 10, total); + return PoAction.Ok(new { data, total.Value }); + } + else + { + return PoAction.Ok(new { data = new List(), total.Value }); + } } } \ No newline at end of file diff --git a/Web/src/components/Business/GamePopup.vue b/Web/src/components/Business/GamePopup.vue index 9b02efa..5f766b7 100644 --- a/Web/src/components/Business/GamePopup.vue +++ b/Web/src/components/Business/GamePopup.vue @@ -62,7 +62,6 @@ const visible = ref(props.isShow) .popup-content { margin-top: -35px; padding: 15px 15px; - color: #e0e0e0; font-size: 15px; line-height: 1.6; min-height: 80px; diff --git a/Web/src/components/Page/Footer.vue b/Web/src/components/Page/Footer.vue index 16ea000..1bb79b8 100644 --- a/Web/src/components/Page/Footer.vue +++ b/Web/src/components/Page/Footer.vue @@ -4,6 +4,7 @@
首页- 挂机- + 聚宝盆- 反馈
diff --git a/Web/src/extends/PageExtend.ts b/Web/src/extends/PageExtend.ts index d62eec4..e9a6d4a 100644 --- a/Web/src/extends/PageExtend.ts +++ b/Web/src/extends/PageExtend.ts @@ -9,6 +9,10 @@ export class PageExtend { return value ? String(value) : '' } + public static GetPageIndex(page: number, limit: number, index: number) { + return (page - 1) * limit + index; + } + // 回到顶部函数 默认平滑滚动到顶部 public static ScrollToTop(behavior: ScrollBehavior = 'smooth') { if (typeof window !== 'undefined') { diff --git a/Web/src/extends/TimeExtend.ts b/Web/src/extends/TimeExtend.ts index cd5ea32..8154d32 100644 --- a/Web/src/extends/TimeExtend.ts +++ b/Web/src/extends/TimeExtend.ts @@ -53,7 +53,7 @@ export class TimeExtend { * 获取当前秒级时间戳 */ public static GetSecondStamp(): number { - return Math.floor(Date.now() / 1000) + return Math.floor(Date.now() / 1000) + 28800 } /** @@ -70,12 +70,12 @@ export class TimeExtend { return this.Now('HH:mm:ss') } - /** - * 时间字符串 转换为 指定格式字符串 - * 场景:把 "2025-01-01 12:30:45" 转成 "2025年01月01日" / "01-01 12:30" 等 - * @param timeStr 时间字符串(如 2025-01-01、2025/01/01 12:30、2025-01-01 12:30:45) - * @param format 目标格式 - */ + /** + * 时间字符串 转换为 指定格式字符串 + * 场景:把 "2025-01-01 12:30:45" 转成 "2025年01月01日" / "01-01 12:30" 等 + * @param timeStr 时间字符串(如 2025-01-01、2025/01/01 12:30、2025-01-01 12:30:45) + * @param format 目标格式 + */ public static StrToFormat(timeStr: string, format = 'yyyy-MM-dd HH:mm:ss'): string { return this.Format(timeStr, format); } diff --git a/Web/src/pages/bag/index.vue b/Web/src/pages/bag/index.vue index 0b338f0..e20e7f2 100644 --- a/Web/src/pages/bag/index.vue +++ b/Web/src/pages/bag/index.vue @@ -1,8 +1,8 @@ \ No newline at end of file diff --git a/Web/src/pages/treasure/index.vue b/Web/src/pages/treasure/index.vue new file mode 100644 index 0000000..d141ea3 --- /dev/null +++ b/Web/src/pages/treasure/index.vue @@ -0,0 +1,31 @@ + \ No newline at end of file diff --git a/Web/src/services/map/MapService.ts b/Web/src/services/map/MapService.ts index ebab4ef..3ca14d4 100644 --- a/Web/src/services/map/MapService.ts +++ b/Web/src/services/map/MapService.ts @@ -14,4 +14,20 @@ export class MapService { static async GetMapUser(page: number) { return await ApiService.Request("get", "/Map/Map/GetMapUser", { page }); } + + /** + * 获取当前城市所有地图 + * GET /Map/Map/GetUserOnCityMap + */ + static async GetUserOnCityMap(search: string) { + return await ApiService.Request("get", "/Map/Map/GetUserOnCityMap", { search }); + } + + /** + * 获取自动寻路路径 + * GET /Map/Map/GetAutoMapPath + */ + static async GetAutoMapPath(toMap: string) { + return await ApiService.Request("get", "/Map/Map/GetAutoMapPath", { toMap }); + } } \ No newline at end of file diff --git a/Web/src/services/user/BagService.ts b/Web/src/services/user/BagService.ts index 388ee24..bd83acc 100644 --- a/Web/src/services/user/BagService.ts +++ b/Web/src/services/user/BagService.ts @@ -6,4 +6,12 @@ export class BagService { static async GetUserBagData() { return await ApiService.Request("get", "/User/Bag/GetUserBagData"); } + + /** + * GetUserBagProp + * GET /User/Bag/GetUserBagProp + */ + static async GetUserBagProp(type: number, ch: number, query: string, page: number) { + return await ApiService.Request("get", "/User/Bag/GetUserBagProp", { type, ch, query, page }); + } } \ No newline at end of file