mirror of
https://github.com/hicccc77/WeFlow.git
synced 2026-03-24 23:06:51 +00:00
fix: 修复聊天记录页面崩溃问题并添加错误边界保护
This commit is contained in:
41
src/components/ErrorBoundary.tsx
Normal file
41
src/components/ErrorBoundary.tsx
Normal file
@@ -0,0 +1,41 @@
|
||||
import { Component, ReactNode } from 'react'
|
||||
|
||||
interface Props {
|
||||
children: ReactNode
|
||||
fallback?: ReactNode
|
||||
}
|
||||
|
||||
interface State {
|
||||
hasError: boolean
|
||||
error?: Error
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends Component<Props, State> {
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
this.state = { hasError: false }
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error): State {
|
||||
return { hasError: true, error }
|
||||
}
|
||||
|
||||
componentDidCatch(error: Error, errorInfo: any) {
|
||||
console.error('ErrorBoundary caught:', error, errorInfo)
|
||||
}
|
||||
|
||||
render() {
|
||||
if (this.state.hasError) {
|
||||
return this.props.fallback || (
|
||||
<div style={{ padding: '20px', textAlign: 'center', color: '#999' }}>
|
||||
<p>消息渲染出错</p>
|
||||
<p style={{ fontSize: '12px', marginTop: '8px' }}>
|
||||
{this.state.error?.message || '未知错误'}
|
||||
</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return this.props.children
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,16 @@
|
||||
gap: 12px;
|
||||
align-items: flex-start;
|
||||
|
||||
&.error-item {
|
||||
padding: 12px;
|
||||
background: var(--bg-secondary);
|
||||
border-radius: 8px;
|
||||
color: var(--text-tertiary);
|
||||
font-size: 13px;
|
||||
text-align: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.avatar {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
@@ -2,6 +2,7 @@ import { useEffect, useState } from 'react'
|
||||
import { useParams, useLocation } from 'react-router-dom'
|
||||
import { ChatRecordItem } from '../types/models'
|
||||
import TitleBar from '../components/TitleBar'
|
||||
import { ErrorBoundary } from '../components/ErrorBoundary'
|
||||
import './ChatHistoryPage.scss'
|
||||
|
||||
export default function ChatHistoryPage() {
|
||||
@@ -166,7 +167,9 @@ export default function ChatHistoryPage() {
|
||||
<div className="status-msg empty">暂无可显示的聊天记录</div>
|
||||
) : (
|
||||
recordList.map((item, i) => (
|
||||
<HistoryItem key={i} item={item} />
|
||||
<ErrorBoundary key={i} fallback={<div className="history-item error-item">消息解析失败</div>}>
|
||||
<HistoryItem item={item} />
|
||||
</ErrorBoundary>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
@@ -175,6 +178,8 @@ export default function ChatHistoryPage() {
|
||||
}
|
||||
|
||||
function HistoryItem({ item }: { item: ChatRecordItem }) {
|
||||
const [imageError, setImageError] = useState(false)
|
||||
|
||||
// sourcetime 在合并转发里有两种格式:
|
||||
// 1) 时间戳(秒) 2) 已格式化的字符串 "2026-01-21 09:56:46"
|
||||
let time = ''
|
||||
@@ -197,19 +202,16 @@ function HistoryItem({ item }: { item: ChatRecordItem }) {
|
||||
if (src) {
|
||||
return (
|
||||
<div className="media-content">
|
||||
{imageError ? (
|
||||
<div className="media-tip">图片无法加载</div>
|
||||
) : (
|
||||
<img
|
||||
src={src}
|
||||
alt="图片"
|
||||
referrerPolicy="no-referrer"
|
||||
onError={(e) => {
|
||||
const target = e.target as HTMLImageElement
|
||||
target.style.display = 'none'
|
||||
const placeholder = document.createElement('div')
|
||||
placeholder.className = 'media-tip'
|
||||
placeholder.textContent = '图片无法加载'
|
||||
target.parentElement?.appendChild(placeholder)
|
||||
}}
|
||||
onError={() => setImageError(true)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user