diff --git a/src/admin/problem/components/BatchTagModal.vue b/src/admin/problem/components/BatchTagModal.vue new file mode 100644 index 0000000..1e780db --- /dev/null +++ b/src/admin/problem/components/BatchTagModal.vue @@ -0,0 +1,109 @@ + + + + + + 已选中 {{ problemIds.length }} 道题目 + + + {{ tag.name }}({{ tag.problem_count }}) + + + + + 取消 + 确定 + + + + diff --git a/src/admin/problem/list.vue b/src/admin/problem/list.vue index bfd306d..0dd98ee 100644 --- a/src/admin/problem/list.vue +++ b/src/admin/problem/list.vue @@ -11,6 +11,8 @@ import Actions from "./components/Actions.vue" import Modal from "./components/Modal.vue" import { useRouteQuery } from "@vueuse/router" import AuthorSelect from "shared/components/AuthorSelect.vue" +import type { DataTableRowKey } from "naive-ui" +import BatchTagModal from "./components/BatchTagModal.vue" interface Props { contestID?: string @@ -36,6 +38,30 @@ const { count, inc } = useCounter(0) const total = ref(0) const problems = ref([]) +const selectedRowKeys = ref([]) +const batchTagAction = ref<"add" | "remove">("add") +const [showBatchTag, toggleBatchTag] = useToggle(false) + +const selectedProblemIds = computed(() => + selectedRowKeys.value.map((key) => Number(key)), +) + +const rowKey = (row: AdminProblemFiltered) => row.id + +function chooseProblems(rowKeys: DataTableRowKey[]) { + selectedRowKeys.value = rowKeys +} + +function openBatchTag(action: "add" | "remove") { + batchTagAction.value = action + toggleBatchTag(true) +} + +function onBatchTagDone() { + selectedRowKeys.value = [] + listProblems() +} + const nextDisplayID = computed(() => { if (!isContestProblemList.value) return "" if (problems.value.length === 0) return "1" @@ -57,7 +83,7 @@ const { query, clearQuery } = usePagination({ author: useRouteQuery("author", "").value, }) -const columns: DataTableColumn[] = [ +const baseColumns: DataTableColumn[] = [ { title: "ID", key: "id", width: 100 }, { title: "显示编号", key: "_id", width: 100 }, { title: "标题", key: "title", minWidth: 200 }, @@ -141,6 +167,12 @@ const columns: DataTableColumn[] = [ }, ] +const columns = computed[]>(() => + isContestProblemList.value + ? baseColumns + : [{ type: "selection" }, ...baseColumns], +) + async function listProblems() { if (query.page < 1) query.page = 1 const offset = (query.page - 1) * query.limit @@ -212,8 +244,20 @@ watch(() => [query.page, query.limit, query.author], listProblems) > 年度趋势 + + 标签管理 + + + + 添加标签({{ selectedProblemIds.length }}) + + 移除标签 + 新建比赛题目 @@ -238,7 +282,13 @@ watch(() => [query.page, query.limit, query.author], listProblems) - + [query.page, query.limit, query.author], listProblems) :next-display-id="nextDisplayID" @change="listProblems" /> +