把大部分的 n-space 替换成 n-flex

This commit is contained in:
2024-07-04 10:12:02 +08:00
parent c84d103418
commit 9a775d523a
31 changed files with 155 additions and 163 deletions

View File

@@ -25,7 +25,7 @@ async function handleDelete() {
</script> </script>
<template> <template>
<n-space> <n-flex>
<n-button size="small" type="success" secondary @click="goEdit"> <n-button size="small" type="success" secondary @click="goEdit">
编辑 编辑
</n-button> </n-button>
@@ -35,6 +35,6 @@ async function handleDelete() {
</template> </template>
确定删除这条公告吗 确定删除这条公告吗
</n-popconfirm> </n-popconfirm>
</n-space> </n-flex>
</template> </template>
<style scoped></style> <style scoped></style>

View File

@@ -98,9 +98,9 @@ onMounted(init)
v-model:value="announcement.content" v-model:value="announcement.content"
:min-height="200" :min-height="200"
/> />
<n-space justify="end"> <n-flex justify="end">
<n-button type="primary" @click="submit">保存</n-button> <n-button type="primary" @click="submit">保存</n-button>
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>
.title { .title {

View File

@@ -1,12 +1,14 @@
<template> <template>
<n-space justify="space-between" class="titleWrapper"> <n-flex justify="space-between" class="titleWrapper">
<h2 class="title">评论列表只列出有内容的</h2> <h2 class="title">评论列表只列出有内容的</h2>
<n-input <div>
<n-input
v-model:value="query.problem" v-model:value="query.problem"
clearable clearable
placeholder="输入题目序号" placeholder="输入题目序号"
/> />
</n-space> </div>
</n-flex>
<n-data-table striped :columns="columns" :data="comments" /> <n-data-table striped :columns="columns" :data="comments" />
<Pagination <Pagination
:total="total" :total="total"

View File

@@ -22,13 +22,13 @@ function goEditProblems() {
} }
</script> </script>
<template> <template>
<n-space> <n-flex>
<n-button size="small" type="primary" secondary @click="goEditProblems"> <n-button size="small" type="primary" secondary @click="goEditProblems">
题目 题目
</n-button> </n-button>
<n-button size="small" type="info" secondary @click="goEdit"> <n-button size="small" type="info" secondary @click="goEdit">
编辑 编辑
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
<style scoped></style> <style scoped></style>

View File

@@ -127,9 +127,9 @@ onMounted(getContestDetail)
v-model:value="contest.description" v-model:value="contest.description"
:min-height="200" :min-height="200"
/> />
<n-space justify="end"> <n-flex justify="end">
<n-button type="primary" @click="submit">保存</n-button> <n-button type="primary" @click="submit">保存</n-button>
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>

View File

@@ -83,10 +83,12 @@ watchDebounced(() => query.keyword, listContests, { debounce: 500, maxWait: 1000
</script> </script>
<template> <template>
<n-space justify="space-between" class="titleWrapper"> <n-flex justify="space-between" class="titleWrapper">
<h2 class="title">比赛列表</h2> <h2 class="title">比赛列表</h2>
<n-input v-model:value="query.keyword" placeholder="输入标题关键字" /> <div>
</n-space> <n-input v-model:value="query.keyword" placeholder="输入标题关键字" />
</div>
</n-flex>
<n-data-table :columns="columns" :data="contests" /> <n-data-table :columns="columns" :data="contests" />
<Pagination <Pagination
:total="total" :total="total"

View File

@@ -55,7 +55,7 @@ function goCheck() {
} }
</script> </script>
<template> <template>
<n-space align="center"> <n-flex>
<n-button size="small" secondary type="primary" @click="goEdit"> <n-button size="small" secondary type="primary" @click="goEdit">
编辑 编辑
</n-button> </n-button>
@@ -74,5 +74,5 @@ function goCheck() {
</template> </template>
下载测试用例 下载测试用例
</n-tooltip> </n-tooltip>
</n-space> </n-flex>
</template> </template>

View File

@@ -37,10 +37,10 @@ async function addProblem() {
<template #trigger> <template #trigger>
<n-button secondary size="small" type="primary">+</n-button> <n-button secondary size="small" type="primary">+</n-button>
</template> </template>
<n-space vertical> <n-flex vertical>
<span>请输入在这场比赛中的显示编号</span> <span>请输入在这场比赛中的显示编号</span>
<n-input autofocus v-model:value="displayID" /> <n-input autofocus v-model:value="displayID" />
</n-space> </n-flex>
</n-popconfirm> </n-popconfirm>
</template> </template>
<style scoped></style> <style scoped></style>

View File

@@ -424,7 +424,7 @@ watch(
title="输出的描述" title="输出的描述"
/> />
<div class="box" v-for="(sample, index) in problem.samples" :key="index"> <div class="box" v-for="(sample, index) in problem.samples" :key="index">
<n-space justify="space-between" align="center"> <n-flex justify="space-between" align="center">
<strong>测试样例 {{ index + 1 }}</strong> <strong>测试样例 {{ index + 1 }}</strong>
<n-button <n-button
tertiary tertiary
@@ -434,19 +434,19 @@ watch(
> >
删除 {{ index + 1 }} 删除 {{ index + 1 }}
</n-button> </n-button>
</n-space> </n-flex>
<n-grid x-gap="20" cols="2"> <n-grid x-gap="20" cols="2">
<n-gi span="1"> <n-gi span="1">
<n-space vertical> <n-flex vertical>
<span>输入样例</span> <span>输入样例</span>
<n-input type="textarea" v-model:value="sample.input" /> <n-input type="textarea" v-model:value="sample.input" />
</n-space> </n-flex>
</n-gi> </n-gi>
<n-gi span="1"> <n-gi span="1">
<n-space vertical> <n-flex vertical>
<span>输出样例</span> <span>输出样例</span>
<n-input type="textarea" v-model:value="sample.output" /> <n-input type="textarea" v-model:value="sample.output" />
</n-space> </n-flex>
</n-gi> </n-gi>
</n-grid> </n-grid>
</div> </div>
@@ -493,7 +493,7 @@ watch(
type="info" type="info"
> >
<template #header> <template #header>
<n-space align="center"> <n-flex align="center">
<div> <div>
测试组编号 {{ problem.test_case_id.slice(0, 12) }} 共有 测试组编号 {{ problem.test_case_id.slice(0, 12) }} 共有
{{ problem.test_case_score.length }} {{ problem.test_case_score.length }}
@@ -508,21 +508,21 @@ watch(
> >
下载 下载
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
</n-alert> </n-alert>
<n-space justify="space-between"> <n-space justify="space-between">
<n-form inline label-placement="left" :show-feedback="false"> <n-form inline label-placement="left" :show-feedback="false">
<n-form-item label="语言"> <n-form-item label="语言">
<n-checkbox-group v-model:value="problem.languages"> <n-checkbox-group v-model:value="problem.languages">
<n-space align="center"> <n-flex align="center">
<n-checkbox <n-checkbox
v-for="(language, index) in languageOptions" v-for="(language, index) in languageOptions"
:key="index" :key="index"
:value="language.value" :value="language.value"
:label="language.label" :label="language.label"
/> />
</n-space> </n-flex>
</n-checkbox-group> </n-checkbox-group>
</n-form-item> </n-form-item>
<n-form-item> <n-form-item>
@@ -543,22 +543,24 @@ watch(
</n-button> </n-button>
</n-form-item> </n-form-item>
</n-form> </n-form>
<n-space align="center"> <n-flex align="center">
<n-tooltip placement="left"> <n-tooltip placement="left">
<template #trigger> <template #trigger>
<n-button text>温馨提醒</n-button> <n-button text>温馨提醒</n-button>
</template> </template>
测试用例最好要有10个要考虑边界情况不要跟测试样例一模一样 测试用例最好要有10个要考虑边界情况不要跟测试样例一模一样
</n-tooltip> </n-tooltip>
<n-upload <div>
:show-file-list="false" <n-upload
accept=".zip" :show-file-list="false"
:custom-request="handleUploadTestcases" accept=".zip"
> :custom-request="handleUploadTestcases"
<n-button type="info">上传测试用例</n-button> >
</n-upload> <n-button type="info">上传测试用例</n-button>
</n-upload>
</div>
<n-button type="primary" @click="submit">提交</n-button> <n-button type="primary" @click="submit">提交</n-button>
</n-space> </n-flex>
</n-space> </n-space>
</template> </template>

View File

@@ -119,9 +119,9 @@ watchDebounced(() => query.keyword, listProblems, {
</script> </script>
<template> <template>
<n-space class="titleWrapper" justify="space-between"> <n-flex class="titleWrapper" justify="space-between">
<h2 class="title">{{ title }}</h2> <h2 class="title">{{ title }}</h2>
<n-space> <n-flex>
<n-button v-if="isContestProblemList" @click="createContestProblem"> <n-button v-if="isContestProblemList" @click="createContestProblem">
新建比赛题目 新建比赛题目
</n-button> </n-button>
@@ -132,9 +132,11 @@ watchDebounced(() => query.keyword, listProblems, {
> >
从题库中选择 从题库中选择
</n-button> </n-button>
<n-input v-model:value="query.keyword" placeholder="输入标题关键字" /> <div>
</n-space> <n-input v-model:value="query.keyword" placeholder="输入标题关键字" />
</n-space> </div>
</n-flex>
</n-flex>
<n-data-table striped :columns="columns" :data="problems" /> <n-data-table striped :columns="columns" :data="problems" />
<Pagination <Pagination
:total="total" :total="total"

View File

@@ -162,12 +162,12 @@ onMounted(() => {
<template> <template>
<n-card class="box"> <n-card class="box">
<template #header> <template #header>
<n-space align="center"> <n-flex align="center">
网站设置 网站设置
<n-button type="primary" size="small" @click="saveWebsiteConfig"> <n-button type="primary" size="small" @click="saveWebsiteConfig">
保存 保存
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
<n-form inline label-placement="left"> <n-form inline label-placement="left">
<n-form-item label="网站 URL"> <n-form-item label="网站 URL">
@@ -185,20 +185,20 @@ onMounted(() => {
<n-input v-model:value="websiteConfig.website_footer" /> <n-input v-model:value="websiteConfig.website_footer" />
</n-form-item> </n-form-item>
</n-form> </n-form>
<n-space align="center"> <n-flex align="center">
<n-space align="center"> <n-flex align="center">
<span>是否允许注册</span> <span>是否允许注册</span>
<n-switch v-model:value="websiteConfig.allow_register" /> <n-switch v-model:value="websiteConfig.allow_register" />
</n-space> </n-flex>
<n-space align="center"> <n-flex align="center">
<span>显示全部题目的提交</span> <span>显示全部题目的提交</span>
<n-switch v-model:value="websiteConfig.submission_list_show_all" /> <n-switch v-model:value="websiteConfig.submission_list_show_all" />
</n-space> </n-flex>
</n-space> </n-flex>
</n-card> </n-card>
<n-card class="box"> <n-card class="box">
<template #header> <template #header>
<n-space align="center"> <n-flex align="center">
判题服务器 判题服务器
<n-button <n-button
v-if="abnormalServers.length" v-if="abnormalServers.length"
@@ -208,7 +208,7 @@ onMounted(() => {
> >
删除无效服务器 删除无效服务器
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
<div class="box"> <div class="box">
接口凭证 <n-tag size="small">{{ token }}</n-tag> 接口凭证 <n-tag size="small">{{ token }}</n-tag>
@@ -222,12 +222,12 @@ onMounted(() => {
</n-card> </n-card>
<n-card class="box" v-if="testcases.length"> <n-card class="box" v-if="testcases.length">
<template #header> <template #header>
<n-space align="center"> <n-flex align="center">
无效的测试用例 无效的测试用例
<n-button size="small" type="warning" @click="() => deleteTestcase()"> <n-button size="small" type="warning" @click="() => deleteTestcase()">
全部删除 全部删除
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
<n-data-table <n-data-table
striped striped

View File

@@ -79,11 +79,11 @@ watch(
</script> </script>
<template> <template>
<n-space align="center"> <n-flex align="center">
<n-avatar round :size="60" :src="userStore.profile?.avatar" /> <n-avatar round :size="60" :src="userStore.profile?.avatar" />
<h1 class="name">亲爱的管理员{{ userStore.user?.username }}</h1> <h1 class="name">亲爱的管理员{{ userStore.user?.username }}</h1>
</n-space> </n-flex>
<n-space> <n-flex>
<h2> <h2>
<n-gradient-text type="info"> 总用户数{{ userCount }} </n-gradient-text> <n-gradient-text type="info"> 总用户数{{ userCount }} </n-gradient-text>
</h2> </h2>
@@ -97,17 +97,19 @@ watch(
近期比赛{{ contestCount }} 近期比赛{{ contestCount }}
</n-gradient-text> </n-gradient-text>
</h2> </h2>
</n-space> </n-flex>
<n-space align="center" class="actions"> <n-flex align="center" class="actions">
<span>我猜你要</span> <span>我猜你要</span>
<n-button @click="router.push('/admin/problem/create')">新题目</n-button> <n-button @click="router.push('/admin/problem/create')">新题目</n-button>
<n-button @click="router.push('/admin/contest/create')">新比赛</n-button> <n-button @click="router.push('/admin/contest/create')">新比赛</n-button>
<n-input <div>
<n-input
clearable clearable
@change="listRanks" @change="listRanks"
v-model:value="query.username" v-model:value="query.username"
placeholder="班级前缀" placeholder="班级前缀"
/> />
</div>
<n-button @click="listRanks">用户排名</n-button> <n-button @click="listRanks">用户排名</n-button>
<Pagination <Pagination
class="pagination" class="pagination"
@@ -115,7 +117,7 @@ watch(
v-model:page="query.page" v-model:page="query.page"
v-model:limit="query.limit" v-model:limit="query.limit"
/> />
</n-space> </n-flex>
<n-data-table v-if="data.length" striped :data="data" :columns="columns" /> <n-data-table v-if="data.length" striped :data="data" :columns="columns" />
</template> </template>

View File

@@ -19,7 +19,7 @@ async function banUser() {
} }
</script> </script>
<template> <template>
<n-space align="center"> <n-flex>
<n-button <n-button
size="small" size="small"
type="primary" type="primary"
@@ -42,5 +42,5 @@ async function banUser() {
</template> </template>
确定删除这个用户吗删除后无法恢复 确定删除这个用户吗删除后无法恢复
</n-popconfirm> </n-popconfirm>
</n-space> </n-flex>
</template> </template>

View File

@@ -9,7 +9,7 @@ const props = defineProps<Props>()
const isAdmin = computed(() => props.user.admin_type !== "Regular User") const isAdmin = computed(() => props.user.admin_type !== "Regular User")
</script> </script>
<template> <template>
<n-space align="center"> <n-flex align="center">
<n-tag v-if="props.user.is_disabled" type="error" size="small"> <n-tag v-if="props.user.is_disabled" type="error" size="small">
封号中 封号中
</n-tag> </n-tag>
@@ -21,5 +21,5 @@ const isAdmin = computed(() => props.user.admin_type !== "Regular User")
{{ getUserRole(props.user.admin_type).tagString }} {{ getUserRole(props.user.admin_type).tagString }}
</n-tag> </n-tag>
{{ props.user.username }} {{ props.user.username }}
</n-space> </n-flex>
</template> </template>

View File

@@ -76,11 +76,11 @@ function handleAll() {
<template> <template>
<n-space> <n-space>
<n-space vertical> <n-flex vertical>
<n-space align="center"> <n-flex align="center">
<n-switch v-model:value="needKs" /> <n-switch v-model:value="needKs" />
<span>前面带上 ks</span> <span>前面带上 ks</span>
</n-space> </n-flex>
<n-input v-model:value="prefix" placeholder="班级号" /> <n-input v-model:value="prefix" placeholder="班级号" />
<n-input <n-input
type="textarea" type="textarea"
@@ -88,7 +88,7 @@ function handleAll() {
placeholder="每行一个用户名" placeholder="每行一个用户名"
v-model:value="rawInput" v-model:value="rawInput"
/> />
</n-space> </n-flex>
<n-scrollbar style="max-height: calc(100vh - 34px)"> <n-scrollbar style="max-height: calc(100vh - 34px)">
<n-data-table <n-data-table
v-if="usersToTable.length" v-if="usersToTable.length"
@@ -96,13 +96,13 @@ function handleAll() {
:data="usersToTable" :data="usersToTable"
/> />
</n-scrollbar> </n-scrollbar>
<n-space vertical> <n-flex vertical>
<n-button @click="generateUsers">让我康康</n-button> <n-button @click="generateUsers">让我康康</n-button>
<n-button type="warning" :disabled="!users.length" @click="uploadUsers"> <n-button type="warning" :disabled="!users.length" @click="uploadUsers">
上传用户 上传用户
</n-button> </n-button>
<n-button type="info" @click="handleAll">一键三连</n-button> <n-button type="info" @click="handleAll">一键三连</n-button>
</n-space> </n-flex>
</n-space> </n-space>
</template> </template>

View File

@@ -29,7 +29,7 @@ const columns: DataTableColumn<User>[] = [
{ {
title: "用户名", title: "用户名",
key: "username", key: "username",
width: 180, width: 200,
render: (row) => h(Name, { user: row }), render: (row) => h(Name, { user: row }),
}, },
{ {
@@ -155,12 +155,12 @@ watch(query, listUsers, { deep: true })
</script> </script>
<template> <template>
<n-space class="titleWrapper" justify="space-between"> <n-flex class="titleWrapper" justify="space-between">
<n-space> <n-flex>
<h2 class="title">用户列表</h2> <h2 class="title">用户列表</h2>
<n-button type="primary" @click="createNewUser">新建用户</n-button> <n-button type="primary" @click="createNewUser">新建用户</n-button>
</n-space> </n-flex>
<n-space> <n-flex>
<n-popconfirm <n-popconfirm
v-if="userIDs.length" v-if="userIDs.length"
@positive-click="onDeleteUsers(userIDs)" @positive-click="onDeleteUsers(userIDs)"
@@ -170,9 +170,11 @@ watch(query, listUsers, { deep: true })
</template> </template>
确定删除选中的用户吗删除后无法恢复 确定删除选中的用户吗删除后无法恢复
</n-popconfirm> </n-popconfirm>
<n-input placeholder="请输入关键字搜索" v-model:value="query.keyword" /> <div>
</n-space> <n-input placeholder="请输入关键字搜索" v-model:value="query.keyword" />
</n-space> </div>
</n-flex>
</n-flex>
<n-data-table <n-data-table
:data="users" :data="users"
:columns="columns" :columns="columns"
@@ -214,10 +216,10 @@ watch(query, listUsers, { deep: true })
<n-switch v-model:value="userEditing.is_disabled">封号</n-switch> <n-switch v-model:value="userEditing.is_disabled">封号</n-switch>
</n-form-item-gi> </n-form-item-gi>
</n-grid> </n-grid>
<n-space justify="end"> <n-flex justify="end">
<n-button @click="onCloseEditModal">取消</n-button> <n-button @click="onCloseEditModal">取消</n-button>
<n-button type="primary" @click="handleEditUser">保存</n-button> <n-button type="primary" @click="handleEditUser">保存</n-button>
</n-space> </n-flex>
</n-form> </n-form>
</n-modal> </n-modal>
</template> </template>

View File

@@ -209,6 +209,7 @@ export function getCommentStatistics(problemID: number) {
return http.get("comment/statistics", { params: { problem_id: problemID } }) return http.get("comment/statistics", { params: { problem_id: problemID } })
} }
// TODO: 这个API有问题
export function refreshUserProblemDisplayIds() { export function refreshUserProblemDisplayIds() {
return http.get("profile/fresh_display_id") return http.get("profile/fresh_display_id")
} }

View File

@@ -32,7 +32,7 @@ const options: DropdownOption[] = [
</script> </script>
<template> <template>
<div v-if="contestMenuVisible"> <div v-if="contestMenuVisible">
<n-space v-if="isDesktop"> <n-flex v-if="isDesktop">
<n-button :type="getCurrentType('problems')" @click="goto('problems')"> <n-button :type="getCurrentType('problems')" @click="goto('problems')">
比赛题目 比赛题目
</n-button> </n-button>
@@ -45,7 +45,7 @@ const options: DropdownOption[] = [
<n-button :type="getCurrentType('rank')" @click="goto('rank')"> <n-button :type="getCurrentType('rank')" @click="goto('rank')">
比赛排名 比赛排名
</n-button> </n-button>
</n-space> </n-flex>
<n-dropdown v-else :options="options" @select="goto"> <n-dropdown v-else :options="options" @select="goto">
<n-button>菜单</n-button> <n-button>菜单</n-button>
</n-dropdown> </n-dropdown>

View File

@@ -30,9 +30,12 @@ const passwordFormVisible = computed(
</script> </script>
<template> <template>
<n-space vertical size="large" v-if="contestStore.contest"> <n-flex vertical size="large" v-if="contestStore.contest">
<n-space align="center" justify="space-between"> <n-flex align="center" justify="space-between">
<n-space align="center"> <n-flex align="center">
<n-tag :type="CONTEST_STATUS[contestStore.contestStatus]['type']">
{{ contestStore.countdown }}
</n-tag>
<Icon <Icon
v-if="contestStore.isPrivate" v-if="contestStore.isPrivate"
icon="streamline-emojis:locked-with-key" icon="streamline-emojis:locked-with-key"
@@ -40,18 +43,12 @@ const passwordFormVisible = computed(
:height="30" :height="30"
></Icon> ></Icon>
<h2 class="contestTitle">{{ contestStore.contest.title }}</h2> <h2 class="contestTitle">{{ contestStore.contest.title }}</h2>
<n-tag </n-flex>
size="small" <n-flex align="center">
:type="CONTEST_STATUS[contestStore.contestStatus]['type']"
>
{{ contestStore.countdown }}
</n-tag>
</n-space>
<n-space align="center">
<ContestInfo /> <ContestInfo />
<ContestMenu /> <ContestMenu />
</n-space> </n-flex>
</n-space> </n-flex>
<n-form <n-form
:inline="isDesktop" :inline="isDesktop"
label-placement="left" label-placement="left"
@@ -74,7 +71,7 @@ const passwordFormVisible = computed(
</n-form-item> </n-form-item>
</n-form> </n-form>
<router-view></router-view> <router-view></router-view>
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>

View File

@@ -143,7 +143,7 @@ function rowProps(row: Contest) {
} }
</script> </script>
<template> <template>
<n-space vertical size="large"> <n-flex vertical size="large">
<n-space> <n-space>
<n-form :show-feedback="false" label-placement="left" inline> <n-form :show-feedback="false" label-placement="left" inline>
<n-form-item label="比赛状态"> <n-form-item label="比赛状态">
@@ -166,10 +166,10 @@ function rowProps(row: Contest) {
</n-form> </n-form>
<n-form :show-feedback="false" label-placement="left" inline> <n-form :show-feedback="false" label-placement="left" inline>
<n-form-item> <n-form-item>
<n-space> <n-flex>
<n-button @click="search(query.keyword)">搜索</n-button> <n-button @click="search(query.keyword)">搜索</n-button>
<n-button @click="clear" quaternary>重置</n-button> <n-button @click="clear" quaternary>重置</n-button>
</n-space> </n-flex>
</n-form-item> </n-form-item>
</n-form> </n-form>
</n-space> </n-space>
@@ -179,7 +179,7 @@ function rowProps(row: Contest) {
:data="data" :data="data"
:row-props="rowProps" :row-props="rowProps"
/> />
</n-space> </n-flex>
<Pagination <Pagination
v-model:limit="query.limit" v-model:limit="query.limit"
v-model:page="query.page" v-model:page="query.page"

View File

@@ -46,7 +46,7 @@ function changeLanguage(v: string) {
</script> </script>
<template> <template>
<n-space vertical> <n-flex vertical>
<Form :storage-key="storageKey" @change-language="changeLanguage" /> <Form :storage-key="storageKey" @change-language="changeLanguage" />
<CodeEditor <CodeEditor
v-model:value="code.value" v-model:value="code.value"
@@ -54,7 +54,7 @@ function changeLanguage(v: string) {
:language="code.language" :language="code.language"
:height="editorHeight" :height="editorHeight"
/> />
</n-space> </n-flex>
</template> </template>
<style scoped></style> <style scoped></style>

View File

@@ -87,7 +87,7 @@ function gotoTestCat() {
</script> </script>
<template> <template>
<n-space align="center"> <n-flex align="center">
<n-select <n-select
class="language" class="language"
v-model:value="code.language" v-model:value="code.language"
@@ -108,7 +108,7 @@ function gotoTestCat() {
> >
编辑 编辑
</n-button> </n-button>
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>

View File

@@ -96,10 +96,10 @@ function type(status: ProblemStatus) {
title="🎉 本 题 已 经 被 你 解 决 啦" title="🎉 本 题 已 经 被 你 解 决 啦"
/> />
<n-space align="center"> <n-flex align="center">
<n-tag>{{ problem._id }}</n-tag> <n-tag>{{ problem._id }}</n-tag>
<h2 class="problemTitle">{{ problem.title }}</h2> <h2 class="problemTitle">{{ problem.title }}</h2>
</n-space> </n-flex>
<p class="title" :style="style"> <p class="title" :style="style">
<n-flex align="center"> <n-flex align="center">
<Icon icon="streamline-emojis:sparkles"></Icon> <Icon icon="streamline-emojis:sparkles"></Icon>
@@ -135,7 +135,7 @@ function type(status: ProblemStatus) {
</div> </div>
<div v-for="(sample, index) of samples" :key="index"> <div v-for="(sample, index) of samples" :key="index">
<n-space align="center"> <n-flex align="center">
<p class="title" :style="style">例子 {{ index + 1 }}</p> <p class="title" :style="style">例子 {{ index + 1 }}</p>
<n-button <n-button
size="small" size="small"
@@ -144,7 +144,7 @@ function type(status: ProblemStatus) {
> >
{{ label(sample.status, sample.loading) }} {{ label(sample.status, sample.loading) }}
</n-button> </n-button>
</n-space> </n-flex>
<n-descriptions <n-descriptions
bordered bordered
:column="2" :column="2"
@@ -152,19 +152,19 @@ function type(status: ProblemStatus) {
> >
<n-descriptions-item> <n-descriptions-item>
<template #label> <template #label>
<n-space> <n-flex>
<span>输入</span> <span>输入</span>
<Copy :value="sample.input" /> <Copy :value="sample.input" />
</n-space> </n-flex>
</template> </template>
<div class="testcase">{{ sample.input }}</div> <div class="testcase">{{ sample.input }}</div>
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item> <n-descriptions-item>
<template #label> <template #label>
<n-space> <n-flex>
<span>输出</span> <span>输出</span>
<Copy :value="sample.output" /> <Copy :value="sample.output" />
</n-space> </n-flex>
</template> </template>
<div class="testcase">{{ sample.output }}</div> <div class="testcase">{{ sample.output }}</div>
</n-descriptions-item> </n-descriptions-item>

View File

@@ -64,11 +64,11 @@ const options = {
{{ getACRate(problem.accepted_number, problem.submission_number) }} {{ getACRate(problem.accepted_number, problem.submission_number) }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item :span="3" label="标签"> <n-descriptions-item :span="3" label="标签">
<n-space> <n-flex>
<n-tag size="small" type="info" v-for="tag in problem.tags" :key="tag"> <n-tag size="small" type="info" v-for="tag in problem.tags" :key="tag">
{{ tag }} {{ tag }}
</n-tag> </n-tag>
</n-space> </n-flex>
</n-descriptions-item> </n-descriptions-item>
</n-descriptions> </n-descriptions>
<div class="pie" v-if="problem && problem.submission_number > 0"> <div class="pie" v-if="problem && problem.submission_number > 0">

View File

@@ -255,7 +255,7 @@ watch(
:title="JUDGE_STATUS[submission.result]['name']" :title="JUDGE_STATUS[submission.result]['name']"
/> />
</template> </template>
<n-space vertical v-if="msg || infoTable.length"> <n-flex vertical v-if="msg || infoTable.length">
<n-card v-if="msg" embedded class="msg">{{ msg }}</n-card> <n-card v-if="msg" embedded class="msg">{{ msg }}</n-card>
<n-data-table <n-data-table
v-if="infoTable.length" v-if="infoTable.length"
@@ -263,7 +263,7 @@ watch(
:data="infoTable" :data="infoTable"
:columns="columns" :columns="columns"
/> />
</n-space> </n-flex>
</n-popover> </n-popover>
<n-modal <n-modal
preset="card" preset="card"

View File

@@ -212,7 +212,7 @@ function rowProps(row: ProblemFiltered) {
</script> </script>
<template> <template>
<n-space vertical size="large"> <n-flex vertical size="large">
<n-space> <n-space>
<n-form :show-feedback="false" inline label-placement="left"> <n-form :show-feedback="false" inline label-placement="left">
<n-form-item label="题目难度"> <n-form-item label="题目难度">
@@ -232,11 +232,11 @@ function rowProps(row: ProblemFiltered) {
</n-form> </n-form>
<n-form :show-feedback="false" inline label-placement="left"> <n-form :show-feedback="false" inline label-placement="left">
<n-form-item> <n-form-item>
<n-space align="center"> <n-flex align="center">
<n-button @click="search(query.keyword)">搜索</n-button> <n-button @click="search(query.keyword)">搜索</n-button>
<n-button @click="clear" quaternary>重置</n-button> <n-button @click="clear" quaternary>重置</n-button>
<n-button @click="getRandom" quaternary>试试手气</n-button> <n-button @click="getRandom" quaternary>试试手气</n-button>
</n-space> </n-flex>
</n-form-item> </n-form-item>
</n-form> </n-form>
<n-button @click="toggleShowTag()" quaternary icon-placement="right"> <n-button @click="toggleShowTag()" quaternary icon-placement="right">
@@ -248,7 +248,7 @@ function rowProps(row: ProblemFiltered) {
</n-button> </n-button>
</n-space> </n-space>
<n-collapse-transition :show="showTag"> <n-collapse-transition :show="showTag">
<n-space> <n-flex>
<n-tag <n-tag
v-for="tag in tags" v-for="tag in tags"
:closable="tag.checked" :closable="tag.checked"
@@ -259,7 +259,7 @@ function rowProps(row: ProblemFiltered) {
> >
{{ tag.name }} {{ tag.name }}
</n-tag> </n-tag>
</n-space> </n-flex>
</n-collapse-transition> </n-collapse-transition>
<n-data-table <n-data-table
striped striped
@@ -267,7 +267,7 @@ function rowProps(row: ProblemFiltered) {
:columns="columns" :columns="columns"
:row-props="rowProps" :row-props="rowProps"
/> />
</n-space> </n-flex>
<Pagination <Pagination
:total="total" :total="total"
v-model:limit="query.limit" v-model:limit="query.limit"

View File

@@ -1,5 +1,5 @@
<template> <template>
<n-space size="large" vertical> <n-flex size="large" vertical>
<n-form :show-feedback="false" inline label-placement="left"> <n-form :show-feedback="false" inline label-placement="left">
<n-form-item> <n-form-item>
<n-input <n-input
@@ -60,18 +60,11 @@
</n-gradient-text> </n-gradient-text>
</n-h1> </n-h1>
</n-space> </n-space>
<n-space v-if="count.total === 0"> <n-h1 v-if="count.total === 0">
<n-h1> <n-gradient-text type="primary">暂无数据统计</n-gradient-text>
<n-gradient-text type="primary">暂无数据统计</n-gradient-text> </n-h1>
</n-h1> <n-data-table v-if="list.length" striped :columns="columns" :data="list" />
</n-space> </n-flex>
<n-data-table
v-if="list.length"
striped
:columns="columns"
:data="list"
/>
</n-space>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { formatISO, sub, type Duration } from "date-fns" import { formatISO, sub, type Duration } from "date-fns"
@@ -85,6 +78,7 @@ interface Props {
const props = defineProps<Props>() const props = defineProps<Props>()
const options: SelectOption[] = [ const options: SelectOption[] = [
{ label: "30分钟内", value: "minutes:30" },
{ label: "本节课内", value: "hours:1" }, { label: "本节课内", value: "hours:1" },
{ label: "两小时内", value: "hours:2" }, { label: "两小时内", value: "hours:2" },
{ label: "一天内", value: "days:1" }, { label: "一天内", value: "days:1" },

View File

@@ -82,16 +82,16 @@ onMounted(init)
</script> </script>
<template> <template>
<n-space vertical v-if="submission" :size="24"> <n-flex vertical v-if="submission" :size="24">
<n-alert <n-alert
:type="JUDGE_STATUS[submission.result]['type']" :type="JUDGE_STATUS[submission.result]['type']"
:title="JUDGE_STATUS[submission.result]['name']" :title="JUDGE_STATUS[submission.result]['name']"
> >
<n-space> <n-flex>
<span>提交时间{{ parseTime(submission.create_time) }}</span> <span>提交时间{{ parseTime(submission.create_time) }}</span>
<span>编程语言{{ submission.language }}</span> <span>编程语言{{ submission.language }}</span>
<span>用户{{ submission.username }}</span> <span>用户{{ submission.username }}</span>
</n-space> </n-flex>
</n-alert> </n-alert>
<n-card embedded> <n-card embedded>
<n-code <n-code
@@ -124,7 +124,7 @@ onMounted(init)
:columns="columns" :columns="columns"
:data="submission.info.data" :data="submission.info.data"
/> />
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>

View File

@@ -254,7 +254,7 @@ const columns = computed(() => {
}) })
</script> </script>
<template> <template>
<n-space vertical size="large"> <n-flex vertical size="large">
<n-space> <n-space>
<n-form :show-feedback="false" inline label-placement="left"> <n-form :show-feedback="false" inline label-placement="left">
<n-form-item label="提交状态"> <n-form-item label="提交状态">
@@ -295,7 +295,7 @@ const columns = computed(() => {
</n-form> </n-form>
</n-space> </n-space>
<n-data-table striped :columns="columns" :data="submissions" /> <n-data-table striped :columns="columns" :data="submissions" />
</n-space> </n-flex>
<Pagination <Pagination
:total="total" :total="total"
v-model:limit="query.limit" v-model:limit="query.limit"

View File

@@ -1,7 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { getProfile } from "~/shared/api" import { getProfile } from "~/shared/api"
import { Profile } from "~/utils/types" import { Profile } from "~/utils/types"
import { refreshUserProblemDisplayIds } from "../api"
const route = useRoute() const route = useRoute()
const router = useRouter() const router = useRouter()
@@ -31,15 +30,10 @@ async function init() {
} }
} }
async function refresh() {
await refreshUserProblemDisplayIds()
init()
}
onMounted(init) onMounted(init)
</script> </script>
<template> <template>
<n-space <n-flex
class="wrapper" class="wrapper"
vertical vertical
justify="center" justify="center"
@@ -49,7 +43,7 @@ onMounted(init)
<n-avatar round :size="140" :src="profile.avatar" /> <n-avatar round :size="140" :src="profile.avatar" />
<h2>{{ profile.user.username }}</h2> <h2>{{ profile.user.username }}</h2>
<p class="desc">{{ profile.mood }}</p> <p class="desc">{{ profile.mood }}</p>
</n-space> </n-flex>
<n-descriptions <n-descriptions
v-if="!loading && profile" v-if="!loading && profile"
class="wrapper" class="wrapper"
@@ -63,14 +57,8 @@ onMounted(init)
<n-descriptions-item label="总提交数"> <n-descriptions-item label="总提交数">
{{ profile.submission_number }} {{ profile.submission_number }}
</n-descriptions-item> </n-descriptions-item>
<n-descriptions-item v-if="problems.length" :span="2"> <n-descriptions-item v-if="problems.length" label="已解决的题目" :span="2">
<template #label> <n-flex>
<n-flex align="center">
已解决的题目
<n-button size="small" @click="refresh">强制刷新</n-button>
</n-flex>
</template>
<n-space>
<n-button <n-button
v-for="id in problems" v-for="id in problems"
key="id" key="id"
@@ -78,7 +66,7 @@ onMounted(init)
> >
{{ id }} {{ id }}
</n-button> </n-button>
</n-space> </n-flex>
</n-descriptions-item> </n-descriptions-item>
</n-descriptions> </n-descriptions>
<n-empty v-if="!loading && !profile" description="该用户不存在"> <n-empty v-if="!loading && !profile" description="该用户不存在">

View File

@@ -40,7 +40,7 @@ async function saveProfile() {
} }
</script> </script>
<template> <template>
<n-space class="container" vertical v-if="userStore.profile"> <n-flex class="container" vertical v-if="userStore.profile">
<h3>个人信息设置</h3> <h3>个人信息设置</h3>
<n-form> <n-form>
<n-avatar round :size="120" :src="userStore.profile.avatar" alt="头像" /> <n-avatar round :size="120" :src="userStore.profile.avatar" alt="头像" />
@@ -67,7 +67,7 @@ async function saveProfile() {
更改信息 更改信息
</n-button> </n-button>
</n-form> </n-form>
</n-space> </n-flex>
</template> </template>
<style scoped> <style scoped>
.container { .container {