From 0c6a1db4e4849c6df03380034f9ba1144dbb0705 Mon Sep 17 00:00:00 2001
From: yuetsh <517252939@qq.com>
Date: Fri, 22 Dec 2023 10:31:32 +0800
Subject: [PATCH] announcement.
---
src/admin/announcement/components/Actions.vue | 44 +++++++++
src/admin/announcement/detail.vue | 94 +++++++++++++++++++
src/admin/announcement/list.vue | 92 ++++++++++++++++++
src/admin/api.ts | 24 +++++
src/admin/contest/detail.vue | 6 +-
src/admin/problem/detail.vue | 2 +-
src/admin/setting/announcement.vue | 7 --
src/admin/user/list.vue | 54 +++++++++--
src/routes.ts | 21 ++++-
src/shared/layout/admin.vue | 28 +++---
src/utils/types.ts | 17 ++++
vite.config.ts | 2 +-
12 files changed, 356 insertions(+), 35 deletions(-)
create mode 100644 src/admin/announcement/components/Actions.vue
create mode 100644 src/admin/announcement/detail.vue
create mode 100644 src/admin/announcement/list.vue
delete mode 100644 src/admin/setting/announcement.vue
diff --git a/src/admin/announcement/components/Actions.vue b/src/admin/announcement/components/Actions.vue
new file mode 100644
index 0000000..a76e319
--- /dev/null
+++ b/src/admin/announcement/components/Actions.vue
@@ -0,0 +1,44 @@
+
+
+
+
+ 编辑
+
+
+ 查看
+
+
+
+ 删除
+
+ 确定删除这条公告吗?
+
+
+
+
diff --git a/src/admin/announcement/detail.vue b/src/admin/announcement/detail.vue
new file mode 100644
index 0000000..4dc9f16
--- /dev/null
+++ b/src/admin/announcement/detail.vue
@@ -0,0 +1,94 @@
+
+
+
+ {{ route.name === "admin announcement create" ? "新建公告" : "编辑公告" }}
+
+
+
+
+
+
+
+
+
+
+
+ 保存
+
+
+
diff --git a/src/admin/announcement/list.vue b/src/admin/announcement/list.vue
new file mode 100644
index 0000000..ac7bce8
--- /dev/null
+++ b/src/admin/announcement/list.vue
@@ -0,0 +1,92 @@
+
+
+
+ 网站公告
+
+
+
+
+
diff --git a/src/admin/api.ts b/src/admin/api.ts
index 25e9d80..bec8086 100644
--- a/src/admin/api.ts
+++ b/src/admin/api.ts
@@ -1,6 +1,8 @@
import http from "utils/http"
import {
AdminProblem,
+ Announcement,
+ AnnouncementEdit,
BlankContest,
BlankProblem,
Contest,
@@ -175,3 +177,25 @@ export function getJudgeServer() {
export function deleteJudgeServer(hostname: string) {
return http.delete("admin/judge_server", { params: { hostname } })
}
+
+export function getAnnouncementList(offset = 0, limit = 10) {
+ return http.get("admin/announcement", {
+ params: { paging: true, offset, limit },
+ })
+}
+
+export function getAnnouncement(id: number) {
+ return http.get("admin/announcement", { params: { id } })
+}
+
+export function deleteAnnouncement(id: number) {
+ return http.delete("admin/announcement", { params: { id } })
+}
+
+export function editAnnouncement(announcement: AnnouncementEdit) {
+ return http.put("admin/announcement", announcement)
+}
+
+export function createAnnouncement(announcement: AnnouncementEdit) {
+ return http.post("admin/announcement", announcement)
+}
diff --git a/src/admin/contest/detail.vue b/src/admin/contest/detail.vue
index 1db2b06..0f0f402 100644
--- a/src/admin/contest/detail.vue
+++ b/src/admin/contest/detail.vue
@@ -29,7 +29,7 @@ const contest = reactive({
rule_type: "ACM",
password: "",
real_time_rank: true,
- visible: true,
+ visible: false,
allowed_ip_ranges: [],
})
@@ -112,7 +112,9 @@ onMounted(getContestDetail)
v-model:value="contest.description"
:min-height="200"
/>
- 保存
+
+ 保存
+
diff --git a/src/admin/user/list.vue b/src/admin/user/list.vue
index c796451..898e4f2 100644
--- a/src/admin/user/list.vue
+++ b/src/admin/user/list.vue
@@ -3,7 +3,7 @@ import { DataTableRowKey, SelectOption } from "naive-ui"
import Pagination from "~/shared/components/Pagination.vue"
import { parseTime } from "~/utils/functions"
import { User } from "~/utils/types"
-import { getUserList, deleteUsers, editUser } from "../api"
+import { getUserList, deleteUsers, editUser, importUsers } from "../api"
import Actions from "./components/Actions.vue"
import Name from "./components/Name.vue"
@@ -17,6 +17,7 @@ const query = reactive({
page: 1,
keyword: "",
})
+const [create, toggleCreate] = useToggle(false)
const password = ref("")
const userIDs = ref([])
@@ -93,14 +94,34 @@ async function onUserBanned(user: User) {
})
}
-async function onOpenEditModal(user: User) {
+function createNewUser() {
+ toggleCreate(true)
+ userEditing.value = {
+ id: 0,
+ username: "",
+ real_name: "",
+ email: "",
+ admin_type: "Regular User",
+ problem_permission: "",
+ create_time: new Date(),
+ last_login: new Date(),
+ two_factor_auth: false,
+ open_api: false,
+ is_disabled: false,
+ password: "",
+ }
+ password.value = ""
+}
+
+function onOpenEditModal(user: User) {
userEditing.value = user
password.value = ""
}
-async function onCloseEditModal() {
+function onCloseEditModal() {
userEditing.value = null
password.value = ""
+ toggleCreate(false)
}
async function handleEditUser() {
@@ -109,10 +130,24 @@ async function handleEditUser() {
message.error("密码长度不得小于 6")
return
}
- const user = Object.assign(userEditing.value, { password: password.value })
- await editUser(user)
+ if (create) {
+ const newUser = [
+ [
+ userEditing.value.username,
+ password.value,
+ userEditing.value.email,
+ userEditing.value.real_name,
+ ],
+ ]
+ await importUsers(newUser)
+ listUsers()
+ } else {
+ const user = Object.assign(userEditing.value, { password: password.value })
+ await editUser(user)
+ }
userEditing.value = null
password.value = ""
+ toggleCreate(false)
}
onMounted(listUsers)
@@ -121,7 +156,10 @@ watch(query, listUsers, { deep: true })
- 用户列表
+
+ 用户列表
+ 新建用户
+
@@ -173,7 +211,7 @@ watch(query, listUsers, { deep: true })
-
+
封号
diff --git a/src/routes.ts b/src/routes.ts
index 434d412..7894612 100644
--- a/src/routes.ts
+++ b/src/routes.ts
@@ -97,11 +97,6 @@ export const admins: RouteRecordRaw = {
name: "admin config",
component: () => import("admin/setting/config.vue"),
},
- {
- path: "announcement",
- name: "admin announcement",
- component: () => import("admin/setting/announcement.vue"),
- },
{
path: "user/list",
name: "admin user list",
@@ -162,5 +157,21 @@ export const admins: RouteRecordRaw = {
component: () => import("admin/problem/detail.vue"),
props: true,
},
+ {
+ path: "announcement/list",
+ name: "admin announcement list",
+ component: () => import("admin/announcement/list.vue"),
+ },
+ {
+ path: "announcement/create",
+ name: "admin announcement create",
+ component: () => import("admin/announcement/detail.vue"),
+ },
+ {
+ path: "announcement/edit/:announcementID",
+ name: "admin announcement edit",
+ component: () => import("admin/announcement/detail.vue"),
+ props: true,
+ },
],
}
diff --git a/src/shared/layout/admin.vue b/src/shared/layout/admin.vue
index 372538d..5eb293d 100644
--- a/src/shared/layout/admin.vue
+++ b/src/shared/layout/admin.vue
@@ -16,11 +16,7 @@ const options: MenuOption[] = [
label: () => h(RouterLink, { to: "/admin" }, { default: () => "首页" }),
key: "admin home",
},
- {
- label: "题目",
- key: "problem",
- disabled: true,
- },
+ { label: "题目", key: "problem", disabled: true },
{
label: () =>
h(
@@ -73,20 +69,30 @@ const options: MenuOption[] = [
),
key: "admin contest create",
},
- { label: "其他", key: "other", disabled: true },
+ { label: "公告", key: "announcement", disabled: true },
{
label: () =>
- h(RouterLink, { to: "/admin/config" }, { default: () => "系统配置" }),
- key: "admin config",
+ h(
+ RouterLink,
+ { to: "/admin/announcement/list" },
+ { default: () => "公告列表" },
+ ),
+ key: "admin announcement list",
},
{
label: () =>
h(
RouterLink,
- { to: "/admin/announcement" },
- { default: () => "公告配置" },
+ { to: "/admin/announcement/create" },
+ { default: () => "新建公告" },
),
- key: "admin announcement",
+ key: "admin announcement create",
+ },
+ { label: "其他", key: "other", disabled: true },
+ {
+ label: () =>
+ h(RouterLink, { to: "/admin/config" }, { default: () => "系统配置" }),
+ key: "admin config",
},
]
diff --git a/src/utils/types.ts b/src/utils/types.ts
index 352150a..1244240 100644
--- a/src/utils/types.ts
+++ b/src/utils/types.ts
@@ -330,3 +330,20 @@ export interface Server {
service_url: string
is_disabled: boolean
}
+
+export interface Announcement {
+ id: number
+ created_by: SampleUser
+ title: string
+ content: string
+ create_time: Date
+ last_update_time: Date
+ visible: boolean
+}
+
+export interface AnnouncementEdit {
+ id: number
+ title: string
+ content: string
+ visible: boolean
+}
\ No newline at end of file
diff --git a/vite.config.ts b/vite.config.ts
index 1b19de8..d878048 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -6,7 +6,7 @@ import AutoImport from "unplugin-auto-import/vite"
import Components from "unplugin-vue-components/vite"
import { NaiveUiResolver } from "unplugin-vue-components/resolvers"
-const dev = false
+const dev = true
const url = dev ? "https://ojtest.hyyz.izhai.net" : "https://oj.xuyue.cc"
const proxyConfig = {
target: url,