@@ -1,25 +1,32 @@
|
||||
<script setup lang="ts">
|
||||
import { NTag } from "naive-ui"
|
||||
import { getContestList } from "oj/api"
|
||||
import { duration, filterEmptyValue, parseTime } from "utils/functions"
|
||||
import { duration, parseTime } from "utils/functions"
|
||||
import { Contest } from "utils/types"
|
||||
import ContestTitle from "~/shared/components/ContestTitle.vue"
|
||||
import Pagination from "~/shared/components/Pagination.vue"
|
||||
import { toggleLogin } from "~/shared/composables/modal"
|
||||
import { usePagination } from "~/shared/composables/pagination"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
import { CONTEST_STATUS, ContestType } from "~/utils/constants"
|
||||
import { renderTableTitle } from "~/utils/renders"
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const userStore = useUserStore()
|
||||
const query = reactive({
|
||||
page: parseInt(<string>route.query.page) || 1,
|
||||
limit: parseInt(<string>route.query.limit) || 10,
|
||||
keyword: <string>route.query.keyword ?? "",
|
||||
status: <string>route.query.status ?? "",
|
||||
tag: <string>route.query.tag ?? "",
|
||||
|
||||
interface ContestQuery {
|
||||
keyword: string
|
||||
status: string
|
||||
tag: string
|
||||
}
|
||||
|
||||
// 使用分页 composable
|
||||
const { query, clearQuery } = usePagination<ContestQuery>({
|
||||
keyword: "",
|
||||
status: "",
|
||||
tag: "",
|
||||
})
|
||||
|
||||
const data = ref<Contest[]>([])
|
||||
const total = ref(0)
|
||||
|
||||
@@ -88,45 +95,28 @@ async function listContests() {
|
||||
total.value = res.data.total
|
||||
}
|
||||
|
||||
function routerPush() {
|
||||
router.push({
|
||||
path: route.path,
|
||||
query: filterEmptyValue(query),
|
||||
})
|
||||
}
|
||||
|
||||
function search(value: string) {
|
||||
query.keyword = value
|
||||
}
|
||||
|
||||
function clear() {
|
||||
query.keyword = ""
|
||||
query.status = ""
|
||||
query.tag = ""
|
||||
clearQuery()
|
||||
}
|
||||
|
||||
onMounted(listContests)
|
||||
watch(() => query.page, routerPush)
|
||||
watch(
|
||||
() => [query.limit, query.status, query.tag],
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
)
|
||||
|
||||
// 监听搜索关键词变化(防抖)
|
||||
watchDebounced(
|
||||
() => query.keyword,
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
listContests,
|
||||
{ debounce: 500, maxWait: 1000 },
|
||||
)
|
||||
|
||||
// 监听其他查询条件变化
|
||||
watch(
|
||||
() => route.name === "contests" && route.query,
|
||||
(newVal) => {
|
||||
if (newVal) listContests()
|
||||
},
|
||||
() => [query.page, query.limit, query.status, query.tag],
|
||||
listContests,
|
||||
)
|
||||
|
||||
function rowProps(row: Contest) {
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
import { Icon } from "@iconify/vue"
|
||||
import { NSpace, NTag } from "naive-ui"
|
||||
import { getProblemList } from "oj/api"
|
||||
import { filterEmptyValue, getTagColor } from "utils/functions"
|
||||
import { getTagColor } from "utils/functions"
|
||||
import { ProblemFiltered } from "utils/types"
|
||||
import { getProblemTagList } from "~/shared/api"
|
||||
import Hitokoto from "~/shared/components/Hitokoto.vue"
|
||||
import Pagination from "~/shared/components/Pagination.vue"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
import { usePagination } from "~/shared/composables/pagination"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
import { renderTableTitle } from "~/utils/renders"
|
||||
import ProblemStatus from "./components/ProblemStatus.vue"
|
||||
@@ -18,12 +19,10 @@ interface Tag {
|
||||
checked: boolean
|
||||
}
|
||||
|
||||
interface Query {
|
||||
interface ProblemQuery {
|
||||
keyword: string
|
||||
difficulty: string
|
||||
tag: string
|
||||
page: number
|
||||
limit: number
|
||||
}
|
||||
|
||||
const difficultyOptions = [
|
||||
@@ -34,7 +33,6 @@ const difficultyOptions = [
|
||||
]
|
||||
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
|
||||
const userStore = useUserStore()
|
||||
const problems = ref<ProblemFiltered[]>([])
|
||||
@@ -42,21 +40,14 @@ const total = ref(0)
|
||||
const tags = ref<Tag[]>([])
|
||||
const [showTag, toggleShowTag] = useToggle(isDesktop.value)
|
||||
|
||||
const query = reactive<Query>({
|
||||
keyword: <string>route.query.keyword ?? "",
|
||||
difficulty: <string>route.query.difficulty ?? "",
|
||||
tag: <string>route.query.tag ?? "",
|
||||
page: parseInt(<string>route.query.page) || 1,
|
||||
limit: parseInt(<string>route.query.limit) || 10,
|
||||
// 使用分页 composable
|
||||
const { query, clearQuery } = usePagination<ProblemQuery>({
|
||||
keyword: "",
|
||||
difficulty: "",
|
||||
tag: "",
|
||||
})
|
||||
|
||||
async function listProblems() {
|
||||
query.keyword = <string>route.query.keyword ?? ""
|
||||
query.difficulty = <string>route.query.difficulty ?? ""
|
||||
query.tag = <string>route.query.tag ?? ""
|
||||
query.page = parseInt(<string>route.query.page) || 1
|
||||
query.limit = parseInt(<string>route.query.limit) || 10
|
||||
|
||||
if (query.page < 1) query.page = 1
|
||||
const offset = (query.page - 1) * query.limit
|
||||
const res = await getProblemList(offset, query.limit, {
|
||||
@@ -76,12 +67,6 @@ async function listTags() {
|
||||
}))
|
||||
}
|
||||
|
||||
function routerPush() {
|
||||
router.push({
|
||||
path: route.path,
|
||||
query: filterEmptyValue(query),
|
||||
})
|
||||
}
|
||||
|
||||
function search(value: string) {
|
||||
query.keyword = value
|
||||
@@ -100,9 +85,7 @@ function chooseTag(tag: Tag) {
|
||||
}
|
||||
|
||||
function clear() {
|
||||
query.keyword = ""
|
||||
query.tag = ""
|
||||
query.difficulty = ""
|
||||
clearQuery()
|
||||
}
|
||||
|
||||
// async function getRandom() {
|
||||
@@ -110,22 +93,20 @@ function clear() {
|
||||
// router.push("/problem/" + res.data)
|
||||
// }
|
||||
|
||||
watch(() => query.page, routerPush)
|
||||
watch(
|
||||
() => [query.tag, query.difficulty, query.limit],
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
)
|
||||
// 监听搜索关键词变化(防抖)
|
||||
watchDebounced(
|
||||
() => query.keyword,
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
{ debounce: 500, maxWait: 1000 },
|
||||
listProblems,
|
||||
{ debounce: 500, maxWait: 1000 }
|
||||
)
|
||||
|
||||
// 监听其他查询条件变化
|
||||
watch(
|
||||
() => [query.tag, query.difficulty, query.limit, query.page],
|
||||
listProblems
|
||||
)
|
||||
|
||||
// 监听标签变化,更新标签选中状态
|
||||
watch(
|
||||
() => query.tag,
|
||||
() => {
|
||||
@@ -135,15 +116,16 @@ watch(
|
||||
}))
|
||||
},
|
||||
)
|
||||
watch(
|
||||
() => route.path === "/" && route.query,
|
||||
(newVal) => {
|
||||
if (newVal) listProblems()
|
||||
},
|
||||
)
|
||||
|
||||
// TODO: 这里会在登录时候执行两次,有BUG
|
||||
watch(() => userStore.isFinished && userStore.isAuthed, listProblems)
|
||||
// 监听用户认证状态变化,只在认证完成且已登录时刷新问题列表
|
||||
watch(
|
||||
() => userStore.isFinished && userStore.isAuthed,
|
||||
(isAuthenticatedAndFinished) => {
|
||||
if (isAuthenticatedAndFinished) {
|
||||
listProblems()
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
listProblems()
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { NButton, NH2, NText } from "naive-ui"
|
||||
import { adminRejudge, getSubmissions, getTodaySubmissionCount } from "oj/api"
|
||||
import { filterEmptyValue, parseTime } from "utils/functions"
|
||||
import { parseTime } from "utils/functions"
|
||||
import { LANGUAGE, SubmissionListItem } from "utils/types"
|
||||
import Pagination from "~/shared/components/Pagination.vue"
|
||||
import SubmissionResultTag from "~/shared/components/SubmissionResultTag.vue"
|
||||
import { isDesktop } from "~/shared/composables/breakpoints"
|
||||
import { usePagination } from "~/shared/composables/pagination"
|
||||
import { useUserStore } from "~/shared/store/user"
|
||||
import { LANGUAGE_SHOW_VALUE } from "~/utils/constants"
|
||||
import { renderTableTitle } from "~/utils/renders"
|
||||
@@ -14,11 +15,9 @@ import StatisticsPanel from "./components/StatisticsPanel.vue"
|
||||
import SubmissionLink from "./components/SubmissionLink.vue"
|
||||
import SubmissionDetail from "./detail.vue"
|
||||
|
||||
interface Query {
|
||||
interface SubmissionQuery {
|
||||
username: string
|
||||
result: string
|
||||
limit: number
|
||||
page: number
|
||||
myself: boolean
|
||||
problem: string
|
||||
language: LANGUAGE | ""
|
||||
@@ -32,14 +31,14 @@ const message = useMessage()
|
||||
const submissions = ref<SubmissionListItem[]>([])
|
||||
const total = ref(0)
|
||||
const todayCount = ref(0)
|
||||
const query = reactive<Query>({
|
||||
result: <string>route.query.result ?? "",
|
||||
page: parseInt(<string>route.query.page) || 1,
|
||||
limit: parseInt(<string>route.query.limit) || 10,
|
||||
username: <string>route.query.username ?? "",
|
||||
myself: route.query.myself === "1",
|
||||
problem: <string>route.query.problem ?? "",
|
||||
language: <LANGUAGE | "">route.query.language ?? "",
|
||||
|
||||
// 使用分页 composable
|
||||
const { query, clearQuery } = usePagination<SubmissionQuery>({
|
||||
username: "",
|
||||
result: "",
|
||||
myself: false,
|
||||
problem: "",
|
||||
language: "",
|
||||
})
|
||||
const submissionID = ref("")
|
||||
const problemDisplayID = ref("")
|
||||
@@ -61,14 +60,6 @@ const languageOptions: SelectOption[] = [
|
||||
{ label: "C++", value: "C++" },
|
||||
]
|
||||
async function listSubmissions() {
|
||||
query.result = <string>route.query.result ?? ""
|
||||
query.page = parseInt(<string>route.query.page) || 1
|
||||
query.limit = parseInt(<string>route.query.limit) || 10
|
||||
query.username = <string>route.query.username ?? ""
|
||||
query.myself = route.query.myself === "1"
|
||||
query.problem = <string>route.query.problem ?? ""
|
||||
query.language = <LANGUAGE>route.query.language ?? ""
|
||||
|
||||
if (query.page < 1) query.page = 1
|
||||
const offset = query.limit * (query.page - 1)
|
||||
try {
|
||||
@@ -76,7 +67,7 @@ async function listSubmissions() {
|
||||
...query,
|
||||
myself: query.myself ? "1" : "0",
|
||||
offset,
|
||||
problem_id: <string>route.query.problem ?? "",
|
||||
problem_id: query.problem,
|
||||
contest_id: <string>route.params.contestID ?? "",
|
||||
language: query.language,
|
||||
})
|
||||
@@ -101,16 +92,6 @@ onMounted(() => {
|
||||
}
|
||||
})
|
||||
|
||||
function routerPush() {
|
||||
const newQuery = {
|
||||
...query,
|
||||
myself: query.myself ? "1" : "0",
|
||||
}
|
||||
router.push({
|
||||
path: route.path,
|
||||
query: filterEmptyValue(newQuery),
|
||||
})
|
||||
}
|
||||
|
||||
function search(username: string, problem: string) {
|
||||
query.username = username
|
||||
@@ -118,11 +99,7 @@ function search(username: string, problem: string) {
|
||||
}
|
||||
|
||||
function clear() {
|
||||
query.username = ""
|
||||
query.myself = false
|
||||
query.result = ""
|
||||
query.problem = ""
|
||||
query.language = ""
|
||||
clearQuery()
|
||||
}
|
||||
|
||||
async function rejudge(submissionID: string) {
|
||||
@@ -151,25 +128,19 @@ function showCodePanel(id: string, problem: string) {
|
||||
problemDisplayID.value = problem
|
||||
}
|
||||
|
||||
watch(() => query.page, routerPush)
|
||||
|
||||
watch(
|
||||
() => [query.limit, query.myself, query.result, query.language],
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
)
|
||||
|
||||
// 监听用户名和题号变化(防抖)
|
||||
watchDebounced(
|
||||
() => [query.username, query.problem],
|
||||
() => {
|
||||
query.page = 1
|
||||
routerPush()
|
||||
},
|
||||
listSubmissions,
|
||||
{ debounce: 500, maxWait: 1000 },
|
||||
)
|
||||
|
||||
// 监听其他查询条件变化
|
||||
watch(
|
||||
() => [query.page, query.limit, query.myself, query.result, query.language],
|
||||
listSubmissions,
|
||||
)
|
||||
|
||||
watch(
|
||||
() =>
|
||||
(route.name === "submissions" || route.name === "contest submissions") &&
|
||||
|
||||
Reference in New Issue
Block a user