fix click textarea.

This commit is contained in:
2023-03-30 09:46:39 +08:00
parent c97b2c4879
commit 301fc1be6d
6 changed files with 63 additions and 22 deletions

View File

@@ -3,6 +3,7 @@ import { deleteContestProblem, deleteProblem } from "~/admin/api"
interface Props {
problemID: number
problemDisplayID: string
}
const props = defineProps<Props>()
const emit = defineEmits(["deleted"])
@@ -37,13 +38,20 @@ function goEdit() {
const name = route.name!.toString().replace("list", "edit")
router.push({ name, params: { problemID: props.problemID } })
}
function goCheck() {
const data = router.resolve("/problem/" + props.problemDisplayID)
window.open(data.href, "_blank")
}
</script>
<template>
<n-space align="center">
<n-button size="small" secondary type="primary" @click="goEdit">
编辑
</n-button>
<n-button size="small" secondary type="info">查看</n-button>
<n-button size="small" secondary type="info" @click="goCheck">
查看
</n-button>
<n-popconfirm @positive-click="handleDeleteProblem">
<template #trigger>
<n-button secondary size="small" type="error">删除</n-button>

View File

@@ -7,7 +7,7 @@ import { unique } from "~/utils/functions"
import { BlankProblem, LANGUAGE, Tag } from "~/utils/types"
import { getProblemTagList } from "~/shared/api"
import { LANGUAGE_SHOW_VALUE, CODE_TEMPLATES } from "~/utils/constants"
import download from "~/utils/download"
import {
createContestProblem,
createProblem,
@@ -192,8 +192,9 @@ async function handleUploadTestcases({ file }: UploadCustomRequestOptions) {
}
}
// TODO: 还没有完成
function downloadTestcases() {}
function downloadTestcases() {
download("test_case?problem_id=" + problem.id)
}
// 题目是否有漏写的
function detectProblemCompletion() {
@@ -265,7 +266,6 @@ async function submit() {
if (notComplete) return
getTemplate()
problem.tags = [...newTags.value, ...fromExistingTags.value]
console.log(problem)
const api = {
"admin problem create": createProblem,
"admin problem edit": editProblem,
@@ -299,7 +299,7 @@ async function submit() {
}
} catch (err: any) {
if (err.data === "Display ID already exists") {
message.error("显示编号重复了,请换一个编号")
message.error("显示编号重复了,请换一个显示编号")
} else {
message.error(err.data)
}
@@ -307,15 +307,14 @@ async function submit() {
}
onMounted(() => {
listTags()
getProblemDetail()
if (
route.name === "admin problem create" ||
route.name === "admin contest problem create"
) {
toggleReady(true)
}
listTags()
getProblemDetail()
})
watch([fromExistingTags, newTags], (tags) => {
@@ -443,7 +442,13 @@ watch([fromExistingTags, newTags], (tags) => {
{{ problem.test_case_score.length }}
条测试用例
</div>
<n-button tertiary type="info" size="small" @click="downloadTestcases">
<n-button
v-if="problem.id"
tertiary
type="info"
size="small"
@click="downloadTestcases"
>
下载
</n-button>
</n-space>

View File

@@ -48,6 +48,7 @@ const columns: DataTableColumn<AdminProblemFiltered>[] = [
render: (row) =>
h(Actions, {
problemID: row.id,
problemDisplayID: row._id,
onDeleted: listProblems,
}),
},

View File

@@ -28,7 +28,7 @@ async function handleLogout() {
onMounted(userStore.getMyProfile)
const menus: MenuOption[] = [
const menus = computed<MenuOption[]>(() => [
{
label: () =>
h(RouterLink, { to: "/learn/step-1" }, { default: () => "自学" }),
@@ -51,9 +51,14 @@ const menus: MenuOption[] = [
label: () => h(RouterLink, { to: "/rank" }, { default: () => "排名" }),
key: "rank",
},
]
{
label: () => h(RouterLink, { to: "/admin" }, { default: () => "后台" }),
show: userStore.isAdminRole,
key: "admin",
},
])
const options = computed<Array<DropdownOption | DropdownDividerOption>>(() => [
const options: Array<DropdownOption | DropdownDividerOption> = [
{
label: "我的主页",
key: "home",
@@ -75,17 +80,9 @@ const options = computed<Array<DropdownOption | DropdownDividerOption>>(() => [
onClick: () => router.push("/setting"),
},
},
{
label: "后台管理",
key: "admin",
show: userStore.isAdminRole,
props: {
onClick: () => router.push("/admin"),
},
},
{ type: "divider" },
{ label: "退出", key: "logout", props: { onClick: handleLogout } },
])
]
function run() {
console.log(code.value)

View File

@@ -39,6 +39,12 @@ onBeforeUnmount(() => {
if (editor) editor.destroy()
})
function onClick() {
if (!editorRef.value) return
editorRef.value.blur()
editorRef.value.focus()
}
function handleCreated(editor: IDomEditor) {
editorRef.value = editor
}
@@ -66,6 +72,7 @@ async function customUpload(file: File, insertFn: InsertFnType) {
mode="simple"
/>
<Editor
@click="onClick"
:style="{ minHeight: props.minHeight + 'px' }"
v-model="rawHtml"
:defaultConfig="editorConfig"

23
src/utils/download.ts Normal file
View File

@@ -0,0 +1,23 @@
import axios from "axios"
const http = axios.create({
baseURL: "/api/admin",
responseType: "blob",
xsrfHeaderName: "X-CSRFToken",
xsrfCookieName: "csrftoken",
})
async function download(url: string) {
const res = await http.get(url)
const headers = res.headers
const link = document.createElement("a")
link.href = window.URL.createObjectURL(
new window.Blob([res.data], { type: headers["content-type"] })
)
link.download = (headers["content-disposition"] || "").split("filename=")[1]
document.body.appendChild(link)
link.click()
link.remove()
}
export default download