From: words Date: Thu, 30 Jul 2026 01:02:30 +0000 (+0800) Subject: feat: 新增组别只读预览功能 X-Git-Url: http://acesimba.cloud/gitweb/?a=commitdiff_plain;h=4109c8b1ceb10c6c87aadb778696073efed7f3b5;p=words.git feat: 新增组别只读预览功能 - 新建 GroupView 组件: 点击首页 Group 名称进入 /group/:groupId - 上方显示该组思维导图, 下方完整词汇表(单词/词性/释义/词根/词缀/例句) - 纯查看, 不触发学习/测试/复习记录 - App.js 加路由, Home.js 组名单元格改为可点击 - 响应式: 移动端表格可横向滚动 --- diff --git a/frontend/src/App.js b/frontend/src/App.js index 8d74f68..ff960f2 100644 --- a/frontend/src/App.js +++ b/frontend/src/App.js @@ -3,6 +3,7 @@ import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; import Home from './components/Home'; import StudyMode from './components/StudyMode'; import TestMode from './components/TestMode'; +import GroupView from './components/GroupView'; function App() { return ( @@ -11,6 +12,7 @@ function App() { } /> } /> } /> + } /> ); diff --git a/frontend/src/components/GroupView.css b/frontend/src/components/GroupView.css new file mode 100644 index 0000000..bc1d72f --- /dev/null +++ b/frontend/src/components/GroupView.css @@ -0,0 +1,133 @@ +/* GroupView.css - 组别只读预览(上图下表) */ + +.group-view-container { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px; + background-color: #f0f7ff; + min-height: 100vh; +} + +.group-view-card { + display: flex; + flex-direction: column; + background: white; + border-radius: 20px; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); + width: 95%; + max-width: 1100px; + overflow: hidden; +} + +.group-view-header { + text-align: center; + padding: 24px 20px 12px; +} + +.group-view-header h1 { + font-size: 22px; + color: #1e40af; + margin: 0 0 6px; +} + +.group-view-count { + color: #475569; + font-size: 14px; + margin: 0; +} + +/* 思维导图(上方) */ +.group-image-section { + background: #fafafa; + display: flex; + align-items: center; + justify-content: center; + padding: 16px; + border-bottom: 1px solid #eee; +} + +.group-image-section img { + max-width: 100%; + max-height: 520px; + object-fit: contain; +} + +/* 词汇列表(下方,可横向滚动) */ +.group-table-wrap { + overflow-x: auto; + padding: 12px 16px 20px; +} + +.group-word-table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; + min-width: 760px; +} + +.group-word-table th { + background-color: #eff6ff; + color: #1e40af; + font-size: 14px; + padding: 12px 10px; + text-align: left; + border-bottom: 2px solid #dbeafe; + white-space: nowrap; +} + +.group-word-table td { + padding: 12px 10px; + font-size: 14px; + color: #1f2937; + border-bottom: 1px solid #f1f5f9; + vertical-align: top; + word-break: break-word; +} + +.group-word-table tr:hover td { + background-color: #f8fafc; +} + +/* 列宽分配 */ +.group-word-table th:nth-child(1), +.group-word-table td:nth-child(1) { width: 15%; font-weight: 600; color: #1d4ed8; } +.group-word-table th:nth-child(2), +.group-word-table td:nth-child(2) { width: 8%; } +.group-word-table th:nth-child(3), +.group-word-table td:nth-child(3) { width: 22%; } +.group-word-table th:nth-child(4), +.group-word-table td:nth-child(4) { width: 10%; color: #64748b; } +.group-word-table th:nth-child(5), +.group-word-table td:nth-child(5) { width: 20%; color: #64748b; font-size: 13px; } +.group-word-table th:nth-child(6), +.group-word-table td:nth-child(6) { width: 25%; color: #475569; font-size: 13px; } + +/* 返回首页按钮 */ +.back-home { + margin-top: 20px; + background: none; + border: none; + color: #64748b; + text-decoration: underline; + cursor: pointer; + font-size: 14px; +} + +/* 响应式 */ +@media (max-width: 768px) { + .group-view-card { + width: 98%; + } + .group-view-header h1 { + font-size: 20px; + } + .group-image-section img { + max-height: 360px; + } + .group-word-table th, + .group-word-table td { + padding: 10px 8px; + font-size: 13px; + } +} diff --git a/frontend/src/components/GroupView.js b/frontend/src/components/GroupView.js new file mode 100644 index 0000000..c0cc8ff --- /dev/null +++ b/frontend/src/components/GroupView.js @@ -0,0 +1,78 @@ +import React, { useState, useEffect } from 'react'; +import { useParams, useNavigate } from 'react-router-dom'; +import axios from 'axios'; +import './GroupView.css'; + +const API_BASE = "http://124.222.157.124:1060"; + +function GroupView() { + const { groupId } = useParams(); + const navigate = useNavigate(); + const [words, setWords] = useState([]); + + useEffect(() => { + axios.get(`${API_BASE}/api/words/${groupId}`) + .then(res => setWords(res.data)) + .catch(err => console.error("获取词汇失败:", err)); + }, [groupId]); + + // 组内所有单词共享同一张思维导图,取首词的 picture_id(兼容 picture_id==groupid 约定) + const pictureId = words.length > 0 ? words[0].picture_id : null; + + if (words.length === 0) { + return ( +
+
+

加载中...

+
+
+ ); + } + + return ( +
+
+
+

Group {groupId} · 词汇预览

+

共 {words.length} 个单词(只读预览,不记录进度)

+
+ + {pictureId && ( +
+ mindmap +
+ )} + +
+ + + + + + + + + + + + + {words.map(w => ( + + + + + + + + + ))} + +
单词词性中文释义词根词缀例句
{w.word}{w.part_of_speech}{w.chinese_meaning}{w.word_root}{w.affix}{w.example_sentence}
+
+
+ +
+ ); +} + +export default GroupView; diff --git a/frontend/src/components/Home.js b/frontend/src/components/Home.js index 2f00eb6..4778bf2 100644 --- a/frontend/src/components/Home.js +++ b/frontend/src/components/Home.js @@ -46,6 +46,10 @@ function Home() { const handleCellClick = (item, type) => { const groupId = item.group.replace('Group ', ''); + if (type === 'group') { + navigate(`/group/${groupId}`); + return; + } if (type === 'study' && item.study && item.study.includes('请开始学习')) { navigate(`/study/${groupId}`); } @@ -93,7 +97,13 @@ function Home() { {filteredData.map((item, index) => ( - {item.group} + handleCellClick(item, 'group')} + style={{ cursor: 'pointer' }} + > + {item.group} + handleCellClick(item, 'study')}