This commit is contained in:
2023-01-20 12:29:32 +08:00
parent 40fae1c7c0
commit 0b2d9e3efd
23 changed files with 271 additions and 150 deletions

144
package-lock.json generated
View File

@@ -10,13 +10,14 @@
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"@monaco-editor/loader": "^1.3.2",
"@vueuse/core": "^9.10.0",
"@vueuse/integrations": "^9.10.0",
"axios": "^1.2.2",
"@vueuse/core": "^9.11.0",
"@vueuse/integrations": "^9.11.0",
"axios": "^1.2.3",
"copy-text-to-clipboard": "^3.0.1",
"highlight.js": "^11.7.0",
"naive-ui": "^2.34.3",
"party-js": "^2.2.0",
"pinia": "^2.0.28",
"pinia": "^2.0.29",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
},
@@ -24,6 +25,7 @@
"@iconify-json/ep": "^1.1.8",
"@types/node": "^18.11.18",
"@vitejs/plugin-vue": "^4.0.0",
"markdown-it-highlightjs": "^4.0.1",
"monaco-editor": "^0.34.1",
"prettier": "^2.8.3",
"typescript": "^4.9.4",
@@ -809,6 +811,11 @@
"csstype": "^2.6.8"
}
},
"node_modules/@vue/runtime-dom/node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"node_modules/@vue/server-renderer": {
"version": "3.2.45",
"resolved": "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.45.tgz",
@@ -827,13 +834,13 @@
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"node_modules/@vueuse/core": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.10.0.tgz",
"integrity": "sha512-CxMewME07qeuzuT/AOIQGv0EhhDoojniqU6pC3F8m5VC76L47UT18DcX88kWlP3I7d3qMJ4u/PD8iSRsy3bmNA==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.11.0.tgz",
"integrity": "sha512-7yZJ8LNOssA8ZmeSjd4F+wbFBA4csiP4TiaXgruqg1H4PAtzSkv93PPwFLvQkSnfo3Bar+e+6QoRvWjhz7l2Xg==",
"dependencies": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.10.0",
"@vueuse/shared": "9.10.0",
"@vueuse/metadata": "9.11.0",
"@vueuse/shared": "9.11.0",
"vue-demi": "*"
}
},
@@ -860,12 +867,12 @@
}
},
"node_modules/@vueuse/integrations": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-9.10.0.tgz",
"integrity": "sha512-MLGVbN3i9gRq3pb8VRZXgPvbNJcUUvgR5pmbc1QZj4Z1vvsvxam159AwWEJdyX2I39a1E7EkmBujtiXtVckO5g==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-9.11.0.tgz",
"integrity": "sha512-t6ox9R1sDOBzHWaycv5bti4t8o0oFyAQx98zDjCxtcrwkyib0ZKtyf/dIHGFS9kHk4ycOT3nwS47A/jXOGfxaQ==",
"dependencies": {
"@vueuse/core": "9.10.0",
"@vueuse/shared": "9.10.0",
"@vueuse/core": "9.11.0",
"@vueuse/shared": "9.11.0",
"vue-demi": "*"
},
"peerDependencies": {
@@ -940,14 +947,14 @@
}
},
"node_modules/@vueuse/metadata": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.10.0.tgz",
"integrity": "sha512-G5VZhgTCapzU9rv0Iq2HBrVOSGzOKb+OE668NxhXNcTjUjwYxULkEhAw70FtRLMZc+hxcFAzDZlKYA0xcwNMuw=="
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.11.0.tgz",
"integrity": "sha512-HhtG2SWkcfZBLbamHdvLn7jKOCFpw/ifXjVTd5ilFkj98WVUk/3UTQ03wF1XIkuhSO4+b45hD2lfG9/GdKCF7w=="
},
"node_modules/@vueuse/shared": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.10.0.tgz",
"integrity": "sha512-vakHJ2ZRklAzqmcVBL38RS7BxdBA4+5poG9NsSyqJxrt9kz0zX3P5CXMy0Hm6LFbZXUgvKdqAS3pUH1zX/5qTQ==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.11.0.tgz",
"integrity": "sha512-8lO7wD5abYxupKy2KynH1pSgP715ky6iCrWYb8aX2AuAVi9uHXj7qE1dw6BnmArSaLHci4x9iuzWPCpAzUkC/A==",
"dependencies": {
"vue-demi": "*"
}
@@ -1019,9 +1026,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"node_modules/axios": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.2.2.tgz",
"integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
"version": "1.2.3",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.2.3.tgz",
"integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"dependencies": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@@ -1127,16 +1134,11 @@
"csstype": "~3.0.5"
}
},
"node_modules/css-render/node_modules/csstype": {
"node_modules/csstype": {
"version": "3.0.11",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.0.11.tgz",
"integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw=="
},
"node_modules/csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"node_modules/date-fns": {
"version": "2.29.3",
"resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-2.29.3.tgz",
@@ -1641,6 +1643,15 @@
"markdown-it": "bin/markdown-it.js"
}
},
"node_modules/markdown-it-highlightjs": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/markdown-it-highlightjs/-/markdown-it-highlightjs-4.0.1.tgz",
"integrity": "sha512-EPXwFEN6P5nqR3G4KjT20r20xbGYKMMA/360hhSYFmeoGXTE6hsLtJAiB/8ID8slVH4CWHHEL7GX0YenyIstVQ==",
"dev": true,
"dependencies": {
"highlight.js": "^11.5.1"
}
},
"node_modules/markdown-it/node_modules/argparse": {
"version": "2.0.1",
"resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz",
@@ -1710,9 +1721,9 @@
}
},
"node_modules/minimatch": {
"version": "5.1.4",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.4.tgz",
"integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==",
"version": "5.1.6",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"dependencies": {
"brace-expansion": "^2.0.1"
@@ -3063,6 +3074,13 @@
"@vue/runtime-core": "3.2.45",
"@vue/shared": "3.2.45",
"csstype": "^2.6.8"
},
"dependencies": {
"csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
}
}
},
"@vue/server-renderer": {
@@ -3080,13 +3098,13 @@
"integrity": "sha512-Ewzq5Yhimg7pSztDV+RH1UDKBzmtqieXQlpTVm2AwraoRL/Rks96mvd8Vgi7Lj+h+TH8dv7mXD3FRZR3TUvbSg=="
},
"@vueuse/core": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.10.0.tgz",
"integrity": "sha512-CxMewME07qeuzuT/AOIQGv0EhhDoojniqU6pC3F8m5VC76L47UT18DcX88kWlP3I7d3qMJ4u/PD8iSRsy3bmNA==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-9.11.0.tgz",
"integrity": "sha512-7yZJ8LNOssA8ZmeSjd4F+wbFBA4csiP4TiaXgruqg1H4PAtzSkv93PPwFLvQkSnfo3Bar+e+6QoRvWjhz7l2Xg==",
"requires": {
"@types/web-bluetooth": "^0.0.16",
"@vueuse/metadata": "9.10.0",
"@vueuse/shared": "9.10.0",
"@vueuse/metadata": "9.11.0",
"@vueuse/shared": "9.11.0",
"vue-demi": "*"
},
"dependencies": {
@@ -3099,12 +3117,12 @@
}
},
"@vueuse/integrations": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-9.10.0.tgz",
"integrity": "sha512-MLGVbN3i9gRq3pb8VRZXgPvbNJcUUvgR5pmbc1QZj4Z1vvsvxam159AwWEJdyX2I39a1E7EkmBujtiXtVckO5g==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/integrations/-/integrations-9.11.0.tgz",
"integrity": "sha512-t6ox9R1sDOBzHWaycv5bti4t8o0oFyAQx98zDjCxtcrwkyib0ZKtyf/dIHGFS9kHk4ycOT3nwS47A/jXOGfxaQ==",
"requires": {
"@vueuse/core": "9.10.0",
"@vueuse/shared": "9.10.0",
"@vueuse/core": "9.11.0",
"@vueuse/shared": "9.11.0",
"vue-demi": "*"
},
"dependencies": {
@@ -3117,14 +3135,14 @@
}
},
"@vueuse/metadata": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.10.0.tgz",
"integrity": "sha512-G5VZhgTCapzU9rv0Iq2HBrVOSGzOKb+OE668NxhXNcTjUjwYxULkEhAw70FtRLMZc+hxcFAzDZlKYA0xcwNMuw=="
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/metadata/-/metadata-9.11.0.tgz",
"integrity": "sha512-HhtG2SWkcfZBLbamHdvLn7jKOCFpw/ifXjVTd5ilFkj98WVUk/3UTQ03wF1XIkuhSO4+b45hD2lfG9/GdKCF7w=="
},
"@vueuse/shared": {
"version": "9.10.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.10.0.tgz",
"integrity": "sha512-vakHJ2ZRklAzqmcVBL38RS7BxdBA4+5poG9NsSyqJxrt9kz0zX3P5CXMy0Hm6LFbZXUgvKdqAS3pUH1zX/5qTQ==",
"version": "9.11.0",
"resolved": "https://registry.npmmirror.com/@vueuse/shared/-/shared-9.11.0.tgz",
"integrity": "sha512-8lO7wD5abYxupKy2KynH1pSgP715ky6iCrWYb8aX2AuAVi9uHXj7qE1dw6BnmArSaLHci4x9iuzWPCpAzUkC/A==",
"requires": {
"vue-demi": "*"
},
@@ -3173,9 +3191,9 @@
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
},
"axios": {
"version": "1.2.2",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.2.2.tgz",
"integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
"version": "1.2.3",
"resolved": "https://registry.npmmirror.com/axios/-/axios-1.2.3.tgz",
"integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"requires": {
"follow-redirects": "^1.15.0",
"form-data": "^4.0.0",
@@ -3259,19 +3277,12 @@
"requires": {
"@emotion/hash": "~0.8.0",
"csstype": "~3.0.5"
}
},
"dependencies": {
"csstype": {
"version": "3.0.11",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.0.11.tgz",
"integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw=="
}
}
},
"csstype": {
"version": "2.6.21",
"resolved": "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz",
"integrity": "sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w=="
},
"date-fns": {
"version": "2.29.3",
@@ -3659,6 +3670,15 @@
}
}
},
"markdown-it-highlightjs": {
"version": "4.0.1",
"resolved": "https://registry.npmmirror.com/markdown-it-highlightjs/-/markdown-it-highlightjs-4.0.1.tgz",
"integrity": "sha512-EPXwFEN6P5nqR3G4KjT20r20xbGYKMMA/360hhSYFmeoGXTE6hsLtJAiB/8ID8slVH4CWHHEL7GX0YenyIstVQ==",
"dev": true,
"requires": {
"highlight.js": "^11.5.1"
}
},
"mdurl": {
"version": "1.0.1",
"resolved": "https://registry.npmmirror.com/mdurl/-/mdurl-1.0.1.tgz",
@@ -3707,9 +3727,9 @@
"dev": true
},
"minimatch": {
"version": "5.1.4",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.4.tgz",
"integrity": "sha512-U0iNYXt9wALljzfnGkhFSy5sAC6/SCR3JrHrlsdJz4kF8MvhTRQNiC59iUi1iqsitV7abrNAJWElVL9pdnoUgw==",
"version": "5.1.6",
"resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-5.1.6.tgz",
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
"dev": true,
"requires": {
"brace-expansion": "^2.0.1"

View File

@@ -12,13 +12,14 @@
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"@monaco-editor/loader": "^1.3.2",
"@vueuse/core": "^9.10.0",
"@vueuse/integrations": "^9.10.0",
"axios": "^1.2.2",
"@vueuse/core": "^9.11.0",
"@vueuse/integrations": "^9.11.0",
"axios": "^1.2.3",
"copy-text-to-clipboard": "^3.0.1",
"highlight.js": "^11.7.0",
"naive-ui": "^2.34.3",
"party-js": "^2.2.0",
"pinia": "^2.0.28",
"pinia": "^2.0.29",
"vue": "^3.2.45",
"vue-router": "^4.1.6"
},
@@ -26,6 +27,7 @@
"@iconify-json/ep": "^1.1.8",
"@types/node": "^18.11.18",
"@vitejs/plugin-vue": "^4.0.0",
"markdown-it-highlightjs": "^4.0.1",
"monaco-editor": "^0.34.1",
"prettier": "^2.8.3",
"typescript": "^4.9.4",

View File

@@ -1,8 +1,22 @@
<script setup lang="ts">
import { zhCN, dateZhCN, darkTheme } from "naive-ui"
import { isDark } from "./shared/composables/dark"
import hljs from "highlight.js/lib/core"
import c from "highlight.js/lib/languages/c"
import cpp from "highlight.js/lib/languages/c"
import java from "highlight.js/lib/languages/java"
import python from "highlight.js/lib/languages/python"
import javascript from "highlight.js/lib/languages/javascript"
import go from "highlight.js/lib/languages/go"
const theme = computed(() => (isDark.value ? darkTheme : null))
hljs.registerLanguage("c", c)
hljs.registerLanguage("cpp", cpp)
hljs.registerLanguage("java", java)
hljs.registerLanguage("python", python)
hljs.registerLanguage("javascript", javascript)
hljs.registerLanguage("go", go)
</script>
<template>
@@ -11,6 +25,7 @@ const theme = computed(() => (isDark.value ? darkTheme : null))
:theme="theme"
:locale="zhCN"
:date-locale="dateZhCN"
:hljs="hljs"
>
<router-view></router-view>
</n-config-provider>

View File

@@ -207,6 +207,7 @@ declare global {
const useParallax: typeof import('@vueuse/core')['useParallax']
const usePermission: typeof import('@vueuse/core')['usePermission']
const usePointer: typeof import('@vueuse/core')['usePointer']
const usePointerLock: typeof import('@vueuse/core')['usePointerLock']
const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe']
const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme']
const usePreferredContrast: typeof import('@vueuse/core')['usePreferredContrast']

4
src/components.d.ts vendored
View File

@@ -12,15 +12,15 @@ declare module '@vue/runtime-core' {
IEpLoading: typeof import('~icons/ep/loading')['default']
NAlert: typeof import('naive-ui')['NAlert']
NButton: typeof import('naive-ui')['NButton']
NCard: typeof import('naive-ui')['NCard']
NCode: typeof import('naive-ui')['NCode']
NConfigProvider: typeof import('naive-ui')['NConfigProvider']
NDataTable: typeof import('naive-ui')['NDataTable']
NDescriptions: typeof import('naive-ui')['NDescriptions']
NDescriptionsItem: typeof import('naive-ui')['NDescriptionsItem']
NDropdown: typeof import('naive-ui')['NDropdown']
NForm: typeof import('naive-ui')['NForm']
NFormGrid: typeof import('naive-ui')['NFormGrid']
NFormItem: typeof import('naive-ui')['NFormItem']
NFormItemGi: typeof import('naive-ui')['NFormItemGi']
NGi: typeof import('naive-ui')['NGi']
NGrid: typeof import('naive-ui')['NGrid']
NIcon: typeof import('naive-ui')['NIcon']

View File

@@ -1 +0,0 @@
<template>loading...</template>

View File

@@ -1,16 +1,13 @@
<script setup lang="ts">
import Loading from "./components/Loading.vue"
import Monaco from "../shared/Monaco.vue"
import raw from "./step-1/1.c?raw"
const route = useRoute()
const step = route.hash.replace("#step-", "") || "1"
const id = route.hash.replace("#step-", "") || "1"
const Md = defineAsyncComponent({
loader: () => import(`./step-${step}/index.md`),
loadingComponent: Loading,
})
const Md = defineAsyncComponent(() => import(`./step-${id}/index.md`))
const code = ref("")
const code = ref(raw)
function change(value: string) {
code.value = value
@@ -21,6 +18,10 @@ function change(value: string) {
<n-grid :cols="2">
<n-gi>
<Md />
<n-space justify="space-between">
<n-button text type="primary">上一步</n-button>
<n-button text type="primary">下一步</n-button>
</n-space>
</n-gi>
<n-gi>
<Monaco :value="code" @change="change" />

6
src/learn/step-1/1.c Normal file
View File

@@ -0,0 +1,6 @@
#include <stdio.h>
int main()
{
return 0;
}

View File

@@ -1,13 +1 @@
# 我的是第一步骤
```c
#include<stdio.h>
int main() {
return 0;
}
```
## nihao
我的
# 11

View File

@@ -1,6 +1,5 @@
import { createRouter, createWebHistory } from "vue-router"
import { createPinia } from "pinia"
import loader from "@monaco-editor/loader"
import storage from "utils/storage"
import { STORAGE_KEY } from "utils/constants"
@@ -9,6 +8,7 @@ import { routes } from "./routes"
import App from "./App.vue"
import { toggleLogin } from "./shared/composables/modal"
import { init } from "./shared/composables/monaco"
const router = createRouter({
history: createWebHistory(),
@@ -27,24 +27,8 @@ router.beforeEach((to, from, next) => {
next()
}
})
init()
const pinia = createPinia()
loader.init().then((monaco) => {
window.monaco = monaco
fetch("/dark.json").then((data) =>
data.json().then((theme) => monaco.editor.defineTheme("dark", theme))
)
fetch("/light.json").then((data) =>
data.json().then((theme) => monaco.editor.defineTheme("light", theme))
)
})
loader.config({
paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.34.1/min/vs" },
"vs/nls": { availableLanguages: { "*": "zh-cn" } },
})
const app = createApp(App)
app.use(router)
app.use(pinia)

View File

@@ -36,7 +36,7 @@ function change(value: string) {
<n-form-item>
<n-space>
<n-button @click="reset">重置</n-button>
<n-button @click="$router.push(`/status?problem=${problem._id}`)">
<n-button @click="$router.push(`/submission?problem=${problem._id}`)">
提交信息
</n-button>
</n-space>

View File

@@ -7,7 +7,7 @@ import { SOURCES, JUDGE_STATUS, SubmissionStatus } from "utils/constants"
import { submissionMemoryFormat, submissionTimeFormat } from "utils/functions"
import { Problem, Submission, SubmitCodePayload } from "utils/types"
import { getSubmission, submitCode } from "oj/api"
import SubmissionResultTag from "../../components/SubmissionResultTag.vue"
import SubmissionResultTag from "../../../shared/SubmissionResultTag.vue"
import { DataTableColumn } from "naive-ui"
const problem = inject<Ref<Problem>>("problem")

View File

@@ -1,5 +0,0 @@
<script setup lang="ts"></script>
<template>status detail</template>
<style scoped></style>

View File

@@ -0,0 +1,80 @@
<script setup lang="ts">
import { getSubmission } from "oj/api"
import { Submission } from "utils/types"
import { JUDGE_STATUS, LANGUAGE_VALUE } from "utils/constants"
import {
parseTime,
submissionMemoryFormat,
submissionTimeFormat,
} from "utils/functions"
import { DataTableColumn, NAlert, NDataTable } from "naive-ui"
import copy from "copy-text-to-clipboard"
import SubmissionResultTag from "~/shared/SubmissionResultTag.vue"
const props = defineProps<{
submissionID: string
}>()
const submission = ref<Submission>()
async function init() {
const res = await getSubmission(props.submissionID)
submission.value = res.data
}
const columns: DataTableColumn<Submission["info"]["data"][number]>[] = [
{ title: "测试用例", key: "test_case" },
{
title: "测试状态",
key: "result",
render: (row) => h(SubmissionResultTag, { result: row.result }),
},
{
title: "占用内存",
key: "memory",
render: (row) => submissionMemoryFormat(row.memory),
},
{
title: "执行耗时",
key: "real_time",
render: (row) => submissionTimeFormat(row.real_time),
},
{ title: "信号", key: "signal" },
]
onMounted(init)
</script>
<template>
<n-space vertical v-if="submission" :size="24">
<n-alert
:type="JUDGE_STATUS[submission.result]['type']"
:title="JUDGE_STATUS[submission.result]['name']"
>
<n-space>
<span>提交时间{{ parseTime(submission.create_time) }}</span>
<span>语言{{ submission.language }}</span>
<span>提交人 {{ submission.username }}</span>
</n-space>
</n-alert>
<n-card embedded>
<n-space justify="end">
<n-button @click="copy(submission!.code)">复制代码</n-button>
</n-space>
<n-code
class="code"
word-wrap
:language="LANGUAGE_VALUE[submission.language]"
:code="submission.code"
show-line-numbers
/>
</n-card>
<n-data-table :columns="columns" :data="submission.info.data" />
</n-space>
</template>
<style scoped>
.code {
font-size: 20px;
}
</style>

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { DataTableColumn, SelectOption } from "naive-ui"
import { NButton } from "naive-ui"
import SubmissionResultTag from "oj/components/SubmissionResultTag.vue"
import SubmissionResultTag from "~/shared/SubmissionResultTag.vue"
import Pagination from "~/shared/Pagination.vue"
import {
submissionMemoryFormat,
@@ -23,8 +23,6 @@ interface Query {
const route = useRoute()
const router = useRouter()
const problemID = <string>route.query.problem ?? ""
const contestID = <string>route.query.contest ?? ""
const submissions = ref([])
const total = ref(0)
@@ -57,8 +55,8 @@ async function listSubmissions() {
...query,
myself: query.myself ? "1" : "0",
offset,
problem_id: problemID,
contest_id: contestID,
problem_id: <string>route.query.problem ?? "",
contest_id: <string>route.params.contestID ?? "",
})
submissions.value = res.data.results
total.value = res.data.total
@@ -98,7 +96,7 @@ watch(
)
watch(
() => route.path === "/status" && route.query,
() => route.path === "/submission" && route.query,
(newVal) => {
if (newVal) listSubmissions()
}
@@ -116,7 +114,15 @@ const columns: DataTableColumn<Submission>[] = [
title: "编号",
key: "id",
render: (row) =>
h(NButton, { text: true, type: "info" }, () => row.id.slice(0, 12)),
h(
NButton,
{
text: true,
type: "info",
onClick: () => router.push("/submission/" + row.id),
},
() => row.id.slice(0, 12)
),
},
{
title: "状态",

View File

@@ -11,13 +11,13 @@ export const routes = [
name: "ProblemDetail",
},
{
path: "status",
component: () => import("oj/status/list.vue"),
path: "submission",
component: () => import("oj/submission/list.vue"),
meta: { requiresAuth: true },
},
{
path: "status/:statusID",
component: () => import("oj/status/detail.vue"),
path: "submission/:submissionID",
component: () => import("oj/submission/detail.vue"),
props: true,
},
{

View File

@@ -45,7 +45,8 @@ const menus: MenuOption[] = [
key: "contest",
},
{
label: () => h(RouterLink, { to: "/status" }, { default: () => "提交" }),
label: () =>
h(RouterLink, { to: "/submission" }, { default: () => "提交" }),
key: "status",
},
{

View File

@@ -4,6 +4,7 @@ import { LANGUAGE_VALUE } from "utils/constants"
import { LANGUAGE } from "utils/types"
import { isMobile } from "~/shared/composables/breakpoints"
import { isDark } from "./composables/dark"
import { monaco } from "./composables/monaco"
interface Props {
value: string
@@ -15,7 +16,7 @@ interface Props {
const props = withDefaults(defineProps<Props>(), {
language: "C",
height: "100%",
height: "calc(100vh - 92px)",
fontSize: 20,
class: "",
})
@@ -26,14 +27,16 @@ const emit = defineEmits<{
const monacoEditorRef = ref()
let editor: Monaco.editor.IStandaloneCodeEditor
let model: Monaco.editor.ITextModel
onMounted(function () {
const model = window.monaco.editor.createModel(
onMounted(() => {
if (!monaco.value) return
model = monaco.value!.editor.createModel(
props.value,
LANGUAGE_VALUE[props.language]
)
editor = window.monaco.editor.create(monacoEditorRef.value, {
editor = monaco.value!.editor.create(monacoEditorRef.value, {
model,
theme: isDark.value ? "dark" : "light", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: {
@@ -70,7 +73,8 @@ onMounted(function () {
})
watchEffect(() => {
window.monaco.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language])
if (!monaco.value) return
monaco.value.editor.setModelLanguage(model, LANGUAGE_VALUE[props.language])
})
watchEffect(() => {
@@ -80,16 +84,17 @@ onMounted(function () {
})
watchEffect(() => {
window.monaco.editor.setTheme(isDark.value ? "dark" : "light")
if (!monaco.value) return
monaco.value.editor.setTheme(isDark.value ? "dark" : "light")
})
})
onUnmounted(() => {
editor && editor.dispose()
})
</script>
<template>
<div
v-if="monaco"
ref="monacoEditorRef"
:class="props.class"
:style="{ height: props.height }"

View File

@@ -1,6 +1,6 @@
<script setup lang="ts">
import { JUDGE_STATUS } from "../../utils/constants"
import { SUBMISSION_RESULT } from "../../utils/types"
import { JUDGE_STATUS } from "utils/constants"
import { SUBMISSION_RESULT } from "utils/types"
interface Props {
result: SUBMISSION_RESULT

View File

@@ -0,0 +1,19 @@
import loader, { Monaco } from "@monaco-editor/loader"
export const monaco = ref<Monaco>()
export async function init() {
loader.config({
paths: { vs: "https://cdn.staticfile.org/monaco-editor/0.34.1/min/vs" },
"vs/nls": { availableLanguages: { "*": "zh-cn" } },
})
const [m, light, dark] = await Promise.all([
loader.init(),
fetch("/light.json").then((t) => t.json()),
fetch("/dark.json").then((t) => t.json()),
])
monaco.value = m
monaco.value.editor.defineTheme("light", light)
monaco.value.editor.defineTheme("dark", dark)
}

11
src/shims.d.ts vendored
View File

@@ -3,14 +3,3 @@ declare module "*.md" {
const Component: ComponentOptions
export default Component
}
declare global {
let monaco: Monaco
interface Window {
monaco: Monaco
}
}
interface Window {
monaco: Monaco
}

View File

@@ -90,7 +90,7 @@ export interface Submission {
code: string
result: SUBMISSION_RESULT
info: Info
language: string
language: LANGUAGE
shared: boolean
statistic_info: {
score?: number

View File

@@ -7,6 +7,8 @@ import { NaiveUiResolver } from "unplugin-vue-components/resolvers"
import IconsResolver from "unplugin-icons/resolver"
import Icons from "unplugin-icons/vite"
import Markdown from "vite-plugin-vue-markdown"
import Highlight from "markdown-it-highlightjs"
import c from "highlight.js/lib/languages/c"
const url = "https://ojtest.hyyz.izhai.net"
const proxyConfig = {
@@ -52,7 +54,15 @@ export default defineConfig({
dts: "./src/components.d.ts",
}),
Icons({ autoInstall: true }),
Markdown(),
Markdown({
markdownItSetup(md) {
md.use(Highlight, {
register: {
c,
},
})
},
}),
],
server: {
proxy: {