This commit is contained in:
Putoo
2026-05-29 19:06:51 +08:00
parent 69ae1e3174
commit bd1535aee9
48 changed files with 1571 additions and 133 deletions

View File

@@ -5,6 +5,7 @@
<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_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> <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>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F51505665371d472f8bdbc333fa4d888cf49938_003F0e_003F7279c963_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AList_00601_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F51505665371d472f8bdbc333fa4d888cf49938_003F0e_003F7279c963_003FList_00601_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003APoAction_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F8fb1d14dca1046e78e0684daa8bc3a1b7800_003Fb7_003F35e46383_003FPoAction_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqlSetup_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F72993acb059c49dcbba437a858c0b0942000_003F46_003F2e14505d_003FSqlSetup_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqlSetup_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F72993acb059c49dcbba437a858c0b0942000_003F46_003F2e14505d_003FSqlSetup_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqlSugarScopeProvider_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6c0f22f0a47643a3b2a40899acd2044c2e3a00_003Fc5_003F4738d33f_003FSqlSugarScopeProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003ASqlSugarScopeProvider_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F6c0f22f0a47643a3b2a40899acd2044c2e3a00_003Fc5_003F4738d33f_003FSqlSugarScopeProvider_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F51505665371d472f8bdbc333fa4d888cf49938_003Fdf_003F23ca03dd_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String> <s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=7020124F_002D9FFC_002D4AC3_002D8F3D_002DAAB8E0240759_002Ff_003AString_002Ecs_002Fl_003AC_0021_003FUsers_003F29055_003FAppData_003FRoaming_003FJetBrains_003FRider2025_002E3_003Fresharper_002Dhost_003FDecompilerCache_003Fdecompiler_003F51505665371d472f8bdbc333fa4d888cf49938_003Fdf_003F23ca03dd_003FString_002Ecs/@EntryIndexedValue">ForceIncluded</s:String>

View File

@@ -7,34 +7,28 @@ namespace Application.Domain.Entity
public class unit_user_friend public class unit_user_friend
{ {
/// <summary> /// <summary>
/// fId /// frId
/// </summary> /// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)] [SugarColumn(IsPrimaryKey = true, Length = 100)]
public string fId { get; set; } public string frId { get; set; }
/// <summary> /// <summary>
/// sId /// userId
/// </summary> /// </summary>
[SugarColumn(Length = 50, IsNullable = true)] [SugarColumn(Length = 50, IsNullable = true)]
public string? sId { get; set; } public string? userId { get; set; }
/// <summary> /// <summary>
/// mId /// toId
/// </summary> /// </summary>
[SugarColumn(Length = 50, IsNullable = true)] [SugarColumn(Length = 50, IsNullable = true)]
public string? mId { get; set; } public string? toId { get; set; }
/// <summary> /// <summary>
/// near /// 亲密度
/// </summary> /// </summary>
[SugarColumn(IsNullable = true)] [SugarColumn(IsNullable = true)]
public int? near { get; set; } public long? near { get; set; }
/// <summary>
/// status
/// </summary>
[SugarColumn(IsNullable = true)]
public int? status { get; set; }
/// <summary> /// <summary>
/// addTime /// addTime
@@ -42,4 +36,4 @@ namespace Application.Domain.Entity
[SugarColumn(IsNullable = true)] [SugarColumn(IsNullable = true)]
public DateTime? addTime { get; set; } public DateTime? addTime { get; set; }
} }
} }

View File

@@ -0,0 +1,63 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Game")]
public class unit_user_mail
{
/// <summary>
/// mailId
/// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string mailId { get; set; }
/// <summary>
/// userId
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? userId { get; set; }
/// <summary>
/// name
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? name { get; set; }
/// <summary>
/// sign
/// </summary>
[SugarColumn(IsNullable = true)]
public string? sign { get; set; }
/// <summary>
/// isRead
/// </summary>
[SugarColumn(IsNullable = true)]
public int? isRead { get; set; }
/// <summary>
/// isGet
/// </summary>
[SugarColumn(IsNullable = true)]
public int? isGet { get; set; }
/// <summary>
/// award
/// </summary>
[SugarColumn(IsNullable = true,IsJson = true)]
public List<TowerGet> award { get; set; }
/// <summary>
/// addTime
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime? addTime { get; set; }
/// <summary>
/// endTime
/// </summary>
[SugarColumn(IsNullable = true)]
public long? endTime { get; set; }
}
}

View File

@@ -0,0 +1,72 @@
using SqlSugar;
using System;
namespace Application.Domain.Entity
{
[Tenant("Kg.SeaTime.Game")]
public class unit_user_message_event
{
/// <summary>
/// eventId
/// </summary>
[SugarColumn(IsPrimaryKey = true, Length = 50)]
public string eventId { get; set; }
/// <summary>
/// userId
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? userId { get; set; }
/// <summary>
/// code
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? code { get; set; }
/// <summary>
/// name
/// </summary>
[SugarColumn(Length = 50, IsNullable = true)]
public string? name { get; set; }
/// <summary>
/// sign
/// </summary>
[SugarColumn(Length = 255, IsNullable = true)]
public string? sign { get; set; }
[SugarColumn(IsNullable = true)]
public string? pars { get; set; }
/// <summary>
/// state
/// </summary>
[SugarColumn(IsNullable = true)]
public int? state { get; set; }
/// <summary>
/// btns
/// </summary>
[SugarColumn(IsNullable = true, IsJson = true)]
public List<MsgEventBtn> btns { get; set; }
/// <summary>
/// addTime
/// </summary>
[SugarColumn(IsNullable = true)]
public DateTime? addTime { get; set; }
/// <summary>
/// endTime
/// </summary>
[SugarColumn(IsNullable = true)]
public long? endTime { get; set; }
/// <summary>
/// token
/// </summary>
[SugarColumn(Length = 255, IsNullable = true)]
public string? token { get; set; }
}
}

View File

@@ -0,0 +1,8 @@
namespace Application.Domain.Entity;
public class MsgEventBtn
{
public int status { get; set; }
public string name { get; set; }
public string tips { get; set; }
}

View File

@@ -0,0 +1,36 @@
namespace Application.Domain.Entity;
public class TowerGet
{
private System.String _code;
/// <summary>
///
/// </summary>
public System.String code
{ get { return this._code; } set { this._code = value; } }
private System.String _name;
/// <summary>
///
/// </summary>
public System.String name
{ get { return this._name; } set { this._name = value; } }
private System.String _parameter;
/// <summary>
///
/// </summary>
public System.String parameter
{ get { return this._parameter; } set { this._parameter = value; } }
private long _count;
/// <summary>
///
/// </summary>
public long count
{ get { return this._count; } set { this._count = value; } }
}

View File

@@ -8,4 +8,5 @@ public class UserModel
public string headImg { get; set; } public string headImg { get; set; }
public int area { get; set; } public int area { get; set; }
public string icon { get; set; } public string icon { get; set; }
public int lev { get; set; }
} }

View File

@@ -0,0 +1,10 @@
namespace Application.Domain.Entity;
public class UserOnMap
{
public string mapId { get; set; }
public string mapName { get; set; }
public int cityId { get; set; }
public string cityName { get; set; }
public int isOnline { get; set; }
}

View File

@@ -0,0 +1,11 @@
namespace Application.Domain.Entity;
public class RelationView
{
public UserModel user { get; set; }
public long near { get; set; }
public string mapName { get; set; }
public string cityName { get; set; }
public long sort { get; set; }
public int isOnline { get; set; }
}

View File

@@ -0,0 +1,11 @@
namespace Application.Domain;
public static class MessageEnum
{
public enum EventCode
{
Friend,//交友消息
Marry,//婚姻消息
Trade,//交易通知
}
}

View File

@@ -0,0 +1,55 @@
namespace Application.Domain;
public class MessageHandle
{
public async Task<MessageHandleResult> HandleMsg(unit_user_message_event events, int state)
{
if (events.code == nameof(MessageEnum.EventCode.Friend))
{
var relationService = App.GetRequiredService<IUnitUserRelationService>();
var isFriend = await relationService.CheckIsFriend(events.userId, events.pars);
if (isFriend)
{
return new MessageHandleResult() { success = true, msg = "你们已经是好友啦!" };
}
if (state == 1)
{
if (await relationService.AddFriend(events.userId, events.pars))
{
var chatService = App.GetService<IGameChatService>();
var userService = App.GetService<IUnitUserService>();
var myInfo = await userService.GetUserInfoByUserId(events.userId);
string sign = $"{UbbTool.HomeUbb(myInfo.userNo, myInfo.nick)}已通过了您的好友申请!";
await chatService.SendChat(events.pars, (int)myInfo.areaId, nameof(GameChatEnum.Code.System), sign);
return new MessageHandleResult() { success = true, msg = "已通过该好友申请!" };
}
else
{
return new MessageHandleResult() { success = false, msg = "好友添加失败,请稍后尝试!" };
}
}
else
{
var chatService = App.GetService<IGameChatService>();
var userService = App.GetService<IUnitUserService>();
var myInfo = await userService.GetUserInfoByUserId(events.userId);
string sign = $"{UbbTool.HomeUbb(myInfo.userNo, myInfo.nick)}拒绝了您的好友申请!";
await chatService.SendChat(events.pars, (int)myInfo.areaId, nameof(GameChatEnum.Code.System), sign);
return new MessageHandleResult() { success = true, msg = "已拒绝该好友申请!" };
}
}
else if (events.code == nameof(MessageEnum.EventCode.Friend))
{
return new MessageHandleResult() { success = true, msg = "消息通知已处理!" };
}
return new MessageHandleResult() { success = false, msg = "暂不支持该操作处理!" };
}
}
public class MessageHandleResult
{
public bool success { get; set; }
public string msg { get; set; }
}

View File

@@ -2,12 +2,13 @@
public interface IGameChatService public interface IGameChatService
{ {
Task<List<GameChatView>> GetChatTop(int areaId, int top, string teamId, string groupId); Task<List<GameChatView>> GetChatTop(string userId,int areaId, int top, string teamId, string groupId);
Task<List<GameChatView>> GetChatData(int type, int areaId, string teamId, string groupId, int page, int limit, Task<List<GameChatView>> GetChatData(string userId, int type, int areaId, string teamId, string groupId, int page,
int limit,
RefAsync<int> total); RefAsync<int> total);
Task<bool> SendChat(string userId, int areaId, string code, string sign, string par = ""); Task<bool> SendChat(string userId, int areaId, string code, string sign, string par = "");
Task<bool> SendChat(string userId, string code, string sign, string par = "");
Task<bool> DeleteChat(string chatId); Task<bool> DeleteChat(string chatId);
} }

View File

@@ -20,6 +20,7 @@ public interface IGameMapService
Task<unit_user_online> GetUserOnMap(string userId); Task<unit_user_online> GetUserOnMap(string userId);
Task UpdateUserOnMap(string userId, string ip, string mapId); Task UpdateUserOnMap(string userId, string ip, string mapId);
Task<bool> UpdateUserOnMap(unit_user_online data, string mapId); Task<bool> UpdateUserOnMap(unit_user_online data, string mapId);
Task<UserOnMap> GetUserOnMapInfo(string userId);
Task SetUserMapDefult(string userId); Task SetUserMapDefult(string userId);
Task<game_city_map> GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, bool isChangeCity = false); Task<game_city_map> GetToMapInfo(string userId, string toMap, bool isUpUserMap = true, bool isChangeCity = false);
#endregion #endregion

View File

@@ -2,15 +2,16 @@
public interface IMessageService public interface IMessageService
{ {
Task<int> GetNoReadCount(string userId); Task<List<int>> GetNoReadCount(string userId);
#region #region
string GetTalkId(string userId, string otId); string GetTalkId(string userId, string otId);
Task<List<unit_user_message>> GetUserNoReadData(string talkId); Task<List<unit_user_message>> GetUserNoReadData(string talkId);
Task<List<unit_user_message>> GetUserMessageData(string talkId, int page, int limit, Task<List<unit_user_message>> GetUserMessageData(string talkId, int page, int limit,
RefAsync<int> total); RefAsync<int> total);
Task<List<MessageView>> GetUserMessage(string userId, int type, int page, int limit, Task<List<MessageView>> GetUserMessage(string userId, int type, int page, int limit,
RefAsync<int> total); RefAsync<int> total);
@@ -19,4 +20,27 @@ public interface IMessageService
Task<bool> DeleteMsgByTalkId(string talkId, string userId); Task<bool> DeleteMsgByTalkId(string talkId, string userId);
#endregion #endregion
#region
Task<List<unit_user_mail>> GetUserMailData(string userId, int page, int limit, RefAsync<int> total);
Task<unit_user_mail> GetMailInfo(string mailId);
Task<bool> SendMaill(string userId, string name, string sign, List<TowerGet> award, int days = 10);
Task<bool> UpdateMaillInfo(unit_user_mail data);
#endregion
#region
Task<List<unit_user_message_event>> GetUserEventMessage(string userId, int page, int limit,
RefAsync<int> total);
Task<unit_user_message_event> GetEventMessageInfo(string eventId);
Task<bool> UpdateEventData(unit_user_message_event data);
Task<bool> CheckAtEventMsg(string token);
Task<bool> SendEventMsg(string userId, string code, string name, string sign, string pars, string token,
List<MsgEventBtn> btns = null, int days = 10);
#endregion
} }

View File

@@ -6,7 +6,7 @@ public interface IUnitUserAttrService
Task<UserAttrModel> GetUserAttrModel(string userId); Task<UserAttrModel> GetUserAttrModel(string userId);
Task<unit_user_attr> GetUserAttr(string userId); Task<unit_user_attr> GetUserAttr(string userId);
Task<int> GetUserLev(string userId);
#endregion #endregion
#region #region

View File

@@ -0,0 +1,14 @@
namespace Application.Domain;
public interface IUnitUserRelationService
{
#region
Task<int> GetUserFriendCount(string userId);
Task<List<RelationView>> GetUserFriend(string userId);
Task<bool> CheckIsFriend(string userId, string toId);
Task<bool> AddFriend(string userId, string toId);
Task<bool> DeleteFriend(string userId, string toId);
#endregion
}

View File

@@ -11,16 +11,18 @@ public class GameChatService : IGameChatService, ITransient
_redisClient = redisClient; _redisClient = redisClient;
} }
public async Task<List<GameChatView>> GetChatTop(int areaId, int top, string teamId, string groupId) public async Task<List<GameChatView>> GetChatTop(string userId, int areaId, int top, string teamId, string groupId)
{ {
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>(); var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
List<string> allCode = new List<string>() { "Public", "Region", "System" }; List<string> allCode = new List<string>() { "Public", "Region" };
var data = await db.Queryable<game_chat>().Where(it => it.state == 1 && var data = await db.Queryable<game_chat>().Where(it => it.state == 1 &&
( (
(allCode.Contains(it.code) && it.areaId == areaId) || (allCode.Contains(it.code) && it.areaId == areaId) ||
(it.code == "Group" && it.par == groupId) || (it.code == "Group" && it.par == groupId) ||
(it.code == "Team" && it.par == teamId) || (it.code == "Team" && it.par == teamId) ||
(it.code == "Dress") (it.code == "Dress") ||
(it.code == "System" && it.areaId == areaId &&
(it.userId == "0" || it.userId == userId))
) )
).Take(top).OrderByDescending(it => it.sort).ToListAsync(); ).Take(top).OrderByDescending(it => it.sort).ToListAsync();
@@ -34,7 +36,8 @@ public class GameChatService : IGameChatService, ITransient
return result; return result;
} }
public async Task<List<GameChatView>> GetChatData(int type, int areaId, string teamId, string groupId, int page, public async Task<List<GameChatView>> GetChatData(string userId, int type, int areaId, string teamId,
string groupId, int page,
int limit, int limit,
RefAsync<int> total) RefAsync<int> total)
{ {
@@ -42,13 +45,15 @@ public class GameChatService : IGameChatService, ITransient
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>(); var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
if (type == 0) if (type == 0)
{ {
List<string> allCode = new List<string>() { "Public", "Region", "System" }; List<string> allCode = new List<string>() { "Public", "Region" };
data = await db.Queryable<game_chat>().Where(it => it.state == 1 && data = await db.Queryable<game_chat>().Where(it => it.state == 1 &&
( (
(allCode.Contains(it.code) && it.areaId == areaId) || (allCode.Contains(it.code) && it.areaId == areaId) ||
(it.code == "Group" && it.par == groupId) || (it.code == "Group" && it.par == groupId) ||
(it.code == "Team" && it.par == teamId) || (it.code == "Team" && it.par == teamId) ||
(it.code == "Dress") (it.code == "Dress") ||
(it.code == "System" && it.areaId == areaId &&
(it.userId == "0" || it.userId == userId))
) )
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total); ).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
} }
@@ -76,13 +81,16 @@ public class GameChatService : IGameChatService, ITransient
else if (type == 5) //系统 else if (type == 5) //系统
{ {
data = await db.Queryable<game_chat>() data = await db.Queryable<game_chat>()
.Where(it => it.state == 1 && it.code == "System" && it.areaId == areaId .Where(it =>
it.state == 1 && it.code == "System" && it.areaId == areaId &&
(it.userId == "0" || it.userId == userId)
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total); ).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
} }
else else
{ {
data = new List<game_chat>(); data = new List<game_chat>();
} }
var result = new List<GameChatView>(); var result = new List<GameChatView>();
foreach (var item in data) foreach (var item in data)
{ {
@@ -138,6 +146,15 @@ public class GameChatService : IGameChatService, ITransient
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>(); var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
return await db.Insertable(chat).ExecuteCommandAsync() > 0; return await db.Insertable(chat).ExecuteCommandAsync() > 0;
} }
public async Task<bool> SendChat(string userId, string code, string sign, string par = "")
{
var userService = App.GetService<IUnitUserService>();
var userInfo = await userService.GetUserInfoByUserId(userId);
if (userInfo == null) return false;
return await SendChat(userId, (int)userInfo.areaId, code, sign, par);
}
/// <summary> /// <summary>
/// 删除聊天 /// 删除聊天

View File

@@ -31,8 +31,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
return data; return data;
} }
public async Task<List<game_city_map>> GetCityMap(int cityId) public async Task<List<game_city_map>> GetCityMap(int cityId)
{ {
@@ -147,6 +146,22 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
return data; return data;
} }
public async Task<UserOnMap> GetUserOnMapInfo(string userId)
{
var onMap = await GetUserOnMap(userId);
var mapInfo = await GetMapInfo(onMap.mapId);
var cityInfo = await GetCityInfo((int)mapInfo.cityId);
int isOnline =
onMap.upTime > (TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddMinutes(0 - GameConfig.OnLineTime)))
? 1
: 0;
return new UserOnMap()
{
mapId = mapInfo.mapId, mapName = mapInfo.mapName, cityId = cityInfo.cityId, cityName = cityInfo.cityName,
isOnline = isOnline
};
}
public async Task UpdateUserOnMap(string userId, string ip, string mapId) public async Task UpdateUserOnMap(string userId, string ip, string mapId)
{ {
unit_user_online onLine = new unit_user_online(); unit_user_online onLine = new unit_user_online();
@@ -320,7 +335,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
#endregion #endregion
#region #region
private async Task<List<game_city>> GetCityDataExcludeParent() private async Task<List<game_city>> GetCityDataExcludeParent()
{ {
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityParent"); string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityParent");
@@ -332,8 +347,10 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
await redis.SetAsync(key, data); await redis.SetAsync(key, data);
} }
return data; return data;
} }
private async Task<List<game_city_map>> GetAllMaoToData() private async Task<List<game_city_map>> GetAllMaoToData()
{ {
string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityInterCityPortal"); string key = string.Format(BaseCache.BaseCacheKeys, "MapPathData", "CityInterCityPortal");
@@ -343,7 +360,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
} }
List<game_city_map> result = new List<game_city_map>(); List<game_city_map> result = new List<game_city_map>();
var cityData = await GetCityDataExcludeParent(); var cityData = await GetCityDataExcludeParent();
foreach (var item in cityData) foreach (var item in cityData)
{ {
@@ -356,9 +373,11 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
} }
} }
} }
await redis.SetAsync(key, result); await redis.SetAsync(key, result);
return result; return result;
} }
/// <summary> /// <summary>
/// 城市信息 /// 城市信息
/// </summary> /// </summary>
@@ -378,7 +397,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
{ {
var cityTemp = new CityNode(city.cityId, city.cityName, new Point((int)mdMap.x, (int)mdMap.y), 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); mdMap.mapName, (int)city.x_s, (int)city.x_e, (int)city.y_s, (int)city.y_e);
data.Add(cityTemp); data.Add(cityTemp);
} }
} }
@@ -413,8 +432,7 @@ public class GameMapService(ISqlSugarClient DbClient, IRedisCache redis) : IGame
return data; return data;
} }
/// <summary> /// <summary>
/// 传送点信息 /// 传送点信息
/// </summary> /// </summary>

View File

@@ -1,30 +1,29 @@
namespace Application.Domain; using Dm.util;
namespace Application.Domain;
public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMessageService, ITransient public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMessageService, ITransient
{ {
public async Task<int> GetNoReadCount(string userId) public async Task<List<int>> GetNoReadCount(string userId)
{ {
string key = string.Format(UserCache.BaseCacheKeys, "Message", "Count"); List<int> result = new List<int>();
if (await redis.HExistsHashAsync(key, userId))
{
return await redis.GetHashAsync<int>(key, userId);
}
int result = 0;
//普通消息 //普通消息
int noRead = await GetUserNoReadDataCountByUserId(userId); int noRead = await GetUserNoReadMsgCount(userId);
result += noRead; result.Add(noRead);
//邮件详细
//通知消息 //通知消息
await redis.AddHashAsync(key, userId, result); int noEvent = await GetUserNoReadEventMsgCount(userId);
result.Add(noEvent);
//邮件详细
int noMail = await GetUserNoReadMailCount(userId);
result.Add(noMail);
//汇总
result.Add(result.Sum());
return result; return result;
} }
private async Task ClearMessageCache(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "Count");
await redis.DelHashAsync(key, userId);
}
#region #region
@@ -38,11 +37,25 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
return talkId.Split('_').ToList(); return talkId.Split('_').ToList();
} }
private async Task<int> GetUserNoReadDataCountByUserId(string userId) private async Task<int> GetUserNoReadMsgCount(string userId)
{ {
string key = string.Format(UserCache.BaseCacheKeys, "Message", "MsgCount");
if (await redis.HExistsHashAsync(key, userId))
{
return await redis.GetHashAsync<int>(key, userId);
}
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message>(); var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message>();
return await db.Queryable<unit_user_message>() int count = await db.Queryable<unit_user_message>()
.Where(it => it.status == 1 && it.userId == userId && it.isRead == 0).CountAsync(); .Where(it => it.status == 1 && it.userId == userId && it.isRead == 0).CountAsync();
await redis.AddHashAsync(key, userId, count);
return count;
}
private async Task ClearMsgCountCache(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "MsgCount");
await redis.DelHashAsync(key, userId);
} }
public async Task<List<unit_user_message>> GetUserNoReadData(string talkId) public async Task<List<unit_user_message>> GetUserNoReadData(string talkId)
@@ -131,7 +144,7 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
bool result = await db.Insertable(adds).ExecuteCommandAsync() > 0; bool result = await db.Insertable(adds).ExecuteCommandAsync() > 0;
if (result) if (result)
{ {
await ClearMessageCache(toUser); await ClearMsgCountCache(toUser);
} }
return result; return result;
@@ -144,7 +157,7 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
.Where(it => msgIds.Contains(it.msgId)).ExecuteCommandAsync() > 0; .Where(it => msgIds.Contains(it.msgId)).ExecuteCommandAsync() > 0;
if (result) if (result)
{ {
await ClearMessageCache(userId); await ClearMsgCountCache(userId);
} }
} }
@@ -156,7 +169,178 @@ public class MessageService(ISqlSugarClient DbClient, IRedisCache redis) : IMess
0; 0;
if (result) if (result)
{ {
await ClearMessageCache(userId); await ClearMsgCountCache(userId);
}
return result;
}
#endregion
#region
private async Task<int> GetUserNoReadMailCount(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "MailCount");
if (await redis.HExistsHashAsync(key, userId))
{
return await redis.GetHashAsync<int>(key, userId);
}
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_mail>();
int count = await db.Queryable<unit_user_mail>().Where(it => it.userId == userId && it.isRead == 0)
.CountAsync();
await redis.AddHashAsync(key, userId, count);
return count;
}
private async Task ClearMailCountCache(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "MailCount");
await redis.DelHashAsync(key, userId);
}
public async Task<List<unit_user_mail>> GetUserMailData(string userId, int page, int limit, RefAsync<int> total)
{
long onTime = TimeExtend.GetTimeStampSeconds;
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_mail>();
return await db.Queryable<unit_user_mail>().Where(it => it.userId == userId && it.endTime > onTime)
.OrderBy(it => it.isGet, OrderByType.Asc)
.OrderBy(it => it.isRead, OrderByType.Asc)
.OrderByDescending(it => it.addTime)
.ToPageListAsync(page, limit, total);
}
public async Task<unit_user_mail> GetMailInfo(string mailId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_mail>();
return await db.Queryable<unit_user_mail>().Where(it => it.mailId == mailId)
.SingleAsync();
}
public async Task<bool> SendMaill(string userId, string name, string sign, List<TowerGet> award, int days = 10)
{
unit_user_mail mail = new unit_user_mail();
mail.mailId = StringAssist.NewGuid;
mail.userId = userId;
mail.name = name;
mail.sign = sign;
mail.isRead = 0;
mail.isGet = award.Count > 0 ? 0 : 1;
mail.award = award;
mail.addTime = DateTime.Now;
mail.endTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddDays(days));
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_mail>();
bool result = await db.Insertable(mail).ExecuteCommandAsync() > 0;
if (result)
{
await ClearMailCountCache(userId);
}
return result;
}
public async Task<bool> UpdateMaillInfo(unit_user_mail data)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_mail>();
bool result = await db.Updateable<unit_user_mail>(data).ExecuteCommandAsync() > 0;
if (result)
{
await ClearMailCountCache(data.userId);
}
return result;
}
#endregion
#region
private async Task<int> GetUserNoReadEventMsgCount(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "EventCount");
if (await redis.HExistsHashAsync(key, userId))
{
return await redis.GetHashAsync<int>(key, userId);
}
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
int Count = await db.Queryable<unit_user_message_event>().Where(it => it.userId == userId && it.state == 0)
.CountAsync();
await redis.AddHashAsync(key, userId, Count);
return Count;
}
private async Task ClearEventCountCache(string userId)
{
string key = string.Format(UserCache.BaseCacheKeys, "Message", "EventCount");
await redis.DelHashAsync(key, userId);
}
public async Task<List<unit_user_message_event>> GetUserEventMessage(string userId, int page, int limit,
RefAsync<int> total)
{
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
return await db.Queryable<unit_user_message_event>().Where(it => it.userId == userId)
.OrderByDescending(it => it.addTime)
.ToPageListAsync(page, limit, total);
}
public async Task<unit_user_message_event> GetEventMessageInfo(string eventId)
{
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
return await db.Queryable<unit_user_message_event>().Where(it => it.eventId == eventId)
.SingleAsync();
}
public async Task<bool> UpdateEventData(unit_user_message_event data)
{
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
var result = await db.Updateable(data).ExecuteCommandAsync() > 0;
if (result)
{
await ClearEventCountCache(data.userId);
}
return result;
}
public async Task<bool> CheckAtEventMsg(string token)
{
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
return await db.Queryable<unit_user_message_event>().Where(it => it.state == 0 && it.token == token).AnyAsync();
}
public async Task<bool> SendEventMsg(string userId, string code, string name, string sign, string pars,string token,
List<MsgEventBtn> btns=null, int days = 10)
{
unit_user_message_event data = new unit_user_message_event();
data.eventId = StringAssist.NewGuid;
data.userId = userId;
data.code = code;
data.name = name;
data.sign = sign;
data.pars = pars;
data.state = 0;
if (btns == null)
{
data.btns = new List<MsgEventBtn>()
{
new MsgEventBtn() { status = 1, name = "我知道啦", tips = "已处理" }
};
}
else
{
data.btns = btns;
}
data.addTime = DateTime.Now;
data.endTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddDays(days));
data.token = token;
var db = DbClient.AsTenant().GetConnectionScopeWithAttr<unit_user_message_event>();
var result = await db.Insertable(data).ExecuteCommandAsync() > 0;
if (result)
{
await ClearEventCountCache(data.userId);
} }
return result; return result;

View File

@@ -44,6 +44,18 @@ public class UnitUserAttrService(ISqlSugarClient DbClient, IRedisCache redis) :
return data; return data;
} }
public async Task<int> GetUserLev(string userId)
{
int lev = 0;
var attrInfo = await GetUserAttr(userId);
if (attrInfo != null)
{
lev = (int)attrInfo.lev;
}
return lev;
}
private async Task ClearUserAttrCache(string userId) private async Task ClearUserAttrCache(string userId)
{ {
string key = string.Format(UserCache.BaseCacheKeys, "AttrData", "UserAttr"); string key = string.Format(UserCache.BaseCacheKeys, "AttrData", "UserAttr");

View File

@@ -0,0 +1,66 @@
namespace Application.Domain;
public class UnitUserRelationService(ISqlSugarClient DbClient, IRedisCache redis) : IUnitUserRelationService, ITransient
{
#region
public async Task<int> GetUserFriendCount(string userId)
{
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_friend>();
return await db.Queryable<unit_user_friend>().Where(it => it.frId.Contains(userId)).CountAsync();
}
public async Task<List<RelationView>> GetUserFriend(string userId)
{
List<RelationView> result = new List<RelationView>();
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_friend>();
var data = await db.Queryable<unit_user_friend>().Where(it => it.frId.Contains(userId))
.ToListAsync();
foreach (var item in data)
{
RelationView temp = new RelationView();
string otUser = item.userId == userId ? item.toId : item.userId;
temp.user = await UserModelTool.GetUserView(otUser);
temp.near = (long)item.near;
var mapService = App.GetService<IGameMapService>();
var onMap = await mapService.GetUserOnMapInfo(otUser);
temp.mapName = onMap.mapName;
temp.cityName = onMap.cityName;
temp.sort = TimeExtend.GetTimeStampBySeconds((DateTime)item.addTime);
temp.isOnline = onMap.isOnline;
result.Add(temp);
}
return result;
}
public async Task<bool> CheckIsFriend(string userId, string toId)
{
string frId = StringAssist.GetSortKey(userId, toId);
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_friend>();
return await db.Queryable<unit_user_friend>().Where(it => it.frId == frId).AnyAsync();
}
public async Task<bool> AddFriend(string userId, string toId)
{
unit_user_friend friend = new unit_user_friend();
friend.frId = StringAssist.GetSortKey(userId, toId);
friend.userId = userId;
friend.toId = toId;
friend.near = 0;
friend.addTime = DateTime.Now;
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_friend>();
return await db.Insertable(friend).ExecuteCommandAsync() > 0;
}
public async Task<bool> DeleteFriend(string userId, string toId)
{
string frId = StringAssist.GetSortKey(userId, toId);
var db = DbClient.AsTenant().GetConnectionWithAttr<unit_user_friend>();
return await db.Deleteable<unit_user_friend>().Where(it => it.frId == frId).ExecuteCommandAsync()>0;
}
#endregion
}

View File

@@ -68,5 +68,29 @@ public class GameBus
return isok; return isok;
} }
public static async Task<bool> UpdateBag(string userId, int operate, dynamic Reward, string remark = "",
long count = 1)
{
try
{
foreach (var item in Reward)
{
long num = Convert.ToInt64(item.count) * count;
if (num <= 0)
{
continue;
}
await UpdateBag(userId, operate, item.code, item.parameter, num, remark);
}
return true;
}
catch
{
return false;
}
}
#endregion #endregion
} }

View File

@@ -0,0 +1,9 @@
namespace Application.Domain;
public class UbbTool
{
public static string HomeUbb(string no, string name)
{
return $"<a data-type='go' data-parms='/user/user?no={no}' href='javascript:void'>{name}</a>";
}
}

View File

@@ -8,7 +8,7 @@ public class UserModelTool
/// <param name="userId"></param> /// <param name="userId"></param>
/// <param name="addIcon"></param> /// <param name="addIcon"></param>
/// <returns></returns> /// <returns></returns>
public static async Task<UserModel> GetUserView(string userId,bool addIcon=false) public static async Task<UserModel> GetUserView(string userId, bool addIcon = false)
{ {
UserModel result = new UserModel(); UserModel result = new UserModel();
if (userId == "0") if (userId == "0")
@@ -19,10 +19,12 @@ public class UserModelTool
result.headImg = ""; result.headImg = "";
result.area = 0; result.area = 0;
result.icon = ""; result.icon = "";
result.lev = 999;
} }
else else
{ {
var userService = App.GetService<IUnitUserService>(); var userService = App.GetService<IUnitUserService>();
var attrService = App.GetRequiredService<IUnitUserAttrService>();
var userInfo = await userService.GetUserInfoByUserId(userId); var userInfo = await userService.GetUserInfoByUserId(userId);
if (userInfo != null) if (userInfo != null)
{ {
@@ -32,12 +34,14 @@ public class UserModelTool
result.headImg = userInfo.headImg; result.headImg = userInfo.headImg;
result.area = (int)userInfo.areaId; result.area = (int)userInfo.areaId;
result.icon = ""; result.icon = "";
if (addIcon)//获取图标信息 if (addIcon) //获取图标信息
{ {
result.icon = ""; result.icon = "";
} }
result.lev = await attrService.GetUserLev(userId);
} }
} }
return result; return result;
} }
} }

View File

@@ -0,0 +1,27 @@
namespace Application.Service.Pub;
public class PageExtend
{
/// <summary>
/// List 通用分页
/// </summary>
/// <param name="list">数据源</param>
/// <param name="pageIndex">当前页码从1开始</param>
/// <param name="pageSize">每页条数</param>
/// <returns>当前页数据</returns>
public static List<T> GetPageList<T>(List<T> list, int pageIndex, int pageSize)
{
// 空值保护
if (list == null || list.Count == 0)
return new List<T>();
// 页码最小为 1
pageIndex = pageIndex < 1 ? 1 : pageIndex;
// 分页核心
return list
.Skip((pageIndex - 1) * pageSize)
.Take(pageSize)
.ToList();
}
}

View File

@@ -12,7 +12,8 @@ public class ChatController : ControllerBase
{ {
private readonly IGameChatService _chatService; private readonly IGameChatService _chatService;
private readonly IGameGoodsService _goodsService; private readonly IGameGoodsService _goodsService;
public ChatController(IGameChatService chatService,IGameGoodsService goodsService)
public ChatController(IGameChatService chatService, IGameGoodsService goodsService)
{ {
_chatService = chatService; _chatService = chatService;
_goodsService = goodsService; _goodsService = goodsService;
@@ -32,28 +33,28 @@ public class ChatController : ControllerBase
string teamId = ""; string teamId = "";
string groupId = ""; string groupId = "";
RefAsync<int> Total = 0; RefAsync<int> Total = 0;
var data = await _chatService.GetChatData(type, areaId, teamId, groupId, page, 10, Total); var data = await _chatService.GetChatData(userId, type, areaId, teamId, groupId, page, 10, Total);
//物品数量 //物品数量
int sendGoodsCount = 0; int sendGoodsCount = 0;
string sendGoodsName = ""; string sendGoodsName = "";
switch (type) switch (type)
{ {
case 0: case 0:
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsBase); sendGoodsCount = await _goodsService.GetUserGoodsCount(userId, GameConfig.SendChatGoodsBase);
sendGoodsName = "小海螺"; sendGoodsName = "小海螺";
break; break;
case 3: case 3:
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsArea); sendGoodsCount = await _goodsService.GetUserGoodsCount(userId, GameConfig.SendChatGoodsArea);
sendGoodsName = "大海螺"; sendGoodsName = "大海螺";
break; break;
case 4: case 4:
sendGoodsCount = await _goodsService.GetUserGoodsCount(userId,GameConfig.SendChatGoodsService); sendGoodsCount = await _goodsService.GetUserGoodsCount(userId, GameConfig.SendChatGoodsService);
sendGoodsName = "金海螺"; sendGoodsName = "金海螺";
break; break;
} }
return PoAction.Ok(new { data, total = Total.Value ,sendGoodsCount,sendGoodsName}); return PoAction.Ok(new { data, total = Total.Value, sendGoodsCount, sendGoodsName });
} }
/// <summary> /// <summary>
@@ -79,7 +80,7 @@ public class ChatController : ControllerBase
{ {
case 0: case 0:
isSend = true; isSend = true;
code =nameof(GameChatEnum.Code.Public); code = nameof(GameChatEnum.Code.Public);
goodsId = GameConfig.SendChatGoodsBase; goodsId = GameConfig.SendChatGoodsBase;
break; break;
case 1: case 1:
@@ -90,7 +91,7 @@ public class ChatController : ControllerBase
case 2: case 2:
isSend = true; isSend = true;
code = nameof(GameChatEnum.Code.Group); code = nameof(GameChatEnum.Code.Group);
par=""; par = "";
break; break;
case 3: case 3:
isSend = true; isSend = true;
@@ -102,8 +103,8 @@ public class ChatController : ControllerBase
goodsId = GameConfig.SendChatGoodsService; goodsId = GameConfig.SendChatGoodsService;
code = nameof(GameChatEnum.Code.Dress); code = nameof(GameChatEnum.Code.Dress);
break; break;
} }
if (isSend == false) if (isSend == false)
{ {
return PoAction.Message("无法发言!"); return PoAction.Message("无法发言!");
@@ -119,19 +120,19 @@ public class ChatController : ControllerBase
} }
string sign = StringAssist.NoHTML(pars.sign); string sign = StringAssist.NoHTML(pars.sign);
bool result = await _chatService.SendChat(userId, areaId, code, sign, par); bool result = await _chatService.SendChat(userId, areaId, code, sign, par);
if (result) if (result)
{ {
if (goodsId != 0)//扣除道具 if (goodsId != 0) //扣除道具
{ {
await _goodsService.UpdateUserGoods(userId, 0, goodsId, 1, "发言"); await _goodsService.UpdateUserGoods(userId, 0, goodsId, 1, "发言");
} }
return PoAction.Ok(true); return PoAction.Ok(true);
} }
else else
{ {
return PoAction.Message("发送失败,请稍后尝试!"); return PoAction.Message("发送失败,请稍后尝试!");
} }
} }
} }

View File

@@ -18,7 +18,7 @@ public class MapController : ControllerBase
private readonly IMessageService _messageService; private readonly IMessageService _messageService;
public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService, public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService,
IUnitUserAttrService attrService,IMessageService messageService) IUnitUserAttrService attrService, IMessageService messageService)
{ {
_userService = userService; _userService = userService;
_mapService = mapService; _mapService = mapService;
@@ -69,7 +69,7 @@ public class MapController : ControllerBase
//公聊信息 //公聊信息
string teamId = ""; string teamId = "";
string groupId = ""; string groupId = "";
var chatData = await _chatService.GetChatTop(area, 2, teamId, groupId); var chatData = await _chatService.GetChatTop(userId, area, 2, teamId, groupId);
var npcData = await _mapService.GetMapNpc(mapInfo.mapId); //NPC信息 var npcData = await _mapService.GetMapNpc(mapInfo.mapId); //NPC信息
@@ -81,7 +81,8 @@ public class MapController : ControllerBase
var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId); //城市信息 var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId); //城市信息
var cityShow = await _mapService.GetCityShowMap(cityInfo.cityId); //城内地图 var cityShow = await _mapService.GetCityShowMap(cityInfo.cityId); //城内地图
int noReadMsg = await _messageService.GetNoReadCount(userId); var noReadMsg = await _messageService.GetNoReadCount(userId);
#region 线 #region 线
string ip = ComHelper.GetClientUserIp(HttpContext); string ip = ComHelper.GetClientUserIp(HttpContext);
@@ -89,7 +90,7 @@ public class MapController : ControllerBase
#endregion #endregion
object ret = new { mapInfo, cityInfo, npcData, chatData, cityShow, nearUser,noReadMsg }; object ret = new { mapInfo, cityInfo, npcData, chatData, cityShow, nearUser, noReadMsg = noReadMsg[3] };
return PoAction.Ok(ret); return PoAction.Ok(ret);
} }
@@ -166,7 +167,7 @@ public class MapController : ControllerBase
} }
} }
#region npc相关 #region npc相关
/// <summary> /// <summary>
/// 获取NPC相关信息 /// 获取NPC相关信息
@@ -197,6 +198,5 @@ public class MapController : ControllerBase
return PoAction.Ok(data); return PoAction.Ok(data);
} }
#endregion #endregion
} }

View File

@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Mvc; using System.Reflection;
using Microsoft.AspNetCore.Mvc;
namespace Application.Web.Controllers.Pub; namespace Application.Web.Controllers.Pub;
@@ -30,19 +31,30 @@ public class MessageController : ControllerBase
{ {
string userId = StateHelper.userId; string userId = StateHelper.userId;
RefAsync<int> total = 0; RefAsync<int> total = 0;
List<int> msgCount = await _messageService.GetNoReadCount(userId);
if (type == 0) if (type == 0)
{ {
var data = await _messageService.GetUserMessage(userId, 0, page, 10, total); var data = await _messageService.GetUserMessage(userId, 0, page, 10, total);
return PoAction.Ok(new { data, total = total.Value }); return PoAction.Ok(new { data, total = total.Value, msgCount });
} }
else if (type == 1) else if (type == 1)
{ {
var data = await _messageService.GetUserMessage(userId, 1, page, 10, total); var data = await _messageService.GetUserMessage(userId, 1, page, 10, total);
return PoAction.Ok(new { data, total = total.Value }); return PoAction.Ok(new { data, total = total.Value, msgCount });
}
else if (type == 2)
{
var data = await _messageService.GetUserEventMessage(userId, page, 10, total);
return PoAction.Ok(new { data, total = total.Value, msgCount });
}
else if (type == 3)
{
var data = await _messageService.GetUserMailData(userId, page, 10, total);
return PoAction.Ok(new { data, total = total.Value, msgCount });
} }
else else
{ {
return PoAction.Ok(new { data = new List<string>(), total = total.Value }); return PoAction.Ok(new { data = new List<string>(), total = total.Value, msgCount });
} }
} }
@@ -193,4 +205,134 @@ public class MessageController : ControllerBase
return PoAction.Message("删除失败,请稍后尝试!"); return PoAction.Message("删除失败,请稍后尝试!");
} }
} }
/// <summary>
/// 获取邮件详情
/// </summary>
/// <param name="no"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetMailInfo(string no)
{
string userId = StateHelper.userId;
var data = await _messageService.GetMailInfo(no);
if (data == null)
{
return PoAction.Message("邮件不存在!");
}
if (data.userId != userId)
{
return PoAction.Message("邮件不存在!");
}
if (data.endTime < TimeExtend.GetTimeStampSeconds)
{
return PoAction.Message("邮件已过期!");
}
if (data.isRead == 0)
{
data.isRead = 1;
await _messageService.UpdateMaillInfo(data);
}
return PoAction.Ok(data);
}
/// <summary>
/// 领取附件
/// </summary>
/// <param name="no"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetAward(string no)
{
string userId = StateHelper.userId;
var data = await _messageService.GetMailInfo(no);
if (data == null)
{
return PoAction.Message("邮件不存在!");
}
if (data.userId != userId)
{
return PoAction.Message("邮件不存在!");
}
if (data.endTime < TimeExtend.GetTimeStampSeconds)
{
return PoAction.Message("邮件已过期!");
}
if (data.isGet == 1)
{
return PoAction.Message("邮件附件已领取!");
}
data.isGet = 1;
data.isRead = 1;
if (await _messageService.UpdateMaillInfo(data))
{
await GameBus.UpdateBag(userId, 1, data.award, $"邮件领取:{data.name}");
return PoAction.Ok(true);
}
else
{
return PoAction.Message("领取失败,请稍后尝试!");
}
}
/// <summary>
/// 处理事件消息
/// </summary>
/// <param name="eventId"></param>
/// <param name="state"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> EventHandle(string eventId, int state)
{
string userId = StateHelper.userId;
var eventInfo = await _messageService.GetEventMessageInfo(eventId);
if (eventInfo == null)
{
return PoAction.Message("通知消息不存在!");
}
if (eventInfo.userId != userId)
{
return PoAction.Message("通知消息不存在!");
}
if (eventInfo.state != 0)
{
return PoAction.Message("消息已处理!");
}
if (eventInfo.btns.All(it => it.status != state))
{
return PoAction.Message("无法进行当前处理,请重试!");
}
eventInfo.state = state;
if (await _messageService.UpdateEventData(eventInfo))
{
MessageHandle handle = new MessageHandle();
var result = await handle.HandleMsg(eventInfo, state);
if (result.success)
{
return PoAction.Ok(true, result.msg);
}
else
{
eventInfo.state = 0;
await _messageService.UpdateEventData(eventInfo);
return PoAction.Message(result.msg);
}
}
else
{
return PoAction.Message("处理失败,请稍后尝试!");
}
}
} }

View File

@@ -0,0 +1,117 @@
using Microsoft.AspNetCore.Mvc;
namespace Application.Web.Controllers.User;
/// <summary>
/// 关系接口
/// </summary>
[ApiExplorerSettings(GroupName = "User")]
[Route("User/[controller]/[action]")]
[ApiController]
[Authorize]
public class RelationController : ControllerBase
{
private readonly IUnitUserRelationService _relationService;
private readonly IUnitUserService _userService;
private readonly IMessageService _messageService;
public RelationController(IUnitUserRelationService relationService, IUnitUserService userService,
IMessageService messageService)
{
_relationService = relationService;
_userService = userService;
_messageService = messageService;
}
/// <summary>
/// 关系列表数据
/// </summary>
/// <param name="type"></param>
/// <param name="page"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetRelation(int type, int page)
{
string userId = StateHelper.userId;
RefAsync<int> total = 0;
List<RelationView> result = new List<RelationView>();
if (type == 0)
{
var data = await _relationService.GetUserFriend(userId);
total = data.Count;
data = data.OrderByDescending(it => it.isOnline).ThenByDescending(it => it.sort).ToList();
result = PageExtend.GetPageList(data, page, 10);
}
else if (type == 1)
{
var data = await _relationService.GetUserFriend(userId);
data = data.FindAll(it => it.near >= 1000);
total = data.Count;
data = data.OrderByDescending(it => it.isOnline).ThenByDescending(it => it.near)
.ThenByDescending(it => it.sort).ToList();
result = PageExtend.GetPageList(data, page, 10);
}
return PoAction.Ok(new { data = result, total = total.Value, online = result.Count(it => it.isOnline == 1) });
}
[HttpGet]
public async Task<IPoAction> FriendHandle(string no)
{
string userId = StateHelper.userId;
var userInfo = await _userService.GetUserInfoByUserNo(no); //基础资料
if (userInfo == null)
{
return PoAction.Message("玩家不存在!");
}
if (userInfo.userId == userId)
{
return PoAction.Message("不能加自己为好友!");
}
if (userInfo.areaId != StateHelper.areaId)
{
return PoAction.Message("玩家不存在!");
}
bool IsFriend = await _relationService.CheckIsFriend(userId, userInfo.userId);
if (IsFriend == false)
{
string token = $"{nameof(MessageEnum.EventCode.Friend)}_{userId}_{userInfo.userId}";
if (await _messageService.CheckAtEventMsg(token))
{
return PoAction.Message("已发送过交友消息,等待对方通过!");
}
var myInfo = await _userService.GetUserInfoByUserId(userId);
string sign = $"{UbbTool.HomeUbb(myInfo.userNo, myInfo.nick)} 希望添加您为好友?";
List<MsgEventBtn> btns = new List<MsgEventBtn>()
{
new MsgEventBtn() { status = 1, name = "通过", tips = "已通过申请" },
new MsgEventBtn() { status = 2, name = "拒绝", tips = "已拒绝申请" }
};
if (await _messageService.SendEventMsg(userInfo.userId, nameof(MessageEnum.EventCode.Friend), "交友消息通知",
sign, userId, token, btns, 3))
{
return PoAction.Ok(true, "好友申请已发送,请等待对方确认!");
}
else
{
return PoAction.Message("添加失败,请稍后尝试!");
}
}
else //删除好友
{
bool result = await _relationService.DeleteFriend(userId, userInfo.userId);
if (result)
{
return PoAction.Ok(true, "删除好友成功!");
}
else
{
return PoAction.Message("删除失败,请稍后尝试.");
}
}
}
}

View File

@@ -12,16 +12,19 @@ public class UserController : ControllerBase
private readonly IUnitUserAttrService _attrService; private readonly IUnitUserAttrService _attrService;
private readonly IUnitUserAccService _accService; private readonly IUnitUserAccService _accService;
private readonly IGameMapService _mapService; private readonly IGameMapService _mapService;
private readonly IUnitUserRelationService _relationService;
public UserController(IUnitUserService userService, IUnitUserAttrService attrService, public UserController(IUnitUserService userService, IUnitUserAttrService attrService,
IUnitUserAccService accService, IGameMapService mapService) IUnitUserAccService accService, IGameMapService mapService,IUnitUserRelationService relationService)
{ {
_userService = userService; _userService = userService;
_attrService = attrService; _attrService = attrService;
_accService = accService; _accService = accService;
_mapService = mapService; _mapService = mapService;
_relationService = relationService;
} }
/// <summary> /// <summary>
/// 获取个人资料信息 /// 获取个人资料信息
@@ -44,6 +47,33 @@ public class UserController : ControllerBase
return PoAction.Ok(result); return PoAction.Ok(result);
} }
/// <summary>
/// 获取基础资料信息
/// </summary>
/// <param name="no"></param>
/// <returns></returns>
[HttpGet]
public async Task<IPoAction> GetUserBaseInfo(string no)
{
string userId = StateHelper.userId;
var userInfo = await _userService.GetUserInfoByUserNo(no); //基础资料
if (userInfo == null)
{
return PoAction.Message("玩家不存在!", 102);
}
if (userInfo.userId == userId)
{
return PoAction.Message("用户本身!", 101);
}
if (userInfo.areaId != StateHelper.areaId)
{
return PoAction.Message("玩家不存在!", 102);
}
var model = await UserModelTool.GetUserView(userInfo.userId);
return PoAction.Ok(model);
}
/// <summary> /// <summary>
/// 获取用户资料 /// 获取用户资料
/// </summary> /// </summary>
@@ -81,8 +111,8 @@ public class UserController : ControllerBase
var onMapInfo = await _mapService.GetMapInfo(online.mapId); var onMapInfo = await _mapService.GetMapInfo(online.mapId);
var onCity = await _mapService.GetCityInfo((int)onMapInfo.cityId); var onCity = await _mapService.GetCityInfo((int)onMapInfo.cityId);
string onMapName = $"{onCity.cityName}-{onMapInfo.mapName}"; string onMapName = $"{onCity.cityName}-{onMapInfo.mapName}";
bool isFriend = await _relationService.CheckIsFriend(userId, userInfo.userId);
object result = new { user, attr = new { attrInfo.lev }, acc, isOnline, onMapName }; object result = new { user, attr = new { attrInfo.lev }, acc, isOnline, onMapName ,isFriend};
return PoAction.Ok(result); return PoAction.Ok(result);
} }
} }

View File

@@ -15,7 +15,7 @@ const { on, emit } = useEventBus()
//连接signlar //连接signlar
const ConnectSignlar = (clientId: string) => { const ConnectSignlar = (clientId: string) => {
console.log(`客户端:${clientId}`); console.log(`客户端:${clientId}`);
} }
@@ -48,14 +48,15 @@ onMounted(() => {
ConnectSignlar(payload); ConnectSignlar(payload);
}) })
}) })
</script> </script>
<style> <style>
/* 页面级样式可以在这里定义 */ /* 页面级样式可以在这里定义 */
/* 全局样式已移至 src/assets/css/style.css */ /* 全局样式已移至 src/assets/css/style.css */
:root{ :root {
--van-base-font: initial !important; --van-base-font: initial !important;
} }
</style> </style>

View File

@@ -3,9 +3,13 @@
<div class="item" v-for="(item, index) in data" :key="index"> <div class="item" v-for="(item, index) in data" :key="index">
<span>[{{ GetChatType(item.chat.code) }}]</span> <span>[{{ GetChatType(item.chat.code) }}]</span>
<span> <span>
<GameUser :data="item.user" :show-icon="1"></GameUser>: <span v-if="item.chat.code == 'System'">
<span> 海精灵:
{{ item.chat.sign }} </span>
<span v-if="item.chat.code != 'System'">
<GameUser :data="item.user" :show-icon="1"></GameUser>:
</span>
<span v-html="item.chat.sign" @click="HtmlEvent">
</span> </span>
<span v-if="showTime == 1"> <span v-if="showTime == 1">
({{ TimeExtend.StrToFormat(item.chat.addTime, "dd日HH:mm") }}) ({{ TimeExtend.StrToFormat(item.chat.addTime, "dd日HH:mm") }})

View File

@@ -1,5 +1,8 @@
<template> <template>
<Abar :href='"/user/user?no=" +data.userNo' >{{ data.nick }}</Abar> <span v-if="data.userNo == '0'">海精灵</span>
<span v-else>
<Abar :href='"/user/user?no=" + data.userNo'>{{ data.nick }}</Abar>
</span>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
const props = defineProps({ const props = defineProps({

View File

@@ -0,0 +1,12 @@
/** Html 富文本事件统一处理(全局自动可用) */
export const HtmlEvent = (e: any) => {
const target = e.target
const type = target.dataset.type
const parms = target.dataset.parms
switch (type) {
case 'go':
navigateTo(parms)
break
}
}

View File

@@ -1,5 +1,9 @@
export class PageExtend { export class PageExtend {
public static Redirect(route: string) { public static Redirect(route: string) {
navigateTo(route)
}
public static RedirectTo(route: string) {
navigateTo(route, { replace: true }) navigateTo(route, { replace: true })
} }

View File

@@ -0,0 +1,43 @@
export class StringExtend {
/**
* 去除字符串【开头和结尾】的指定字符
* @param str 原始字符串
* @param char 要删除的字符(单个)
*/
static trim(str: string | null | undefined, char: string): string {
if (!str) return ''
if (char.length !== 1) return str
const escaped = this.#escapeRegChar(char)
return str.replace(new RegExp(`^${escaped}+|${escaped}+$`, 'g'), '')
}
/**
* 仅去除字符串【开头】的指定字符
*/
static trimStart(str: string | null | undefined, char: string): string {
if (!str) return ''
if (char.length !== 1) return str
const escaped = this.#escapeRegChar(char)
return str.replace(new RegExp(`^${escaped}+`, 'g'), '')
}
/**
* 仅去除字符串【结尾】的指定字符
*/
static trimEnd(str: string | null | undefined, char: string): string {
if (!str) return ''
if (char.length !== 1) return str
const escaped = this.#escapeRegChar(char)
return str.replace(new RegExp(`${escaped}+$`, 'g'), '')
}
/**
* 私有:转义正则特殊字符(. * + ? ^ $ 等)
*/
static #escapeRegChar(char: string): string {
return char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
}
}

View File

@@ -8,6 +8,7 @@ export class TimeExtend {
public static Format(date: Date | string | number, format = 'yyyy-MM-dd HH:mm:ss'): string { public static Format(date: Date | string | number, format = 'yyyy-MM-dd HH:mm:ss'): string {
let targetDate: Date let targetDate: Date
if (typeof date === 'number') { if (typeof date === 'number') {
date = date - 28800;
targetDate = date.toString().length === 10 ? new Date(date * 1000) : new Date(date) targetDate = date.toString().length === 10 ? new Date(date * 1000) : new Date(date)
} else { } else {
targetDate = new Date(date) targetDate = new Date(date)

View File

@@ -9,7 +9,7 @@
<Acheak @click="ChangeChat('2')" :on-value="type" on-cheak="2">帮派</Acheak>. <Acheak @click="ChangeChat('2')" :on-value="type" on-cheak="2">帮派</Acheak>.
<Acheak @click="ChangeChat('3')" :on-value="type" on-cheak="3">全区</Acheak>. <Acheak @click="ChangeChat('3')" :on-value="type" on-cheak="3">全区</Acheak>.
<Acheak @click="ChangeChat('4')" :on-value="type" on-cheak="4">全服</Acheak>. <Acheak @click="ChangeChat('4')" :on-value="type" on-cheak="4">全服</Acheak>.
<Acheak @click="ChangeChat('5')" :on-value="type" on-cheak="5">系统</Acheak> <Acheak @click="ChangeChat('5')" :on-value="type" on-cheak="5">系统</Acheak>
</div> </div>
<div class="content"> <div class="content">
<GameChat :data="data" :show-time="1"></GameChat> <GameChat :data="data" :show-time="1"></GameChat>

View File

@@ -1 +1,129 @@
<template></template> <template>
<div class="content">
<Acheak @click="ChangeBag('0')" :on-value="type" on-cheak="0">好友</Acheak>|<Acheak @click="ChangeBag('1')"
:on-value="type" on-cheak="1">密友</Acheak>|<Acheak @click="ChangeBag('2')" :on-value="type" on-cheak="2">
师徒</Acheak>|<Acheak @click="ChangeBag('3')" :on-value="type" on-cheak="3">仇人</Acheak>
</div>
<div class="content">
在线/所有({{ online }}/{{ total }})<Abutton @click="Refresh">刷新</Abutton>
</div>
<div class="content" v-if="type == '0' || type == '1'">
<div class="item" v-for="(item, index) in data" :key="index">
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
{{ item.isOnline == 1 ? "[在线]" : "[离线]" }}
<GameUser :data="item.user" :show-icon="1"></GameUser>
<span v-if="type == '0'">
({{ item.user.lev }},{{ item.cityName }}{{ item.mapName }})
<Abutton @click="FriendHandle(item.user.userNo)">[×]</Abutton>
</span>
<span v-else>
(亲密度:{{ item.near }})
</span>
</div>
<span v-if="data.length == 0">
{{ type == '0' ? "暂无好友." : "暂无密友." }}
</span>
</div>
<div class="content" v-if="type == '2'">
<span v-if="data.length == 0">暂无师徒.</span>
</div>
<div class="content" v-if="type == '3'">
<span v-if="data.length == 0">暂无仇人.</span>
</div>
<div class="content">
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
</div>
<div class="clear"></div>
<div class="content">
<Abar href="/friend/search">添加好友</Abar>
</div>
</template>
<script setup lang="ts">
interface friendStorage {
type: string
page: number
}
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const currentPage = ref<number>(1);
const total = ref<number>(0);
const data = ref<Array<any>>([]);
const type = ref('0');
const online = ref(0);
onMounted(async () => {
try {
let localData = LocalStorageExtend.Get<friendStorage>("FriendCache");
if (localData != null) {
type.value = localData.type;
currentPage.value = localData.page;
}
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let result = await RelationService.GetRelation(Number(type.value), currentPage.value);
if (result.code == 0) {
data.value = result.data.data;
total.value = result.data.total;
online.value = result.data.online;
console.log(result);
//存储请求参数
let addLocalData: friendStorage = { type: type.value, page: currentPage.value };
LocalStorageExtend.Set("FriendCache", addLocalData);
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
};
/**切换背包 */
const ChangeBag = async (_type: string): Promise<void> => {
type.value = _type;
await BindData();
}
/**刷新 */
const Refresh = async (): Promise<void> => {
MessageExtend.LoadingToast("刷新中...");
currentPage.value = 1;
await BindData();
MessageExtend.LoadingClose();
PageExtend.ScrollToTop();
}
/**翻页 */
const handlePageChange = async (page: number): Promise<void> => {
currentPage.value = page;
await BindData();
};
const FriendHandle = async (no:string): Promise<void> => {
MessageExtend.ShowConfirmDialogAsyc("好友操作", `您确定要删除好友吗?`, async () => {
let result = await RelationService.FriendHandle(no);
if (result.code == 0) {
await BindData();
MessageExtend.Notify(result.msg, "success");
}
else {
MessageExtend.Notify(result.msg, "danger");
}
return true;
});
}
</script>

View File

@@ -0,0 +1,50 @@
<template>
<div class="content">
查找好友
</div>
<div class="content">
<div class="common">
<div class="input">
玩家ID:<input name="no" type="number" placeholder="输入玩家ID" maxlength="12" class="ipt" v-model="no" />
</div>
<div class="input">
<input type="button"" class=" btn btn-danger" value="查找玩家" @click="search" />
</div>
</div>
</div>
<div class="clear"></div>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: middleware.loading
})
const no = ref('');
const search = async (): Promise<void> => {
if (no.value == null || no.value == '') {
MessageExtend.ShowToast("玩家ID不能为空!", "default");
return;
}
MessageExtend.LoadingToast("查找中...");
let result = await UserService.GetUserBaseInfo(no.value);
MessageExtend.LoadingClose();
if (result.code == 0) {
PageExtend.Redirect("/user/user?no=" + result.data.userNo);
}
else {
MessageExtend.ShowDialog("查找玩家", result.msg);
}
}
onMounted(async () => {
try {
}
finally {
PageLoading.Close();
}
})
</script>

View File

@@ -3,12 +3,18 @@
游戏消息 游戏消息
</div> </div>
<div class="module-title"> <div class="module-title">
<Acheak @click="Change('0')" :on-value="type" on-cheak="0">未读</Acheak>| <Acheak @click="Change('0')" :on-value="type" on-cheak="0">未读</Acheak>
<Acheak @click="Change('1')" :on-value="type" on-cheak="1">已读</Acheak>| <span v-if="(countInfo[0] ?? 0) > 0">({{ countInfo[0] }})</span>
<Acheak @click="Change('2')" :on-value="type" on-cheak="2">通知</Acheak>| |
<Acheak @click="Change('1')" :on-value="type" on-cheak="1">已读</Acheak>
|
<Acheak @click="Change('2')" :on-value="type" on-cheak="2">通知</Acheak>
<span v-if="(countInfo[1] ?? 0) > 0">({{ countInfo[1] }})</span>
|
<Acheak @click="Change('3')" :on-value="type" on-cheak="3">邮件</Acheak> <Acheak @click="Change('3')" :on-value="type" on-cheak="3">邮件</Acheak>
<span v-if="(countInfo[2] ?? 0) > 0">({{ countInfo[2] }})</span>
</div> </div>
<div class="module-content"> <div class="module-content" v-if="type == '0' || type == '1'">
<div class="item border-btm" v-for="(item, index) in data" :key="index"> <div class="item border-btm" v-for="(item, index) in data" :key="index">
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}. {{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
<Abar :href='"/message/read?id=" + item.user.userNo'> <Abar :href='"/message/read?id=" + item.user.userNo'>
@@ -17,6 +23,42 @@
</div> </div>
<span v-if="data.length == 0">暂无消息.</span> <span v-if="data.length == 0">暂无消息.</span>
</div> </div>
<div class="module-content" v-if="type == '2'">
<div class="item border-btm" v-for="(item, index) in data" :key="index">
<div>
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
<strong style="font-size: 16px;">{{ item.name }}</strong>
<span v-if="item.state == 0" style="color: red;font-size: 16px;">(未处理)</span>
</div>
<div style="font-size: 14px;">
{{ TimeExtend.Format(item.addTime, "yyyy-MM-dd HH:mm:ss") }}
</div>
<div v-html="item.sign" style="font-size: 15px;" @click="HtmlEvent"></div>
<div v-if="item.state == 0">
<span v-for="(btn, btn_num) in item.btns" :key="btn_num">
<Abutton @click="EventHandle(item.eventId, btn.status)" style="font-size: 16px;">{{ btn.name }}
</Abutton>
</span>
</div>
<div v-else>
<span style="font-size: 15px; ">{{
EventTips(item.btns, item.state) }}</span>
</div>
</div>
<span v-if="data.length == 0">暂无通知.</span>
</div>
<div class="module-content" v-if="type == '3'">
<div class="item border-btm" v-for="(item, index) in data" :key="index">
{{ PageExtend.GetPageIndex(currentPage, 10, index + 1) }}.
<Abar :href='"/message/mail?id=" + item.mailId'>
{{ item.name }}</Abar>
<span v-if="item.isRead == 0" style="color: red;font-size: 16px;">(未读)</span>
<span v-else-if="item.isGet == 0" style="color: red;font-size: 16px;">(未领取)</span>
</div>
<span v-if="data.length == 0">暂无邮件.</span>
</div>
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" /> <Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -29,6 +71,7 @@ const type = ref('0');
const currentPage = ref<number>(1); const currentPage = ref<number>(1);
const total = ref<number>(0); const total = ref<number>(0);
const data = ref<Array<any>>([]); const data = ref<Array<any>>([]);
const countInfo = ref<number[]>([]);
onMounted(async () => { onMounted(async () => {
try { try {
let local_type = LocalStorageExtend.Get<string>("MsgType"); let local_type = LocalStorageExtend.Get<string>("MsgType");
@@ -50,7 +93,7 @@ const BindData = async (): Promise<void> => {
if (result.code == 0) { if (result.code == 0) {
data.value = result.data.data; data.value = result.data.data;
total.value = result.data.total; total.value = result.data.total;
console.log(result); countInfo.value = result.data.msgCount;
} }
else { else {
MessageExtend.ShowDialog("提示", result.msg); MessageExtend.ShowDialog("提示", result.msg);
@@ -59,6 +102,7 @@ const BindData = async (): Promise<void> => {
const Change = async (_type: string): Promise<void> => { const Change = async (_type: string): Promise<void> => {
currentPage.value = 1; currentPage.value = 1;
data.value = [];
type.value = _type; type.value = _type;
LocalStorageExtend.Set("MsgType", type.value); LocalStorageExtend.Set("MsgType", type.value);
await BindData(); await BindData();
@@ -83,5 +127,26 @@ const delTlak = async (no: number): Promise<void> => {
} }
} }
/**消息时间处理 */
const EventHandle = async (eventId: string, state: number): Promise<void> => {
MessageExtend.ShowConfirmDialogAsyc("通知消息处理", "您确定要进行该操作吗?", async () => {
let result = await MessageService.EventHandle(eventId, state);
if (result.code == 0) {
MessageExtend.Notify(result.msg, "success");
await BindData();
}
else {
MessageExtend.Notify(result.msg, "danger");
}
return true;
});
}
const EventTips = (btns: Array<any>, state: number): string => {
var data = btns.find(it => it.status == state);
return data.tips;
}
</script> </script>

View File

@@ -0,0 +1,77 @@
<template>
<div class="crumb-nav-large">
<Abar href="/message/">我的邮件</Abar>&gt;邮件信息
</div>
<div class="module-title">
{{ data.name }}
</div>
<div class="module-content">
<div class=" spacing-3">
<span class="data_detail">
{{ data.sign }}
</span>
</div>
<div class=" spacing-3" v-if="award.length > 0">
---附件信息---<br />
<div class="common" v-html="GameTool.GetPropHtml(award, 1, 1)">
</div>
<div class="common" v-if="data.isGet == 0">
<Abutton @click="GetAward">[领取附件]</Abutton>
</div>
<div class="common" style="color:red;font-size:14px;font-weight:bold" v-if="data.isGet == 1">
*附件已领取!
</div>
</div>
<div class=" spacing-3">
发件人:海精灵<br />
发件时间:<small>[{{ TimeExtend.Format(data.addTime) }}]</small><br />
有效时间:<small>[{{ TimeExtend.Format(data.endTime) }}]</small><br />
</div>
</div>
</template>
<script setup lang="ts">
definePageMeta({
layout: layout.default,
middleware: 'page-loading'
})
const data = ref<any>({});
const award = ref<Array<any>>([]);
onMounted(async () => {
try {
await BindData();
}
finally {
PageLoading.Close();
}
})
const BindData = async (): Promise<void> => {
let no = PageExtend.QueryString("id");
let result = await MessageService.GetMailInfo(no);
if (result.code == 0) {
data.value = result.data;
award.value = result.data.award;
}
else {
MessageExtend.ShowDialogEvent("提示", result.msg, () => {
return PageExtend.Redirect("/message");
}, "确认");
}
};
const GetAward = async (): Promise<void> => {
MessageExtend.LoadingToast("领取中...");
let no = PageExtend.QueryString("id");
let result = await MessageService.GetAward(no);
MessageExtend.LoadingClose();
if (result.code == 0) {
await BindData();
MessageExtend.Notify("领取成功!", "success");
}
else {
MessageExtend.ShowDialog("提示", result.msg);
}
}
</script>

View File

@@ -68,8 +68,7 @@ const BindData = async (): Promise<void> => {
if (result.code == 0) { if (result.code == 0) {
data.value = result.data.data; data.value = result.data.data;
user.value = result.data.user; user.value = result.data.user;
logs.value = result.data.logs; logs.value = result.data.logs;
console.log(result);
} }
else { else {
MessageExtend.ShowDialogEvent("提示", result.msg, () => { MessageExtend.ShowDialogEvent("提示", result.msg, () => {

View File

@@ -2,7 +2,7 @@
<div class="content"> <div class="content">
<Abar :href='"/message/read?id=" + userData.userNo'>私聊</Abar>. <Abar>送礼物</Abar>. <Abar>逗一下</Abar><br /> <Abar :href='"/message/read?id=" + userData.userNo'>私聊</Abar>. <Abar>送礼物</Abar>. <Abar>逗一下</Abar><br />
<Abar>拜师</Abar>. <Abar>山寨</Abar>. <Abar>送道具</Abar><br> <Abar>拜师</Abar>. <Abar>山寨</Abar>. <Abar>送道具</Abar><br>
<Abar>加好友</Abar>. <Abar>加仇人</Abar> <Abutton @click="FriendHandle">{{ isFriend ? "删除好友" : "加好友" }}</Abutton>. <Abar>加仇人</Abar>
</div> </div>
<div class="content"></div> <div class="content"></div>
<div class="content"> <div class="content">
@@ -51,6 +51,7 @@ const attrData = ref<any>({});
const accData = ref<any>({}); const accData = ref<any>({});
const online = ref(0); const online = ref(0);
const onMap = ref(''); const onMap = ref('');
const isFriend = ref(false);
onMounted(async () => { onMounted(async () => {
try { try {
@@ -72,14 +73,15 @@ const BindData = async (): Promise<void> => {
accData.value = result.data.acc; accData.value = result.data.acc;
online.value = result.data.isOnline; online.value = result.data.isOnline;
onMap.value = result.data.onMapName; onMap.value = result.data.onMapName;
isFriend.value = result.data.isFriend;
console.log(result); console.log(result);
} }
else if (result.code == 101) { else if (result.code == 101) {
return PageExtend.Redirect("/user"); return PageExtend.RedirectTo("/user");
} }
else if (result.code == 102) { else if (result.code == 102) {
MessageExtend.ShowDialogEvent("提示", "玩家不存在!", () => { MessageExtend.ShowDialogEvent("提示", "玩家不存在!", () => {
return PageExtend.Redirect("/user"); return PageExtend.RedirectTo("/user");
}, "确认"); }, "确认");
} }
else { else {
@@ -87,4 +89,20 @@ const BindData = async (): Promise<void> => {
} }
}; };
const FriendHandle = async (): Promise<void> => {
MessageExtend.ShowConfirmDialogAsyc("好友操作", `您确定要${isFriend.value ? "删除" : "添加"}好友吗?`, async () => {
let no = PageExtend.QueryString("no");
let result = await RelationService.FriendHandle(no);
if (result.code == 0) {
await BindData();
MessageExtend.Notify(result.msg, "success");
}
else {
MessageExtend.Notify(result.msg, "danger");
}
return true;
});
}
</script> </script>

View File

@@ -40,4 +40,28 @@ export class MessageService {
static async DeleteMsg(no: number) { static async DeleteMsg(no: number) {
return await ApiService.Request("get", "/Message/DeleteMsg", { no }); return await ApiService.Request("get", "/Message/DeleteMsg", { no });
} }
/**
* 获取邮件详情
* GET /Message/GetMailInfo
*/
static async GetMailInfo(no: string) {
return await ApiService.Request("get", "/Message/GetMailInfo", { no });
}
/**
* 领取附件
* GET /Message/GetAward
*/
static async GetAward(no: string) {
return await ApiService.Request("get", "/Message/GetAward", { no });
}
/**
* 处理事件消息
* GET /Message/EventHandle
*/
static async EventHandle(eventId: string, state: number) {
return await ApiService.Request("get", "/Message/EventHandle", { eventId, state });
}
} }

View File

@@ -0,0 +1,17 @@
export class RelationService {
/**
* 关系列表数据
* GET /User/Relation/GetRelation
*/
static async GetRelation(type: number, page: number) {
return await ApiService.Request("get", "/User/Relation/GetRelation", { type, page });
}
/**
* FriendHandle
* GET /User/Relation/FriendHandle
*/
static async FriendHandle(no: string) {
return await ApiService.Request("get", "/User/Relation/FriendHandle", { no });
}
}

View File

@@ -7,6 +7,14 @@ export class UserService {
return await ApiService.Request("get", "/User/User/GetUserInfo"); return await ApiService.Request("get", "/User/User/GetUserInfo");
} }
/**
* 获取基础资料信息
* GET /User/User/GetUserBaseInfo
*/
static async GetUserBaseInfo(no: string) {
return await ApiService.Request("get", "/User/User/GetUserBaseInfo", { no });
}
/** /**
* 获取用户资料 * 获取用户资料
* GET /User/User/GetHomeInfo * GET /User/User/GetHomeInfo

View File

@@ -68,7 +68,7 @@ export class GameTool {
result = '金贝'; result = '金贝';
break; break;
case 'copper': case 'copper':
return this.FormatCopper(num); return this.FormatCopper(num);
break; break;
case 'teach': case 'teach':
result = '师德'; result = '师德';
@@ -80,4 +80,35 @@ export class GameTool {
return `${num}${result}`; return `${num}${result}`;
} }
/**物品连接处理 */
public static GetPropHtml(data: Array<any>, count: number, type: number): string {
let result = ''
data.forEach(element => {
let num = Number(element.count) * count;
if (type == 0) {
result += `${element.name}+${num}`
}
else {
result += `<div class='n-item'>▸${this.GetPropUrl(element.code, element.name, element.parameter)}+${num}</div>`;
}
});
result = StringExtend.trimEnd(result, ',');
return result;
}
public static GetPropUrl(code: string, name: string, par: string): string {
let result = name;
switch (code) {
case "Equ":
result = `<a href='/prop/equ?id=${par}'>${name}</a>`;
break;
case "Goods":
result = `<a href='/prop/goods?id=${par}'>${name}</a>`;
break;
}
return result;
}
} }