1111
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AIRedisCache_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F55e5569a0f314a0db6a665eafad446dd6800_003F9e_003F88bbb06d_003FIRedisCache_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AISqlSugarClient_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6c0f22f0a47643a3b2a40899acd2044c2e3a00_003F5b_003F113fef0a_003FISqlSugarClient_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJwtExtensions_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6b089d08a87d4ddd82371ae63e754ba05000_003F26_003Fd6433acb_003FJwtExtensions_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJwtHelper_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6b089d08a87d4ddd82371ae63e754ba05000_003Fe2_003F86047f24_003FJwtHelper_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AJwtSecurityTokenHandler_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FSourcesCache_003Ff9d3fc33fd2fba97d4e718534a67f1d3c61e492634cd51c4798ce5621f780f3_003FJwtSecurityTokenHandler_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
|
||||
|
||||
@@ -63,8 +63,8 @@ namespace Application.Domain.Entity
|
||||
/// <summary>
|
||||
/// qualityAttr
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 2000, IsNullable = true)]
|
||||
public string? qualityAttr { get; set; }
|
||||
[SugarColumn( IsNullable = true,IsJson = true)]
|
||||
public List<AttrItem>? qualityAttr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sex
|
||||
@@ -172,7 +172,7 @@ namespace Application.Domain.Entity
|
||||
/// useEndTime
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public DateTime? useEndTime { get; set; }
|
||||
public long? useEndTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// weight
|
||||
@@ -189,8 +189,8 @@ namespace Application.Domain.Entity
|
||||
/// <summary>
|
||||
/// sysPrice
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 10, IsNullable = true)]
|
||||
public decimal? sysPrice { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? sysPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// canEqualUp
|
||||
@@ -199,28 +199,28 @@ namespace Application.Domain.Entity
|
||||
public int? canEqualUp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EquAttr
|
||||
/// 装备属性
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? EquAttr { get; set; }
|
||||
[SugarColumn(IsNullable = true,IsJson = true)]
|
||||
public List<AttrItem>? EquAttr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EquMent
|
||||
/// 附魔属性
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? EquMent { get; set; }
|
||||
[SugarColumn(IsNullable = true,IsJson = true)]
|
||||
public EquMent? EquMent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// EquAwaken
|
||||
/// 觉醒属性
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? EquAwaken { get; set; }
|
||||
[SugarColumn(IsNullable = true,IsJson = true)]
|
||||
public List<EquAwaken>? EquAwaken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// GemMent
|
||||
/// 宝石属性
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? GemMent { get; set; }
|
||||
[SugarColumn(IsNullable = true,IsJson = true)]
|
||||
public List<EquGem>? GemMent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// isDeal
|
||||
@@ -235,33 +235,21 @@ namespace Application.Domain.Entity
|
||||
public int? isGive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// score
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? score { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// start
|
||||
/// 星级
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? start { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// exp
|
||||
/// 0不需要鉴定 1需要鉴定
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? exp { get; set; }
|
||||
public int? isAppr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// startAttr
|
||||
/// 是否穿戴
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? startAttr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// swallow
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? swallow { get; set; }
|
||||
public int? isOn { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@ namespace Application.Domain.Entity
|
||||
/// <summary>
|
||||
/// count
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 65, IsNullable = true)]
|
||||
public decimal? count { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public long? count { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// weight
|
||||
@@ -57,8 +57,8 @@ namespace Application.Domain.Entity
|
||||
/// <summary>
|
||||
/// sysPrice
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 18, IsNullable = true)]
|
||||
public decimal? sysPrice { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? sysPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0不可交易1可交易
|
||||
@@ -72,4 +72,4 @@ namespace Application.Domain.Entity
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? isGive { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Service/Application.Domain.Entity/model/AttrItem.cs
Normal file
36
Service/Application.Domain.Entity/model/AttrItem.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
namespace Application.Domain.Entity;
|
||||
|
||||
public class AttrItem
|
||||
{
|
||||
private System.String _code;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String code
|
||||
{ get { return this._code; } set { this._code = value; } }
|
||||
|
||||
private System.String _compute;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String compute
|
||||
{ get { return this._compute; } set { this._compute = value; } }
|
||||
|
||||
private System.Decimal _parameter;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Decimal parameter
|
||||
{ get { return this._parameter; } set { this._parameter = value; } }
|
||||
|
||||
private System.String _tip;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String tip
|
||||
{ get { return this._tip; } set { this._tip = value; } }
|
||||
}
|
||||
37
Service/Application.Domain.Entity/model/EquAwaken.cs
Normal file
37
Service/Application.Domain.Entity/model/EquAwaken.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
namespace Application.Domain.Entity;
|
||||
|
||||
public class EquAwaken
|
||||
{
|
||||
private System.String _atId;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String atId
|
||||
{ get { return this._atId; } set { this._atId = value; } }
|
||||
|
||||
private System.Int32 _lev;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32 lev
|
||||
{ get { return this._lev; } set { this._lev = value; } }
|
||||
|
||||
private System.String _name;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String name
|
||||
{ get { return this._name; } set { this._name = value; } }
|
||||
|
||||
private List<AttrItem> _awaken;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SqlSugar.SugarColumn(ColumnDataType = "varchar(max)", IsJson = true)]
|
||||
public List<AttrItem> awaken
|
||||
{ get { return this._awaken; } set { this._awaken = value; } }
|
||||
}
|
||||
50
Service/Application.Domain.Entity/model/EquGem.cs
Normal file
50
Service/Application.Domain.Entity/model/EquGem.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
namespace Application.Domain.Entity;
|
||||
|
||||
public class EquGem
|
||||
{
|
||||
private System.String _Id;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String Id
|
||||
{ get { return this._Id; } set { this._Id = value; } }
|
||||
|
||||
private System.Int32 _goodsId;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32 goodsId
|
||||
{ get { return this._goodsId; } set { this._goodsId = value; } }
|
||||
|
||||
private System.String _goodsName;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String goodsName
|
||||
{ get { return this._goodsName; } set { this._goodsName = value; } }
|
||||
|
||||
private System.Int32? _isDeal;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32? isDeal
|
||||
{ get { return this._isDeal; } set { this._isDeal = value; } }
|
||||
|
||||
public EquGemItem gemItem { get; set; }
|
||||
}
|
||||
public class EquGemItem
|
||||
{
|
||||
private System.String _place;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String place
|
||||
{ get { return this._place; } set { this._place = value; } }
|
||||
|
||||
public List<AttrItem> GemAttr { get; set; }
|
||||
}
|
||||
45
Service/Application.Domain.Entity/model/EquMent.cs
Normal file
45
Service/Application.Domain.Entity/model/EquMent.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
namespace Application.Domain.Entity;
|
||||
|
||||
public class EquMent
|
||||
{
|
||||
private System.String _name;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.String name
|
||||
{ get { return this._name; } set { this._name = value; } }
|
||||
|
||||
private System.Int32 _goodsId;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32 goodsId
|
||||
{ get { return this._goodsId; } set { this._goodsId = value; } }
|
||||
|
||||
private System.Int32? _isDeal;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32? isDeal
|
||||
{ get { return this._isDeal; } set { this._isDeal = value; } }
|
||||
|
||||
private System.Int32? _isGive;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public System.Int32? isGive
|
||||
{ get { return this._isGive; } set { this._isGive = value; } }
|
||||
|
||||
private List<AttrItem> _EquAttr;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[SqlSugar.SugarColumn(ColumnDataType = "varchar(max)", IsJson = true)]
|
||||
public List<AttrItem> EquAttr
|
||||
{ get { return this._EquAttr; } set { this._EquAttr = value; } }
|
||||
}
|
||||
171
Service/Application.Domain.Entity/resource/game/game_equ.cs
Normal file
171
Service/Application.Domain.Entity/resource/game/game_equ.cs
Normal file
@@ -0,0 +1,171 @@
|
||||
using SqlSugar;
|
||||
using System;
|
||||
|
||||
namespace Application.Domain.Entity
|
||||
{
|
||||
[Tenant("Kg.SeaTime.Resource")]
|
||||
public class game_equ
|
||||
{
|
||||
/// <summary>
|
||||
/// equId
|
||||
/// </summary>
|
||||
[SugarColumn(IsPrimaryKey = true)]
|
||||
public int equId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// equName
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? equName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// lev
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? lev { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// quality
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? quality { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// code
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sex
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? sex { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// img
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? img { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// minAtk
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? minAtk { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// maxAtk
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? maxAtk { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// defense
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? defense { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// agility
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? agility { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// blood
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? blood { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// morale
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? morale { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0非套装
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 50, IsNullable = true)]
|
||||
public string? suitCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// durability
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? durability { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否可强化
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? isIntensify { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// holeCount
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? holeCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0永久 其他为小时
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? useTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// weight
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? weight { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// remark
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public string? remark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// source
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 255, IsNullable = true)]
|
||||
public string? source { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// sysPrice
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? sysPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// equAttr
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true,IsJson = true)]
|
||||
public List<AttrItem>? equAttr { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 可穿戴数量
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? canEqualUp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0不可交易1可交易
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? isDeal { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0不可赠送 1可赠送
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? isGive { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 0不需要鉴定 1需要鉴定
|
||||
/// </summary>
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? isAppr { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ namespace Application.Domain.Entity
|
||||
/// sysPrice
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 18, IsNullable = true)]
|
||||
public decimal? sysPrice { get; set; }
|
||||
public int? sysPrice { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// content
|
||||
|
||||
6
Service/Application.Domain/Enum/EquEnum.cs
Normal file
6
Service/Application.Domain/Enum/EquEnum.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
public static class EquEnum
|
||||
{
|
||||
|
||||
}
|
||||
@@ -7,5 +7,12 @@ public static class GoodsEnum
|
||||
Drug,//药品
|
||||
Prop,//物品
|
||||
Cargo,//货物
|
||||
Gem,//宝石
|
||||
Mak,//材料
|
||||
Palace,//九宫
|
||||
Paper,//图纸
|
||||
Card,//附魔卡片
|
||||
Mark,//圣痕
|
||||
Pack,//宝箱
|
||||
}
|
||||
}
|
||||
@@ -2,5 +2,22 @@
|
||||
|
||||
public interface IGameEquService
|
||||
{
|
||||
#region 装备资源
|
||||
|
||||
Task<game_equ> GetEquInfo(int equId);
|
||||
|
||||
#endregion
|
||||
#region 用户装备
|
||||
|
||||
Task<List<unit_user_equ>> GetUserEquData(string userId, int type, string equName, int PageIndex, int PageSize,
|
||||
RefAsync<int> Total);
|
||||
|
||||
Task<List<unit_user_equ>> GetUserEquData(string userId, int equId);
|
||||
Task<bool> AddUserEqu(string userId, int equId, int count, string remark);
|
||||
Task<bool> DeductUserEqu(string userId, List<unit_user_equ> equData, string remark);
|
||||
Task<bool> DeductUserEqu(string userId, int equId, int count, string remark);
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public interface IGameGoodsService
|
||||
Task<unit_user_goods> GetUserGoodsInfo(string userId, int goodsId);
|
||||
Task<int> GetUserGoodsCount(string userId, int goodsId);
|
||||
|
||||
Task<List<unit_user_goods>> GetUserGoodsData(string userId, List<string> code, string search, int page,
|
||||
Task<List<unit_user_goods>> GetUserGoodsData(string userId, List<string> code, List<string> noCode, string search, int page,
|
||||
int limit, RefAsync<int> total);
|
||||
|
||||
Task<bool> UpdateUserGoods(string userId, int op, int goodsId, int count, string remark = "");
|
||||
|
||||
@@ -5,8 +5,10 @@ public interface IGameMapService
|
||||
#region 城市地图数据
|
||||
|
||||
Task<game_city> GetCityInfo(int cityId);
|
||||
Task<List<game_city>> GetCityData();
|
||||
Task<List<game_city_map>> GetCityMap(int cityId);
|
||||
Task<List<game_city_map>> GetCityShowMap(int cityId);
|
||||
Task<game_city_map> GetMapInfo(string mapId);
|
||||
Task<List<game_city_map>> GetMapCity(int cityId);
|
||||
Task<int> GetMapCityByMapId(string mapId);
|
||||
Task<List<game_city_npc>> GetMapNpc(string mapId);
|
||||
Task<game_city_npc> GetNpcInfo(int npcId);
|
||||
@@ -17,7 +19,9 @@ public interface IGameMapService
|
||||
Task<string> GetUserOnMapId(string userId);
|
||||
Task<unit_user_online> GetUserOnMap(string userId);
|
||||
Task UpdateUserOnMap(string userId, string ip, string mapId);
|
||||
|
||||
Task<bool> UpdateUserOnMap(unit_user_online data, string mapId);
|
||||
Task SetUserMapDefult(string userId);
|
||||
Task<game_city_map> GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, bool isChangeCity = false);
|
||||
#endregion
|
||||
|
||||
#region 其他相关
|
||||
@@ -27,5 +31,12 @@ public interface IGameMapService
|
||||
Task<List<UserModel>> GetMapUser(string mapId, int area, int showArea, List<string> noUser, int page,
|
||||
int limit, RefAsync<int> total);
|
||||
|
||||
#endregion
|
||||
|
||||
#region 自动寻路
|
||||
|
||||
Task<List<MapLine>> CreateAutoMap(string start, string end);
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
public interface IUnitUserAttrService
|
||||
{
|
||||
Task<unit_user_blood> GetUserBlood(string userId);
|
||||
Task<bool> UpdateUserBlood(string userId, int op, int count, bool mustUp = false);
|
||||
}
|
||||
@@ -2,4 +2,237 @@
|
||||
|
||||
public class GameEquService(ISqlSugarClient DbClient, IRedisCache redis) : IGameEquService, ITransient
|
||||
{
|
||||
#region 装备资源
|
||||
|
||||
public async Task<game_equ> GetEquInfo(int equId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "EquData", "EquInfo");
|
||||
var data = await redis.GetHashAsync<game_equ>(key, equId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_equ>();
|
||||
data = await db.Queryable<game_equ>().Where(it => it.equId == equId).SingleAsync();
|
||||
await redis.AddHashAsync(key, equId.ToString(), data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 用户装备
|
||||
|
||||
public async Task<List<unit_user_equ>> GetUserEquData(string userId, int type, string equName, int PageIndex,
|
||||
int PageSize, RefAsync<int> Total)
|
||||
{
|
||||
long onTime = TimeExtend.GetTimeStampSeconds;
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_equ>();
|
||||
return await db.Queryable<unit_user_equ>().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<List<unit_user_equ>> GetUserEquData(string userId, int equId)
|
||||
{
|
||||
long onTime = TimeExtend.GetTimeStampSeconds;
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_equ>();
|
||||
return await db.Queryable<unit_user_equ>().Where(it => it.userId == userId && it.equId == equId).ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<bool> AddUserEqu(string userId, int equId, int count, string remark)
|
||||
{
|
||||
bool result = false;
|
||||
var equ = await GetEquInfo(equId);
|
||||
if (equ != null)
|
||||
{
|
||||
List<unit_user_equ> adds = new List<unit_user_equ>();
|
||||
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<AttrItem>();
|
||||
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<EquAwaken>();
|
||||
ue.GemMent = new List<EquGem>();
|
||||
ue.useEndTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddYears(20));
|
||||
adds.Add(ue);
|
||||
}
|
||||
|
||||
if (adds.Count > 0)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_equ>();
|
||||
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<IUnitUserWeight>();
|
||||
await attrService.UpdateUserWeight(userId, 1, weightCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> DeductUserEqu(string userId, List<unit_user_equ> equData, string remark)
|
||||
{
|
||||
bool result = false;
|
||||
List<string> DelEqu = new List<string>();
|
||||
List<unit_user_equ_log> logs = new List<unit_user_equ_log>();
|
||||
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<unit_user_equ>();
|
||||
result = await db.Deleteable<unit_user_equ>().Where(i => DelEqu.Contains(i.ueId)).ExecuteCommandAsync() > 0;
|
||||
if (result) //生成成功
|
||||
{
|
||||
//更新负重
|
||||
if (weightCount > 0)
|
||||
{
|
||||
var attrService = App.GetService<IUnitUserWeight>();
|
||||
await attrService.UpdateUserWeight(userId, 0, weightCount);
|
||||
}
|
||||
|
||||
if (logs.Count > 0)
|
||||
{
|
||||
await AddEquLog(logs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<bool> 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<unit_user_equ> ues, int code, string remark, string userId,
|
||||
bool isAddAttr = false)
|
||||
{
|
||||
List<unit_user_equ_log> adds = new List<unit_user_equ_log>();
|
||||
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<unit_user_equ_log>();
|
||||
await db.Insertable(adds).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
private async Task AddEquLog(List<unit_user_equ_log> logs)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_equ_log>();
|
||||
await db.Insertable(logs).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -55,12 +55,13 @@ public class GameGoodsService(ISqlSugarClient DbClient, IRedisCache redis) : IGa
|
||||
return info == null ? 0 : (int)info.count;
|
||||
}
|
||||
|
||||
public async Task<List<unit_user_goods>> GetUserGoodsData(string userId, List<string> code, string search, int page,
|
||||
public async Task<List<unit_user_goods>> GetUserGoodsData(string userId, List<string> code, List<string> noCode, string search, int page,
|
||||
int limit, RefAsync<int> total)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_goods>();
|
||||
return await db.Queryable<unit_user_goods>().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)
|
||||
|
||||
@@ -6,7 +6,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
|
||||
public async Task<game_city> GetCityInfo(int cityId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "CityData");
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInfo");
|
||||
var data = await redis.GetHashAsync<game_city>(key, cityId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
@@ -18,9 +18,53 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<game_city>> GetCityData()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityData");
|
||||
var data = await redis.GetAsync<List<game_city>>(key);
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city>();
|
||||
data = await db.Queryable<game_city>().ToListAsync();
|
||||
await redis.SetAsync(key, data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public async Task<List<game_city_map>> GetCityMap(int cityId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityMap");
|
||||
var data = await redis.GetHashAsync<List<game_city_map>>(key, cityId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
||||
data = await db.Queryable<game_city_map>().Where(it => it.cityId == cityId).ToListAsync();
|
||||
await redis.AddHashAsync(key, cityId.ToString(), data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<game_city_map>> GetCityShowMap(int cityId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityShowMap");
|
||||
var data = await redis.GetHashAsync<List<game_city_map>>(key, cityId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
||||
data = await db.Queryable<game_city_map>().Where(it => it.cityId == cityId && it.show == 1).ToListAsync();
|
||||
await redis.AddHashAsync(key, cityId.ToString(), data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<game_city_map> GetMapInfo(string mapId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "MapData");
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "MapData");
|
||||
var data = await redis.GetHashAsync<game_city_map>(key, mapId);
|
||||
if (data == null)
|
||||
{
|
||||
@@ -32,19 +76,6 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<List<game_city_map>> GetMapCity(int cityId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "CityShowMap");
|
||||
var data = await redis.GetHashAsync<List<game_city_map>>(key, cityId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city_map>();
|
||||
data = await db.Queryable<game_city_map>().Where(it => it.cityId == cityId && it.show == 1).ToListAsync();
|
||||
await redis.AddHashAsync(key, cityId.ToString(), data);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<int> GetMapCityByMapId(string mapId)
|
||||
{
|
||||
@@ -61,7 +92,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
|
||||
public async Task<List<game_city_npc>> GetMapNpc(string mapId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "NpcData");
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcData");
|
||||
var data = await redis.GetHashAsync<List<game_city_npc>>(key, mapId);
|
||||
if (data == null)
|
||||
{
|
||||
@@ -75,7 +106,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
|
||||
public async Task<game_city_npc> GetNpcInfo(int npcId)
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapCityData", "NpcInfo");
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "NpcInfo");
|
||||
var data = await redis.GetHashAsync<game_city_npc>(key, npcId.ToString());
|
||||
if (data == null)
|
||||
{
|
||||
@@ -131,6 +162,119 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
|
||||
}
|
||||
}
|
||||
|
||||
public async Task<bool> 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<unit_user_online>();
|
||||
await db.Updateable<unit_user_online>(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<game_city_map> 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<unit_user_online>().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<UserModel> result = new List<UserModel>();
|
||||
@@ -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<List<game_city>> GetCityDataExcludeParent()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityParent");
|
||||
var data = await redis.GetAsync<List<game_city>>(key);
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<game_city>();
|
||||
data = await db.Queryable<game_city>().Where(it => it.parent != 0).ToListAsync();
|
||||
|
||||
await redis.SetAsync(key, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
private async Task<List<game_city_map>> GetAllMaoToData()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityInterCityPortal");
|
||||
if (await redis.ExistsAsync(key))
|
||||
{
|
||||
return await redis.GetAsync<List<game_city_map>>(key);
|
||||
}
|
||||
|
||||
List<game_city_map> result = new List<game_city_map>();
|
||||
|
||||
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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 城市信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<List<CityNode>> GetCityNode()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityNode");
|
||||
var data = await redis.GetAsync<List<CityNode>>(key);
|
||||
if (data == null)
|
||||
{
|
||||
data = new List<CityNode>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 城市网络
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<Dictionary<int, List<game_city_map>>> GetCityRoadNetwork()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityRoadNetwork");
|
||||
var data = await redis.GetAsync<Dictionary<int, List<game_city_map>>>(key);
|
||||
if (data == null)
|
||||
{
|
||||
data = new Dictionary<int, List<game_city_map>>();
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 传送点信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private async Task<List<InterCityPortal>> GetCityInterCityPortal()
|
||||
{
|
||||
string key = string.Format(BaseCache.BaseCacheKeys, "CityData", "CityInterCityPortal");
|
||||
var data = await redis.GetAsync<List<InterCityPortal>>(key);
|
||||
if (data == null)
|
||||
{
|
||||
data = new List<InterCityPortal>();
|
||||
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<List<MapLine>> 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<CityRoadNetwork> NetworkData = new List<CityRoadNetwork>();
|
||||
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<int> cityRoute = cityData.Select(it => it.cityId).ToList();
|
||||
var path = pathFinder.FindCrossCityPath(start, end);
|
||||
List<MapLine> result = new List<MapLine>();
|
||||
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<List<MapLine>> 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
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) : IUnitUserAttrService, ITransient
|
||||
{
|
||||
|
||||
#region 体力操作
|
||||
public async Task<unit_user_blood> GetUserBlood(string userId)
|
||||
{
|
||||
string key = string.Format(UserCache.BaseCacheKeys, "AttrData","Blood");
|
||||
var data = await redis.GetHashAsync<unit_user_blood>(key, userId);
|
||||
if (data == null)
|
||||
{
|
||||
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_blood>();
|
||||
data = await db.Queryable<unit_user_blood>().Where(it => it.userId == userId).SingleAsync();
|
||||
await redis.AddHashAsync(key, userId, data);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public async Task<bool> 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<unit_user_blood>();
|
||||
result = await db.Updateable<unit_user_blood>()
|
||||
.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
|
||||
|
||||
}
|
||||
8
Service/Application.Domain/Tool/MapPath/MapLine.cs
Normal file
8
Service/Application.Domain/Tool/MapPath/MapLine.cs
Normal file
@@ -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; }
|
||||
}
|
||||
692
Service/Application.Domain/Tool/MapPath/MapRunTool.cs
Normal file
692
Service/Application.Domain/Tool/MapPath/MapRunTool.cs
Normal file
@@ -0,0 +1,692 @@
|
||||
namespace Application.Domain;
|
||||
|
||||
// ===================== 核心定义:全局坐标体系 =====================
|
||||
/// <summary>
|
||||
/// 全局坐标结构体(所有城市共享唯一坐标)
|
||||
/// </summary>
|
||||
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})";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 城市节点(全局坐标管辖范围)
|
||||
/// </summary>
|
||||
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<InterCityPortal> 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<InterCityPortal>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验全局坐标是否属于当前城市管辖范围
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 城际传送点(全局坐标,PortalId改为字符串)
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 全局路网(基于全局坐标管理城市+传送点)
|
||||
/// </summary>
|
||||
public class GlobalRoadNetwork
|
||||
{
|
||||
public Dictionary<int, CityNode> CityDict { get; private set; }
|
||||
public Dictionary<string, InterCityPortal> PortalDict { get; private set; } // 适配字符串PortalId
|
||||
|
||||
public GlobalRoadNetwork()
|
||||
{
|
||||
CityDict = new Dictionary<int, CityNode>();
|
||||
PortalDict = new Dictionary<string, InterCityPortal>(); // 改为字符串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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据全局坐标获取所属城市
|
||||
/// </summary>
|
||||
public CityNode GetCityByGlobalPoint(Point point)
|
||||
{
|
||||
return CityDict.Values.FirstOrDefault(city => city.IsPointInCity(point));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最优传送点(修复反向寻路筛选逻辑)
|
||||
/// </summary>
|
||||
public InterCityPortal GetOptimalPortal(int startCityId, int targetCityId, Point startPos,
|
||||
Dictionary<int, CityRoadNetwork> 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取反向传送点(适配字符串PortalId)
|
||||
/// </summary>
|
||||
public InterCityPortal GetReversePortal(InterCityPortal portal)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(portal.ReversePortalId) && PortalDict.ContainsKey(portal.ReversePortalId))
|
||||
return PortalDict[portal.ReversePortalId];
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验全局坐标合法性(属于某城市+该城市内可通行)
|
||||
/// </summary>
|
||||
public bool IsPointValid(Point point, Dictionary<int, CityRoadNetwork> cityNetworks)
|
||||
{
|
||||
var city = GetCityByGlobalPoint(point);
|
||||
if (city == null || !cityNetworks.ContainsKey(city.CityId))
|
||||
return false;
|
||||
return cityNetworks[city.CityId].IsPointWalkable(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修复:使用BFS获取所有连通的城市链(支持多中转)
|
||||
/// </summary>
|
||||
public List<int> GetConnectedCityChain(int startCityId, int endCityId)
|
||||
{
|
||||
if (startCityId == endCityId)
|
||||
return new List<int> { startCityId };
|
||||
|
||||
// BFS队列:存储(当前城市ID, 路径)
|
||||
var queue = new Queue<Tuple<int, List<int>>>();
|
||||
var visited = new HashSet<int>();
|
||||
|
||||
queue.Enqueue(Tuple.Create(startCityId, new List<int> { startCityId }));
|
||||
visited.Add(startCityId);
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
int currCityId = current.Item1;
|
||||
List<int> 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<int>(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<AStarNode>
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 单城市路网(基于全局坐标管理可通行区域)
|
||||
/// </summary>
|
||||
public class CityRoadNetwork
|
||||
{
|
||||
public int CityId { get; set; }
|
||||
public Dictionary<Point, bool> WalkablePoints { get; private set; } // 全局坐标可通行列表
|
||||
|
||||
public CityRoadNetwork(int cityId)
|
||||
{
|
||||
CityId = cityId;
|
||||
WalkablePoints = new Dictionary<Point, bool>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加全局坐标可通行点
|
||||
/// </summary>
|
||||
public void AddWalkablePoint(int x, int y, bool walkable = true)
|
||||
{
|
||||
var point = new Point(x, y);
|
||||
WalkablePoints[point] = walkable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 批量添加全局坐标可通行区域
|
||||
/// </summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验全局坐标是否可走
|
||||
/// </summary>
|
||||
public bool IsPointWalkable(Point point)
|
||||
{
|
||||
return WalkablePoints.TryGetValue(point, out bool walkable) && walkable;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修复后的A*寻路(基于全局坐标)
|
||||
/// </summary>
|
||||
public List<Point> 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<Point> { start };
|
||||
|
||||
// 开放列表(排序集合)和关闭列表
|
||||
var openSet = new SortedSet<AStarNode>();
|
||||
var openDict = new Dictionary<Point, AStarNode>(); // 快速查找
|
||||
var closeDict = new Dictionary<Point, AStarNode>();
|
||||
|
||||
// 初始化起点
|
||||
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<Point>();
|
||||
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<int, CityRoadNetwork> _cityNetworks;
|
||||
|
||||
public CrossCityPathFinder(GlobalRoadNetwork globalNetwork)
|
||||
{
|
||||
_globalNetwork = globalNetwork;
|
||||
_cityNetworks = new Dictionary<int, CityRoadNetwork>();
|
||||
}
|
||||
|
||||
public void AddCityRoadNetwork(CityRoadNetwork cityNetwork)
|
||||
{
|
||||
if (!_cityNetworks.ContainsKey(cityNetwork.CityId))
|
||||
_cityNetworks.Add(cityNetwork.CityId, cityNetwork);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 核心方法:输入起止点,全自动判定同城/跨城/多城市,自动适配正向/反向
|
||||
/// </summary>
|
||||
public List<PathStep> 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<int, Point>
|
||||
{
|
||||
{ startCity.CityId, startPos },
|
||||
{ endCity.CityId, endPos }
|
||||
};
|
||||
|
||||
// 自动判断是否需要反向寻路
|
||||
var isReverse = IsNeedReverseRoute(startCity.CityId, endCity.CityId);
|
||||
|
||||
return FindMultiCityPath(cityChain, cityStartPoints, isReverse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 同城寻路
|
||||
/// </summary>
|
||||
private List<PathStep> 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();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 多城市寻路(自动适配正向/反向)
|
||||
/// </summary>
|
||||
private List<PathStep> FindMultiCityPath(List<int> cityChain, Dictionary<int, Point> cityStartPoints,
|
||||
bool isReverse)
|
||||
{
|
||||
var finalPath = new List<PathStep>();
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动判断是否需要反向寻路
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 辅助方法:获取城市名称
|
||||
/// </summary>
|
||||
private string GetCityName(CityNode city)
|
||||
{
|
||||
return city?.CityName ?? "未知城市";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简化路径描述(用于展示)
|
||||
/// </summary>
|
||||
public List<string> SimplifyPathForWap(List<PathStep> fullPath)
|
||||
{
|
||||
if (fullPath == null || fullPath.Count == 0)
|
||||
return new List<string>();
|
||||
|
||||
var simplified = new List<string>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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<string> { userId }, page,
|
||||
var data = await _mapService.GetMapUser(onMap.mapId, areaId, (int)mapInfo.lookArea, new List<string> { userId },
|
||||
page,
|
||||
10, Total);
|
||||
|
||||
return PoAction.Ok(new { data, total = Total.Value});
|
||||
|
||||
return PoAction.Ok(new { data, total = Total.Value });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前城市所有地图
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<IPoAction> 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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取自动寻路路径
|
||||
/// </summary>
|
||||
/// <param name="toMap"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<IPoAction> 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("无法自动寻路!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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 });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户道具数据
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="type"></param>
|
||||
/// <param name="ch"></param>
|
||||
/// <param name="page"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<IPoAction> GetUserBagProp(int type, int ch, string? query, int page)
|
||||
{
|
||||
RefAsync<int> 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<string> code = new List<string>() { nameof(GoodsEnum.Code.Drug) };
|
||||
var data = await _goodsService.GetUserGoodsData(userId, code, new List<string>(), query, page, 10, total);
|
||||
return PoAction.Ok(new { data, total.Value });
|
||||
}
|
||||
else if (type == 2)
|
||||
{
|
||||
List<string> code = new List<string>();
|
||||
List<string> noCode = new List<string>() { 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<string>(), total.Value });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
<div class="common">
|
||||
<Abar href="/">首页</Abar>-
|
||||
<Abar href="/">挂机</Abar>-
|
||||
<Abar href="/treasure">聚宝盆</Abar>-
|
||||
<a target="_blank" href="https://work.weixin.qq.com/kfid/kfc86bc348120aea3e7">反馈</a>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -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') {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="content">
|
||||
【我的物品】.<Abutton @click="Refresh">刷新</Abutton> <br>
|
||||
金元: {{ bagInfo.gold }}<br />
|
||||
金贝: {{ bagInfo.cowry }} <br />
|
||||
金元:{{ bagInfo.gold }}<br />
|
||||
金贝:{{ bagInfo.cowry }} <br />
|
||||
负重:{{ bagInfo.onWeight }}/{{ bagInfo.maxWeight }} <br />
|
||||
{{ bagInfo.copper }}铜<br />
|
||||
<Abar href="/">交易记录</Abar><br>
|
||||
@@ -27,7 +27,8 @@
|
||||
<div v-if="type == '0'">
|
||||
<Acheak @click="ChangeChildBag('0')" :on-value="type_ch" on-cheak="0">全部</Acheak>.<Acheak
|
||||
@click="ChangeChildBag('1')" :on-value="type_ch" on-cheak="1">穿戴</Acheak>.<Acheak
|
||||
@click="ChangeChildBag('2')" :on-value="type_ch" on-cheak="2">到期</Acheak>
|
||||
@click="ChangeChildBag('2')" :on-value="type_ch" on-cheak="2">过期</Acheak>.<Acheak
|
||||
@click="ChangeChildBag('3')" :on-value="type_ch" on-cheak="3">未鉴定</Acheak>
|
||||
</div>
|
||||
<div v-if="type == '2'">
|
||||
<Acheak @click="ChangeChildBag('0')" :on-value="type_ch" on-cheak="0">全部</Acheak>.<Acheak
|
||||
@@ -45,7 +46,37 @@
|
||||
|
||||
</div>
|
||||
<div class="content">
|
||||
暂无.
|
||||
<div class="common" v-if="type == '0'">
|
||||
<div class="item" v-for="(item, index) in data" :key="index">
|
||||
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
|
||||
<Abar href="">{{ item.equName }}({{item.lev}}级)</Abar>
|
||||
<span v-if="item.isOn == 1">(穿)</span>
|
||||
<span v-if="item.isAppr == 0">(未鉴定)</span>
|
||||
<span v-if="item.useEndTime < onTime" style="color: red;">(过期)</span>
|
||||
<span v-if="item.durability < 1" style="color: red;">(损坏)</span>
|
||||
<span v-if="item.isLock == 1" style="color: green;">(锁)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="common" v-if="type == '1'">
|
||||
<div class="item" v-for="(item, index) in data" :key="index">
|
||||
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
|
||||
<Abar href="">{{ item.goodsName }}</Abar>({{ item.count }})
|
||||
</div>
|
||||
</div>
|
||||
<div class="common" v-if="type == '2'">
|
||||
<div class="item" v-for="(item, index) in data" :key="index">
|
||||
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
|
||||
<span v-if="item.code == 'Card'">
|
||||
<Abar href="">{{ item.goodsName }}</Abar>({{ item.count }})
|
||||
</span>
|
||||
<span v-else>
|
||||
<Abar href="">{{ item.goodsName }}</Abar>({{ item.count }})
|
||||
</span>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span v-if="data.length == 0">暂无.</span>
|
||||
</div>
|
||||
<div class="content">
|
||||
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
|
||||
@@ -65,17 +96,17 @@ const data = ref<Array<any>>([]);
|
||||
const type = ref('0');
|
||||
const type_ch = ref('0');
|
||||
const serch = ref('');
|
||||
const onTime = ref(0);
|
||||
|
||||
|
||||
onMounted(async () => {
|
||||
try {
|
||||
|
||||
onTime.value = TimeExtend.GetSecondStamp();
|
||||
let result = await BagService.GetUserBagData();
|
||||
if (result.code == 0) {
|
||||
bagInfo.value = result.data;
|
||||
await BindData();
|
||||
}
|
||||
console.log(result);
|
||||
}
|
||||
finally {
|
||||
PageLoading.Close();
|
||||
@@ -83,11 +114,11 @@ onMounted(async () => {
|
||||
})
|
||||
|
||||
const BindData = async (): Promise<void> => {
|
||||
let result = await MapService.GetMapUser(currentPage.value);
|
||||
let result = await BagService.GetUserBagProp(Number(type.value), Number(type_ch.value), serch.value, currentPage.value)
|
||||
if (result.code == 0) {
|
||||
data.value = result.data.data;
|
||||
total.value = result.data.total;
|
||||
console.log(result);
|
||||
console.log(data.value);
|
||||
}
|
||||
else {
|
||||
MessageExtend.ShowDialog("提示", result.msg);
|
||||
@@ -109,6 +140,7 @@ const ChangeChildBag = async (ch: string): Promise<void> => {
|
||||
/**刷新 */
|
||||
const Refresh = async (): Promise<void> => {
|
||||
serch.value = '';
|
||||
onTime.value = TimeExtend.GetSecondStamp();
|
||||
MessageExtend.LoadingToast("刷新中...");
|
||||
currentPage.value = 1;
|
||||
await BindData();
|
||||
|
||||
@@ -14,27 +14,32 @@
|
||||
</div>
|
||||
<div class="content">
|
||||
您看到:
|
||||
<Abar href="/map/user" v-if="mapUser.length>0">
|
||||
<span v-for="item in mapUser">{{item.nick}} </span>
|
||||
</Abar>
|
||||
<Abar href="/map/user" v-if="mapUser.length > 0">
|
||||
<span v-for="item in mapUser">{{ item.nick }} </span>
|
||||
</Abar>
|
||||
</div>
|
||||
<div class="content">
|
||||
<div class="item" v-for="item in npcData">
|
||||
<Abar href="">{{ item.npcName }}{{ item.tips }}</Abar>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="content">
|
||||
请选择出口:<br />
|
||||
<span v-if="mapDong.mapId != ''">东:<Abutton @click="BindData(mapDong.mapId)">{{ mapDong.name }}</Abutton></span>
|
||||
<span v-if="mapXi.mapId != ''">西:<Abutton @click="BindData(mapXi.mapId)">{{ mapXi.name }}</Abutton></span>
|
||||
<span v-if="mapDong.mapId != ''">东:<Abutton @click="BindData(mapDong.mapId)">{{ mapDong.name }}</Abutton>
|
||||
<b v-if="toMapPathData.some(it => it.mapId == mapDong.mapId)">🚩</b>
|
||||
</span>
|
||||
<span v-if="mapXi.mapId != ''">西:<Abutton @click="BindData(mapXi.mapId)">{{ mapXi.name }}</Abutton>
|
||||
<b v-if="toMapPathData.some(it => it.mapId == mapXi.mapId)">🚩</b></span>
|
||||
<br v-if="mapDong.mapId != '' || mapXi.mapId != ''">
|
||||
<span v-if="mapNan.mapId != ''">南:<Abutton @click="BindData(mapNan.mapId)">{{ mapNan.name }}</Abutton></span>
|
||||
<span v-if="mapBei.mapId != ''">北:<Abutton @click="BindData(mapBei.mapId)">{{ mapBei.name }}</Abutton></span>
|
||||
<span v-if="mapNan.mapId != ''">南:<Abutton @click="BindData(mapNan.mapId)">{{ mapNan.name }}</Abutton>
|
||||
<b v-if="toMapPathData.some(it => it.mapId == mapNan.mapId)">🚩</b></span>
|
||||
<span v-if="mapBei.mapId != ''">北:<Abutton @click="BindData(mapBei.mapId)">{{ mapBei.name }}</Abutton>
|
||||
<b v-if="toMapPathData.some(it => it.mapId == mapBei.mapId)">🚩</b></span>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
【<Abutton @click="ShowCityProp">城内地图</Abutton>】.<Abar href="/">寻路</Abar><br />
|
||||
【<Abutton @click="ShowCityProp">城内地图</Abutton>】.<Abutton @click="ShowMapPathProp">寻路</Abutton>
|
||||
</div>
|
||||
<div class="content">
|
||||
{{ mapInfo.tips }}
|
||||
@@ -53,6 +58,26 @@
|
||||
</span>
|
||||
</div>
|
||||
</GamePopup>
|
||||
<!--寻路-->
|
||||
<GamePopup v-model:show="showPath" title="【自动寻路】">
|
||||
<!-- 自定义内容 -->
|
||||
<div class="content">
|
||||
<div class="common serch" style="font-size: 16px; margin-top: 10px;">
|
||||
搜索: <input type="text" class="search-ipt" v-model="mapPathSerch">
|
||||
<button class="ipt-btn" name="serch" @click="ShowMapPathProp">搜索</button>
|
||||
</div>
|
||||
|
||||
<div class="mapList" style="max-height: 300px;">
|
||||
<span v-for="(item, index) in cityMapData" :key="index">
|
||||
{{ index + 1 }}.
|
||||
<Abutton @click="ChangeMapPath(item.mapId)">{{ item.mapName }}</Abutton>({{ item.x }},{{ item.y }})
|
||||
<br>
|
||||
</span>
|
||||
<span v-if="cityMapData.length == 0">暂无地图.</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</GamePopup>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
definePageMeta({
|
||||
@@ -132,4 +157,62 @@ const ChangeMap = async (mapId: string): Promise<void> => {
|
||||
showCity.value = false;
|
||||
};
|
||||
|
||||
/**寻路 */
|
||||
const cityMapData = ref<Array<any>>([]);
|
||||
const toMapPathData = ref<Array<any>>([]);
|
||||
const showPath = ref(false);
|
||||
const mapPathSerch = ref('');
|
||||
let changPathLock = true;//寻路锁
|
||||
const ShowMapPathProp = () => {
|
||||
//加载数据
|
||||
MapService.GetUserOnCityMap(mapPathSerch.value).then(res => {
|
||||
if (res.code == 0) {
|
||||
showPath.value = true;
|
||||
mapPathSerch.value = '';
|
||||
cityMapData.value = res.data;
|
||||
}
|
||||
else {
|
||||
MessageExtend.ShowDialog("提示", res.msg);
|
||||
}
|
||||
});
|
||||
}
|
||||
const ChangeMapPath = async (mapId: string): Promise<void> => {
|
||||
if (changPathLock) {
|
||||
changPathLock = false;
|
||||
//此处获取寻路路径信息
|
||||
let result = await MapService.GetAutoMapPath(mapId);
|
||||
changPathLock = true;
|
||||
showPath.value = false;
|
||||
if (result.code == 0) {
|
||||
toMapPathData.value = []
|
||||
toMapPathData.value = result.data;
|
||||
StartToMap()
|
||||
}
|
||||
else {
|
||||
MessageExtend.ShowDialog("提示", result.msg);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
const timer = ref(0) // 定时器实例
|
||||
const RunMap = async (): Promise<void> => {
|
||||
if (toMapPathData.value.length > 0) {
|
||||
var toPath = toMapPathData.value.shift();
|
||||
await BindData(toPath.mapId);
|
||||
toMapPathData.value = toMapPathData.value.filter(item => item !== toPath.mapId)
|
||||
}
|
||||
else {
|
||||
clearInterval(timer.value);
|
||||
MessageExtend.LoadingClose();
|
||||
MessageExtend.Notify("寻路完成,已达到目的地!", "success");
|
||||
}
|
||||
}
|
||||
const StartToMap = () => {
|
||||
MessageExtend.LoadingToast("自动寻路中...");
|
||||
timer.value = setInterval(async () => {
|
||||
await RunMap()
|
||||
}, 1000)
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
31
Web/src/pages/treasure/index.vue
Normal file
31
Web/src/pages/treasure/index.vue
Normal file
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<div class="content">【聚宝盆】</div>
|
||||
<div class="content">
|
||||
金元宝:51000 <br>
|
||||
余额:5.22 元<br>
|
||||
抽奖次数:3次 [<Abar>领取</Abar>] <br>
|
||||
<Abar href="">我要抽奖</Abar>.<Abar>设置支付宝</Abar>
|
||||
</div>
|
||||
<div class="content">
|
||||
我要提现:<br>
|
||||
周一:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周二:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周三:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周四:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周五:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周六:<Abutton>提现(0.3元)</Abutton><br>
|
||||
周日:<Abutton>提现(1元)</Abutton><br>
|
||||
</div>
|
||||
<div class="content">
|
||||
超级提现:<br>
|
||||
<Abutton>提现(20元)</Abutton><br>
|
||||
<Abutton>提现(50元)</Abutton><br>
|
||||
<Abutton>提现(100元)</Abutton><br>
|
||||
</div>
|
||||
<div class="content">
|
||||
说明:<br>
|
||||
1.每天完成日常任务可以领取抽奖次数。<br>
|
||||
2.抽奖将获得不同数额得金元宝,每日0点按照10000:1结算到余额。<br>
|
||||
3.在羁绊时间内每天可通过支付宝提现领取游戏福利红包。<br>
|
||||
</div>
|
||||
</template>
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user