|
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