+
diff --git a/web/src/pages/Question.less b/web/src/pages/Question.less
deleted file mode 100644
index 034e397..0000000
--- a/web/src/pages/Question.less
+++ /dev/null
@@ -1,209 +0,0 @@
-// 变量定义
-@bg-color: #f5f5f5;
-@white: #fff;
-@primary-color: #1677ff;
-@text-color: #333;
-@text-secondary: #666;
-@text-tertiary: #888;
-@border-color: #e8e8e8;
-@shadow-light: 0 2px 8px rgba(0, 0, 0, 0.06);
-@shadow-medium: 0 2px 8px rgba(0, 0, 0, 0.08);
-@success-bg: #f6ffed;
-@success-border: #b7eb8f;
-@success-color: #52c41a;
-@error-bg: #fff2f0;
-@error-border: #ffccc7;
-@error-color: #ff4d4f;
-
-// 页面容器
-.question-page {
- min-height: 100vh;
- background: @bg-color;
- padding-bottom: 80px;
-}
-
-// 头部
-.header {
- background: @white;
- padding: 16px 20px;
- display: flex;
- justify-content: space-between;
- align-items: center;
- box-shadow: @shadow-light;
- position: sticky;
- top: 0;
- z-index: 100;
-
- h1 {
- margin: 0;
- font-size: 20px;
- font-weight: 600;
- color: @primary-color;
- }
-}
-
-// 内容区域
-.content {
- padding: 16px;
-}
-
-// 题目部分
-.question-header {
- display: flex;
- gap: 8px;
- margin-bottom: 12px;
-}
-
-.question-number {
- font-size: 14px;
- color: @text-secondary;
- margin-bottom: 12px;
-}
-
-.question-content {
- font-size: 18px;
- font-weight: 500;
- color: @text-color;
- line-height: 1.6;
- margin-bottom: 8px;
-}
-
-// 答案结果
-.answer-result {
- margin-top: 20px;
- padding: 16px;
- border-radius: 8px;
- background: @success-bg;
- border: 1px solid @success-border;
-
- &.wrong {
- background: @error-bg;
- border: 1px solid @error-border;
- }
-
- .result-icon {
- display: flex;
- align-items: center;
- justify-content: center;
- margin-bottom: 8px;
- }
-
- &.correct .result-icon {
- color: @success-color;
- }
-
- &.wrong .result-icon {
- color: @error-color;
- }
-
- .result-text {
- font-size: 16px;
- font-weight: 600;
- margin-bottom: 12px;
- text-align: center;
- }
-
- .correct-answer {
- font-size: 14px;
- color: @text-secondary;
- margin-bottom: 8px;
- }
-
- .explanation {
- font-size: 14px;
- color: @text-tertiary;
- line-height: 1.5;
- margin-top: 8px;
- padding-top: 8px;
- border-top: 1px solid @border-color;
- }
-}
-
-// 按钮组
-.button-group {
- margin-top: 24px;
-}
-
-.action-buttons {
- display: flex;
- gap: 8px;
- padding: 16px;
- background: @white;
- position: sticky;
- bottom: 0;
- box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
-
- button {
- flex: 1;
- }
-}
-
-// 统计内容
-.stats-content {
- padding: 20px;
-
- h2 {
- margin: 0 0 20px 0;
- text-align: center;
- font-size: 20px;
- }
-}
-
-.stat-item {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 16px 0;
- border-bottom: 1px solid #f0f0f0;
-
- &:last-child {
- border-bottom: none;
- }
-
- span {
- font-size: 16px;
- color: @text-secondary;
- }
-
- strong {
- font-size: 20px;
- color: @primary-color;
- }
-}
-
-// 筛选内容
-.filter-content {
- padding: 20px;
-
- h2 {
- margin: 0 0 20px 0;
- text-align: center;
- font-size: 20px;
- }
-}
-
-.filter-group {
- margin-bottom: 20px;
-
- p {
- margin: 0 0 12px 0;
- font-size: 14px;
- color: @text-secondary;
- font-weight: 500;
- }
-}
-
-// 覆盖 antd-mobile 样式
-.adm-card {
- border-radius: 12px;
- box-shadow: @shadow-medium;
-}
-
-.adm-list-item {
- padding: 12px 16px;
-}
-
-.adm-modal-body {
- max-height: 70vh;
- overflow-y: auto;
-}
diff --git a/web/src/pages/Question.module.less b/web/src/pages/Question.module.less
new file mode 100644
index 0000000..4b2b79c
--- /dev/null
+++ b/web/src/pages/Question.module.less
@@ -0,0 +1,212 @@
+// 变量定义
+@bg-color: #f5f5f5;
+@white: #fff;
+@primary-color: #1677ff;
+@text-color: #333;
+@text-secondary: #666;
+@text-tertiary: #888;
+@border-color: #e8e8e8;
+@shadow-light: 0 2px 8px rgba(0, 0, 0, 0.06);
+@shadow-medium: 0 2px 8px rgba(0, 0, 0, 0.08);
+@success-bg: #f6ffed;
+@success-border: #b7eb8f;
+@success-color: #52c41a;
+@error-bg: #fff2f0;
+@error-border: #ffccc7;
+@error-color: #ff4d4f;
+
+// 使用 :global 包裹所有样式,因为 Question 组件使用直接类名
+:global {
+ // 页面容器
+ .question-page {
+ min-height: 100vh;
+ background: @bg-color;
+ padding-bottom: 80px;
+ }
+
+ // 头部
+ .header {
+ background: @white;
+ padding: 16px 20px;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ box-shadow: @shadow-light;
+ position: sticky;
+ top: 0;
+ z-index: 100;
+
+ h1 {
+ margin: 0;
+ font-size: 20px;
+ font-weight: 600;
+ color: @primary-color;
+ }
+ }
+
+ // 内容区域
+ .content {
+ padding: 16px;
+ }
+
+ // 题目部分
+ .question-header {
+ display: flex;
+ gap: 8px;
+ margin-bottom: 12px;
+ }
+
+ .question-number {
+ font-size: 14px;
+ color: @text-secondary;
+ margin-bottom: 12px;
+ }
+
+ .question-content {
+ font-size: 18px;
+ font-weight: 500;
+ color: @text-color;
+ line-height: 1.6;
+ margin-bottom: 8px;
+ }
+
+ // 答案结果
+ .answer-result {
+ margin-top: 20px;
+ padding: 16px;
+ border-radius: 8px;
+ background: @success-bg;
+ border: 1px solid @success-border;
+
+ &.wrong {
+ background: @error-bg;
+ border: 1px solid @error-border;
+ }
+
+ .result-icon {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-bottom: 8px;
+ }
+
+ &.correct .result-icon {
+ color: @success-color;
+ }
+
+ &.wrong .result-icon {
+ color: @error-color;
+ }
+
+ .result-text {
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 12px;
+ text-align: center;
+ }
+
+ .correct-answer {
+ font-size: 14px;
+ color: @text-secondary;
+ margin-bottom: 8px;
+ }
+
+ .explanation {
+ font-size: 14px;
+ color: @text-tertiary;
+ line-height: 1.5;
+ margin-top: 8px;
+ padding-top: 8px;
+ border-top: 1px solid @border-color;
+ }
+ }
+
+ // 按钮组
+ .button-group {
+ margin-top: 24px;
+ }
+
+ .action-buttons {
+ display: flex;
+ gap: 8px;
+ padding: 16px;
+ background: @white;
+ position: sticky;
+ bottom: 0;
+ box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.06);
+
+ button {
+ flex: 1;
+ }
+ }
+
+ // 统计内容
+ .stats-content {
+ padding: 20px;
+
+ h2 {
+ margin: 0 0 20px 0;
+ text-align: center;
+ font-size: 20px;
+ }
+ }
+
+ .stat-item {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 16px 0;
+ border-bottom: 1px solid #f0f0f0;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ span {
+ font-size: 16px;
+ color: @text-secondary;
+ }
+
+ strong {
+ font-size: 20px;
+ color: @primary-color;
+ }
+ }
+
+ // 筛选内容
+ .filter-content {
+ padding: 20px;
+
+ h2 {
+ margin: 0 0 20px 0;
+ text-align: center;
+ font-size: 20px;
+ }
+ }
+
+ .filter-group {
+ margin-bottom: 20px;
+
+ p {
+ margin: 0 0 12px 0;
+ font-size: 14px;
+ color: @text-secondary;
+ font-weight: 500;
+ }
+ }
+
+ // 覆盖 antd-mobile 样式
+ .adm-card {
+ border-radius: 12px;
+ box-shadow: @shadow-medium;
+ }
+
+ .adm-list-item {
+ padding: 12px 16px;
+ }
+
+ .adm-modal-body {
+ max-height: 70vh;
+ overflow-y: auto;
+ }
+}
diff --git a/web/src/pages/Question.tsx b/web/src/pages/Question.tsx
index bb3c384..7af1d31 100644
--- a/web/src/pages/Question.tsx
+++ b/web/src/pages/Question.tsx
@@ -22,7 +22,7 @@ import {
} from 'antd-mobile-icons'
import type { Question, AnswerResult } from '../types/question'
import * as questionApi from '../api/question'
-import './Question.less'
+import './Question.module.less'
const QuestionPage: React.FC = () => {
const [currentQuestion, setCurrentQuestion] = useState(null)