前端&后端:
互发消息流程打通
This commit is contained in:
@@ -98,7 +98,7 @@ const handleLogin = async () => {
|
||||
if(res.code === 0){ // Assuming 0 is success
|
||||
message.success('登录成功')
|
||||
authStore.setLoginInfo(res.data.token, res.data.refreshToken, res.data.userInfo);
|
||||
signalRStore.initSignalR(res.data.token);
|
||||
signalRStore.initSignalR();
|
||||
router.push('/messages')
|
||||
}else{
|
||||
message.error(res.message || '登录失败')
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</header>
|
||||
|
||||
<div class="chat-history" ref="historyRef">
|
||||
<div v-for="m in messages" :key="m.id" :class="['msg', m.senderId == myInfo.id ? 'mine' : 'other']">
|
||||
<div v-for="m in chatStore.messages" :key="m.id" :class="['msg', m.senderId == myInfo.id ? 'mine' : 'other']">
|
||||
<img :src="m.senderId == myInfo.id ? (myInfo?.avatar || defaultAvatar) : defaultAvatar" class="avatar-chat" />
|
||||
|
||||
<div class="msg-content">
|
||||
@@ -42,11 +42,14 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, nextTick, onMounted } from 'vue';
|
||||
import { ref, computed, nextTick, onMounted, watch } from 'vue';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import defaultAvatar from '@/assets/default_avatar.png';
|
||||
import { messageService } from '@/services/message';
|
||||
import { formatDate } from '@/utils/formatDate';
|
||||
import { useChatStore } from '@/stores/chat';
|
||||
import { generateSessionId } from '@/utils/sessionIdTools';
|
||||
import { useSignalRStore } from '@/stores/signalr';
|
||||
|
||||
const props = defineProps({
|
||||
id:{
|
||||
@@ -54,26 +57,26 @@ const props = defineProps({
|
||||
required:true
|
||||
}
|
||||
})
|
||||
|
||||
const chatStore = useChatStore();
|
||||
const signalRStore = useSignalRStore();
|
||||
|
||||
const input = ref(''); // 输入框内容
|
||||
const historyRef = ref(null); // 绑定 DOM 用于滚动
|
||||
const myInfo = useAuthStore().userInfo;
|
||||
|
||||
const conversationInfo = ref(null)
|
||||
|
||||
// --- 模拟会话数据 (实际开发中应从后端或 store 获取) ---
|
||||
const sessions = ref([
|
||||
{ id: 1, name: '南浔', avatar: 'https://i.pravatar.cc/40?1', last: '' },
|
||||
{ id: 2, name: '技术群', avatar: 'https://i.pravatar.cc/40?2', last: '' }
|
||||
]);
|
||||
|
||||
// --- 消息数据 ---
|
||||
const messages = ref({
|
||||
1: [
|
||||
{ id: 1, type: 'text', content: '在干嘛?', mine: false, time: '14:00' },
|
||||
{ id: 2, type: 'text', content: '在写代码呢,帮你调样式', mine: true, time: '14:02' }
|
||||
],
|
||||
2: []
|
||||
});
|
||||
const messages = ref([]);
|
||||
|
||||
watch(
|
||||
() => chatStore.messages,
|
||||
async (newVal) => {
|
||||
scrollToBottom();
|
||||
},
|
||||
{deep: true}
|
||||
);
|
||||
|
||||
// 自动滚动到底部
|
||||
const scrollToBottom = async () => {
|
||||
@@ -84,31 +87,19 @@ const scrollToBottom = async () => {
|
||||
};
|
||||
|
||||
// 发送文本
|
||||
function sendText() {
|
||||
async function sendText() {
|
||||
if (!input.value.trim()) return;
|
||||
|
||||
const now = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
|
||||
const newMessage = {
|
||||
id: Date.now(),
|
||||
type: 'text',
|
||||
content: input.value,
|
||||
mine: true,
|
||||
time: now
|
||||
};
|
||||
|
||||
// 插入消息
|
||||
if (!messages.value[props.id]) {
|
||||
messages.value[props.id] = [];
|
||||
}
|
||||
messages.value[props.id].push(newMessage);
|
||||
|
||||
// 同步更新会话列表最后一条摘要
|
||||
if (currentSession.value) {
|
||||
currentSession.value.last = input.value;
|
||||
}
|
||||
|
||||
// 根据 C# MessageBaseDto 构造的示例对象
|
||||
const msg = {
|
||||
type: "Text", // 消息类型,例如 'Text', 'Image', 'File'
|
||||
chatType: "PRIVATE", // 'PRIVATE' 或 'GROUP'
|
||||
senderId: conversationInfo.value.userId, // 当前用户ID (对应 int)
|
||||
receiverId: conversationInfo.value.targetId, // 接收者ID (对应 int)
|
||||
content: input.value,
|
||||
timeStamp: new Date().toISOString() // 对应 DateTime,建议存标准 ISO 字符串
|
||||
};
|
||||
await signalRStore.sendMsg(msg);
|
||||
input.value = ''; // 清空输入框
|
||||
scrollToBottom(); // 滚动
|
||||
}
|
||||
|
||||
// 通话模拟
|
||||
@@ -140,7 +131,8 @@ async function loadMessages(conversationId, msgId = null, pageSize = null) {
|
||||
// 初始化时滚动到底部
|
||||
onMounted(async () => {
|
||||
await loadConversation(props.id);
|
||||
await loadMessages(props.id);
|
||||
const sessionid = generateSessionId(conversationInfo.userId, conversationInfo.targetId)
|
||||
await chatStore.swtichSession(sessionid,props.id);
|
||||
scrollToBottom();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -49,7 +49,6 @@ const currentSession = computed(() => sessions.value.find(s => s.id === activeId
|
||||
|
||||
function selectSession(s) {
|
||||
activeId.value = s.id
|
||||
s.unread = 0
|
||||
router.push(`/messages/chat/${s.id}`)
|
||||
scrollToBottom()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user