Browse Source

增加新热事件来源展示

xueyiming 2 ngày trước cách đây
mục cha
commit
9f7d61a5fe
2 tập tin đã thay đổi với 51 bổ sung8 xóa
  1. 38 8
      frontend/src/HotContentSourcePage.tsx
  2. 13 0
      frontend/src/styles.css

+ 38 - 8
frontend/src/HotContentSourcePage.tsx

@@ -5,6 +5,8 @@ import type { ColumnsType } from "antd/es/table";
 const API_BASE_URL =
   import.meta.env.VITE_API_BASE_URL ?? "/demand/api/v1";
 
+const BODY_PREVIEW_LENGTH = 160;
+
 const getResolvedApiBaseUrl = () => {
   if (API_BASE_URL.startsWith("http://") || API_BASE_URL.startsWith("https://")) {
     return API_BASE_URL;
@@ -154,6 +156,7 @@ export default function HotContentSourcePage({
   const [loading, setLoading] = useState(true);
   const [error, setError] = useState("");
   const [detail, setDetail] = useState<HotContentSourceDetail | null>(null);
+  const [bodyExpanded, setBodyExpanded] = useState(false);
 
   useEffect(() => {
     let cancelled = false;
@@ -256,13 +259,22 @@ export default function HotContentSourcePage({
 
   const record = detail?.record;
   const syncLog = detail?.sync_log;
-  const bodyPreview = useMemo(() => {
-    const text = (record?.article_body ?? "").replace(/\s+/g, " ").trim();
-    if (!text) {
-      return "暂无正文";
-    }
-    return text.length > 160 ? `${text.slice(0, 160)}…` : text;
-  }, [record?.article_body]);
+
+  const articleBodyText = useMemo(
+    () => (record?.article_body ?? "").replace(/\s+/g, " ").trim(),
+    [record?.article_body],
+  );
+
+  useEffect(() => {
+    setBodyExpanded(false);
+  }, [record?.id]);
+
+  const bodyTruncated = articleBodyText.length > BODY_PREVIEW_LENGTH;
+  const displayBody = !articleBodyText
+    ? "暂无正文"
+    : bodyExpanded || !bodyTruncated
+      ? articleBodyText
+      : `${articleBodyText.slice(0, BODY_PREVIEW_LENGTH)}…`;
 
   return (
     <div className="page hot-source-page">
@@ -333,7 +345,25 @@ export default function HotContentSourcePage({
               </span>
             </div>
             <div className="hot-source-record-subtitle">{record.article_title || "-"}</div>
-            <div className="hot-source-record-preview">{bodyPreview}</div>
+            <div
+              className={
+                bodyExpanded
+                  ? "hot-source-record-preview hot-source-record-preview--expanded"
+                  : "hot-source-record-preview"
+              }
+            >
+              {displayBody}
+            </div>
+            {bodyTruncated ? (
+              <Button
+                type="link"
+                size="small"
+                className="hot-source-body-toggle"
+                onClick={() => setBodyExpanded((value) => !value)}
+              >
+                {bodyExpanded ? "收起正文" : "展开全文"}
+              </Button>
+            ) : null}
             <Typography.Title level={5} className="hot-source-section-label">
               贡献匹配摘要
             </Typography.Title>

+ 13 - 0
frontend/src/styles.css

@@ -475,6 +475,19 @@ body {
   border: 1px solid #dbe3ef;
   color: #334155;
   line-height: 1.6;
+  white-space: pre-wrap;
+  word-break: break-word;
+}
+
+.hot-source-record-preview--expanded {
+  max-height: 480px;
+  overflow-y: auto;
+}
+
+.hot-source-body-toggle {
+  padding-left: 0;
+  margin-top: 4px;
+  height: auto;
 }
 
 .hot-source-section-label {