|
1 | 1 | <template>
|
2 | 2 | <div ref="messageContainer" class="h-100% overflow-y-auto relative">
|
3 |
| - <div class="chat-list" v-for="(item, index) in list" :key="index"> |
| 3 | + <div class="flex flex-col overflow-y-hidden px-20px" v-for="(item, index) in list" :key="index"> |
4 | 4 | <!-- 靠左 message:system、assistant 类型 -->
|
5 |
| - <div class="left-message message-item" v-if="item.type !== 'user'"> |
| 5 | + <div class="flex flex-row mt-50px" v-if="item.type !== 'user'"> |
6 | 6 | <div class="avatar">
|
7 | 7 | <el-avatar :src="roleAvatar" />
|
8 | 8 | </div>
|
9 |
| - <div class="message"> |
| 9 | + <div class="flex flex-col text-left mx-15px"> |
10 | 10 | <div>
|
11 |
| - <el-text class="time">{{ formatDate(item.createTime) }}</el-text> |
| 11 | + <el-text class="text-left leading-30px">{{ formatDate(item.createTime) }}</el-text> |
12 | 12 | </div>
|
13 |
| - <div class="left-text-container" ref="markdownViewRef"> |
14 |
| - <MarkdownView class="left-text" :content="item.content" /> |
| 13 | + <div class="relative flex flex-col break-words bg-[var(--el-fill-color-light)] shadow-[0_0_0_1px_var(--el-border-color-light)] rounded-10px pt-10px px-10px pb-5px" ref="markdownViewRef"> |
| 14 | + <MarkdownView class="text-[var(--el-text-color-primary)] text-[0.95rem]" :content="item.content" /> |
15 | 15 | <MessageKnowledge v-if="item.segments" :segments="item.segments" />
|
16 | 16 | </div>
|
17 |
| - <div class="left-btns"> |
18 |
| - <el-button class="btn-cus" link @click="copyContent(item.content)"> |
19 |
| - <img class="btn-image" src="@/assets/ai/copy.svg" /> |
| 17 | + <div class="flex flex-row mt-8px"> |
| 18 | + <el-button class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="copyContent(item.content)"> |
| 19 | + <img class="h-20px" src="@/assets/ai/copy.svg" /> |
20 | 20 | </el-button>
|
21 |
| - <el-button v-if="item.id > 0" class="btn-cus" link @click="onDelete(item.id)"> |
22 |
| - <img class="btn-image h-17px" src="@/assets/ai/delete.svg" /> |
| 21 | + <el-button v-if="item.id > 0" class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="onDelete(item.id)"> |
| 22 | + <img class="h-17px" src="@/assets/ai/delete.svg" /> |
23 | 23 | </el-button>
|
24 | 24 | </div>
|
25 | 25 | </div>
|
26 | 26 | </div>
|
27 | 27 | <!-- 靠右 message:user 类型 -->
|
28 |
| - <div class="right-message message-item" v-if="item.type === 'user'"> |
| 28 | + <div class="flex flex-row-reverse justify-start mt-50px" v-if="item.type === 'user'"> |
29 | 29 | <div class="avatar">
|
30 | 30 | <el-avatar :src="userAvatar" />
|
31 | 31 | </div>
|
32 |
| - <div class="message"> |
| 32 | + <div class="flex flex-col text-left mx-15px"> |
33 | 33 | <div>
|
34 |
| - <el-text class="time">{{ formatDate(item.createTime) }}</el-text> |
| 34 | + <el-text class="text-left leading-30px">{{ formatDate(item.createTime) }}</el-text> |
35 | 35 | </div>
|
36 |
| - <div class="right-text-container"> |
37 |
| - <div class="right-text">{{ item.content }}</div> |
| 36 | + <div class="flex flex-row-reverse"> |
| 37 | + <div class="text-[0.95rem] text-[var(--el-color-white)] inline bg-[var(--el-color-primary)] shadow-[0_0_0_1px_var(--el-color-primary)] rounded-10px p-10px w-auto break-words whitespace-pre-wrap">{{ item.content }}</div> |
38 | 38 | </div>
|
39 |
| - <div class="right-btns"> |
40 |
| - <el-button class="btn-cus" link @click="copyContent(item.content)"> |
41 |
| - <img class="btn-image" src="@/assets/ai/copy.svg" /> |
| 39 | + <div class="flex flex-row-reverse mt-8px"> |
| 40 | + <el-button class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="copyContent(item.content)"> |
| 41 | + <img class="h-20px" src="@/assets/ai/copy.svg" /> |
42 | 42 | </el-button>
|
43 |
| - <el-button class="btn-cus" link @click="onDelete(item.id)"> |
44 |
| - <img class="btn-image h-17px mr-12px" src="@/assets/ai/delete.svg" /> |
| 43 | + <el-button class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="onDelete(item.id)"> |
| 44 | + <img class="h-17px mr-12px" src="@/assets/ai/delete.svg" /> |
45 | 45 | </el-button>
|
46 |
| - <el-button class="btn-cus" link @click="onRefresh(item)"> |
| 46 | + <el-button class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="onRefresh(item)"> |
47 | 47 | <el-icon size="17"><RefreshRight /></el-icon>
|
48 | 48 | </el-button>
|
49 |
| - <el-button class="btn-cus" link @click="onEdit(item)"> |
| 49 | + <el-button class="flex bg-transparent items-center hover:cursor-pointer hover:bg-[var(--el-fill-color-lighter)]" link @click="onEdit(item)"> |
50 | 50 | <el-icon size="17"><Edit /></el-icon>
|
51 | 51 | </el-button>
|
52 | 52 | </div>
|
|
55 | 55 | </div>
|
56 | 56 | </div>
|
57 | 57 | <!-- 回到底部 -->
|
58 |
| - <div v-if="isScrolling" class="to-bottom" @click="handleGoBottom"> |
| 58 | + <div v-if="isScrolling" class="absolute z-1000 bottom-0 right-50%" @click="handleGoBottom"> |
59 | 59 | <el-button :icon="ArrowDownBold" circle />
|
60 | 60 | </div>
|
61 | 61 | </template>
|
@@ -142,7 +142,7 @@ defineExpose({ scrollToBottom, handlerGoTop }) // 提供方法给 parent 调用
|
142 | 142 | // ============ 处理消息操作 ==============
|
143 | 143 |
|
144 | 144 | /** 复制 */
|
145 |
| -const copyContent = async (content) => { |
| 145 | +const copyContent = async (content: string) => { |
146 | 146 | await copy(content)
|
147 | 147 | message.success('复制成功!')
|
148 | 148 | }
|
@@ -172,113 +172,4 @@ onMounted(async () => {
|
172 | 172 | })
|
173 | 173 | </script>
|
174 | 174 |
|
175 |
| -<style scoped lang="scss"> |
176 |
| -.message-container { |
177 |
| - position: relative; |
178 |
| - overflow-y: scroll; |
179 |
| -} |
180 |
| -
|
181 |
| -// 中间 |
182 |
| -.chat-list { |
183 |
| - display: flex; |
184 |
| - flex-direction: column; |
185 |
| - overflow-y: hidden; |
186 |
| - padding: 0 20px; |
187 |
| - .message-item { |
188 |
| - margin-top: 50px; |
189 |
| - } |
190 |
| -
|
191 |
| - .left-message { |
192 |
| - display: flex; |
193 |
| - flex-direction: row; |
194 |
| - } |
195 |
| -
|
196 |
| - .right-message { |
197 |
| - display: flex; |
198 |
| - flex-direction: row-reverse; |
199 |
| - justify-content: flex-start; |
200 |
| - } |
201 |
| -
|
202 |
| - .message { |
203 |
| - display: flex; |
204 |
| - flex-direction: column; |
205 |
| - text-align: left; |
206 |
| - margin: 0 15px; |
207 |
| -
|
208 |
| - .time { |
209 |
| - text-align: left; |
210 |
| - line-height: 30px; |
211 |
| - } |
212 |
| -
|
213 |
| - .left-text-container { |
214 |
| - position: relative; |
215 |
| - display: flex; |
216 |
| - flex-direction: column; |
217 |
| - overflow-wrap: break-word; |
218 |
| - background-color: var(--el-fill-color-light); |
219 |
| - box-shadow: 0 0 0 1px var(--el-border-color-light); |
220 |
| - border-radius: 10px; |
221 |
| - padding: 10px 10px 5px 10px; |
222 |
| -
|
223 |
| - .left-text { |
224 |
| - color: var(--el-text-color-primary); |
225 |
| - font-size: 0.95rem; |
226 |
| - } |
227 |
| - } |
228 |
| -
|
229 |
| - .right-text-container { |
230 |
| - display: flex; |
231 |
| - flex-direction: row-reverse; |
232 | 175 |
|
233 |
| - .right-text { |
234 |
| - font-size: 0.95rem; |
235 |
| - color: var(--el-color-white); |
236 |
| - display: inline; |
237 |
| - background-color: var(--el-color-primary); |
238 |
| - box-shadow: 0 0 0 1px var(--el-color-primary); |
239 |
| - border-radius: 10px; |
240 |
| - padding: 10px; |
241 |
| - width: auto; |
242 |
| - overflow-wrap: break-word; |
243 |
| - white-space: pre-wrap; |
244 |
| - } |
245 |
| - } |
246 |
| -
|
247 |
| - .left-btns { |
248 |
| - display: flex; |
249 |
| - flex-direction: row; |
250 |
| - margin-top: 8px; |
251 |
| - } |
252 |
| -
|
253 |
| - .right-btns { |
254 |
| - display: flex; |
255 |
| - flex-direction: row-reverse; |
256 |
| - margin-top: 8px; |
257 |
| - } |
258 |
| - } |
259 |
| -
|
260 |
| - // 复制、删除按钮 |
261 |
| - .btn-cus { |
262 |
| - display: flex; |
263 |
| - background-color: transparent; |
264 |
| - align-items: center; |
265 |
| -
|
266 |
| - .btn-image { |
267 |
| - height: 20px; |
268 |
| - } |
269 |
| - } |
270 |
| -
|
271 |
| - .btn-cus:hover { |
272 |
| - cursor: pointer; |
273 |
| - background-color: var(--el-fill-color-lighter); |
274 |
| - } |
275 |
| -} |
276 |
| -
|
277 |
| -// 回到底部 |
278 |
| -.to-bottom { |
279 |
| - position: absolute; |
280 |
| - z-index: 1000; |
281 |
| - bottom: 0; |
282 |
| - right: 50%; |
283 |
| -} |
284 |
| -</style> |
0 commit comments