From b9efaee7ee19572b4cf8906713d1c122e545a80a Mon Sep 17 00:00:00 2001 From: SunWuyuan Date: Sun, 12 Oct 2025 08:32:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=B7=BB=E5=8A=A0ea2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- package.json | 3 + pnpm-lock.yaml | 135 +++++++++++ src/assets/fonts/TCloudNumberVF.ttf | Bin 0 -> 13160 bytes src/components/ExamConfigEditor.vue | 2 + src/components/MigrationTool.vue | 4 +- .../settings/cards/CloudNamespaceInfoCard.vue | 2 +- src/main.js | 5 +- src/pages/exam-editor/[id].vue | 79 +++++++ src/pages/exam-player.vue | 216 ++++++++++++++++++ src/utils/api.js | 2 +- src/utils/providers/kvServerProvider.js | 1 - vite.config.mjs | 9 +- 13 files changed, 454 insertions(+), 8 deletions(-) create mode 100644 src/assets/fonts/TCloudNumberVF.ttf create mode 100644 src/pages/exam-editor/[id].vue create mode 100644 src/pages/exam-player.vue diff --git a/.gitignore b/.gitignore index 16b24ca..1139e42 100644 --- a/.gitignore +++ b/.gitignore @@ -170,4 +170,6 @@ dist # Vite 临时文件 vite.config.*.timestamp-*.mjs -*.timestamp-* \ No newline at end of file +*.timestamp-* + +kv-admin \ No newline at end of file diff --git a/package.json b/package.json index 9f448e2..01e1b34 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,8 @@ "lint": "eslint . --fix" }, "dependencies": { + "@examaware-cs/core": "^1.0.0", + "@examaware-cs/player": "^1.0.2", "@mdi/font": "7.4.47", "@microsoft/clarity": "^1.0.0", "axios": "^1.11.0", @@ -19,6 +21,7 @@ "pinyin-pro": "^3.27.0", "ratelimit-header-parser": "^0.1.0", "roboto-fontface": "*", + "tdesign-vue-next": "^1.17.1", "typewriter-effect": "^2.21.0", "uuid": "^9.0.1", "vue": "^3.5.20", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a33e1e1..47676e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + '@examaware-cs/core': + specifier: ^1.0.0 + version: 1.0.0 + '@examaware-cs/player': + specifier: ^1.0.2 + version: 1.0.2(tdesign-vue-next@1.17.1(vue@3.5.20))(vue@3.5.20) '@mdi/font': specifier: 7.4.47 version: 7.4.47 @@ -35,6 +41,9 @@ importers: roboto-fontface: specifier: '*' version: 0.10.0 + tdesign-vue-next: + specifier: ^1.17.1 + version: 1.17.1(vue@3.5.20) typewriter-effect: specifier: ^2.21.0 version: 2.21.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -816,6 +825,15 @@ packages: resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@examaware-cs/core@1.0.0': + resolution: {integrity: sha512-JSnyYe4/wpKfoPdA1CVNjLyBSpFSL+H/rKTZlbJyFCymtBRlXthzswKzLCwioyw7y/C3lioUFXLJ2g+CwDnS6w==} + + '@examaware-cs/player@1.0.2': + resolution: {integrity: sha512-Fid58JL0X5TP/O3DNp8QY0B5B8Svv1I8Qi8AObw5HK571/UU6/ri1YQS03ujxt6yupzd7qhiX+7C7EO4nLglJg==} + peerDependencies: + tdesign-vue-next: ^1.15.5 + vue: ^3.0.0 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1062,6 +1080,9 @@ packages: resolution: {integrity: sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==} engines: {node: '>= 10.0.0'} + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@quansync/fs@0.1.2': resolution: {integrity: sha512-ezIadUb1aFhwJLd++WVqVpi9rnlX8vnd4ju7saPhwLHJN1mJgOv0puePTGV+FbtSnWtwoHDT8lAm4kagDZmpCg==} engines: {node: '>=20.0.0'} @@ -1236,12 +1257,27 @@ packages: '@types/json5@0.0.29': resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + '@types/lodash-es@4.17.12': + resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} + + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/resolve@1.20.2': resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/sortablejs@1.15.8': + resolution: {integrity: sha512-b79830lW+RZfwaztgs1aVPgbasJ8e7AXtZYHTELNXZPsERt4ymJdjV4OccDbHQAvHrCcFpbF78jkm0R6h/pZVg==} + + '@types/tinycolor2@1.4.6': + resolution: {integrity: sha512-iEN8J0BoMnsWBqjVbWH/c0G0Hh7O21lpR2/+PrvAVgWdzL7eexIFm4JN/Wn10PTcmNdtS6U67r499mlWMXOxNw==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/validator@13.15.3': + resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==} + '@vite-pwa/assets-generator@1.0.0': resolution: {integrity: sha512-tWRF/tsqGkND5+dDVnJz7DzQkIRjtTRRYvA3y6l4FwTwK47OK72p1X7ResSz6T7PimIZMuFd+arsB8NRIG+Sww==} engines: {node: '>=16.14.0'} @@ -1611,6 +1647,9 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + dayjs@1.11.18: + resolution: {integrity: sha512-zFBQ7WFRvVRhKcWoUh+ZA1g2HVgUbsZm9sbddh8EC5iv93sui8DVVz1Npvz+r6meo9VKfa8NyLWBsQK1VvIKPA==} + debug@3.2.7: resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} peerDependencies: @@ -2413,6 +2452,9 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + lodash.debounce@4.0.8: resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} @@ -2475,6 +2517,9 @@ packages: minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + misans@4.1.0: + resolution: {integrity: sha512-CcIRrIVhnt+OpGXvw1Q8llGBVAy5P2mdov/kJ0gGa81sJ0RY7mZp2fNAt2ySTCeZos+wo7ZnzDZxl1In//7FdA==} + mitt@3.0.1: resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==} @@ -2542,6 +2587,9 @@ packages: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} + ogl@1.0.11: + resolution: {integrity: sha512-kUpC154AFfxi16pmZUK4jk3J+8zxwTWGPo03EoYA8QPbzikHoaC82n6pNTbd+oEaJonaE8aPWBlX7ad9zrqLsA==} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2993,12 +3041,18 @@ packages: resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} engines: {node: '>= 0.4'} + simple-keyboard@3.8.85: + resolution: {integrity: sha512-ewZgPgisKsRsBpBW8wfOoR/fn4ApxD6lhhfw6u354fLAM6fHnkJLOHs8o1q5S/zhJQF0sSDPoIO0EojveNylfQ==} + simple-swizzle@0.2.2: resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==} smob@1.5.0: resolution: {integrity: sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==} + sortablejs@1.15.6: + resolution: {integrity: sha512-aNfiuwMEpfBM/CN6LY0ibyhxPfPbyFeBTYJKCvzkJ2GkUpazIt3H+QIPAMHwqQ7tMKaHz1Qj+rJJCqljnf4p3A==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -3089,6 +3143,17 @@ packages: resolution: {integrity: sha512-GTt8rSKje5FilG+wEdfCkOcLL7LWqpMlr2c3LRuKt/YXxcJ52aGSbGBAdI4L3aaqfrBt6y711El53ItyH1NWzg==} engines: {node: '>=16.0.0'} + tdesign-icons-vue-next@0.4.1: + resolution: {integrity: sha512-uDPuTLRORnGcTyVGNoentNaK4V+ZcBmhYwcY3KqDaQQ5rrPeLMxu0ZVmgOEf0JtF2QZiqAxY7vodNEiLUdoRKA==} + peerDependencies: + vue: ^3.0.0 + + tdesign-vue-next@1.17.1: + resolution: {integrity: sha512-rqRPHSfPn5Y7Nxffa9Q6JumPguc+K2YfcaaxrvyYkZIQwCQ8Fwi2rhh6KpgQud2SAPMP/N1SxfIvYJVS5Lyu8Q==} + engines: {node: '>= 18'} + peerDependencies: + vue: '>=3.1.0' + temp-dir@2.0.0: resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} engines: {node: '>=8'} @@ -3102,6 +3167,9 @@ packages: engines: {node: '>=10'} hasBin: true + tinycolor2@1.6.0: + resolution: {integrity: sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw==} + tinyglobby@0.2.12: resolution: {integrity: sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==} engines: {node: '>=12.0.0'} @@ -3291,6 +3359,10 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + validator@13.15.15: + resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} + engines: {node: '>= 0.10'} + varint@6.0.0: resolution: {integrity: sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg==} @@ -4288,6 +4360,17 @@ snapshots: dependencies: levn: 0.4.1 + '@examaware-cs/core@1.0.0': {} + + '@examaware-cs/player@1.0.2(tdesign-vue-next@1.17.1(vue@3.5.20))(vue@3.5.20)': + dependencies: + '@examaware-cs/core': 1.0.0 + misans: 4.1.0 + ogl: 1.0.11 + simple-keyboard: 3.8.85 + tdesign-vue-next: 1.17.1(vue@3.5.20) + vue: 3.5.20 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -4475,6 +4558,8 @@ snapshots: '@parcel/watcher-win32-x64': 2.5.1 optional: true + '@popperjs/core@2.11.8': {} + '@quansync/fs@0.1.2': dependencies: quansync: 0.2.10 @@ -4606,10 +4691,22 @@ snapshots: '@types/json5@0.0.29': {} + '@types/lodash-es@4.17.12': + dependencies: + '@types/lodash': 4.17.20 + + '@types/lodash@4.17.20': {} + '@types/resolve@1.20.2': {} + '@types/sortablejs@1.15.8': {} + + '@types/tinycolor2@1.4.6': {} + '@types/trusted-types@2.0.7': {} + '@types/validator@13.15.3': {} + '@vite-pwa/assets-generator@1.0.0': dependencies: cac: 6.7.14 @@ -5086,6 +5183,8 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + dayjs@1.11.18: {} + debug@3.2.7: dependencies: ms: 2.1.3 @@ -6036,6 +6135,8 @@ snapshots: dependencies: p-locate: 5.0.0 + lodash-es@4.17.21: {} + lodash.debounce@4.0.8: {} lodash.merge@4.6.2: {} @@ -6093,6 +6194,8 @@ snapshots: minimist@1.2.8: {} + misans@4.1.0: {} + mitt@3.0.1: {} mlly@1.7.4: @@ -6162,6 +6265,8 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + ogl@1.0.11: {} + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -6653,12 +6758,16 @@ snapshots: side-channel-map: 1.0.1 side-channel-weakmap: 1.0.2 + simple-keyboard@3.8.85: {} + simple-swizzle@0.2.2: dependencies: is-arrayish: 0.3.2 smob@1.5.0: {} + sortablejs@1.15.6: {} + source-map-js@1.2.1: {} source-map-support@0.5.21: @@ -6764,6 +6873,28 @@ snapshots: sync-message-port@1.1.3: {} + tdesign-icons-vue-next@0.4.1(vue@3.5.20): + dependencies: + '@babel/runtime': 7.27.0 + vue: 3.5.20 + + tdesign-vue-next@1.17.1(vue@3.5.20): + dependencies: + '@babel/runtime': 7.27.0 + '@popperjs/core': 2.11.8 + '@types/lodash-es': 4.17.12 + '@types/sortablejs': 1.15.8 + '@types/tinycolor2': 1.4.6 + '@types/validator': 13.15.3 + dayjs: 1.11.18 + lodash-es: 4.17.21 + mitt: 3.0.1 + sortablejs: 1.15.6 + tdesign-icons-vue-next: 0.4.1(vue@3.5.20) + tinycolor2: 1.6.0 + validator: 13.15.15 + vue: 3.5.20 + temp-dir@2.0.0: {} tempy@0.6.0: @@ -6780,6 +6911,8 @@ snapshots: commander: 2.20.3 source-map-support: 0.5.21 + tinycolor2@1.6.0: {} + tinyglobby@0.2.12: dependencies: fdir: 6.4.3(picomatch@4.0.2) @@ -7027,6 +7160,8 @@ snapshots: uuid@9.0.1: {} + validator@13.15.15: {} + varint@6.0.0: {} vite-plugin-pwa@1.0.3(@vite-pwa/assets-generator@1.0.0)(vite@5.4.17(sass-embedded@1.86.3)(sass@1.86.3)(terser@5.39.0))(workbox-build@7.3.0)(workbox-window@7.3.0): diff --git a/src/assets/fonts/TCloudNumberVF.ttf b/src/assets/fonts/TCloudNumberVF.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6abfb9255308f4e2fc2594e05af18dcd1cc81ce3 GIT binary patch literal 13160 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 literal 0 HcmV?d00001 diff --git a/src/components/ExamConfigEditor.vue b/src/components/ExamConfigEditor.vue index a7cf125..d3efa2b 100644 --- a/src/components/ExamConfigEditor.vue +++ b/src/components/ExamConfigEditor.vue @@ -1073,6 +1073,8 @@ export default { } }, + + /** * 确认删除配置 */ diff --git a/src/components/MigrationTool.vue b/src/components/MigrationTool.vue index a10c655..ed5993d 100644 --- a/src/components/MigrationTool.vue +++ b/src/components/MigrationTool.vue @@ -225,7 +225,7 @@ + + diff --git a/src/pages/exam-player.vue b/src/pages/exam-player.vue new file mode 100644 index 0000000..b03877a --- /dev/null +++ b/src/pages/exam-player.vue @@ -0,0 +1,216 @@ + + + + diff --git a/src/utils/api.js b/src/utils/api.js index 34a7d16..69be721 100644 --- a/src/utils/api.js +++ b/src/utils/api.js @@ -44,4 +44,4 @@ export const getNamespaceInfo = async () => { } catch (error) { throw new Error(error.response?.data?.message || "获取命名空间信息失败"); } -}; \ No newline at end of file +}; diff --git a/src/utils/providers/kvServerProvider.js b/src/utils/providers/kvServerProvider.js index fca4f2a..72d9dcc 100644 --- a/src/utils/providers/kvServerProvider.js +++ b/src/utils/providers/kvServerProvider.js @@ -23,7 +23,6 @@ export const kvServerProvider = { async loadNamespaceInfo() { try { // 使用 Classworks Cloud 或者用户配置的服务器域名 - const provider = getSetting("server.provider"); const serverUrl = getSetting("server.domain"); const res = await axios.get(`${serverUrl}/kv/_info`, { diff --git a/vite.config.mjs b/vite.config.mjs index 1f73778..b4354a5 100644 --- a/vite.config.mjs +++ b/vite.config.mjs @@ -7,6 +7,7 @@ import Vue from '@vitejs/plugin-vue' import VueRouter from 'unplugin-vue-router/vite' import Vuetify, { transformAssetUrls } from 'vite-plugin-vuetify' import { VitePWA } from 'vite-plugin-pwa' +import { TDesignResolver } from 'unplugin-vue-components/resolvers' // Utilities import { defineConfig } from 'vite' @@ -154,7 +155,13 @@ export default defineConfig({ configFile: 'src/styles/settings.scss', }, }), - Components(), + Components({ + resolvers: [ + TDesignResolver({ + library: 'vue-next' + }) + ] + }), Fonts({ google: { families: [{