1111
This commit is contained in:
@@ -10,8 +10,4 @@
|
|||||||
<ProjectReference Include="..\Application.Service.Pub\Application.Service.Pub.csproj" />
|
<ProjectReference Include="..\Application.Service.Pub\Application.Service.Pub.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Folder Include="game\" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
69
Service/Application.Domain.Entity/game/game/game_chat.cs
Normal file
69
Service/Application.Domain.Entity/game/game/game_chat.cs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
using SqlSugar;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Application.Domain.Entity
|
||||||
|
{
|
||||||
|
[Tenant("Kg.SeaTime.Game")]
|
||||||
|
public class game_chat
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// chatId
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsPrimaryKey = true, Length = 50)]
|
||||||
|
public string chatId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// code
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 50, IsNullable = true)]
|
||||||
|
public string? code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// areaId
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public int? areaId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// userId
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 50, IsNullable = true)]
|
||||||
|
public string? userId { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// par
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 50, IsNullable = true)]
|
||||||
|
public string? par { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// sign
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(Length = 255, IsNullable = true)]
|
||||||
|
public string? sign { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// addTime
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public DateTime? addTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// sort
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public long? sort { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// delTime
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public long? delTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// state
|
||||||
|
/// </summary>
|
||||||
|
[SugarColumn(IsNullable = true)]
|
||||||
|
public int? state { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Service/Application.Domain.Entity/model/UserModel.cs
Normal file
11
Service/Application.Domain.Entity/model/UserModel.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
namespace Application.Domain.Entity;
|
||||||
|
|
||||||
|
public class UserModel
|
||||||
|
{
|
||||||
|
public string userNo { get; set; }
|
||||||
|
public string nick { get; set; }
|
||||||
|
public string sex { get; set; }
|
||||||
|
public string headImg { get; set; }
|
||||||
|
public int area { get; set; }
|
||||||
|
public string icon { get; set; }
|
||||||
|
}
|
||||||
8
Service/Application.Domain.Entity/view/GameChatView.cs
Normal file
8
Service/Application.Domain.Entity/view/GameChatView.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
namespace Application.Domain.Entity;
|
||||||
|
|
||||||
|
public class GameChatView
|
||||||
|
{
|
||||||
|
public game_chat chat { get; set; }
|
||||||
|
public UserModel user { get; set; }
|
||||||
|
|
||||||
|
}
|
||||||
14
Service/Application.Domain/Enum/GameChatEnum.cs
Normal file
14
Service/Application.Domain/Enum/GameChatEnum.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Application.Domain;
|
||||||
|
|
||||||
|
public class GameChatEnum
|
||||||
|
{
|
||||||
|
public enum Code
|
||||||
|
{
|
||||||
|
Public,//公共
|
||||||
|
Group,//帮派
|
||||||
|
Team,//队伍
|
||||||
|
Region,//全区
|
||||||
|
Dress,//全服
|
||||||
|
System//系统
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,3 +3,4 @@ global using SqlSugar;
|
|||||||
global using Application.Domain.Entity;
|
global using Application.Domain.Entity;
|
||||||
global using Photon.Core.Redis;
|
global using Photon.Core.Redis;
|
||||||
global using Photon.Core.Assist;
|
global using Photon.Core.Assist;
|
||||||
|
global using Application.Service.Pub;
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
namespace Application.Domain;
|
||||||
|
|
||||||
|
public interface IGameChatService
|
||||||
|
{
|
||||||
|
Task<List<GameChatView>> GetChatTop(int areaId, int top, string teamId, string groupId);
|
||||||
|
|
||||||
|
Task<List<GameChatView>> GetChatData(int type, int areaId, string teamId, string groupId, int page, int limit,
|
||||||
|
RefAsync<int> total);
|
||||||
|
|
||||||
|
Task<bool> SendChat(string userId, int areaId, string code, string sign, string par = "");
|
||||||
|
Task<bool> DeleteChat(string chatId);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,153 @@
|
|||||||
|
namespace Application.Domain;
|
||||||
|
|
||||||
|
public class GameChatService : IGameChatService, ITransient
|
||||||
|
{
|
||||||
|
private readonly ISqlSugarClient _dbClient;
|
||||||
|
private readonly IRedisCache _redisClient;
|
||||||
|
|
||||||
|
public GameChatService(ISqlSugarClient dbClient, IRedisCache redisClient)
|
||||||
|
{
|
||||||
|
_dbClient = dbClient;
|
||||||
|
_redisClient = redisClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<GameChatView>> GetChatTop(int areaId, int top, string teamId, string groupId)
|
||||||
|
{
|
||||||
|
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
|
||||||
|
List<string> allCode = new List<string>() { "Public", "Region", "System" };
|
||||||
|
var data = await db.Queryable<game_chat>().Where(it => it.state == 1 &&
|
||||||
|
(
|
||||||
|
(allCode.Contains(it.code) && it.areaId == areaId) ||
|
||||||
|
(it.code == "Group" && it.par == groupId) ||
|
||||||
|
(it.code == "Team" && it.par == teamId) ||
|
||||||
|
(it.code == "Dress")
|
||||||
|
)
|
||||||
|
).Take(top).OrderByDescending(it => it.sort).ToListAsync();
|
||||||
|
|
||||||
|
var result = new List<GameChatView>();
|
||||||
|
foreach (var item in data)
|
||||||
|
{
|
||||||
|
var userModel = await UserModelTool.GetUserView(item.userId, true);
|
||||||
|
result.Add(new GameChatView() { chat = item, user = userModel });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<List<GameChatView>> GetChatData(int type, int areaId, string teamId, string groupId, int page,
|
||||||
|
int limit,
|
||||||
|
RefAsync<int> total)
|
||||||
|
{
|
||||||
|
List<game_chat> data = new List<game_chat>();
|
||||||
|
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
|
||||||
|
if (type == 0)
|
||||||
|
{
|
||||||
|
List<string> allCode = new List<string>() { "Public", "Region", "System" };
|
||||||
|
data = await db.Queryable<game_chat>().Where(it => it.state == 1 &&
|
||||||
|
(
|
||||||
|
(allCode.Contains(it.code) && it.areaId == areaId) ||
|
||||||
|
(it.code == "Group" && it.par == groupId) ||
|
||||||
|
(it.code == "Team" && it.par == teamId) ||
|
||||||
|
(it.code == "Dress")
|
||||||
|
)
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else if (type == 1) //队伍
|
||||||
|
{
|
||||||
|
data = await db.Queryable<game_chat>().Where(it => it.state == 1 && it.code == "Team" && it.par == teamId
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else if (type == 2) //帮派
|
||||||
|
{
|
||||||
|
data = await db.Queryable<game_chat>().Where(it => it.state == 1 && it.code == "Group" && it.par == groupId
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else if (type == 3) //全区
|
||||||
|
{
|
||||||
|
data = await db.Queryable<game_chat>()
|
||||||
|
.Where(it => it.state == 1 && it.code == "Region" && it.areaId == areaId
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else if (type == 4) //全服
|
||||||
|
{
|
||||||
|
data = await db.Queryable<game_chat>().Where(it => it.state == 1 && it.code == "Dress"
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else if (type == 5) //系统
|
||||||
|
{
|
||||||
|
data = await db.Queryable<game_chat>()
|
||||||
|
.Where(it => it.state == 1 && it.code == "System" && it.areaId == areaId
|
||||||
|
).OrderByDescending(it => it.sort).ToPageListAsync(page, limit, total);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data = new List<game_chat>();
|
||||||
|
}
|
||||||
|
var result = new List<GameChatView>();
|
||||||
|
foreach (var item in data)
|
||||||
|
{
|
||||||
|
var userModel = await UserModelTool.GetUserView(item.userId, true);
|
||||||
|
result.Add(new GameChatView() { chat = item, user = userModel });
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加聊天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <param name="areaId"></param>
|
||||||
|
/// <param name="code"></param>
|
||||||
|
/// <param name="sign"></param>
|
||||||
|
/// <param name="par"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> SendChat(string userId, int areaId, string code, string sign, string par = "")
|
||||||
|
{
|
||||||
|
game_chat chat = new game_chat();
|
||||||
|
chat.chatId = StringAssist.NewGuid;
|
||||||
|
chat.userId = userId;
|
||||||
|
chat.areaId = areaId;
|
||||||
|
chat.code = code;
|
||||||
|
chat.par = par;
|
||||||
|
chat.sign = sign;
|
||||||
|
chat.state = 1;
|
||||||
|
chat.addTime = DateTime.Now;
|
||||||
|
chat.sort = TimeExtend.GetTimeStampSeconds;
|
||||||
|
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddDays(3));
|
||||||
|
switch (code)
|
||||||
|
{
|
||||||
|
case "Region":
|
||||||
|
chat.sort += 300; //五分钟
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "Dress":
|
||||||
|
chat.sort += 600; //10分钟
|
||||||
|
break;
|
||||||
|
case "System":
|
||||||
|
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddHours(6));
|
||||||
|
break;
|
||||||
|
case "Group":
|
||||||
|
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddHours(6));
|
||||||
|
break;
|
||||||
|
case "Team":
|
||||||
|
chat.delTime = TimeExtend.GetTimeStampBySeconds(DateTime.Now.AddHours(6));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
|
||||||
|
return await db.Insertable(chat).ExecuteCommandAsync() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 删除聊天
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="chatId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public async Task<bool> DeleteChat(string chatId)
|
||||||
|
{
|
||||||
|
var db = _dbClient.AsTenant().GetConnectionWithAttr<game_chat>();
|
||||||
|
return await db.Updateable<game_chat>().SetColumns(it => it.state == 0).Where(it => it.chatId == chatId)
|
||||||
|
.ExecuteCommandAsync() > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
using Photon.Core.Assist;
|
|
||||||
|
|
||||||
namespace Application.Domain;
|
namespace Application.Domain;
|
||||||
|
|
||||||
public class GameTool
|
public class GameTool
|
||||||
@@ -38,4 +37,5 @@ public class GameTool
|
|||||||
List<string> onArea = new List<string>() {"0",area.ToString() };
|
List<string> onArea = new List<string>() {"0",area.ToString() };
|
||||||
return onArea.Any(it => areas.Contains(it));
|
return onArea.Any(it => areas.Contains(it));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
32
Service/Application.Domain/Tool/ModelTool/UserModelTool.cs
Normal file
32
Service/Application.Domain/Tool/ModelTool/UserModelTool.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
namespace Application.Domain;
|
||||||
|
|
||||||
|
public class UserModelTool
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取用户模型
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="userId"></param>
|
||||||
|
/// <param name="addIcon"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static async Task<UserModel> GetUserView(string userId,bool addIcon=false)
|
||||||
|
{
|
||||||
|
UserModel result = new UserModel();
|
||||||
|
var userService = App.GetService<IUnitUserService>();
|
||||||
|
var userInfo = await userService.GetUserInfoByUserId(userId);
|
||||||
|
if (userInfo != null)
|
||||||
|
{
|
||||||
|
result.userNo = userInfo.userNo;
|
||||||
|
result.nick = userInfo.nick;
|
||||||
|
result.sex = userInfo.sex;
|
||||||
|
result.headImg = userInfo.headImg;
|
||||||
|
result.area = (int)userInfo.areaId;
|
||||||
|
result.icon = "";
|
||||||
|
if (addIcon)//获取图标信息
|
||||||
|
{
|
||||||
|
result.icon = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
Service/Application.Service.Pub/Extends/TimeExtend.cs
Normal file
24
Service/Application.Service.Pub/Extends/TimeExtend.cs
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
namespace Application.Service.Pub;
|
||||||
|
|
||||||
|
public class TimeExtend
|
||||||
|
{
|
||||||
|
public static long GetTimeStampSeconds
|
||||||
|
{
|
||||||
|
get => Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long GetTimeStampMilliseconds
|
||||||
|
{
|
||||||
|
get => Convert.ToInt64((DateTime.Now - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long GetTimeStampBySeconds(DateTime time)
|
||||||
|
{
|
||||||
|
return Convert.ToInt64((time - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalSeconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static long GetTimeStampByMilliseconds(DateTime time)
|
||||||
|
{
|
||||||
|
return Convert.ToInt64((time - new DateTime(1970, 1, 1, 0, 0, 0, 0)).TotalMilliseconds);
|
||||||
|
}
|
||||||
|
}
|
||||||
117
Service/Application.Web/Controllers/Chat/ChatController.cs
Normal file
117
Service/Application.Web/Controllers/Chat/ChatController.cs
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Application.Web.Controllers.Chat;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公聊接口
|
||||||
|
/// </summary>
|
||||||
|
[Route("Chat/[controller]/[action]")]
|
||||||
|
[ApiController]
|
||||||
|
[Authorize]
|
||||||
|
public class ChatController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IGameChatService _chatService;
|
||||||
|
|
||||||
|
public ChatController(IGameChatService chatService)
|
||||||
|
{
|
||||||
|
_chatService = chatService;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取公聊信息
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type"></param>
|
||||||
|
/// <param name="page"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IPoAction> GetChatData(int type, int page)
|
||||||
|
{
|
||||||
|
int areaId = StateHelper.areaId;
|
||||||
|
string teamId = "";
|
||||||
|
string groupId = "";
|
||||||
|
RefAsync<int> Total = 0;
|
||||||
|
var data = await _chatService.GetChatData(type, areaId, teamId, groupId, page, 10, Total);
|
||||||
|
//物品数量
|
||||||
|
int sendGoodsCount = 0;
|
||||||
|
string sendGoodsName = "";
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
sendGoodsCount = 199;
|
||||||
|
sendGoodsName = "小海螺";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
sendGoodsCount = 15;
|
||||||
|
sendGoodsName = "大海螺";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
sendGoodsCount = 9;
|
||||||
|
sendGoodsName = "金海螺";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return PoAction.Ok(new { data, total = Total.Value ,sendGoodsCount,sendGoodsName});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 发言
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="pars"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost]
|
||||||
|
public async Task<IPoAction> SendChat([FromBody] SendChatParms pars)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(pars.sign))
|
||||||
|
{
|
||||||
|
return PoAction.Message("发言内容不能为空!");
|
||||||
|
}
|
||||||
|
|
||||||
|
string userId = StateHelper.userId;
|
||||||
|
int areaId = StateHelper.areaId;
|
||||||
|
string par = string.Empty;
|
||||||
|
string code = GameChatEnum.Code.Public.ToString();
|
||||||
|
bool isSend = false;
|
||||||
|
switch (pars.type)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
isSend = true;
|
||||||
|
code =nameof(GameChatEnum.Code.Public);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
isSend = true;
|
||||||
|
code = nameof(GameChatEnum.Code.Team);
|
||||||
|
par = "";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
isSend = true;
|
||||||
|
code = nameof(GameChatEnum.Code.Group);
|
||||||
|
par="";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
isSend = true;
|
||||||
|
code = nameof(GameChatEnum.Code.Region);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
isSend = true;
|
||||||
|
code = nameof(GameChatEnum.Code.Dress);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isSend == false)
|
||||||
|
{
|
||||||
|
return PoAction.Message("无法发言!");
|
||||||
|
}
|
||||||
|
string sign = StringAssist.NoHTML(pars.sign);
|
||||||
|
bool result = await _chatService.SendChat(userId, areaId, code, sign, par);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
return PoAction.Ok(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return PoAction.Message("发送失败,请稍后尝试!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,11 +13,13 @@ public class MapController : ControllerBase
|
|||||||
{
|
{
|
||||||
private readonly IUnitUserService _userService;
|
private readonly IUnitUserService _userService;
|
||||||
private readonly IGameMapService _mapService;
|
private readonly IGameMapService _mapService;
|
||||||
|
private readonly IGameChatService _chatService;
|
||||||
|
|
||||||
public MapController(IUnitUserService userService, IGameMapService mapService)
|
public MapController(IUnitUserService userService, IGameMapService mapService, IGameChatService chatService)
|
||||||
{
|
{
|
||||||
_userService = userService;
|
_userService = userService;
|
||||||
_mapService = mapService;
|
_mapService = mapService;
|
||||||
|
_chatService = chatService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -29,6 +31,7 @@ public class MapController : ControllerBase
|
|||||||
public async Task<IPoAction> GetMapData(string? map)
|
public async Task<IPoAction> GetMapData(string? map)
|
||||||
{
|
{
|
||||||
string userId = StateHelper.userId;
|
string userId = StateHelper.userId;
|
||||||
|
int area = StateHelper.areaId;
|
||||||
var onMap = await _mapService.GetUserOnMap(userId);
|
var onMap = await _mapService.GetUserOnMap(userId);
|
||||||
game_city_map mapInfo = new game_city_map();
|
game_city_map mapInfo = new game_city_map();
|
||||||
if (string.IsNullOrEmpty(map))
|
if (string.IsNullOrEmpty(map))
|
||||||
@@ -40,10 +43,14 @@ public class MapController : ControllerBase
|
|||||||
mapInfo = await _mapService.GetMapInfo(map);
|
mapInfo = await _mapService.GetMapInfo(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//公聊信息
|
||||||
|
string teamId = "";
|
||||||
|
string groupId = "";
|
||||||
|
var chatData = await _chatService.GetChatTop(area, 2, teamId, groupId);
|
||||||
//NPC信息
|
//NPC信息
|
||||||
|
|
||||||
var npcData = await _mapService.GetMapNpc(mapInfo.mapId);
|
var npcData = await _mapService.GetMapNpc(mapInfo.mapId);
|
||||||
npcData = npcData.FindAll(it => GameTool.AreaVerify(StateHelper.areaId,it.areaId));
|
npcData = npcData.FindAll(it => GameTool.AreaVerify(StateHelper.areaId, it.areaId));
|
||||||
//城市信息
|
//城市信息
|
||||||
var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId);
|
var cityInfo = await _mapService.GetCityInfo((int)mapInfo.cityId);
|
||||||
|
|
||||||
@@ -54,7 +61,7 @@ public class MapController : ControllerBase
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
object ret = new { mapInfo, cityInfo, npcData };
|
object ret = new { mapInfo, cityInfo, npcData, chatData };
|
||||||
|
|
||||||
return PoAction.Ok(ret);
|
return PoAction.Ok(ret);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Application.Web;
|
||||||
|
|
||||||
|
public class SendChatParms
|
||||||
|
{
|
||||||
|
public int type { get; set; }
|
||||||
|
public string sign { get; set; }
|
||||||
|
}
|
||||||
@@ -1,31 +1,26 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="pagination">
|
<div class="pagination" v-if="totalPages > 1">
|
||||||
<!-- 第一行:导航按钮 -->
|
<!-- 第一行:导航按钮 -->
|
||||||
<div class="pagination-nav">
|
<div class="pagination-nav">
|
||||||
<span v-if="currentPage > 1" @click="changePage('first')">首页</span>
|
<span v-if="currentPage > 1" @click="changePage('first')">首页</span>
|
||||||
|
<span v-if="currentPage > 1"> . </span>
|
||||||
<span v-if="currentPage > 1" @click="changePage('prev')">上一页</span>
|
<span v-if="currentPage > 1" @click="changePage('prev')">上一页</span>
|
||||||
|
<span v-if="currentPage > 1 && currentPage < totalPages"> . </span>
|
||||||
<span v-if="currentPage < totalPages" @click="changePage('next')">下一页</span>
|
<span v-if="currentPage < totalPages" @click="changePage('next')">下一页</span>
|
||||||
|
<span v-if="currentPage < totalPages"> . </span>
|
||||||
<span v-if="currentPage < totalPages" @click="changePage('last')">尾页</span>
|
<span v-if="currentPage < totalPages" @click="changePage('last')">尾页</span>
|
||||||
</div>
|
</div>
|
||||||
<!-- 第二行:页码信息与跳转 -->
|
<!-- 第二行:页码信息与跳转 -->
|
||||||
<div class="pagination-info">
|
<div class="pagination-info" style="margin-top: 0px;">
|
||||||
<span>第{{ currentPage }}/{{ totalPages }}页</span>
|
<span>第{{ currentPage }}/{{ totalPages }}页</span>
|
||||||
<input
|
<input v-model.number="goPage" type="number" min="1" :max="totalPages" class="page-input"
|
||||||
v-model.number="goPage"
|
@keyup.enter="changePage('input')" />
|
||||||
type="number"
|
<button @click="changePage('input')" style="padding: 0px 10px; font-size: 15px; ">跳转</button>
|
||||||
min="1"
|
|
||||||
:max="totalPages"
|
|
||||||
class="page-input"
|
|
||||||
@keyup.enter="changePage('input')"
|
|
||||||
/>
|
|
||||||
<button @click="changePage('input')">跳转</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch } from 'vue'
|
|
||||||
|
|
||||||
// 定义Props
|
// 定义Props
|
||||||
interface Props {
|
interface Props {
|
||||||
currentPage: number; // 当前页
|
currentPage: number; // 当前页
|
||||||
@@ -103,7 +98,7 @@ const changePage = (type: 'first' | 'prev' | 'next' | 'last' | 'input') => {
|
|||||||
goPage.value = currentPage.value
|
goPage.value = currentPage.value
|
||||||
// 向父组件抛出最新页码
|
// 向父组件抛出最新页码
|
||||||
emit('pageChange', currentPage.value)
|
emit('pageChange', currentPage.value)
|
||||||
scrollToTop();
|
scrollToTop();
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -114,10 +109,7 @@ const changePage = (type: 'first' | 'prev' | 'next' | 'last' | 'input') => {
|
|||||||
margin: 16px 0;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-nav {
|
.pagination-nav {}
|
||||||
display: flex;
|
|
||||||
gap: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pagination-nav span {
|
.pagination-nav span {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@@ -128,7 +120,8 @@ const changePage = (type: 'first' | 'prev' | 'next' | 'last' | 'input') => {
|
|||||||
.pagination-nav span.disabled {
|
.pagination-nav span.disabled {
|
||||||
color: #999;
|
color: #999;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
pointer-events: none; /* 禁用点击 */
|
pointer-events: none;
|
||||||
|
/* 禁用点击 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-info {
|
.pagination-info {
|
||||||
@@ -140,7 +133,8 @@ const changePage = (type: 'first' | 'prev' | 'next' | 'last' | 'input') => {
|
|||||||
|
|
||||||
.page-input {
|
.page-input {
|
||||||
width: 46px;
|
width: 46px;
|
||||||
padding: 4px 6px;
|
font-size: 14px;
|
||||||
|
padding: 0px 6px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|||||||
51
Web/src/components/Business/GameChat.vue
Normal file
51
Web/src/components/Business/GameChat.vue
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<template>
|
||||||
|
<div class="chat">
|
||||||
|
<div class="item" v-for="(item, index) in data" :key="index">
|
||||||
|
<span>[{{ GetChatType(item.chat.code) }}]</span>
|
||||||
|
<span>
|
||||||
|
<GameUser :data="item.user" :show-icon="1"></GameUser>:
|
||||||
|
<span>
|
||||||
|
{{ item.chat.sign }}
|
||||||
|
</span>
|
||||||
|
<span v-if="showTime == 1">
|
||||||
|
({{ TimeExtend.StrToFormat(item.chat.addTime, "dd日HH:mm") }})
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const props = defineProps({
|
||||||
|
// 字段名、类型、默认值
|
||||||
|
data: Array<any>,
|
||||||
|
showTime: Number,
|
||||||
|
page: Number,
|
||||||
|
limit: Number
|
||||||
|
})
|
||||||
|
|
||||||
|
const GetChatType = (type: string) => {
|
||||||
|
let result = "";
|
||||||
|
switch (type) {
|
||||||
|
case "Public":
|
||||||
|
result = "公共";
|
||||||
|
break;
|
||||||
|
case "Team":
|
||||||
|
result = "队伍";
|
||||||
|
break;
|
||||||
|
case "Group":
|
||||||
|
result = "帮派";
|
||||||
|
break;
|
||||||
|
case "Region":
|
||||||
|
result = "全区";
|
||||||
|
break;
|
||||||
|
case "Dress":
|
||||||
|
result = "全服";
|
||||||
|
break;
|
||||||
|
case "System":
|
||||||
|
result = "系统";
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
10
Web/src/components/Business/GameUser.vue
Normal file
10
Web/src/components/Business/GameUser.vue
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<template>
|
||||||
|
<Abar href="">{{data.nick}}</Abar>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
const props = defineProps({
|
||||||
|
// 字段名、类型、默认值
|
||||||
|
data: null,
|
||||||
|
showIcon: Number
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@@ -69,4 +69,31 @@ export class TimeExtend {
|
|||||||
public static GetTimeStr(): string {
|
public static GetTimeStr(): string {
|
||||||
return this.Now('HH:mm:ss')
|
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 目标格式
|
||||||
|
*/
|
||||||
|
public static StrToFormat(timeStr: string, format = 'yyyy-MM-dd HH:mm:ss'): string {
|
||||||
|
return this.Format(timeStr, format);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 时间字符串 转 日期对象
|
||||||
|
* @param timeStr 时间字符串
|
||||||
|
*/
|
||||||
|
public static StrToDate(timeStr: string): Date | null {
|
||||||
|
const date = new Date(timeStr);
|
||||||
|
return isNaN(date.getTime()) ? null : date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时间字符串 转 秒级时间戳
|
||||||
|
* @param timeStr 时间字符串
|
||||||
|
*/
|
||||||
|
public static StrToSecondStamp(timeStr: string): number | null {
|
||||||
|
const date = this.StrToDate(timeStr);
|
||||||
|
return date ? Math.floor(date.getTime() / 1000) : null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,26 +4,53 @@
|
|||||||
<Abar href="/news">*更新内容早知道</Abar>
|
<Abar href="/news">*更新内容早知道</Abar>
|
||||||
</div>
|
</div>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<Acheak @click="BindData('')" :on-value="type" on-cheak="">公共</Acheak>.
|
<Acheak @click="BindData('0')" :on-value="type" on-cheak="0">公共</Acheak>.
|
||||||
<Acheak @click="BindData('1')" :on-value="type" on-cheak="1">队伍</Acheak>.
|
<Acheak @click="BindData('1')" :on-value="type" on-cheak="1">队伍</Acheak>.
|
||||||
<Acheak @click="BindData('2')" :on-value="type" on-cheak="2">帮派</Acheak>.
|
<Acheak @click="BindData('2')" :on-value="type" on-cheak="2">帮派</Acheak>.
|
||||||
<Acheak @click="BindData('3')" :on-value="type" on-cheak="3">全区</Acheak>.
|
<Acheak @click="BindData('3')" :on-value="type" on-cheak="3">全区</Acheak>.
|
||||||
<Acheak @click="BindData('4')" :on-value="type" on-cheak="4">系统</Acheak>.
|
<Acheak @click="BindData('4')" :on-value="type" on-cheak="4">全服</Acheak>.
|
||||||
<Acheak @click="BindData('5')" :on-value="type" on-cheak="5">全服</Acheak>
|
<Acheak @click="BindData('5')" :on-value="type" on-cheak="5">系统</Acheak>
|
||||||
</div>
|
</div>
|
||||||
<div class="chat">
|
<div class="content">
|
||||||
<div class="item">
|
<GameChat :data="data" :show-time="1"></GameChat>
|
||||||
暂无发言.
|
<span v-if="data.length == 0">暂无发言.</span>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<Pagination :currentPage="currentPage" :limit="10" :total="total" @pageChange="handlePageChange" />
|
||||||
|
</div>
|
||||||
|
<div class="content" v-if="type != '5'">
|
||||||
|
<span>请输入聊天信息:</span><br>
|
||||||
|
<div v-if="goodsName != ''">
|
||||||
|
{{ goodsName }}:{{ goodsCount }} <span style="font-size: 18px;">(每次发言需要1个哦)</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<textarea name="sign" id="sign" rows="2" cols="20" maxlength="80" class="ipt emojiTxt"
|
||||||
|
v-model="sign"></textarea>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit" value="发言" class="btn btn-danger" @click="SendChat" />.
|
||||||
|
<Abutton @click="Refresh">刷新</Abutton>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content">
|
||||||
|
<Abar href="/">*公聊频道发言规范</Abar><br />
|
||||||
|
<Abar href="/">*游戏用户守则规范</Abar>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: layout.default,
|
layout: layout.default,
|
||||||
middleware: 'page-loading'
|
middleware: 'page-loading'
|
||||||
})
|
})
|
||||||
|
|
||||||
const type = ref('');
|
const type = ref('0');
|
||||||
|
const currentPage = ref<number>(1);
|
||||||
|
const total = ref<number>(0);
|
||||||
|
const data = ref<Array<any>>([]);
|
||||||
|
const goodsCount = ref(0);
|
||||||
|
const goodsName = ref('');
|
||||||
|
const sign = ref('');
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -38,6 +65,16 @@ const BindData = async (typeid: string): Promise<void> => {
|
|||||||
if (type.value != typeid) {
|
if (type.value != typeid) {
|
||||||
type.value = typeid;
|
type.value = typeid;
|
||||||
}
|
}
|
||||||
|
let result = await ChatService.GetChatData(Number(typeid), currentPage.value);
|
||||||
|
if (result.code == 0) {
|
||||||
|
data.value = result.data.data;
|
||||||
|
goodsCount.value = result.data.sendGoodsCount
|
||||||
|
goodsName.value = result.data.sendGoodsName
|
||||||
|
total.value = result.data.total;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MessageExtend.ShowDialog("提示", result.msg);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**刷新 */
|
/**刷新 */
|
||||||
@@ -48,4 +85,35 @@ const Refresh = async (): Promise<void> => {
|
|||||||
MessageExtend.Notify("刷新成功!", "success");
|
MessageExtend.Notify("刷新成功!", "success");
|
||||||
PageExtend.ScrollToTop();
|
PageExtend.ScrollToTop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**翻页 */
|
||||||
|
const handlePageChange = async (page: number): Promise<void> => {
|
||||||
|
currentPage.value = page;
|
||||||
|
await BindData(type.value);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**发送消息 */
|
||||||
|
let send = true;
|
||||||
|
const SendChat = async (): Promise<void> => {
|
||||||
|
if (sign.value == '' || sign.value == null) {
|
||||||
|
MessageExtend.ShowToast('聊天内容不能为空!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (send) {
|
||||||
|
send = false;
|
||||||
|
//发送消息请求
|
||||||
|
let result = await ChatService.SendChat(Number(type.value), sign.value);
|
||||||
|
send = true;
|
||||||
|
if (result.code == 0) {
|
||||||
|
sign.value = '';
|
||||||
|
await BindData(type.value);
|
||||||
|
PageExtend.ScrollToTop();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
MessageExtend.ShowDialog("提示", result.msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@@ -10,26 +10,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="notification">
|
<div class="notification">
|
||||||
<div class="chat">
|
<GameChat :data="chatData" :show-time="0"></GameChat>
|
||||||
<div class="item">
|
|
||||||
[公共]
|
|
||||||
<span><img src='http://gree.pccsh.com/res/badge/9001.gif' class='user-head' alt='头像' /><a
|
|
||||||
class='a-nodec' href='/User/Index/Home/250822?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'><span
|
|
||||||
class='Nick-Gold'> 航海百曉生 </span></a><img src='http://gree.pccsh.com/res/badge/9001.gif'
|
|
||||||
alt='vip' class='vip' /> <span class='icon-cry'><i
|
|
||||||
class='icon-crystal liangHao'></i></span><img src='http://gree.pccsh.com/res/badge/9001.gif'
|
|
||||||
alt='心愿星河' class='badge' /> </span>
|
|
||||||
:
|
|
||||||
<span class=''>出身上天魔套15,复仇8,白副手10块,白四象5块,4级审判20,一套5级房子材料20</span>
|
|
||||||
</div>
|
|
||||||
<div class="item">
|
|
||||||
[公共]
|
|
||||||
<span><a class='a-nodec'
|
|
||||||
href='/User/Index/Home/14637160?sid=W6Wg8iH9gY7wIBNSEdtFcQ3KbI5YiKDo'>长剑小苍穹失散多年的亲爹</a></span>
|
|
||||||
:
|
|
||||||
<span class=''><img src='http://r.kexunkeji.cn/em/unit/1.png' alt='嘟嘴' class='em' /></span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
您看到:
|
您看到:
|
||||||
@@ -38,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<div class="item" v-for="item in npcData">
|
<div class="item" v-for="item in npcData">
|
||||||
<Abar href="">{{item.npcName}}{{item.tips}}</Abar>
|
<Abar href="">{{ item.npcName }}{{ item.tips }}</Abar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -73,6 +54,7 @@ definePageMeta({
|
|||||||
const mapInfo = ref<any>({});
|
const mapInfo = ref<any>({});
|
||||||
const cityInfo = ref<any>({});
|
const cityInfo = ref<any>({});
|
||||||
const npcData = ref<Array<any>>([]);
|
const npcData = ref<Array<any>>([]);
|
||||||
|
const chatData = ref<Array<any>>([]);
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
@@ -90,6 +72,7 @@ const BindData = async (map: string): Promise<void> => {
|
|||||||
mapInfo.value = result.data.mapInfo;
|
mapInfo.value = result.data.mapInfo;
|
||||||
cityInfo.value = result.data.cityInfo;
|
cityInfo.value = result.data.cityInfo;
|
||||||
npcData.value = result.data.npcData;
|
npcData.value = result.data.npcData;
|
||||||
|
chatData.value = result.data.chatData;
|
||||||
MapVent(result.data.mapInfo.near);
|
MapVent(result.data.mapInfo.near);
|
||||||
console.log(result.data);
|
console.log(result.data);
|
||||||
|
|
||||||
|
|||||||
19
Web/src/services/Index/ChatService.ts
Normal file
19
Web/src/services/Index/ChatService.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
export class ChatService {
|
||||||
|
/**
|
||||||
|
* 获取公聊信息
|
||||||
|
* GET /Chat/Chat/GetChatData
|
||||||
|
*/
|
||||||
|
static async GetChatData(type: number, page: number) {
|
||||||
|
return await ApiService.Request("get", "/Chat/Chat/GetChatData", { type, page });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发言
|
||||||
|
* POST /Chat/Chat/SendChat
|
||||||
|
* @param type body
|
||||||
|
* @param sign body
|
||||||
|
*/
|
||||||
|
static async SendChat(type: number, sign: string) {
|
||||||
|
return await ApiService.Request("post", "/Chat/Chat/SendChat", { type, sign });
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user