Просмотр исходного кода

🐛 fix(home): prevent empty notice modal from auto-showing

Previously, the notice modal would automatically show every day even when
the notice content was empty, causing unnecessary user interruption.

This commit modifies the logic to:
- Check notice content before showing the modal
- Only display the modal when notice content exists and is not empty
- Add proper error handling to prevent modal showing on API failures
- Improve user experience by avoiding empty notice interruptions

Changes:
- Modified useEffect in Home component to fetch notice content first
- Added API call to /api/notice before setting noticeVisible state
- Added try-catch block for graceful error handling
- Only show modal when notice data is truthy and non-empty after trimming
Apple\Apple 9 месяцев назад
Родитель
Сommit
0d724af6e3
2 измененных файлов с 91 добавлено и 79 удалено
  1. 74 74
      web/src/components/layout/NoticeModal.js
  2. 17 5
      web/src/pages/Home/index.js

+ 74 - 74
web/src/components/layout/NoticeModal.js

@@ -6,89 +6,89 @@ import { marked } from 'marked';
 import { IllustrationNoContent, IllustrationNoContentDark } from '@douyinfe/semi-illustrations';
 
 const NoticeModal = ({ visible, onClose, isMobile }) => {
-    const { t } = useTranslation();
-    const [noticeContent, setNoticeContent] = useState('');
-    const [loading, setLoading] = useState(false);
+  const { t } = useTranslation();
+  const [noticeContent, setNoticeContent] = useState('');
+  const [loading, setLoading] = useState(false);
 
-    const handleCloseTodayNotice = () => {
-        const today = new Date().toDateString();
-        localStorage.setItem('notice_close_date', today);
-        onClose();
-    };
+  const handleCloseTodayNotice = () => {
+    const today = new Date().toDateString();
+    localStorage.setItem('notice_close_date', today);
+    onClose();
+  };
 
-    const displayNotice = async () => {
-        setLoading(true);
-        try {
-            const res = await API.get('/api/notice');
-            const { success, message, data } = res.data;
-            if (success) {
-                if (data !== '') {
-                    const htmlNotice = marked.parse(data);
-                    setNoticeContent(htmlNotice);
-                } else {
-                    setNoticeContent('');
-                }
-            } else {
-                showError(message);
-            }
-        } catch (error) {
-            showError(error.message);
-        } finally {
-            setLoading(false);
+  const displayNotice = async () => {
+    setLoading(true);
+    try {
+      const res = await API.get('/api/notice');
+      const { success, message, data } = res.data;
+      if (success) {
+        if (data !== '') {
+          const htmlNotice = marked.parse(data);
+          setNoticeContent(htmlNotice);
+        } else {
+          setNoticeContent('');
         }
-    };
+      } else {
+        showError(message);
+      }
+    } catch (error) {
+      showError(error.message);
+    } finally {
+      setLoading(false);
+    }
+  };
 
-    useEffect(() => {
-        if (visible) {
-            displayNotice();
-        }
-    }, [visible]);
+  useEffect(() => {
+    if (visible) {
+      displayNotice();
+    }
+  }, [visible]);
 
-    const renderContent = () => {
-        if (loading) {
-            return <div className="py-12"><Empty description={t('加载中...')} /></div>;
-        }
+  const renderContent = () => {
+    if (loading) {
+      return <div className="py-12"><Empty description={t('加载中...')} /></div>;
+    }
 
-        if (!noticeContent) {
-            return (
-                <div className="py-12">
-                    <Empty
-                        image={<IllustrationNoContent style={{ width: 150, height: 150 }} />}
-                        darkModeImage={<IllustrationNoContentDark style={{ width: 150, height: 150 }} />}
-                        description={t('暂无公告')}
-                    />
-                </div>
-            );
-        }
-
-        return (
-            <div
-                dangerouslySetInnerHTML={{ __html: noticeContent }}
-                className="max-h-[60vh] overflow-y-auto pr-2"
-                style={{
-                    scrollbarWidth: 'thin',
-                    scrollbarColor: 'var(--semi-color-tertiary) transparent'
-                }}
-            />
-        );
-    };
+    if (!noticeContent) {
+      return (
+        <div className="py-12">
+          <Empty
+            image={<IllustrationNoContent style={{ width: 150, height: 150 }} />}
+            darkModeImage={<IllustrationNoContentDark style={{ width: 150, height: 150 }} />}
+            description={t('暂无公告')}
+          />
+        </div>
+      );
+    }
 
     return (
-        <Modal
-            title={t('系统公告')}
-            visible={visible}
-            onCancel={onClose}
-            footer={(
-                <div className="flex justify-end">
-                    <Button type='secondary' className='!rounded-full' onClick={handleCloseTodayNotice}>{t('今日关闭')}</Button>
-                    <Button type="primary" className='!rounded-full' onClick={onClose}>{t('关闭公告')}</Button>
-                </div>
-            )}
-            size={isMobile ? 'full-width' : 'large'}
-        >
-            {renderContent()}
-        </Modal>
+      <div
+        dangerouslySetInnerHTML={{ __html: noticeContent }}
+        className="max-h-[60vh] overflow-y-auto pr-2"
+        style={{
+          scrollbarWidth: 'thin',
+          scrollbarColor: 'var(--semi-color-tertiary) transparent'
+        }}
+      />
     );
+  };
+
+  return (
+    <Modal
+      title={t('系统公告')}
+      visible={visible}
+      onCancel={onClose}
+      footer={(
+        <div className="flex justify-end">
+          <Button type='secondary' className='!rounded-full' onClick={handleCloseTodayNotice}>{t('今日关闭')}</Button>
+          <Button type="primary" className='!rounded-full' onClick={onClose}>{t('关闭公告')}</Button>
+        </div>
+      )}
+      size={isMobile ? 'full-width' : 'large'}
+    >
+      {renderContent()}
+    </Modal>
+  );
 };
 
 export default NoticeModal; 

+ 17 - 5
web/src/pages/Home/index.js

@@ -22,11 +22,23 @@ const Home = () => {
   const isDemoSiteMode = statusState?.status?.demo_site_enabled || false;
 
   useEffect(() => {
-    const lastCloseDate = localStorage.getItem('notice_close_date');
-    const today = new Date().toDateString();
-    if (lastCloseDate !== today) {
-      setNoticeVisible(true);
-    }
+    const checkNoticeAndShow = async () => {
+      const lastCloseDate = localStorage.getItem('notice_close_date');
+      const today = new Date().toDateString();
+      if (lastCloseDate !== today) {
+        try {
+          const res = await API.get('/api/notice');
+          const { success, data } = res.data;
+          if (success && data && data.trim() !== '') {
+            setNoticeVisible(true);
+          }
+        } catch (error) {
+          console.error('获取公告失败:', error);
+        }
+      }
+    };
+
+    checkNoticeAndShow();
   }, []);
 
   const displayHomePageContent = async () => {