feat: 添加加载动画,优化table展示

This commit is contained in:
yangzhe 2025-07-15 14:39:22 +08:00
parent 5851a70aae
commit 4b4f65845f
2 changed files with 256 additions and 1 deletions

View File

@ -41,6 +41,21 @@ renderer.link = function(href, title, text) {
return `<a href="${href}" title="${title || ''}" style="display:inline !important;white-space:normal !important;word-break:break-all !important;letter-spacing:normal !important;word-spacing:normal !important;text-align:left !important;">${text}</a>`;
};
// 使
renderer.table = function(header, body) {
return `<div class="table-container"><table class="custom-table">
<thead>${header}</thead>
<tbody>${body}</tbody>
</table></div>`;
};
//
renderer.tablecell = function(content, flags) {
const type = flags.header ? 'th' : 'td';
const align = flags.align ? ` style="text-align:${flags.align}"` : '';
return `<${type}${align}>${content}</${type}>`;
};
// marked
marked.use({
renderer: renderer,
@ -164,6 +179,22 @@ export default {
color: inherit !important; /* 确保颜色正确继承 */
}
/* 专门修复mp-html组件生成的列表结构 */
div[data-v-7e5387f] {
display: inline !important;
}
/* 处理列表编号所在的容器 - 重要修复 */
div[data-v-7e5387f] {
display: inline !important;
white-space: nowrap !important; /* 防止编号和首个字符分开 */
}
/* 首行缩进优化(确保列表项不会被意外截断) */
div div {
display: inline !important;
}
/* 有序列表样式 */
.custom-ordered-list, ol {
display: block !important;
@ -183,6 +214,19 @@ export default {
list-style-type: none !important;
}
/* 针对mp-html生成的列表标记容器 */
div[style*="undefined"] {
display: inline !important;
white-space: nowrap !important;
}
/* 对列表项第一个元素特殊处理 */
h4 {
display: inline !important;
margin: 0 !important;
padding: 0 !important;
}
/* 列表项共用样式 */
.custom-list-item, ol li, ul li {
display: flex !important;
@ -308,6 +352,13 @@ export default {
// HTML
let processedHtml = htmlContent;
//
processedHtml = processedHtml.replace(/<table([^>]*)>/g, (match, attrs) => {
return `<div class="table-container"><table${attrs || ''} class="custom-table">`;
});
processedHtml = processedHtml.replace(/<\/table>/g, '</table></div>');
// div
processedHtml = processedHtml.replace(/<p([^>]*)>(.*?)<\/p>/gs, (match, attrs, content) => {
//
@ -361,6 +412,27 @@ export default {
word-spacing: normal !important; /* 正常词间距 */
text-align: left !important; /* 左对齐 */
}
/* 表格样式 */
table {
border-collapse: collapse !important;
width: 100% !important;
margin: 16rpx 0 !important;
table-layout: fixed !important;
border: 1px solid #e0e0e0 !important;
overflow-x: auto !important;
}
th, td {
border: 1px solid #e0e0e0 !important;
padding: 12rpx !important;
text-align: left !important;
word-break: break-word !important;
white-space: normal !important;
font-size: 28rpx !important;
}
th {
background-color: #f5f5f5 !important;
font-weight: bold !important;
}
/* 禁用所有可能导致文本被拉伸的样式 */
* {
text-align-last: left !important;
@ -471,6 +543,22 @@ export default {
text-decoration: none !important;
}
/* 专门修复mp-html组件生成的列表结构 */
.markdown-container >>> div[data-v-7e5387f] {
display: inline !important;
}
/* 处理列表编号所在的容器 - 重要修复 */
.markdown-container >>> div[data-v-7e5387f] {
display: inline !important;
white-space: nowrap !important; /* 防止编号和首个字符分开 */
}
/* 首行缩进优化(确保列表项不会被意外截断) */
.markdown-container >>> div div {
display: inline !important;
}
/* 有序列表样式 */
.markdown-container >>> .custom-ordered-list,
.markdown-container >>> ol {
@ -492,6 +580,19 @@ export default {
list-style-type: none !important;
}
/* 针对mp-html生成的列表标记容器 */
.markdown-container >>> div[style*="undefined"] {
display: inline !important;
white-space: nowrap !important;
}
/* 对列表项第一个元素特殊处理 */
.markdown-container >>> h4 {
display: inline !important;
margin: 0 !important;
padding: 0 !important;
}
/* 列表项共用样式 */
.markdown-container >>> .custom-list-item,
.markdown-container >>> ol li,
@ -586,4 +687,64 @@ export default {
overflow-wrap: break-word !important;
max-width: 100% !important;
}
/* 表格样式 */
.markdown-container >>> table {
border-collapse: collapse !important;
width: 100% !important;
margin: 0 !important;
table-layout: fixed !important;
border: 1px solid #e0e0e0 !important;
font-size: 24rpx !important; /* 稍微减小字体大小,适应移动端 */
}
.markdown-container >>> table th,
.markdown-container >>> table td {
border: 1px solid #e0e0e0 !important;
padding: 8rpx 10rpx !important; /* 减小内边距 */
text-align: left !important;
word-break: break-word !important;
white-space: normal !important;
vertical-align: middle !important;
min-width: 80rpx !important; /* 设置最小宽度 */
}
.markdown-container >>> table th {
background-color: #f5f5f5 !important;
font-weight: bold !important;
color: #333333 !important;
}
.markdown-container >>> table tr:nth-child(even) {
background-color: #fafafa !important;
}
.markdown-container >>> table tr:hover {
background-color: #f0f0f0 !important;
}
/* 表格容器,使表格可以水平滚动 */
.markdown-container >>> .table-container {
width: 100% !important;
overflow-x: auto !important;
margin: 16rpx 0 !important;
-webkit-overflow-scrolling: touch !important; /* 为iOS设备提供平滑滚动 */
position: relative !important;
display: block !important;
}
/* 自定义表格类 */
.markdown-container >>> .custom-table {
min-width: 100% !important;
border-spacing: 0 !important;
}
/* 表格标题 */
.markdown-container >>> table caption {
font-weight: bold !important;
padding: 10rpx !important;
caption-side: top !important;
text-align: center !important;
color: #333333 !important;
}
</style>

View File

@ -161,7 +161,14 @@
mode="scaleToFill"
/>
<view class="message-content">
<markdown-viewer :content="message.message" />
<!-- 加载动画 -->
<view v-if="message.isLoading" class="loading-dots">
<view class="dot"></view>
<view class="dot"></view>
<view class="dot"></view>
</view>
<!-- 正常消息内容 -->
<markdown-viewer v-else :content="message.message" />
</view>
</view>
</block>
@ -495,6 +502,23 @@ export default {
//
this.messageGroups.push(userMessage);
this.messageValue = "";
// AI
const loadingMessage = {
id: "loading_" + Math.random().toString(36).substring(2, 15),
message: "",
sendDate: "",
isSend: true,
isRead: false,
interactMode: 1, // AI
messageType: 0,
timeLabel: 0,
displayTime: "",
isLoading: true //
};
//
this.messageGroups.push(loadingMessage);
this.$u.api
.SendMessageApi({
@ -507,6 +531,9 @@ export default {
this.currentConversationId = data.conversationId;
//
this.messageGroups = this.messageGroups.filter(msg => !msg.isLoading);
// AI
const aiMessage = {
id:
@ -524,6 +551,27 @@ export default {
//
this.messageGroups.push(aiMessage);
})
.catch((error) => {
console.error("API请求失败:", error);
//
this.messageGroups = this.messageGroups.filter(msg => !msg.isLoading);
//
const errorMessage = {
id: "error_" + Math.random().toString(36).substring(2, 15),
message: "请求失败,请稍后重试",
sendDate: "",
isSend: true,
isRead: false,
interactMode: 1, // AI
messageType: 0,
timeLabel: 0,
displayTime: "",
};
this.messageGroups.push(errorMessage);
});
},
@ -997,6 +1045,52 @@ export default {
font-size: 28rpx;
line-height: 1.5;
/* 加载动画样式 */
.loading-dots {
display: flex;
align-items: center;
justify-content: flex-start;
.dot {
display: inline-block;
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background-color: #cccccc;
margin: 0 6rpx;
opacity: 0.6;
animation: dot-flashing 1.5s infinite linear alternate;
&:nth-child(1) {
animation-delay: 0s;
}
&:nth-child(2) {
animation-delay: 0.5s;
}
&:nth-child(3) {
animation-delay: 1s;
}
}
@keyframes dot-flashing {
0% {
opacity: 0.6;
transform: scale(1);
}
50% {
opacity: 1;
transform: scale(1.2);
background-color: #4370fe;
}
100% {
opacity: 0.6;
transform: scale(1);
}
}
}
/* Markdown内容样式调整 */
/deep/ .markdown-container {
padding: 0;