2026-10-12 16:22:04 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 发起会话 - 用户点击客服入口时调用
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 发送消息 - 在会话中发送文字或图片消息
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 获取消息列表 - 获取指定会话的所有聊天记录
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 获取会话列表 - 获取所有会话或指定客服的会话
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 获取当前用户的会话列表 - 获取当前登录用户的所有会话及聊天记录
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 结束会话 - 关闭指定的会话
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 获取在线客服列表 - 获取当前所有在线的客服人员
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 更新客服状态 - 设置客服的在线/离线状态
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 标记会话已读 - 客服点击会话时调用,更新该用户所有会话的最后读取时间
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-19 00:44:00 +08:00
|
|
|
/// <summary>
|
|
|
|
|
/// 获取聊天记录 - 获取指定会话的所有消息
|
|
|
|
|
/// </summary>
|
2026-10-12 16:22:04 +08:00
|
|
|
[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; } = "";
|
|
|
|
|
}
|