管理员可以看到所有会话了

This commit is contained in:
yml
2026-06-05 19:43:55 +08:00
parent 59093f8fd5
commit 92c603794a
5 changed files with 236 additions and 31 deletions
@@ -276,12 +276,17 @@ function roleLabel(role: string) {
support: '客服',
customer: '咨询',
system: '系统',
admin: '管理员',
}
return map[role] || '成员'
}
function senderLabel(item: ChatMessage) {
if (item.sender_type === 'system') return '系统'
// 管理员消息特殊标识
if (item.sender_role === 'admin') {
return `管理员 · ${item.sender_name}`
}
return `${roleLabel(item.sender_role)} · ${item.sender_name}`
}
@@ -374,13 +379,19 @@ function getSupportName(item: ChatConversation) {
v-for="item in messages"
:key="item.id"
class="message-row"
:class="{ self: item.is_self, system: item.sender_type === 'system' }"
:class="{
self: item.is_self,
system: item.sender_type === 'system',
admin: item.sender_role === 'admin'
}"
>
<template v-if="item.sender_type === 'system'">
<span>{{ item.content }}</span>
</template>
<template v-else>
<small>{{ senderLabel(item) }} · {{ formatDateMinute(item.created_at) }}</small>
<small :class="{ 'admin-label': item.sender_role === 'admin' }">
{{ senderLabel(item) }} · {{ formatDateMinute(item.created_at) }}
</small>
<p v-if="item.content">{{ item.content }}</p>
<div v-if="item.attachment_urls.length > 0" class="message-attachments">
<ChatAttachmentImage
@@ -678,6 +689,16 @@ function getSupportName(item: ChatConversation) {
background: #dff5eb;
}
.message-row.admin p {
background: #fff4e6;
border-left: 3px solid #ff9800;
}
.admin-label {
color: #ff9800 !important;
font-weight: 600;
}
.message-attachments {
display: grid;
justify-items: start;
+3 -3
View File
@@ -6,7 +6,7 @@ export interface ChatParticipant {
conversation_id: number
participant_type: 'user' | 'admin'
participant_id: number
role: 'renter' | 'owner' | 'support' | 'customer'
role: 'renter' | 'owner' | 'support' | 'customer' | 'admin'
remark: string
display_name: string
avatar_url: string
@@ -20,7 +20,7 @@ export interface ChatConversation {
type: string
title: string
status: string
role: 'renter' | 'owner' | 'support' | 'customer'
role: 'renter' | 'owner' | 'support' | 'customer' | 'admin'
participants?: ChatParticipant[]
last_message_id?: number
last_message_preview: string
@@ -35,7 +35,7 @@ export interface ChatMessage {
conversation_id: number
sender_type: 'user' | 'admin' | 'system'
sender_id: number
sender_role: 'renter' | 'owner' | 'support' | 'customer' | 'system'
sender_role: 'renter' | 'owner' | 'support' | 'customer' | 'system' | 'admin'
sender_name: string
sender_avatar: string
is_self: boolean
+27 -2
View File
@@ -204,12 +204,17 @@ function roleLabel(role: string) {
support: '客服',
customer: '咨询',
system: '系统',
admin: '管理员',
}
return map[role] || '成员'
}
function senderLabel(message: ChatMessage) {
if (message.sender_type === 'system') return '系统'
// 管理员消息特殊标识
if (message.sender_role === 'admin') {
return `管理员 · ${message.sender_name}`
}
return `${roleLabel(message.sender_role)} · ${message.sender_name}`
}
@@ -255,7 +260,11 @@ function handleKeydown(e: KeyboardEvent) {
v-for="item in messages"
:key="item.id"
class="message-row"
:class="{ self: item.is_self, system: item.sender_type === 'system' }"
:class="{
self: item.is_self,
system: item.sender_type === 'system',
admin: item.sender_role === 'admin' && !item.is_self
}"
>
<template v-if="item.sender_type === 'system'">
<span class="system-message">{{ item.content }}</span>
@@ -263,7 +272,9 @@ function handleKeydown(e: KeyboardEvent) {
<template v-else>
<div class="avatar" :class="{ self: item.is_self }">{{ roleLabel(item.sender_role).slice(0, 1) }}</div>
<div class="bubble-wrap" :class="{ self: item.is_self }">
<span class="sender-name">{{ senderLabel(item) }}</span>
<span class="sender-name" :class="{ 'admin-label': item.sender_role === 'admin' && !item.is_self }">
{{ senderLabel(item) }}
</span>
<div v-if="item.content" class="bubble">{{ item.content }}</div>
<div v-if="item.attachment_urls.length > 0" class="message-attachments">
<ChatAttachmentImage
@@ -469,6 +480,20 @@ function handleKeydown(e: KeyboardEvent) {
color: #0f5132;
}
.message-row.admin .bubble {
background: #fff4e6;
border-left: 3px solid #ff9800;
}
.message-row.admin .avatar {
background: #ff9800;
}
.admin-label {
color: #ff9800;
font-weight: 600;
}
.message-attachments {
display: grid;
gap: 6px;
@@ -196,12 +196,17 @@ function roleLabel(role: string) {
support: '客服',
customer: '咨询',
system: '系统',
admin: '管理员',
}
return map[role] || '成员'
}
function senderLabel(message: ChatMessage) {
if (message.sender_type === 'system') return '系统'
// 管理员消息特殊标识
if (message.sender_role === 'admin') {
return `管理员 · ${message.sender_name}`
}
return `${roleLabel(message.sender_role)} · ${message.sender_name}`
}
</script>
@@ -228,7 +233,11 @@ function senderLabel(message: ChatMessage) {
v-for="item in messages"
:key="item.id"
class="message-row"
:class="{ self: item.is_self, system: item.sender_type === 'system' }"
:class="{
self: item.is_self,
system: item.sender_type === 'system',
admin: item.sender_role === 'admin' && !item.is_self
}"
>
<template v-if="item.sender_type === 'system'">
<span class="system-message">{{ item.content }}</span>
@@ -236,7 +245,9 @@ function senderLabel(message: ChatMessage) {
<template v-else>
<div class="avatar">{{ roleLabel(item.sender_role).slice(0, 1) }}</div>
<div class="bubble-wrap">
<span class="sender-name">{{ senderLabel(item) }}</span>
<span class="sender-name" :class="{ 'admin-label': item.sender_role === 'admin' && !item.is_self }">
{{ senderLabel(item) }}
</span>
<div v-if="item.content" class="bubble">{{ item.content }}</div>
<div v-if="item.attachment_urls.length > 0" class="message-attachments">
<ChatAttachmentImage
@@ -421,6 +432,20 @@ function senderLabel(message: ChatMessage) {
background: #dff5eb;
}
.message-row.admin .bubble {
background: #fff4e6;
border-left: 3px solid #ff9800;
}
.message-row.admin .avatar {
background: #ff9800;
}
.admin-label {
color: #ff9800;
font-weight: 600;
}
.message-attachments {
display: grid;
gap: 6px;