diff --git a/package-lock.json b/package-lock.json index 10d1ba3..9e47555 100644 --- a/package-lock.json +++ b/package-lock.json @@ -187,6 +187,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -1538,6 +1539,7 @@ "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -2027,6 +2029,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -2792,6 +2795,7 @@ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", "integrity": "sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.21.0" }, @@ -2807,7 +2811,8 @@ "version": "1.11.19", "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.19.tgz", "integrity": "sha512-t5EcLVS6QPBNqM2z8fakk/NKel+Xzshgt8FFKAn+qwlD1pzZWxh0nVCrvFK7ZDb6XucZeF9z8C7CBWTRIVApAw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/debug": { "version": "4.4.3", @@ -3937,6 +3942,7 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -4943,6 +4949,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5876,6 +5883,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5888,6 +5896,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -5908,6 +5917,7 @@ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", "license": "MIT", + "peer": true, "dependencies": { "@types/use-sync-external-store": "^0.0.6", "use-sync-external-store": "^1.4.0" @@ -6039,7 +6049,8 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/redux-thunk": { "version": "3.1.0", @@ -6940,6 +6951,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -7013,6 +7025,7 @@ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" @@ -7220,6 +7233,7 @@ "integrity": "sha512-+v57oAaoYNnO3hIu5Z/tJRZjq5aHM2zDve9YZ8HngVHbhk66RStobhb1sqPMIPEleV6cNKYK4eGrAbE9Ulbl2g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "esbuild": "^0.18.10", "postcss": "^8.4.27", diff --git a/src/assets/中等宽度LOGO.svg b/src/assets/中等宽度LOGO.svg new file mode 100644 index 0000000..e3b0545 --- /dev/null +++ b/src/assets/中等宽度LOGO.svg @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/主要LOGO.svg b/src/assets/主要LOGO.svg new file mode 100644 index 0000000..5a6a08d --- /dev/null +++ b/src/assets/主要LOGO.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/正方形LOGO.svg b/src/assets/正方形LOGO.svg new file mode 100644 index 0000000..ec186d7 --- /dev/null +++ b/src/assets/正方形LOGO.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/src/assets/纯字母LOGO.svg b/src/assets/纯字母LOGO.svg new file mode 100644 index 0000000..b79dce0 --- /dev/null +++ b/src/assets/纯字母LOGO.svg @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/layouts/AdminLayout.tsx b/src/layouts/AdminLayout.tsx index c2cbe04..5b479fe 100644 --- a/src/layouts/AdminLayout.tsx +++ b/src/layouts/AdminLayout.tsx @@ -16,7 +16,8 @@ import { MenuUnfoldOutlined } from '@ant-design/icons'; import { useAdmin } from '../contexts'; -import { Logo } from '../components/common/Logo'; +import 主要LOGO from '../assets/主要LOGO.svg'; +import 纯字母LOGO from '../assets/纯字母LOGO.svg'; const { Header, Sider, Content, Footer } = Layout; @@ -103,7 +104,7 @@ const AdminLayout = ({ children }: { children: React.ReactNode }) => { {collapsed ? ( OA ) : ( - + 主要LOGO )} { © {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
- + 纯字母LOGO
diff --git a/src/layouts/UserLayout.tsx b/src/layouts/UserLayout.tsx index f3a4521..b056aab 100644 --- a/src/layouts/UserLayout.tsx +++ b/src/layouts/UserLayout.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { Layout } from 'antd'; -import { Logo } from '../components/common/Logo'; +import 主要LOGO from '../assets/主要LOGO.svg'; +import 纯字母LOGO from '../assets/纯字母LOGO.svg'; const { Header, Content, Footer } = Layout; @@ -8,7 +9,7 @@ export const UserLayout: React.FC<{ children: React.ReactNode }> = ({ children } return (
- + 主要LOGO
@@ -21,7 +22,7 @@ export const UserLayout: React.FC<{ children: React.ReactNode }> = ({ children }
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
- + 纯字母LOGO
); diff --git a/src/pages/HomePage.tsx b/src/pages/HomePage.tsx index 504e6b1..108ed1a 100644 --- a/src/pages/HomePage.tsx +++ b/src/pages/HomePage.tsx @@ -4,7 +4,8 @@ import { useNavigate } from 'react-router-dom'; import { useUser } from '../contexts'; import { userAPI } from '../services/api'; import { validateUserForm } from '../utils/validation'; -import { Logo } from '../components/common/Logo'; +import 主要LOGO from '../assets/主要LOGO.svg'; +import 纯字母LOGO from '../assets/纯字母LOGO.svg'; const { Header, Content, Footer } = Layout; const { Title } = Typography; @@ -120,7 +121,7 @@ const HomePage = () => { return (
- + 主要LOGO
@@ -219,7 +220,7 @@ const HomePage = () => {
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
- + 纯字母LOGO
); diff --git a/src/pages/QuizPage.tsx b/src/pages/QuizPage.tsx index d00af86..279a5ba 100644 --- a/src/pages/QuizPage.tsx +++ b/src/pages/QuizPage.tsx @@ -450,7 +450,7 @@ const QuizPage = () => { />
-
+
{ } `} > -
-
- +
+
+ {questionTypeMap[currentQuestion.type]} {currentQuestion.category && ( - + {currentQuestion.category} )} @@ -479,7 +479,7 @@ const QuizPage = () => {

{currentQuestion.content}

@@ -511,28 +511,28 @@ const QuizPage = () => { onCancel={() => setAnswerSheetOpen(false)} footer={null} centered - width={560} + width={340} destroyOnClose > -
-
+
+
已答 {answeredCount} / {questions.length}
-
+
{questions.map((q, idx) => { const isCurrent = idx === currentQuestionIndex; const isAnswered = !!answers[q.id]; - let className = 'h-10 w-10 rounded-full flex items-center justify-center text-sm font-medium border transition-colors '; + let className = 'h-9 w-9 rounded-full flex items-center justify-center text-xs font-medium border transition-colors '; if (isCurrent) { className += 'border-[#00897B] bg-[#E0F2F1] text-[#00695C]'; } else if (isAnswered) { diff --git a/src/pages/ResultPage.tsx b/src/pages/ResultPage.tsx index 8a1435a..13d3f52 100644 --- a/src/pages/ResultPage.tsx +++ b/src/pages/ResultPage.tsx @@ -155,10 +155,10 @@ const ResultPage = () => { if (loading) { return ( -
+
-
-

正在加载答题结果...

+
+

正在加载答题结果...

@@ -168,10 +168,10 @@ const ResultPage = () => { if (!record) { return ( -
+
-

答题记录不存在

-
@@ -185,15 +185,15 @@ const ResultPage = () => { return ( -
+
{/* 结果概览 */} - + + ]} @@ -201,9 +201,9 @@ const ResultPage = () => { {/* 基本信息 */} - -

答题信息

- + +

答题信息

+ {user?.name} {user?.phone} {formatDateTime(record.createdAt)} @@ -215,30 +215,30 @@ const ResultPage = () => { {/* 答案详情 */} -

答案详情

-
+

答案详情

+
{answers.map((answer, index) => (
-
-
- +
+
+ 第 {index + 1} 题 - + {answer.questionType === 'single' ? '单选题' : answer.questionType === 'multiple' ? '多选题' : answer.questionType === 'judgment' ? '判断题' : '简答题'}
{ {answer.isCorrect ? '正确' : '错误'}
-
- 题目: - {answer.questionContent || '题目内容加载失败'} +
+ 题目: + {answer.questionContent || '题目内容加载失败'}
-
- 您的答案: +
+ 您的答案: {renderUserAnswer(answer)}
{!answer.isCorrect && ( -
- 正确答案: +
+ 正确答案: {renderCorrectAnswer(answer)}
)} {String(answer.questionAnalysis ?? '').trim() ? ( -
- 解析: - {answer.questionAnalysis} +
+ 解析: + {answer.questionAnalysis}
) : null} -
- +
+ 本题分值:{answer.questionScore || 0} 分,你的得分:{answer.score}
diff --git a/src/pages/SubjectSelectionPage.tsx b/src/pages/SubjectSelectionPage.tsx index 19bbb05..610b74e 100644 --- a/src/pages/SubjectSelectionPage.tsx +++ b/src/pages/SubjectSelectionPage.tsx @@ -136,25 +136,25 @@ export const SubjectSelectionPage: React.FC = () => { return ( -
-
- + <div className="container mx-auto px-4 max-w-md"> + <div className="mb-4 text-center"> + <Title level={3} className="!text-mars-600 mb-1 !text-lg"> 选择考试科目 - + 请选择您要参加的考试科目或考试任务
-
+
{/* 考试科目选择 */}
-
- - 考试科目 +
+ + 考试科目
-
+
{subjects.map((subject) => ( { >
- + <Title level={5} className={`mb-1 ${selectedSubject === subject.id ? 'text-mars-700' : 'text-gray-800'} !text-sm`}> {subject.name} - +
- - {subject.timeLimitMinutes}分钟 + + {subject.timeLimitMinutes}分钟
- 总分: - {subject.totalScore}分 + 总分: + {subject.totalScore}分
-
-
题型分布:
-
{formatTypeRatio(subject.typeRatios)}
+
+
题型分布:
+
{formatTypeRatio(subject.typeRatios)}
{selectedSubject === subject.id && (
-
- +
+
)} @@ -203,12 +203,12 @@ export const SubjectSelectionPage: React.FC = () => { {/* 考试任务选择 */}
-
- - 考试任务 +
+ + 考试任务
-
+
{tasks.map((task) => { const subject = subjects.find(s => s.id === task.subjectId); const usedAttempts = Number(task.usedAttempts) || 0; @@ -230,41 +230,41 @@ export const SubjectSelectionPage: React.FC = () => { >
- + <Title level={5} className={`mb-1 ${selectedTask === task.id ? 'text-mars-700' : 'text-gray-800'} !text-sm`}> {task.name}
- + {usedAttempts}/{maxAttempts} {typeof task.bestScore === 'number' ? ( - 最高分 {task.bestScore} 分 + 最高分 {task.bestScore} 分 ) : null} - {attemptsExhausted ? 次数用尽 : null} + {attemptsExhausted ? 次数用尽 : null}
- +
- - {subject?.name || '未知科目'} + + {subject?.name || '未知科目'}
- - + + {new Date(task.startAt).toLocaleDateString()} - {new Date(task.endAt).toLocaleDateString()}
{subject && (
- 时长: - {subject.timeLimitMinutes}分钟 + 时长: + {subject.timeLimitMinutes}分钟
)}
{selectedTask === task.id && (
-
- +
+
)} @@ -275,18 +275,18 @@ export const SubjectSelectionPage: React.FC = () => {
{tasks.length === 0 && ( - - 暂无可用考试任务 + + 暂无可用考试任务 )}
-
+
diff --git a/src/pages/admin/AdminLoginPage.tsx b/src/pages/admin/AdminLoginPage.tsx index 1b67048..27dc0bf 100644 --- a/src/pages/admin/AdminLoginPage.tsx +++ b/src/pages/admin/AdminLoginPage.tsx @@ -3,7 +3,8 @@ import { Card, Form, Input, Button, message, Select, Layout } from 'antd'; import { useNavigate } from 'react-router-dom'; import { useAdmin } from '../../contexts'; import { adminAPI } from '../../services/api'; -import { Logo } from '../../components/common/Logo'; +import 主要LOGO from '../../assets/主要LOGO.svg'; +import 纯字母LOGO from '../../assets/纯字母LOGO.svg'; const { Header, Content, Footer } = Layout; @@ -95,7 +96,7 @@ const AdminLoginPage = () => { return (
- + 主要LOGO
@@ -201,7 +202,7 @@ const AdminLoginPage = () => {
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
- + 纯字母LOGO
); diff --git a/src/pages/quiz/components/OptionList.tsx b/src/pages/quiz/components/OptionList.tsx index 2871822..1572770 100644 --- a/src/pages/quiz/components/OptionList.tsx +++ b/src/pages/quiz/components/OptionList.tsx @@ -36,14 +36,14 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL if (type === 'text') { return ( -
+