diff --git a/src/admin/api.ts b/src/admin/api.ts index 343e3bc..1c0b0d5 100644 --- a/src/admin/api.ts +++ b/src/admin/api.ts @@ -1,5 +1,5 @@ import http from "utils/http" -import { Problem, User } from "~/utils/types" +import { Problem, TestcaseUploadedReturns, User } from "~/utils/types" export function getBaseInfo() { return http.get("admin/dashboard_info") @@ -90,3 +90,13 @@ export async function uploadImage(file: File): Promise { }) return res.success ? res.file_path : "" } + +// 上传测试用例 +export function uploadTestcases(file: File) { + const form = new window.FormData() + form.append("file", file) + form.append("spj", "false") + return http.post("admin/test_case", form, { + headers: { "content-type": "multipart/form-data" }, + }) +} diff --git a/src/admin/problem/detail.vue b/src/admin/problem/detail.vue index c036514..cd508f7 100644 --- a/src/admin/problem/detail.vue +++ b/src/admin/problem/detail.vue @@ -2,18 +2,20 @@ import TextEditor from "~/shared/TextEditor.vue" import Monaco from "~/shared/Monaco.vue" -import { SelectOption } from "naive-ui" -import { encode, unique } from "~/utils/functions" -import { LANGUAGE, Problem, Tag } from "~/utils/types" +import { SelectOption, UploadCustomRequestOptions } from "naive-ui" +import { unique } from "~/utils/functions" +import { LANGUAGE, Problem, Tag, Testcase } from "~/utils/types" import { getProblemTagList } from "~/shared/api" import { LANGUAGE_SHOW_VALUE, CODE_TEMPLATES } from "~/utils/constants" +import { uploadTestcases } from "../api" + interface AlterProblem { spj_language: string spj_code: string spj_compile_ok: boolean test_case_id: string - test_case_score: any[] + test_case_score: Testcase[] } type ExcludeKeys = @@ -44,7 +46,11 @@ const problem = reactive & AlterProblem>({ tags: [], languages: ["C", "Python3"], template: {}, - samples: [{ input: "", output: "" }], + samples: [ + { input: "", output: "" }, + { input: "", output: "" }, + { input: "", output: "" }, + ], spj: false, spj_language: "", spj_code: "", @@ -62,6 +68,7 @@ const problem = reactive & AlterProblem>({ }) const template = reactive(JSON.parse(JSON.stringify(CODE_TEMPLATES))) +const currentActiveTemplate = ref("C") const existingTags = shallowRef([]) const fromExistingTags = shallowRef([]) @@ -120,6 +127,30 @@ function resetTemplate(language: LANGUAGE) { template[language] = CODE_TEMPLATES[language] } +async function handleUploadTestcases({ file }: UploadCustomRequestOptions) { + try { + const res = await uploadTestcases(file.file!) + // @ts-ignore: + if (res.error) { + message.error("上传测试用例失败") + return + } + const testcases = res.data.info + for (let file of testcases) { + file.score = (100 / testcases.length).toFixed(0) + if (!file.output_name && problem.spj) { + file.output_name = "-" + } + } + problem.test_case_score = testcases + problem.test_case_id = res.data.id + } catch (err) { + message.error("上传测试用例失败") + } +} + +function downloadTestcases() {} + function saveProblem() { if (!needTemplate.value) { problem.template = {} @@ -148,35 +179,23 @@ watch([fromExistingTags, newTags], (tags) => { diff --git a/src/utils/types.ts b/src/utils/types.ts index 0a0a260..8ec74ad 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -262,3 +262,18 @@ export interface ContestRank { submission_info: { [key: string]: SubmissionInfo } contest: number } + +export interface TestcaseUploadedReturns { + id: string + info: Testcase[] + spj: boolean +} + +export interface Testcase { + stripped_output_md5: string + input_size: number + output_size: number + input_name: string + output_name: string + score?: string +}