feat: 添加LOGO文件,修改考试界面的比例
添加多个LOGO文件,修改用户看到的考试界面的比例,并且调整了部分元素尺寸
This commit is contained in:
18
package-lock.json
generated
18
package-lock.json
generated
@@ -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",
|
||||
|
||||
40
src/assets/中等宽度LOGO.svg
Normal file
40
src/assets/中等宽度LOGO.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
64
src/assets/主要LOGO.svg
Normal file
64
src/assets/主要LOGO.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 28 KiB |
21
src/assets/正方形LOGO.svg
Normal file
21
src/assets/正方形LOGO.svg
Normal file
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Creator: CorelDRAW 2020 (64-Bit) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="477px" height="621px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||
viewBox="0 0 80.92 105.37"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.fil0 {fill:#008C8C}
|
||||
.fil1 {fill:#008C8C;fill-rule:nonzero}
|
||||
]]>
|
||||
</style>
|
||||
</defs>
|
||||
<g id="图层_x0020_1">
|
||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||
<path class="fil0" d="M72.67 62.65c2.16,-4 3.39,-8.58 3.39,-13.45 0,-15.66 -12.69,-28.35 -28.35,-28.35 -4.92,0 -9.54,1.26 -13.57,3.46l0 11.7c3.44,-3.54 8.25,-5.74 13.57,-5.74 10.46,0 18.93,8.47 18.93,18.93 0,10.45 -8.47,18.93 -18.93,18.93 -5.21,0 -9.93,-2.11 -13.35,-5.51 -3.4,-3.35 -4.19,-8.41 -4.36,-13.47l0 -31.15 0 -15.23 0 -0.35 0 -0.01 0 -1.04c3.33,-0.89 6.84,-1.37 10.46,-1.37 22.35,0 40.46,18.12 40.46,40.46 0,22.35 -18.11,40.46 -40.46,40.46 -22.34,0 -40.46,-18.11 -40.46,-40.46 0,-14.88 8.04,-27.89 20.01,-34.92l0 1.18 0 0 0 0.4 0 10.88 0 29.2c0,4.65 0.18,6.98 1.17,10.53 2.24,8.04 7.74,14.13 15.26,17.49 3.45,1.49 7.27,2.33 11.27,2.33 3.02,0 5.93,-0.48 8.66,-1.35 6.6,-2.95 12.23,-7.66 16.3,-13.55z"/>
|
||||
<polygon class="fil1" points="15.53,105.37 15.53,97.52 65.39,97.52 65.39,105.37 "/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
37
src/assets/纯字母LOGO.svg
Normal file
37
src/assets/纯字母LOGO.svg
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Creator: CorelDRAW 2020 (64-Bit) -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1035px" height="165px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
|
||||
viewBox="0 0 1536.65 244.88"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:xodm="http://www.corel.com/coreldraw/odm/2003">
|
||||
<defs>
|
||||
<style type="text/css">
|
||||
<![CDATA[
|
||||
.fil1 {fill:#008C8C}
|
||||
.fil0 {fill:#008C8C;fill-rule:nonzero}
|
||||
]]>
|
||||
</style>
|
||||
</defs>
|
||||
<g id="图层_x0020_1">
|
||||
<metadata id="CorelCorpID_0Corel-Layer"/>
|
||||
<g id="_2291884961744">
|
||||
<path class="fil0" d="M944.87 143.53l64.56 -35.63c-3.6,-3.73 -7.46,-6.68 -11.43,-8.86 -3.93,-2.16 -10.25,-3.29 -18.76,-3.29 -8.41,0 -15.77,2.12 -22.04,6.26 -6.3,4.16 -11.19,9.88 -14.53,17 -3.34,7.12 -5.2,15.11 -5.04,23.71 0.13,7.17 2.24,14.16 5.62,20.7 3.35,6.48 8.26,11.87 14.53,15.88 6.31,4.02 13.9,6.15 22.5,6.07 13.11,-0.12 22.96,-3.82 29.42,-10.53 6.48,-6.72 11.07,-16.82 13.77,-30.27l23.8 3.33c-0.14,6.25 -1.67,12.86 -4.59,19.75 -2.93,6.88 -7.31,13.54 -13.1,19.75 -5.8,6.23 -13.07,11.37 -21.63,15.2 -8.56,3.84 -18.39,5.95 -29.29,5.98 -11.4,0.04 -22.25,-2.96 -32.39,-8.81 -10.18,-5.87 -18.34,-13.9 -24.39,-23.89 -6.03,-9.96 -9.08,-20.79 -9.08,-32.35 0,-11.74 2.02,-22.12 5.98,-31.09 3.94,-8.91 9.27,-16.38 15.83,-22.18 6.56,-5.79 13.81,-10.17 21.6,-12.95 7.76,-2.78 15.48,-4.23 23.03,-4.23 14.8,0 27.27,3.33 37.34,10.03 10.08,6.71 18.77,17.05 26.05,31.04l-87.46 48.55 -10.3 -19.17z"/>
|
||||
<path class="fil0" d="M773.48 76.32l25.91 0 38.01 100.68 37.84 -100.68 25.37 0 -45.34 120.12c-1.44,3.79 -4.04,6.87 -7.38,8.95 -3.35,2.09 -7.07,3.2 -11.03,3.2 -4.13,0 -7.96,-1.22 -11.38,-3.6 -3.42,-2.39 -5.58,-5.89 -7.2,-10.17l-44.8 -118.5z"/>
|
||||
<polygon class="fil0" points="727.68,208.59 727.68,76.44 751.44,76.44 751.44,208.59 "/>
|
||||
<path class="fil0" d="M725.39 47.36c0.08,-3.83 1.79,-7.16 4.54,-9.81 2.74,-2.62 6.03,-3.96 9.77,-3.96 3.73,0 7.01,1.4 9.8,4.1 2.79,2.7 4.23,6.12 4.23,10.26 0,4.36 -1.32,7.85 -3.91,10.39 -2.59,2.54 -5.8,3.87 -9.54,3.87 -4,0 -7.48,-1.39 -10.44,-4.1 -2.93,-2.69 -4.55,-6.34 -4.45,-10.75z"/>
|
||||
<polygon class="fil0" points="671.89,19.36 695.65,19.36 695.65,208.59 671.89,208.59 "/>
|
||||
<path class="fil0" d="M532.05 208.59l0 -79.09c0,-9.59 2.44,-18.45 7.34,-26.55 4.91,-8.13 11.65,-14.63 20.29,-19.48 8.58,-4.82 18.03,-7.51 28.25,-7.69 7.33,-0.13 15.31,1.86 23.93,5.62 8.61,3.75 15.97,9.86 22.14,18.27 6.16,8.41 9.27,19.07 9.27,31.99l0 76.93 -23.76 0 0 -76.4c0,-8.99 -2.96,-16.83 -8.86,-23.43 -5.93,-6.63 -13.49,-10.17 -22.72,-10.31 -8.82,-0.13 -16.29,3.11 -22.4,9.32 -6.12,6.2 -9.18,13.63 -9.18,22.27l0 78.55 -24.3 0z"/>
|
||||
<path class="fil1" d="M439.59 74.62c37,0 66.98,29.99 66.98,66.98 0,37 -29.98,66.99 -66.98,66.99 -23.45,0 -44.08,-12.06 -56.05,-30.3 -11.96,18.24 -32.59,30.3 -56.04,30.3 -36.99,0 -66.99,-29.99 -66.99,-66.99 0,-36.99 30,-66.98 66.99,-66.98 23.45,0 44.08,12.05 56.04,30.29 11.97,-18.24 32.6,-30.29 56.05,-30.29zm0 23.19c24.19,0 43.79,19.61 43.79,43.79 0,24.19 -19.6,43.79 -43.79,43.79 -24.18,0 -43.79,-19.6 -43.79,-43.79 0,-24.18 19.61,-43.79 43.79,-43.79zm-112.09 0c24.18,0 43.79,19.61 43.79,43.79 0,24.19 -19.61,43.79 -43.79,43.79 -24.19,0 -43.79,-19.6 -43.79,-43.79 0,-24.18 19.6,-43.79 43.79,-43.79z"/>
|
||||
<g>
|
||||
<path class="fil1" d="M1177.77 161.09l15.29 0c1.33,0 2.62,1.09 2.87,2.42l4.15 22.01c0.25,1.33 -0.63,2.41 -1.96,2.41l-15.29 0c-1.33,0 -2.62,-1.08 -2.87,-2.41l-4.15 -22.01c-0.25,-1.33 0.63,-2.42 1.96,-2.42z"/>
|
||||
<path class="fil1" d="M1082.58 75.99l50.72 0 0 -10.92c0,-1.33 1.09,-2.41 2.41,-2.41l21.35 0c1.33,0 2.42,1.08 2.42,2.41l0 10.92 50.72 0c1.33,0 2.42,1.09 2.42,2.42l0 21.9 -23.39 0 0 -9.43 -85.68 0 0 9.43 -23.39 0 0 -21.9c0,-1.33 1.09,-2.42 2.42,-2.42z"/>
|
||||
<path class="fil1" d="M1078.98 193.83l54.32 0 0 -39.25 -54 0 0 -12.34c0,-1.33 1.09,-2.42 2.42,-2.42l51.58 0 0 -18.09 -54 0 0 -12.35c0,-1.32 1.09,-2.41 2.42,-2.41l129.34 0c1.33,0 2.42,1.09 2.42,2.41l0 12.35 -54 0 0 18.09 51.58 0c1.33,0 2.42,1.09 2.42,2.42l0 12.34 -54 0 0 39.25 54.32 0c1.33,0 2.42,1.09 2.42,2.42l0 12.34 -139.66 0 0 -12.34c0,-1.33 1.09,-2.42 2.42,-2.42z"/>
|
||||
<path class="fil1" d="M1244.06 75.59l50.17 0 0 -10.52c0,-1.33 1.09,-2.41 2.42,-2.41l21.35 0c1.33,0 2.41,1.08 2.41,2.41l0 10.52 50.18 0c1.33,0 2.42,1.09 2.42,2.42l0 13.51 -52.6 0 0 38.55 53.31 0c1.56,0 2.84,1.28 2.84,2.84l0 15.89 -20.91 0 20.91 59.64 -23.94 0 -20.9 -59.64 -11.31 0 0 58.94 -26.18 0 0 -58.94 -11.3 0 -20.91 59.64 -23.93 0 20.91 -59.64 -20.91 0 0 -15.89c0,-1.56 1.28,-2.84 2.84,-2.84l53.3 0 0 -38.55 -52.59 0 0 -13.51c0,-1.33 1.09,-2.42 2.42,-2.42zm114.65 19.98l-19.1 0c-1.33,0 -2.77,1.09 -3.21,2.42l-9.14 27.74c-0.44,1.33 0.29,2.42 1.62,2.42l19.1 0c1.33,0 2.77,-1.09 3.21,-2.42l9.14 -27.74c0.44,-1.33 -0.29,-2.42 -1.62,-2.42zm-104.39 0l19.1 0c1.33,0 2.77,1.09 3.21,2.42l9.14 27.74c0.44,1.33 -0.29,2.42 -1.62,2.42l-19.1 0c-1.33,0 -2.77,-1.09 -3.21,-2.42l-9.14 -27.74c-0.44,-1.33 0.29,-2.42 1.62,-2.42z"/>
|
||||
<path class="fil1" d="M1428.97 101.49l56.32 0c1.32,0 2.41,1.09 2.41,2.42l0 7.08c0,1.33 -1.09,2.41 -2.41,2.41l-57.07 0 -6.01 95.04 -24.16 0 8.26 -130.43c0.08,-1.33 1.24,-2.42 2.57,-2.42l0.85 0 20.88 0 56.58 0 -2.12 -10.5c-0.26,-1.33 0.6,-2.41 1.93,-2.41l17.83 0c1.33,0 2.63,1.08 2.9,2.41l2.12 10.5 23.15 0c1.33,0 2.41,1.09 2.41,2.42l0 13.51 -22.35 0 3.76 18.61 1.98 -5.65c0.46,-1.33 1.93,-2.42 3.26,-2.42l13.5 0 -12.93 36.9 14.02 69.48 -20.24 0c-1.33,0 -2.63,-1.08 -2.9,-2.41l-5.25 -26.03 -9.12 26.03c-0.47,1.33 -1.93,2.41 -3.26,2.41l-13.5 0 20.06 -57.26 -12.04 -59.66 -60.79 0 -0.64 9.97zm88.31 -39.15l12.91 0c1.33,0 2.42,1.09 2.42,2.42l0 5.71c0,1.33 -1.09,2.42 -2.42,2.42l-12.91 0c-1.33,0 -2.41,-1.09 -2.41,-2.42l0 -5.71c0,-1.33 1.08,-2.42 2.41,-2.42z"/>
|
||||
<path class="fil1" d="M1450.07 165.22l8.29 0 9.16 -22.49 -9.27 0 -8.18 22.49zm22.11 -33.93l0.01 -0.02 16.44 0 0 0.02 0.08 0 -4.08 11.44 -0.14 0c-2.86,8.19 -4.6,13.81 -8.92,25.36l-10.29 -0.5 -0.03 0.09 17.29 40.76 -20.46 0 -7.07 -16.64 -7.06 16.64 -20.46 0 17.29 -40.76 -0.07 -0.17 -9.79 0c-1.32,0 -2.02,-1.08 -1.53,-2.41l8.13 -22.37 -6.02 0c-1.32,0 -2.41,-1.09 -2.41,-2.42l0 -6.61c0,-1.32 1.09,-2.41 2.41,-2.41l10.18 0 3.65 -10.05c0.48,-1.33 1.96,-2.42 3.29,-2.42l11.9 0c1.33,0 2.02,1.09 1.54,2.42l-3.65 10.05 9.77 0z"/>
|
||||
</g>
|
||||
<path class="fil1" d="M219.9 189.6c6.54,-12.12 10.26,-25.98 10.26,-40.71 0,-47.38 -38.41,-85.78 -85.78,-85.78 -14.88,0 -28.88,3.79 -41.08,10.45l0 35.4c10.41,-10.71 24.97,-17.36 41.08,-17.36 31.64,0 57.29,25.65 57.29,57.29 0,31.63 -25.65,57.28 -57.29,57.28 -15.77,0 -30.05,-6.37 -40.4,-16.68 -10.3,-10.13 -12.69,-25.45 -13.2,-40.76l0 -94.25 0 -46.11 0 -1.04 0 -0.03 0 -3.16c10.1,-2.7 20.71,-4.14 31.66,-4.14 67.62,0 122.44,54.82 122.44,122.44 0,67.62 -54.82,122.44 -122.44,122.44 -67.62,0 -122.44,-54.82 -122.44,-122.44 0,-45.05 24.33,-84.41 60.56,-105.67l0 3.55 0 0.03 0 1.19 0 32.94 0 88.35c0,14.08 0.54,21.14 3.52,31.86 6.78,24.33 23.43,42.77 46.19,52.92 10.45,4.54 21.99,7.05 34.11,7.05 9.14,0 17.95,-1.43 26.21,-4.08 19.97,-8.9 37.01,-23.17 49.31,-40.98z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
@@ -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 ? (
|
||||
<span className="text-xl font-bold text-mars-500">OA</span>
|
||||
) : (
|
||||
<Logo variant="primary" />
|
||||
<img src={主要LOGO} alt="主要LOGO" style={{ width: '180px', height: '72px' }} />
|
||||
)}
|
||||
</div>
|
||||
<Menu
|
||||
@@ -149,7 +150,7 @@ const AdminLayout = ({ children }: { children: React.ReactNode }) => {
|
||||
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
|
||||
</div>
|
||||
<div className="mt-4 md:mt-0">
|
||||
<Logo variant="secondary" />
|
||||
<img src={纯字母LOGO} alt="纯字母LOGO" style={{ width: '136px', height: '51px' }} />
|
||||
</div>
|
||||
</Footer>
|
||||
</Layout>
|
||||
|
||||
@@ -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 (
|
||||
<Layout className="min-h-screen bg-gray-50">
|
||||
<Header className="bg-white shadow-sm flex items-center px-6 h-16 sticky top-0 z-10">
|
||||
<Logo variant="primary" />
|
||||
<img src={主要LOGO} alt="主要LOGO" style={{ width: '180px', height: '72px' }} />
|
||||
</Header>
|
||||
|
||||
<Content className="flex flex-col">
|
||||
@@ -21,7 +22,7 @@ export const UserLayout: React.FC<{ children: React.ReactNode }> = ({ children }
|
||||
<div className="mb-4 md:mb-0">
|
||||
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
|
||||
</div>
|
||||
<Logo variant="secondary" />
|
||||
<img src={纯字母LOGO} alt="纯字母LOGO" style={{ width: '136px', height: '51px' }} />
|
||||
</Footer>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -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 (
|
||||
<Layout className="min-h-screen bg-gray-50">
|
||||
<Header className="bg-white shadow-sm flex items-center px-6 h-16 sticky top-0 z-10">
|
||||
<Logo variant="primary" />
|
||||
<img src={主要LOGO} alt="主要LOGO" style={{ width: '180px', height: '72px' }} />
|
||||
</Header>
|
||||
|
||||
<Content className="flex items-center justify-center p-4 bg-gradient-to-br from-mars-50 to-white">
|
||||
@@ -219,7 +220,7 @@ const HomePage = () => {
|
||||
<div className="mb-4 md:mb-0">
|
||||
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
|
||||
</div>
|
||||
<Logo variant="secondary" />
|
||||
<img src={纯字母LOGO} alt="纯字母LOGO" style={{ width: '136px', height: '51px' }} />
|
||||
</Footer>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -450,7 +450,7 @@ const QuizPage = () => {
|
||||
/>
|
||||
|
||||
<div className="flex-1 overflow-y-auto pb-24 safe-area-bottom">
|
||||
<div className="max-w-4xl mx-auto p-4">
|
||||
<div className="max-w-md mx-auto px-4">
|
||||
<div
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
@@ -464,13 +464,13 @@ const QuizPage = () => {
|
||||
}
|
||||
`}
|
||||
>
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-5 md:p-8 min-h-[400px]">
|
||||
<div className="mb-6">
|
||||
<span className={`inline-block px-3 py-1 rounded-md text-sm font-medium border ${getTagColor(currentQuestion.type)}`}>
|
||||
<div className="bg-white rounded-xl shadow-sm border border-gray-100 p-4 min-h-[350px]">
|
||||
<div className="mb-4">
|
||||
<span className={`inline-block px-2 py-0.5 rounded-md text-xs font-medium border ${getTagColor(currentQuestion.type)}`}>
|
||||
{questionTypeMap[currentQuestion.type]}
|
||||
</span>
|
||||
{currentQuestion.category && (
|
||||
<span className="ml-2 inline-block px-2 py-1 bg-gray-50 text-gray-600 text-xs rounded border border-gray-100">
|
||||
<span className="ml-2 inline-block px-1.5 py-0.5 bg-gray-50 text-gray-600 text-xs rounded border border-gray-100">
|
||||
{currentQuestion.category}
|
||||
</span>
|
||||
)}
|
||||
@@ -479,7 +479,7 @@ const QuizPage = () => {
|
||||
<h2
|
||||
ref={questionHeadingRef}
|
||||
tabIndex={-1}
|
||||
className="text-lg md:text-xl font-medium text-gray-900 leading-relaxed mb-8 outline-none"
|
||||
className="text-base font-medium text-gray-900 leading-relaxed mb-6 outline-none"
|
||||
>
|
||||
{currentQuestion.content}
|
||||
</h2>
|
||||
@@ -511,28 +511,28 @@ const QuizPage = () => {
|
||||
onCancel={() => setAnswerSheetOpen(false)}
|
||||
footer={null}
|
||||
centered
|
||||
width={560}
|
||||
width={340}
|
||||
destroyOnClose
|
||||
>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="text-sm text-gray-700">
|
||||
<div className="flex items-center justify-between mb-3">
|
||||
<div className="text-xs text-gray-700">
|
||||
已答 <span className="text-[#00897B] font-medium">{answeredCount}</span> / {questions.length}
|
||||
</div>
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={() => setAnswerSheetOpen(false)}
|
||||
className="bg-[#00897B] hover:bg-[#00796B]"
|
||||
className="bg-[#00897B] hover:bg-[#00796B] text-xs h-7 px-3"
|
||||
>
|
||||
回到当前题
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-5 sm:grid-cols-6 gap-3">
|
||||
<div className="grid grid-cols-5 gap-2">
|
||||
{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) {
|
||||
|
||||
@@ -155,10 +155,10 @@ const ResultPage = () => {
|
||||
if (loading) {
|
||||
return (
|
||||
<UserLayout>
|
||||
<div className="flex justify-center items-center h-full min-h-[500px]">
|
||||
<div className="flex justify-center items-center h-full min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<div className="animate-spin rounded-full h-12 w-12 border-b-2 border-mars-600 mx-auto mb-4"></div>
|
||||
<p className="text-gray-600">正在加载答题结果...</p>
|
||||
<div className="animate-spin rounded-full h-10 w-10 border-b-2 border-mars-600 mx-auto mb-3"></div>
|
||||
<p className="text-gray-600 text-sm">正在加载答题结果...</p>
|
||||
</div>
|
||||
</div>
|
||||
</UserLayout>
|
||||
@@ -168,10 +168,10 @@ const ResultPage = () => {
|
||||
if (!record) {
|
||||
return (
|
||||
<UserLayout>
|
||||
<div className="flex justify-center items-center h-full min-h-[500px]">
|
||||
<div className="flex justify-center items-center h-full min-h-[400px]">
|
||||
<div className="text-center">
|
||||
<p className="text-gray-600 mb-4">答题记录不存在</p>
|
||||
<Button type="primary" onClick={handleBackToHome} className="bg-mars-500 hover:bg-mars-600">
|
||||
<p className="text-gray-600 mb-4 text-sm">答题记录不存在</p>
|
||||
<Button type="primary" onClick={handleBackToHome} className="bg-mars-500 hover:bg-mars-600 text-sm">
|
||||
返回首页
|
||||
</Button>
|
||||
</div>
|
||||
@@ -185,15 +185,15 @@ const ResultPage = () => {
|
||||
|
||||
return (
|
||||
<UserLayout>
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<div className="max-w-md mx-auto px-4">
|
||||
{/* 结果概览 */}
|
||||
<Card className="shadow-lg mb-8 rounded-xl border-t-4 border-t-mars-500">
|
||||
<Card className="shadow-lg mb-6 rounded-xl border-t-4 border-t-mars-500">
|
||||
<Result
|
||||
status={status as any}
|
||||
title={`答题完成!您的得分是 ${record.totalScore} 分`}
|
||||
subTitle={`正确率 ${correctRate}% (${record.correctCount}/${record.totalCount})`}
|
||||
extra={[
|
||||
<Button key="back" type="primary" onClick={handleBackToHome} className="bg-mars-500 hover:bg-mars-600 border-none px-8 h-10">
|
||||
<Button key="back" type="primary" onClick={handleBackToHome} className="bg-mars-500 hover:bg-mars-600 border-none px-6 h-9 text-sm">
|
||||
返回首页
|
||||
</Button>
|
||||
]}
|
||||
@@ -201,9 +201,9 @@ const ResultPage = () => {
|
||||
</Card>
|
||||
|
||||
{/* 基本信息 */}
|
||||
<Card className="shadow-lg mb-8 rounded-xl">
|
||||
<h3 className="text-lg font-semibold mb-4 text-gray-800 border-l-4 border-mars-500 pl-3">答题信息</h3>
|
||||
<Descriptions bordered column={2}>
|
||||
<Card className="shadow-lg mb-6 rounded-xl">
|
||||
<h3 className="text-base font-semibold mb-3 text-gray-800 border-l-4 border-mars-500 pl-3">答题信息</h3>
|
||||
<Descriptions bordered column={1} size="small">
|
||||
<Item label="姓名">{user?.name}</Item>
|
||||
<Item label="手机号">{user?.phone}</Item>
|
||||
<Item label="答题时间">{formatDateTime(record.createdAt)}</Item>
|
||||
@@ -215,30 +215,30 @@ const ResultPage = () => {
|
||||
|
||||
{/* 答案详情 */}
|
||||
<Card className="shadow-lg rounded-xl">
|
||||
<h3 className="text-lg font-semibold mb-4 text-gray-800 border-l-4 border-mars-500 pl-3">答案详情</h3>
|
||||
<div className="space-y-4">
|
||||
<h3 className="text-base font-semibold mb-3 text-gray-800 border-l-4 border-mars-500 pl-3">答案详情</h3>
|
||||
<div className="space-y-3">
|
||||
{answers.map((answer, index) => (
|
||||
<div
|
||||
key={answer.id}
|
||||
className={`p-4 rounded-lg border ${
|
||||
className={`p-3 rounded-lg border ${
|
||||
answer.isCorrect
|
||||
? 'border-green-200 bg-green-50/50'
|
||||
: 'border-red-200 bg-red-50/50'
|
||||
}`}
|
||||
>
|
||||
<div className="flex justify-between items-start mb-2">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium text-gray-800">
|
||||
<div className="flex justify-between items-start mb-1.5">
|
||||
<div className="flex items-center gap-1.5">
|
||||
<span className="font-medium text-gray-800 text-sm">
|
||||
第 {index + 1} 题
|
||||
</span>
|
||||
<span className={`${getTagColor(answer.questionType || '')} px-2 py-0.5 rounded text-xs`}>
|
||||
<span className={`${getTagColor(answer.questionType || '')} px-1.5 py-0.5 rounded text-xs`}>
|
||||
{answer.questionType === 'single' ? '单选题' :
|
||||
answer.questionType === 'multiple' ? '多选题' :
|
||||
answer.questionType === 'judgment' ? '判断题' : '简答题'}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
className={`px-2 py-1 rounded text-sm ${
|
||||
className={`px-1.5 py-0.5 rounded text-xs ${
|
||||
answer.isCorrect
|
||||
? 'bg-green-100 text-green-800'
|
||||
: 'bg-red-100 text-red-800'
|
||||
@@ -247,28 +247,28 @@ const ResultPage = () => {
|
||||
{answer.isCorrect ? '正确' : '错误'}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<span className="text-gray-600">题目:</span>
|
||||
<span className="text-gray-800 font-medium">{answer.questionContent || '题目内容加载失败'}</span>
|
||||
<div className="mb-1.5">
|
||||
<span className="text-gray-600 text-xs">题目:</span>
|
||||
<span className="text-gray-800 font-medium text-sm">{answer.questionContent || '题目内容加载失败'}</span>
|
||||
</div>
|
||||
<div className="mb-2">
|
||||
<span className="text-gray-600">您的答案:</span>
|
||||
<div className="mb-1.5">
|
||||
<span className="text-gray-600 text-xs">您的答案:</span>
|
||||
{renderUserAnswer(answer)}
|
||||
</div>
|
||||
{!answer.isCorrect && (
|
||||
<div className="mb-2">
|
||||
<span className="text-gray-600">正确答案:</span>
|
||||
<div className="mb-1.5">
|
||||
<span className="text-gray-600 text-xs">正确答案:</span>
|
||||
{renderCorrectAnswer(answer)}
|
||||
</div>
|
||||
)}
|
||||
{String(answer.questionAnalysis ?? '').trim() ? (
|
||||
<div className="mb-2">
|
||||
<span className="text-gray-600">解析:</span>
|
||||
<span className="text-gray-800 whitespace-pre-wrap">{answer.questionAnalysis}</span>
|
||||
<div className="mb-1.5">
|
||||
<span className="text-gray-600 text-xs">解析:</span>
|
||||
<span className="text-gray-800 whitespace-pre-wrap text-sm">{answer.questionAnalysis}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mb-2 pt-2 border-t border-gray-100 mt-2">
|
||||
<span className="text-gray-500 text-sm">
|
||||
<div className="mb-1 pt-1.5 border-t border-gray-100 mt-1.5">
|
||||
<span className="text-gray-500 text-xs">
|
||||
本题分值:{answer.questionScore || 0} 分,你的得分:<span className="font-medium text-gray-800">{answer.score}</span> 分
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -136,25 +136,25 @@ export const SubjectSelectionPage: React.FC = () => {
|
||||
|
||||
return (
|
||||
<UserLayout>
|
||||
<div className="container mx-auto max-w-6xl">
|
||||
<div className="mb-8 text-center">
|
||||
<Title level={2} className="!text-mars-600 mb-2">
|
||||
<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">
|
||||
选择考试科目
|
||||
</Title>
|
||||
<Text type="secondary" className="block text-lg">
|
||||
<Text type="secondary" className="block text-sm">
|
||||
请选择您要参加的考试科目或考试任务
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
|
||||
<div className="grid grid-cols-1 gap-4">
|
||||
{/* 考试科目选择 */}
|
||||
<div>
|
||||
<div className="flex items-center mb-6 border-b border-gray-200 pb-2">
|
||||
<BookOutlined className="text-2xl mr-3 text-mars-600" />
|
||||
<Title level={3} className="!mb-0 !text-gray-700">考试科目</Title>
|
||||
<div className="flex items-center mb-3 border-b border-gray-200 pb-1">
|
||||
<BookOutlined className="text-lg mr-2 text-mars-600" />
|
||||
<Title level={4} className="!mb-0 !text-gray-700 !text-base">考试科目</Title>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
{subjects.map((subject) => (
|
||||
<Card
|
||||
key={subject.id}
|
||||
@@ -170,28 +170,28 @@ export const SubjectSelectionPage: React.FC = () => {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<Title level={4} className={`mb-2 ${selectedSubject === subject.id ? 'text-mars-700' : 'text-gray-800'}`}>
|
||||
<Title level={5} className={`mb-1 ${selectedSubject === subject.id ? 'text-mars-700' : 'text-gray-800'} !text-sm`}>
|
||||
{subject.name}
|
||||
</Title>
|
||||
<Space direction="vertical" size="small" className="mb-3">
|
||||
<Space direction="vertical" size="small" className="mb-2">
|
||||
<div className="flex items-center">
|
||||
<ClockCircleOutlined className="mr-2 text-gray-400" />
|
||||
<Text className="text-gray-600">{subject.timeLimitMinutes}分钟</Text>
|
||||
<ClockCircleOutlined className="mr-1 text-gray-400 text-xs" />
|
||||
<Text className="text-gray-600 text-xs">{subject.timeLimitMinutes}分钟</Text>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<span className="mr-2 text-gray-400">总分:</span>
|
||||
<Text strong className="text-gray-700">{subject.totalScore}分</Text>
|
||||
<span className="mr-1 text-gray-400 text-xs">总分:</span>
|
||||
<Text strong className="text-gray-700 text-xs">{subject.totalScore}分</Text>
|
||||
</div>
|
||||
</Space>
|
||||
<div className="text-sm text-gray-500 bg-gray-50 p-2 rounded">
|
||||
<div className="mb-1 font-medium">题型分布:</div>
|
||||
<div>{formatTypeRatio(subject.typeRatios)}</div>
|
||||
<div className="text-xs text-gray-500 bg-gray-50 p-1.5 rounded">
|
||||
<div className="mb-0.5 font-medium text-xs">题型分布:</div>
|
||||
<div className="text-xs">{formatTypeRatio(subject.typeRatios)}</div>
|
||||
</div>
|
||||
</div>
|
||||
{selectedSubject === subject.id && (
|
||||
<div className="text-mars-600">
|
||||
<div className="w-8 h-8 bg-mars-500 rounded-full flex items-center justify-center shadow-sm">
|
||||
<span className="text-white text-lg font-bold">✓</span>
|
||||
<div className="w-6 h-6 bg-mars-500 rounded-full flex items-center justify-center shadow-sm">
|
||||
<span className="text-white text-sm font-bold">✓</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -203,12 +203,12 @@ export const SubjectSelectionPage: React.FC = () => {
|
||||
|
||||
{/* 考试任务选择 */}
|
||||
<div>
|
||||
<div className="flex items-center mb-6 border-b border-gray-200 pb-2">
|
||||
<UserOutlined className="text-2xl mr-3 text-mars-400" />
|
||||
<Title level={3} className="!mb-0 !text-gray-700">考试任务</Title>
|
||||
<div className="flex items-center mb-3 border-b border-gray-200 pb-1">
|
||||
<UserOutlined className="text-lg mr-2 text-mars-400" />
|
||||
<Title level={4} className="!mb-0 !text-gray-700 !text-base">考试任务</Title>
|
||||
</div>
|
||||
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
{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 = () => {
|
||||
>
|
||||
<div className="flex justify-between items-start">
|
||||
<div className="flex-1">
|
||||
<Title level={4} className={`mb-2 ${selectedTask === task.id ? 'text-mars-700' : 'text-gray-800'}`}>
|
||||
<Title level={5} className={`mb-1 ${selectedTask === task.id ? 'text-mars-700' : 'text-gray-800'} !text-sm`}>
|
||||
{task.name}
|
||||
</Title>
|
||||
<div className="mb-2">
|
||||
<Tag color={attemptsExhausted ? 'red' : 'blue'}>
|
||||
<Tag color={attemptsExhausted ? 'red' : 'blue'} className="text-xs">
|
||||
{usedAttempts}/{maxAttempts}
|
||||
</Tag>
|
||||
{typeof task.bestScore === 'number' ? (
|
||||
<Tag color="green">最高分 {task.bestScore} 分</Tag>
|
||||
<Tag color="green" className="text-xs">最高分 {task.bestScore} 分</Tag>
|
||||
) : null}
|
||||
{attemptsExhausted ? <Tag color="red">次数用尽</Tag> : null}
|
||||
{attemptsExhausted ? <Tag color="red" className="text-xs">次数用尽</Tag> : null}
|
||||
</div>
|
||||
<Space direction="vertical" size="small" className="mb-3">
|
||||
<Space direction="vertical" size="small" className="mb-2">
|
||||
<div className="flex items-center">
|
||||
<BookOutlined className="mr-2 text-gray-400" />
|
||||
<Text className="text-gray-600">{subject?.name || '未知科目'}</Text>
|
||||
<BookOutlined className="mr-1 text-gray-400 text-xs" />
|
||||
<Text className="text-gray-600 text-xs">{subject?.name || '未知科目'}</Text>
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<ClockCircleOutlined className="mr-2 text-gray-400" />
|
||||
<Text className="text-gray-600">
|
||||
<ClockCircleOutlined className="mr-1 text-gray-400 text-xs" />
|
||||
<Text className="text-gray-600 text-xs">
|
||||
{new Date(task.startAt).toLocaleDateString()} - {new Date(task.endAt).toLocaleDateString()}
|
||||
</Text>
|
||||
</div>
|
||||
{subject && (
|
||||
<div className="flex items-center">
|
||||
<span className="mr-2 text-gray-400">时长:</span>
|
||||
<Text className="text-gray-600">{subject.timeLimitMinutes}分钟</Text>
|
||||
<span className="mr-1 text-gray-400 text-xs">时长:</span>
|
||||
<Text className="text-gray-600 text-xs">{subject.timeLimitMinutes}分钟</Text>
|
||||
</div>
|
||||
)}
|
||||
</Space>
|
||||
</div>
|
||||
{selectedTask === task.id && (
|
||||
<div className="text-mars-400">
|
||||
<div className="w-8 h-8 bg-mars-400 rounded-full flex items-center justify-center shadow-sm">
|
||||
<span className="text-white text-lg font-bold">✓</span>
|
||||
<div className="w-6 h-6 bg-mars-400 rounded-full flex items-center justify-center shadow-sm">
|
||||
<span className="text-white text-sm font-bold">✓</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
@@ -275,18 +275,18 @@ export const SubjectSelectionPage: React.FC = () => {
|
||||
</div>
|
||||
|
||||
{tasks.length === 0 && (
|
||||
<Card className="text-center py-12 bg-gray-50 border-dashed border-2 border-gray-200">
|
||||
<Text type="secondary" className="text-lg">暂无可用考试任务</Text>
|
||||
<Card className="text-center py-8 bg-gray-50 border-dashed border-2 border-gray-200">
|
||||
<Text type="secondary" className="text-sm">暂无可用考试任务</Text>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-12 text-center space-x-6">
|
||||
<div className="mt-6 text-center space-x-3">
|
||||
<Button
|
||||
type="primary"
|
||||
size="large"
|
||||
className="px-12 h-14 text-lg font-medium shadow-lg hover:scale-105 transition-transform bg-mars-500 hover:bg-mars-600 border-none"
|
||||
className="px-6 h-10 text-sm font-medium shadow-lg hover:scale-105 transition-transform bg-mars-500 hover:bg-mars-600 border-none"
|
||||
onClick={startQuiz}
|
||||
disabled={!selectedSubject && !selectedTask}
|
||||
>
|
||||
@@ -295,7 +295,7 @@ export const SubjectSelectionPage: React.FC = () => {
|
||||
<Button
|
||||
type="default"
|
||||
size="large"
|
||||
className="px-8 h-14 text-lg hover:border-mars-500 hover:text-mars-500"
|
||||
className="px-4 h-10 text-sm hover:border-mars-500 hover:text-mars-500"
|
||||
onClick={() => navigate('/tasks')}
|
||||
icon={<UserOutlined />}
|
||||
>
|
||||
|
||||
@@ -204,12 +204,12 @@ export const UserTaskPage: React.FC = () => {
|
||||
|
||||
return (
|
||||
<UserLayout>
|
||||
<div className="container mx-auto max-w-6xl">
|
||||
<div className="mb-8 text-center">
|
||||
<Title level={2} className="!text-mars-600 mb-2">
|
||||
<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">
|
||||
我的考试任务
|
||||
</Title>
|
||||
<Text type="secondary" className="block text-lg">
|
||||
<Text type="secondary" className="block text-sm">
|
||||
查看您被分派的所有考试任务
|
||||
</Text>
|
||||
</div>
|
||||
@@ -220,23 +220,25 @@ export const UserTaskPage: React.FC = () => {
|
||||
dataSource={tasks}
|
||||
rowKey="id"
|
||||
pagination={{
|
||||
pageSize: 10,
|
||||
showSizeChanger: true,
|
||||
showTotal: (total) => `共 ${total} 条记录`
|
||||
pageSize: 5,
|
||||
showSizeChanger: false,
|
||||
showTotal: (total) => `共 ${total} 条`
|
||||
}}
|
||||
locale={{
|
||||
emptyText: '暂无考试任务'
|
||||
}}
|
||||
size="small"
|
||||
scroll={{ x: 'max-content' }}
|
||||
/>
|
||||
</Card>
|
||||
|
||||
<div className="mt-8 text-center">
|
||||
<div className="mt-6 text-center">
|
||||
<Button
|
||||
type="default"
|
||||
size="large"
|
||||
onClick={() => navigate('/subjects')}
|
||||
icon={<BookOutlined />}
|
||||
className="px-8 h-12 hover:border-mars-500 hover:text-mars-500"
|
||||
className="px-6 h-10 text-sm hover:border-mars-500 hover:text-mars-500"
|
||||
>
|
||||
返回科目选择
|
||||
</Button>
|
||||
|
||||
@@ -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 (
|
||||
<Layout className="min-h-screen bg-gray-50">
|
||||
<Header className="bg-white shadow-sm flex items-center px-6 h-16 sticky top-0 z-10">
|
||||
<Logo variant="primary" />
|
||||
<img src={主要LOGO} alt="主要LOGO" style={{ width: '180px', height: '72px' }} />
|
||||
</Header>
|
||||
|
||||
<Content className="flex items-center justify-center p-4 bg-gradient-to-br from-mars-50 to-white">
|
||||
@@ -201,7 +202,7 @@ const AdminLoginPage = () => {
|
||||
<div className="mb-4 md:mb-0">
|
||||
© {new Date().getFullYear()} Boonlive OA System. All Rights Reserved.
|
||||
</div>
|
||||
<Logo variant="secondary" />
|
||||
<img src={纯字母LOGO} alt="纯字母LOGO" style={{ width: '136px', height: '51px' }} />
|
||||
</Footer>
|
||||
</Layout>
|
||||
);
|
||||
|
||||
@@ -36,14 +36,14 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL
|
||||
|
||||
if (type === 'text') {
|
||||
return (
|
||||
<div className="mt-4">
|
||||
<div className="mt-3">
|
||||
<TextArea
|
||||
rows={6}
|
||||
rows={5}
|
||||
value={value as string || ''}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
placeholder="请输入您的答案..."
|
||||
disabled={disabled}
|
||||
className="rounded-lg border-gray-300 focus:border-[#00897B] focus:ring-[#00897B] text-base p-4"
|
||||
className="rounded-lg border-gray-300 focus:border-[#00897B] focus:ring-[#00897B] text-sm p-3"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -57,7 +57,7 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-3 mt-2">
|
||||
<div className="space-y-2.5 mt-2">
|
||||
{renderOptions().map((opt, index) => {
|
||||
const selected = isSelected(opt.value);
|
||||
return (
|
||||
@@ -65,7 +65,7 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL
|
||||
key={opt.key}
|
||||
onClick={() => handleSelect(opt.value)}
|
||||
className={`
|
||||
relative flex items-start p-4 rounded-xl border-2 transition-all duration-200 active:scale-[0.99] cursor-pointer
|
||||
relative flex items-start p-3 rounded-xl border-2 transition-all duration-200 active:scale-[0.99] cursor-pointer
|
||||
${selected
|
||||
? 'border-[#00897B] bg-[#E0F2F1]'
|
||||
: 'border-transparent bg-white shadow-sm hover:border-gray-200'}
|
||||
@@ -73,7 +73,7 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL
|
||||
>
|
||||
{/* 选项圆圈 */}
|
||||
<div className={`
|
||||
flex-shrink-0 w-8 h-8 rounded-full flex items-center justify-center text-sm font-medium border mr-3 mt-0.5 transition-colors
|
||||
flex-shrink-0 w-7 h-7 rounded-full flex items-center justify-center text-xs font-medium border mr-2.5 mt-0.5 transition-colors
|
||||
${selected
|
||||
? 'bg-[#00897B] border-[#00897B] text-white'
|
||||
: 'bg-white border-gray-300 text-gray-500'}
|
||||
@@ -82,7 +82,7 @@ export const OptionList = ({ type, options, value, onChange, disabled }: OptionL
|
||||
</div>
|
||||
|
||||
{/* 选项内容 */}
|
||||
<div className={`text-base leading-snug select-none ${selected ? 'text-[#00695C] font-medium' : 'text-gray-700'}`}>
|
||||
<div className={`text-sm leading-snug select-none ${selected ? 'text-[#00695C] font-medium' : 'text-gray-700'}`}>
|
||||
{opt.label}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -24,23 +24,23 @@ export const QuizFooter = ({
|
||||
const isLast = current === total - 1;
|
||||
|
||||
return (
|
||||
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 px-4 py-3 safe-area-bottom z-30 shadow-[0_-2px_10px_rgba(0,0,0,0.05)]">
|
||||
<div className="max-w-4xl mx-auto flex items-center justify-between">
|
||||
<div className="fixed bottom-0 left-0 right-0 bg-white border-t border-gray-100 px-3 py-2.5 safe-area-bottom z-30 shadow-[0_-2px_10px_rgba(0,0,0,0.05)]">
|
||||
<div className="max-w-md mx-auto flex items-center justify-between">
|
||||
<Button
|
||||
type="text"
|
||||
icon={<LeftOutlined />}
|
||||
onClick={onPrev}
|
||||
disabled={isFirst}
|
||||
className={`flex items-center text-gray-600 hover:text-[#00897B] ${isFirst ? 'opacity-30' : ''}`}
|
||||
className={`flex items-center text-gray-600 hover:text-[#00897B] text-sm ${isFirst ? 'opacity-30' : ''}`}
|
||||
>
|
||||
上一题
|
||||
</Button>
|
||||
|
||||
<div
|
||||
onClick={onOpenSheet}
|
||||
className="flex flex-col items-center justify-center -mt-8 bg-white rounded-full h-16 w-16 shadow-lg border border-gray-100 cursor-pointer active:scale-95 transition-transform"
|
||||
className="flex flex-col items-center justify-center -mt-6 bg-white rounded-full h-14 w-14 shadow-lg border border-gray-100 cursor-pointer active:scale-95 transition-transform"
|
||||
>
|
||||
<AppstoreOutlined className="text-xl text-[#00897B] mb-1" />
|
||||
<AppstoreOutlined className="text-lg text-[#00897B] mb-0.5" />
|
||||
<span className="text-[10px] text-gray-500 scale-90">
|
||||
{answeredCount}/{total}
|
||||
</span>
|
||||
@@ -50,7 +50,7 @@ export const QuizFooter = ({
|
||||
<Button
|
||||
type="text"
|
||||
onClick={onSubmit}
|
||||
className="flex items-center text-[#00897B] font-medium hover:bg-teal-50"
|
||||
className="flex items-center text-[#00897B] font-medium hover:bg-teal-50 text-sm"
|
||||
>
|
||||
提交 <RightOutlined />
|
||||
</Button>
|
||||
@@ -58,7 +58,7 @@ export const QuizFooter = ({
|
||||
<Button
|
||||
type="text"
|
||||
onClick={onNext}
|
||||
className="flex items-center text-gray-600 hover:text-[#00897B]"
|
||||
className="flex items-center text-gray-600 hover:text-[#00897B] text-sm"
|
||||
>
|
||||
下一题 <RightOutlined />
|
||||
</Button>
|
||||
|
||||
@@ -19,18 +19,18 @@ export const QuizHeader = ({ current, total, timeLeft, onGiveUp }: QuizHeaderPro
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-[#00897B] text-white px-4 h-14 flex items-center justify-between shadow-md sticky top-0 z-30">
|
||||
<div className="bg-[#00897B] text-white px-3 h-12 flex items-center justify-between shadow-md sticky top-0 z-30">
|
||||
<div className="flex items-center gap-1" onClick={onGiveUp}>
|
||||
<LeftOutlined className="text-lg" />
|
||||
<span className="text-base">返回</span>
|
||||
<LeftOutlined className="text-base" />
|
||||
<span className="text-sm">返回</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 bg-[#00796B] px-3 py-1 rounded-full text-sm">
|
||||
<div className="flex items-center gap-1.5 bg-[#00796B] px-2 py-0.5 rounded-full text-xs">
|
||||
<EyeOutlined />
|
||||
<span>监控中</span>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 text-base font-medium tabular-nums">
|
||||
<div className="flex items-center gap-1.5 text-sm font-medium tabular-nums">
|
||||
<ClockCircleOutlined />
|
||||
<span>{timeLeft !== null ? formatTime(timeLeft) : '--:--'}</span>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user