|
@@ -1,5 +1,5 @@
|
|
|
import React, { useEffect, useState } from 'react';
|
|
import React, { useEffect, useState } from 'react';
|
|
|
-import { CloseOutlined } from '@ant-design/icons';
|
|
|
|
|
|
|
+import { CloseOutlined, ExclamationCircleOutlined } from '@ant-design/icons';
|
|
|
import ReactMarkdown from 'react-markdown';
|
|
import ReactMarkdown from 'react-markdown';
|
|
|
import rehypeRaw from 'rehype-raw';
|
|
import rehypeRaw from 'rehype-raw';
|
|
|
import { shouldShowUpdate, isUpdateNotificationDisabled, getCurrentVersion, getVersionHistory } from './version';
|
|
import { shouldShowUpdate, isUpdateNotificationDisabled, getCurrentVersion, getVersionHistory } from './version';
|
|
@@ -29,17 +29,30 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({ version }) => {
|
|
|
// 立即保存版本号,防止退出登录或刷新后重复显示
|
|
// 立即保存版本号,防止退出登录或刷新后重复显示
|
|
|
localStorage.setItem('lastViewedUpdateVersion', version);
|
|
localStorage.setItem('lastViewedUpdateVersion', version);
|
|
|
|
|
|
|
|
- // 加载更新内容
|
|
|
|
|
- import('./update.md?raw')
|
|
|
|
|
|
|
+ // 加载更新内容 - 从历史记录中提取最新版本
|
|
|
|
|
+ import('../../docs/update-history/index.md?raw')
|
|
|
.then((module) => {
|
|
.then((module) => {
|
|
|
- setContent(module.default);
|
|
|
|
|
|
|
+ const fullContent = module.default;
|
|
|
|
|
+ // 提取第一个版本的内容(从第一个 ## 📅 到下一个 --- 之间的内容)
|
|
|
|
|
+ const versionRegex = /##\s+📅.*?\n\n([\s\S]*?)(?=\n---)/;
|
|
|
|
|
+ const match = fullContent.match(versionRegex);
|
|
|
|
|
+
|
|
|
|
|
+ if (match && match[1]) {
|
|
|
|
|
+ // 只取内容部分,不包括版本标题
|
|
|
|
|
+ setContent(match[1].trim());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 如果匹配失败,显示整个文档
|
|
|
|
|
+ console.warn('无法提取最新版本内容,显示完整文档');
|
|
|
|
|
+ setContent(fullContent);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
setTimeout(() => {
|
|
setTimeout(() => {
|
|
|
setVisible(true);
|
|
setVisible(true);
|
|
|
setIsAnimating(true);
|
|
setIsAnimating(true);
|
|
|
}, 800);
|
|
}, 800);
|
|
|
})
|
|
})
|
|
|
- .catch(() => {
|
|
|
|
|
- console.error('Failed to load update content');
|
|
|
|
|
|
|
+ .catch((error) => {
|
|
|
|
|
+ console.error('Failed to load update content:', error);
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
}, [version]);
|
|
}, [version]);
|
|
@@ -84,32 +97,18 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({ version }) => {
|
|
|
<ReactMarkdown
|
|
<ReactMarkdown
|
|
|
rehypePlugins={[rehypeRaw]}
|
|
rehypePlugins={[rehypeRaw]}
|
|
|
components={{
|
|
components={{
|
|
|
- h1: (props) => <h2 style={{ fontSize: '16px', marginTop: 0, marginBottom: '16px' }} {...props} />,
|
|
|
|
|
- h2: (props) => <h2 {...props} />,
|
|
|
|
|
h3: (props) => <h3 {...props} />,
|
|
h3: (props) => <h3 {...props} />,
|
|
|
- h4: (props) => <h4 {...props} />,
|
|
|
|
|
- p: (props) => <p style={{ fontSize: '14px', lineHeight: '1.8', margin: '8px 0' }} {...props} />,
|
|
|
|
|
- ul: (props) => <ul {...props} />,
|
|
|
|
|
- li: (props) => <li style={{ fontSize: '14px' }} {...props} />,
|
|
|
|
|
- strong: (props) => <strong {...props} />,
|
|
|
|
|
- code: (props) => (
|
|
|
|
|
- <code style={{
|
|
|
|
|
- background: '#f6f7f9',
|
|
|
|
|
- padding: '2px 6px',
|
|
|
|
|
- borderRadius: 3,
|
|
|
|
|
- fontSize: '13px',
|
|
|
|
|
- color: '#c7254e'
|
|
|
|
|
- }} {...props} />
|
|
|
|
|
|
|
+ h4: (props: React.HTMLAttributes<HTMLHeadingElement> & { className?: string }) => (
|
|
|
|
|
+ <h4 className={props.className} {...props} />
|
|
|
),
|
|
),
|
|
|
|
|
+ p: (props) => <p {...props} />,
|
|
|
div: (props: React.HTMLAttributes<HTMLDivElement> & { className?: string }) => {
|
|
div: (props: React.HTMLAttributes<HTMLDivElement> & { className?: string }) => {
|
|
|
- // 支持自定义 class 的 div
|
|
|
|
|
if (props.className === 'update-item') {
|
|
if (props.className === 'update-item') {
|
|
|
return <div className="update-item" {...props} />;
|
|
return <div className="update-item" {...props} />;
|
|
|
}
|
|
}
|
|
|
return <div {...props} />;
|
|
return <div {...props} />;
|
|
|
},
|
|
},
|
|
|
img: (props: React.ImgHTMLAttributes<HTMLImageElement> & { src?: string; alt?: string }) => {
|
|
img: (props: React.ImgHTMLAttributes<HTMLImageElement> & { src?: string; alt?: string }) => {
|
|
|
- // 处理图片路径,确保从 public 目录正确加载
|
|
|
|
|
const src = props.src?.startsWith('/') ? props.src : `/${props.src || ''}`;
|
|
const src = props.src?.startsWith('/') ? props.src : `/${props.src || ''}`;
|
|
|
return (
|
|
return (
|
|
|
<img
|
|
<img
|
|
@@ -127,17 +126,17 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({ version }) => {
|
|
|
</ReactMarkdown>
|
|
</ReactMarkdown>
|
|
|
</div>
|
|
</div>
|
|
|
<div className="update-notification-footer">
|
|
<div className="update-notification-footer">
|
|
|
- <button
|
|
|
|
|
- className="update-notification-button secondary"
|
|
|
|
|
- onClick={() => {
|
|
|
|
|
- window.open('/help/update-history', '_blank');
|
|
|
|
|
- }}
|
|
|
|
|
- >
|
|
|
|
|
- 查看历史更新
|
|
|
|
|
- </button>
|
|
|
|
|
<button className="update-notification-button" onClick={handleClose}>
|
|
<button className="update-notification-button" onClick={handleClose}>
|
|
|
关闭
|
|
关闭
|
|
|
</button>
|
|
</button>
|
|
|
|
|
+ <div
|
|
|
|
|
+ className="footer-notice"
|
|
|
|
|
+ onClick={() => window.open('/help/update-history', '_blank')}
|
|
|
|
|
+ style={{ cursor: 'pointer' }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <ExclamationCircleOutlined className="info-icon" />
|
|
|
|
|
+ <span className="notice-text">版本公告将在帮助文档中</span>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
@@ -148,4 +147,3 @@ const UpdateNotification: React.FC<UpdateNotificationProps> = ({ version }) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
export default UpdateNotification;
|
|
export default UpdateNotification;
|
|
|
-
|
|
|