添加项目文件。
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
**/.classpath
|
||||
**/.dockerignore
|
||||
**/.env
|
||||
**/.git
|
||||
**/.gitignore
|
||||
**/.project
|
||||
**/.settings
|
||||
**/.toolstarget
|
||||
**/.vs
|
||||
**/.vscode
|
||||
**/*.*proj.user
|
||||
**/*.dbmdl
|
||||
**/*.jfm
|
||||
**/azds.yaml
|
||||
**/bin
|
||||
**/charts
|
||||
**/docker-compose*
|
||||
**/Dockerfile*
|
||||
**/node_modules
|
||||
**/npm-debug.log
|
||||
**/obj
|
||||
**/secrets.dev.yaml
|
||||
**/values.dev.yaml
|
||||
LICENSE
|
||||
README.md
|
||||
!**/.gitignore
|
||||
!.git/HEAD
|
||||
!.git/config
|
||||
!.git/packed-refs
|
||||
!.git/refs/heads/**
|
||||
@@ -0,0 +1,157 @@
|
||||
using Common;
|
||||
using CommonInfrastructure;
|
||||
using CustomerService.Customer;
|
||||
using CustomerService.Domain.Entity;
|
||||
using CustomerService.Domain.Response;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CustomerApi.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Route("customerapi/[controller]")]
|
||||
public class CustomerController : BaseController
|
||||
{
|
||||
private readonly ICustomerService _customerService;
|
||||
|
||||
public CustomerController(ICustomerService customerService)
|
||||
{
|
||||
_customerService = customerService;
|
||||
}
|
||||
|
||||
[HttpPost("start")]
|
||||
public async Task<BaseResponse<ConversationEntity>> StartConversation([FromBody] StartConversationParam param)
|
||||
{
|
||||
var result = await _customerService.StartConversation(param.UserId, param.UserName);
|
||||
if (result.isOk)
|
||||
return this.ToResult(result.conversation);
|
||||
else
|
||||
return this.ToFailResult<ConversationEntity>(result.msg);
|
||||
}
|
||||
|
||||
[HttpPost("message")]
|
||||
public async Task<BaseResponse<string>> SendMessage([FromBody] SendMessageParam param)
|
||||
{
|
||||
var result = await _customerService.SendMessage(param.ConversationId, param.SenderType, param.SenderId, param.SenderName, param.ContentType, param.Content, param.SenderAvatar);
|
||||
if (result.isOk)
|
||||
return this.ToResult(result.msg);
|
||||
else
|
||||
return this.ToFailResult<string>(result.msg);
|
||||
}
|
||||
|
||||
[HttpGet("messages/{conversationId}")]
|
||||
public async Task<ListResponse<MessageEntity>> GetMessages(string conversationId)
|
||||
{
|
||||
var result = await _customerService.GetMessages(conversationId);
|
||||
if (result.isOk)
|
||||
return this.ToListResult(result.messages ?? new List<MessageEntity>());
|
||||
else
|
||||
return this.ToListFailResult<MessageEntity>(result.msg);
|
||||
}
|
||||
|
||||
[HttpGet("conversations")]
|
||||
public async Task<ListResponse<ConversationResponse>> GetConversations([FromQuery] string? customerId)
|
||||
{
|
||||
var result = await _customerService.GetConversations(customerId);
|
||||
if (result.isOk)
|
||||
return this.ToListResult(result.conversations ?? new List<ConversationResponse>());
|
||||
else
|
||||
return this.ToListFailResult<ConversationResponse>(result.msg);
|
||||
}
|
||||
|
||||
[HttpGet("my-conversations")]
|
||||
public async Task<ListResponse<ConversationResponse>> GetMyConversations()
|
||||
{
|
||||
var userId = loginUser.UserId;
|
||||
var result = await _customerService.GetUserConversations(userId);
|
||||
if (result.isOk)
|
||||
return this.ToListResult(result.conversations ?? new List<ConversationResponse>());
|
||||
else
|
||||
return this.ToListFailResult<ConversationResponse>(result.msg);
|
||||
}
|
||||
|
||||
[HttpPost("end")]
|
||||
public async Task<BaseResponse<string>> EndConversation([FromBody] EndConversationParam param)
|
||||
{
|
||||
var result = await _customerService.EndConversation(param.ConversationId);
|
||||
if (result.isOk)
|
||||
return this.ToResult(result.msg);
|
||||
else
|
||||
return this.ToFailResult<string>(result.msg);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("online")]
|
||||
public async Task<ListResponse<CustomerEntity>> GetOnlineCustomers()
|
||||
{
|
||||
var result = await _customerService.GetOnlineCustomers();
|
||||
if (result.isOk)
|
||||
return this.ToListResult(result.customers ?? new List<CustomerEntity>());
|
||||
else
|
||||
return this.ToListFailResult<CustomerEntity>(result.msg);
|
||||
}
|
||||
|
||||
[HttpPost("status")]
|
||||
public async Task<BaseResponse<string>> UpdateCustomerStatus([FromBody] UpdateStatusParam param)
|
||||
{
|
||||
var result = await _customerService.UpdateCustomerStatus(param.UserId, param.Status);
|
||||
if (result.isOk)
|
||||
return this.ToResult(result.msg);
|
||||
else
|
||||
return this.ToFailResult<string>(result.msg);
|
||||
}
|
||||
|
||||
[HttpPost("mark-read")]
|
||||
public async Task<BaseResponse<string>> MarkAsRead([FromBody] MarkReadParam param)
|
||||
{
|
||||
var result = await _customerService.MarkAsRead(param.CustomerId, param.UserId);
|
||||
if (result.isOk)
|
||||
return this.ToResult(result.msg);
|
||||
else
|
||||
return this.ToFailResult<string>(result.msg);
|
||||
}
|
||||
|
||||
[HttpGet("chatlog/{conversationId}")]
|
||||
public async Task<ListResponse<MessageEntity>> GetChatLog(string conversationId)
|
||||
{
|
||||
var result = await _customerService.GetMessages(conversationId);
|
||||
if (result.isOk)
|
||||
return this.ToListResult(result.messages ?? new List<MessageEntity>());
|
||||
else
|
||||
return this.ToListFailResult<MessageEntity>(result.msg);
|
||||
}
|
||||
}
|
||||
|
||||
public class StartConversationParam
|
||||
{
|
||||
public string UserId { get; set; } = "";
|
||||
public string UserName { get; set; } = "";
|
||||
}
|
||||
|
||||
public class SendMessageParam
|
||||
{
|
||||
public string ConversationId { get; set; } = "";
|
||||
public int SenderType { get; set; }
|
||||
public string SenderId { get; set; } = "";
|
||||
public string SenderName { get; set; } = "";
|
||||
public string? SenderAvatar { get; set; }
|
||||
public int ContentType { get; set; }
|
||||
public string Content { get; set; } = "";
|
||||
}
|
||||
|
||||
public class EndConversationParam
|
||||
{
|
||||
public string ConversationId { get; set; } = "";
|
||||
}
|
||||
|
||||
public class UpdateStatusParam
|
||||
{
|
||||
public string UserId { get; set; } = "";
|
||||
public int Status { get; set; }
|
||||
}
|
||||
|
||||
public class MarkReadParam
|
||||
{
|
||||
public string CustomerId { get; set; } = "";
|
||||
|
||||
public string UserId { get; set; } = "";
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
using Common;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CustomerApi.Controllers
|
||||
{
|
||||
[Route("customerapi/[controller]")]
|
||||
[ApiController]
|
||||
public class ImageUploadController : ControllerBase
|
||||
{
|
||||
public class ImageUploadResponse
|
||||
{
|
||||
public string Path { get; set; } = "";
|
||||
}
|
||||
|
||||
[HttpPost("upload")]
|
||||
public async Task<BaseResponse<ImageUploadResponse>> UploadFile(IFormFile file)
|
||||
{
|
||||
if (file == null || file.Length == 0)
|
||||
{
|
||||
return new BaseResponse<ImageUploadResponse>
|
||||
{
|
||||
Code = CommonResponseCodeEnum.ParamError,
|
||||
Info = "No file uploaded."
|
||||
};
|
||||
}
|
||||
var guid = Guid.NewGuid().ToString("N");
|
||||
var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot/uploads", guid + Path.GetExtension(file.FileName));
|
||||
using (var stream = new FileStream(path, FileMode.Create))
|
||||
{
|
||||
await file.CopyToAsync(stream);
|
||||
}
|
||||
return new BaseResponse<ImageUploadResponse>
|
||||
{
|
||||
Code = CommonResponseCodeEnum.Success,
|
||||
Info = "上传成功",
|
||||
Data = new ImageUploadResponse { Path = $"uploads/{guid + Path.GetExtension(file.FileName)}" }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\CommonDomain\CommonDomain.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\CommonInfrastructure\CommonInfrastructure.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\Common\Common.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\JWTHelper\JWTHelper.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\MongoRepository\MongoRepository.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\RabbitMQHelper\RabbitMQHelper.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\RedisHelper\RedisHelper.csproj" />
|
||||
<ProjectReference Include="..\..\Infrastructure\SharpAbp.Infrastructure.Api\SharpAbp.Infrastructure.Api.csproj" />
|
||||
<ProjectReference Include="..\..\RedisService\RedisService.csproj" />
|
||||
<ProjectReference Include="..\..\CommonService\CommonService.csproj" />
|
||||
<ProjectReference Include="..\CustomerService\CustomerService.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,159 @@
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using CustomerService.Customer;
|
||||
|
||||
namespace CustomerApi.Hubs;
|
||||
|
||||
public class CustomerHub : Hub
|
||||
{
|
||||
private readonly ICustomerService _customerService;
|
||||
|
||||
public CustomerHub(ICustomerService customerService)
|
||||
{
|
||||
_customerService = customerService;
|
||||
}
|
||||
|
||||
public async Task JoinConversation(string conversationId)
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, conversationId);
|
||||
}
|
||||
|
||||
public async Task LeaveConversation(string conversationId)
|
||||
{
|
||||
await Groups.RemoveFromGroupAsync(Context.ConnectionId, conversationId);
|
||||
}
|
||||
|
||||
public async Task JoinCustomerQueue(string customerId)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customerId))
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, "customer_" + customerId);
|
||||
}
|
||||
|
||||
public async Task LeaveCustomerQueue(string customerId)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(customerId))
|
||||
await Groups.RemoveFromGroupAsync(Context.ConnectionId, "customer_" + customerId);
|
||||
}
|
||||
|
||||
public async Task SendMessage(string conversationId, int senderType, string senderId, string senderName, string? senderAvatar, int contentType, string content, string guId = "")
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(conversationId) && senderType == 1)
|
||||
{
|
||||
var startResult = await _customerService.StartConversation(senderId, senderName, senderAvatar);
|
||||
if (startResult.isOk && startResult.conversation != null)
|
||||
{
|
||||
conversationId = startResult.conversation.Id;
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, conversationId);
|
||||
|
||||
if (!string.IsNullOrEmpty(startResult.conversation.CustomerId))
|
||||
{
|
||||
await Clients.Group("customer_" + startResult.conversation.CustomerId).SendAsync("OnNewConversation", new
|
||||
{
|
||||
conversationId = startResult.conversation.Id,
|
||||
customerId = startResult.conversation.CustomerId,
|
||||
customerName = startResult.conversation.CustomerName,
|
||||
userId = startResult.conversation.UserId,
|
||||
userName = startResult.conversation.UserName,
|
||||
status = startResult.conversation.Status,
|
||||
createTime = startResult.conversation.CreateTime
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Clients.Caller.SendAsync("ErrorMessage", startResult.msg);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, conversationId);
|
||||
|
||||
var result = await _customerService.SendMessage(conversationId, senderType, senderId, senderName, contentType, content, senderAvatar);
|
||||
|
||||
if (result.isOk)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(guId))
|
||||
guId = Guid.NewGuid().ToString("N");
|
||||
|
||||
await Clients.Group(conversationId).SendAsync("OnMessageReceived", new
|
||||
{
|
||||
GuId = guId,
|
||||
ConversationId = conversationId,
|
||||
SenderType = senderType,
|
||||
SenderId = senderId,
|
||||
SenderName = senderName,
|
||||
SenderAvatar = senderAvatar,
|
||||
ContentType = contentType,
|
||||
Content = content,
|
||||
CreateTime = DateTime.Now
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Clients.Caller.SendAsync("ErrorMessage", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task StartConversation(string userId, string userName)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(userName))
|
||||
{
|
||||
await Clients.Caller.SendAsync("ErrorMessage", "参数错误");
|
||||
return;
|
||||
}
|
||||
|
||||
var result = await _customerService.StartConversation(userId, userName);
|
||||
|
||||
if (result.isOk && result.conversation != null)
|
||||
{
|
||||
await Clients.Caller.SendAsync("OnConversationStarted", result.conversation);
|
||||
|
||||
if (!string.IsNullOrEmpty(result.conversation.Id))
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, result.conversation.Id);
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(result.conversation.CustomerId))
|
||||
{
|
||||
await Clients.Group("customer_" + result.conversation.CustomerId).SendAsync("OnNewConversation", new
|
||||
{
|
||||
conversationId = result.conversation.Id,
|
||||
customerId = result.conversation.CustomerId,
|
||||
customerName = result.conversation.CustomerName,
|
||||
userId = result.conversation.UserId,
|
||||
userName = result.conversation.UserName,
|
||||
status = result.conversation.Status,
|
||||
createTime = result.conversation.CreateTime
|
||||
});
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Clients.Caller.SendAsync("ErrorMessage", result.msg);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await Clients.Caller.SendAsync("ErrorMessage", ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
var userId = Context.User?.Claims?.FirstOrDefault(c => c.Type == "uid")?.Value;
|
||||
if (!string.IsNullOrEmpty(userId))
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, "customer_" + userId);
|
||||
}
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
|
||||
public override async Task OnDisconnectedAsync(Exception? exception)
|
||||
{
|
||||
await base.OnDisconnectedAsync(exception);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace CustomerApi
|
||||
{
|
||||
public partial class AssemblyMarker { }
|
||||
}
|
||||
|
||||
public class Program
|
||||
{
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("CustomerApi is a library project. Use CustomerHost to run the application.");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"profiles": {
|
||||
"CustomerApi": {
|
||||
"commandName": "Project",
|
||||
"launchBrowser": true,
|
||||
"environmentVariables": {
|
||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||
},
|
||||
"applicationUrl": "https://localhost:8007/"
|
||||
}
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.9 MiB |
Reference in New Issue
Block a user