feature-nxdev #30
@@ -12,6 +12,7 @@ namespace IM_API.Configs
|
|||||||
services.AddTransient<IUserService, UserService>();
|
services.AddTransient<IUserService, UserService>();
|
||||||
services.AddTransient<IFriendSerivce, FriendService>();
|
services.AddTransient<IFriendSerivce, FriendService>();
|
||||||
services.AddTransient<IMessageSevice, MessageService>();
|
services.AddTransient<IMessageSevice, MessageService>();
|
||||||
|
services.AddTransient<IConversationService, ConversationService>();
|
||||||
services.AddSingleton<IJWTService, JWTService>();
|
services.AddSingleton<IJWTService, JWTService>();
|
||||||
services.AddSingleton<IRefreshTokenService,RedisRefreshTokenService>();
|
services.AddSingleton<IRefreshTokenService,RedisRefreshTokenService>();
|
||||||
return services;
|
return services;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
using IM_API.Dtos;
|
||||||
|
using IM_API.Interface.Services;
|
||||||
|
using IM_API.Models;
|
||||||
|
using Microsoft.AspNetCore.Authorization;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Security.Claims;
|
||||||
|
|
||||||
|
namespace IM_API.Controllers
|
||||||
|
{
|
||||||
|
[Route("api/[controller]/[action]")]
|
||||||
|
[Authorize]
|
||||||
|
[ApiController]
|
||||||
|
public class ConversationController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly IConversationService _conversationSerivice;
|
||||||
|
private readonly ILogger<ConversationController> _logger;
|
||||||
|
public ConversationController(IConversationService conversationSerivice, ILogger<ConversationController> logger)
|
||||||
|
{
|
||||||
|
_conversationSerivice = conversationSerivice;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
[HttpGet]
|
||||||
|
public async Task<IActionResult> List()
|
||||||
|
{
|
||||||
|
var userIdStr = User.FindFirstValue(ClaimTypes.NameIdentifier);
|
||||||
|
var list = await _conversationSerivice.GetConversationsAsync(int.Parse(userIdStr));
|
||||||
|
var res = new BaseResponse<List<Conversation>>(list);
|
||||||
|
return Ok(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -10,12 +10,18 @@ namespace IM_API.Interface.Services
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="clearConversationsDto"></param>
|
/// <param name="clearConversationsDto"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<bool> ClearConversationsAsync(ClearConversationsDto clearConversationsDto);
|
Task<bool> ClearConversationsAsync(int userId);
|
||||||
|
/// <summary>
|
||||||
|
/// 删除单个聊天会话
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="conversationId"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task<bool> DeleteConversationAsync(int conversationId);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取用户当前消息会话
|
/// 获取用户当前消息会话
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="userId">用户id</param>
|
/// <param name="userId">用户id</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
Task<Conversation> GetConversationsAsync(int userId);
|
Task<List<Conversation>> GetConversationsAsync(int userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using IM_API.Dtos;
|
||||||
|
using IM_API.Exceptions;
|
||||||
|
using IM_API.Interface.Services;
|
||||||
|
using IM_API.Models;
|
||||||
|
using IM_API.Tools;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
|
||||||
|
namespace IM_API.Services
|
||||||
|
{
|
||||||
|
public class ConversationService : IConversationService
|
||||||
|
{
|
||||||
|
private readonly ImContext _context;
|
||||||
|
public ConversationService(ImContext context)
|
||||||
|
{
|
||||||
|
_context = context;
|
||||||
|
}
|
||||||
|
#region 删除用户会话
|
||||||
|
public async Task<bool> ClearConversationsAsync(int userId)
|
||||||
|
{
|
||||||
|
await _context.Conversations.Where(x => x.UserId == userId).ExecuteDeleteAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
#region 获取用户会话列表
|
||||||
|
public async Task<List<Conversation>> GetConversationsAsync(int userId)
|
||||||
|
{
|
||||||
|
return await _context.Conversations.Where(x => x.UserId == userId)
|
||||||
|
.ToListAsync();
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 删除单个会话
|
||||||
|
public async Task<bool> DeleteConversationAsync(int conversationId)
|
||||||
|
{
|
||||||
|
var conversation = await _context.Conversations.FirstOrDefaultAsync(x => x.Id == conversationId);
|
||||||
|
if (conversation == null) throw new BaseException(CodeDefine.CONVERSATION_NOT_FOUND);
|
||||||
|
_context.Conversations.Remove(conversation);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -68,7 +68,7 @@ namespace IM_API.Services
|
|||||||
{
|
{
|
||||||
query = query.OrderByDescending(x => x.UserId);
|
query = query.OrderByDescending(x => x.UserId);
|
||||||
}
|
}
|
||||||
var friendList = await query.Skip((page - 1 * limit)).Take(limit).ToListAsync();
|
var friendList = await query.Skip(((page - 1) * limit)).Take(limit).ToListAsync();
|
||||||
return _mapper.Map<List<FriendInfoDto>>(friendList);
|
return _mapper.Map<List<FriendInfoDto>>(friendList);
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|||||||
@@ -54,12 +54,24 @@ namespace IM_API.Services
|
|||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
#region 发送群消息
|
||||||
public Task<bool> SendGroupMessageAsync(int senderId, int groupId, MessageBaseDto dto)
|
public async Task<bool> SendGroupMessageAsync(int senderId, int groupId, MessageBaseDto dto)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
//判断群存在
|
||||||
}
|
var isExist = await _context.Groups.AnyAsync(x => x.Id == groupId);
|
||||||
|
if (!isExist) throw new BaseException(CodeDefine.GROUP_NOT_FOUND);
|
||||||
|
//判断是否是群成员
|
||||||
|
var isMember = await _context.GroupMembers.AnyAsync(x => x.GroupId == groupId && x.UserId == senderId);
|
||||||
|
if (!isMember) throw new BaseException(CodeDefine.NO_GROUP_PERMISSION);
|
||||||
|
var message = _mapper.Map<Message>(dto);
|
||||||
|
message.Sender = senderId;
|
||||||
|
_context.Messages.Add(message);
|
||||||
|
await _context.SaveChangesAsync();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
#region 发送私聊消息
|
||||||
public async Task<bool> SendPrivateMessageAsync(int senderId, int receiverId, MessageBaseDto dto)
|
public async Task<bool> SendPrivateMessageAsync(int senderId, int receiverId, MessageBaseDto dto)
|
||||||
{
|
{
|
||||||
bool isExist = await _context.Friends.AnyAsync(x => x.FriendId == receiverId);
|
bool isExist = await _context.Friends.AnyAsync(x => x.FriendId == receiverId);
|
||||||
@@ -70,5 +82,6 @@ namespace IM_API.Services
|
|||||||
await _context.SaveChangesAsync();
|
await _context.SaveChangesAsync();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,5 +102,8 @@
|
|||||||
/// <summary>后台日志写入失败</summary>
|
/// <summary>后台日志写入失败</summary>
|
||||||
public static CodeDefine OPERATION_LOG_FAILED = new CodeDefine(3004, "操作记录失败");
|
public static CodeDefine OPERATION_LOG_FAILED = new CodeDefine(3004, "操作记录失败");
|
||||||
|
|
||||||
|
// 3.9 会话相关错误(3100 ~ 3199)
|
||||||
|
/// <summary>发送时异常</summary>
|
||||||
|
public static CodeDefine CONVERSATION_NOT_FOUND = new CodeDefine(3100, "会话不存在");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
VITE_API_BASE_URL = http://192.168.5.116:7070/api
|
VITE_API_BASE_URL = http://localhost:5202/api
|
||||||
@@ -1,8 +1,10 @@
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useMessage } from '@/components/messages/useAlert';
|
import { useMessage } from '@/components/messages/useAlert';
|
||||||
import router from '@/router';
|
import router from '@/router';
|
||||||
|
import { useAuthStore } from '@/stores/auth';
|
||||||
|
|
||||||
const message = useMessage()
|
const message = useMessage();
|
||||||
|
const authStore = useAuthStore();
|
||||||
|
|
||||||
const api = axios.create({
|
const api = axios.create({
|
||||||
baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api', // 从环境变量中读取基础 URL
|
baseURL: import.meta.env.VITE_API_BASE_URL || 'http://localhost:3000/api', // 从环境变量中读取基础 URL
|
||||||
@@ -14,7 +16,7 @@ const api = axios.create({
|
|||||||
|
|
||||||
api.interceptors.request.use(
|
api.interceptors.request.use(
|
||||||
config => {
|
config => {
|
||||||
const token = localStorage.getItem('authToken');
|
const token = authStore.token;
|
||||||
if (token) {
|
if (token) {
|
||||||
config.headers.Authorization = `Bearer ${token}`;
|
config.headers.Authorization = `Bearer ${token}`;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { request } from "./api";
|
||||||
|
|
||||||
|
export const friendService = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取好友列表
|
||||||
|
* @param {*} page 当前页
|
||||||
|
* @param {*} limit 页大小
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
getFriendList: (page = 1, limit = 100) => request.get(`/friend/list?page=${page}&limit=${limit}`)
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -84,11 +84,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
|
import { friendService } from '@/services/friend'
|
||||||
|
|
||||||
const searchQuery = ref('')
|
const searchQuery = ref('')
|
||||||
const activeContactId = ref(null)
|
const activeContactId = ref(null)
|
||||||
|
|
||||||
|
const contacts1 = ref([]);
|
||||||
|
|
||||||
// 模拟联系人数据
|
// 模拟联系人数据
|
||||||
const contacts = ref([
|
const contacts = ref([
|
||||||
{ id: 101, name: '南浔', wxid: 'nan_xun_99', region: '浙江 杭州', avatar: 'https://i.pravatar.cc/40?1', gender: 'f', signature: '山有木兮木有枝', alias: '南酱' },
|
{ id: 101, name: '南浔', wxid: 'nan_xun_99', region: '浙江 杭州', avatar: 'https://i.pravatar.cc/40?1', gender: 'f', signature: '山有木兮木有枝', alias: '南酱' },
|
||||||
@@ -114,6 +117,15 @@ function handleGoToChat() {
|
|||||||
emit('start-chat', { ...currentContact.value })
|
emit('start-chat', { ...currentContact.value })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadContactList = async (page = 1,limit = 100) => {
|
||||||
|
const res = await friendService.getFriendList(page,limit);
|
||||||
|
contacts1.value = res.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
await loadContactList();
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
|||||||
Reference in New Issue
Block a user