Build Phase 2 judge vertical slice
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
import { userProfileSchema } from "@oj2/contract"
|
||||
import api2 from "utils/api2"
|
||||
import http from "utils/http"
|
||||
import type { ApiResponse } from "utils/http"
|
||||
import type { Profile, Tag } from "utils/types"
|
||||
|
||||
export function login(data: { username: string; password: string }) {
|
||||
return http.post("login", data)
|
||||
return api2.post("auth/login", data)
|
||||
}
|
||||
|
||||
export function signup(data: {
|
||||
@@ -14,11 +17,47 @@ export function signup(data: {
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return http.get("logout")
|
||||
return api2.delete("auth/session")
|
||||
}
|
||||
|
||||
export function getProfile(username: string = "") {
|
||||
return http.get<Profile>("profile", { params: { username } })
|
||||
export async function getProfile(
|
||||
username: string = "",
|
||||
): Promise<ApiResponse<Profile | null>> {
|
||||
if (username) return http.get<Profile>("profile", { params: { username } })
|
||||
|
||||
const response = await api2.get<unknown>("me")
|
||||
if (response.data === null) return { error: null, data: null }
|
||||
const profile = userProfileSchema.parse(response.data)
|
||||
return {
|
||||
error: null,
|
||||
data: {
|
||||
id: profile.id,
|
||||
user: {
|
||||
id: profile.user.id,
|
||||
username: profile.user.username,
|
||||
real_name: profile.realName ?? "",
|
||||
email: profile.user.email ?? "",
|
||||
admin_type: profile.user.adminType as Profile["user"]["admin_type"],
|
||||
problem_permission: profile.user.problemPermission,
|
||||
create_time: profile.user.createTime as unknown as Date,
|
||||
last_login: profile.user.lastLogin as unknown as Date,
|
||||
open_api: profile.user.openApi,
|
||||
is_disabled: profile.user.isDisabled,
|
||||
class_name: profile.user.className,
|
||||
},
|
||||
real_name: profile.realName ?? "",
|
||||
acm_problems_status: profile.acmProblemsStatus as Profile["acm_problems_status"],
|
||||
avatar: profile.avatar,
|
||||
blog: profile.blog as null,
|
||||
mood: profile.mood ?? "",
|
||||
github: profile.github ?? "",
|
||||
school: profile.school ?? "",
|
||||
major: profile.major ?? "",
|
||||
language: profile.language ?? "",
|
||||
accepted_number: profile.acceptedNumber,
|
||||
submission_number: profile.submissionNumber,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function getProblemTagList() {
|
||||
|
||||
@@ -4,12 +4,10 @@ import { storeToRefs } from "pinia"
|
||||
import { useAuthModalStore } from "../store/authModal"
|
||||
import { useConfigStore } from "../store/config"
|
||||
import { useUserStore } from "../store/user"
|
||||
import { useLoginSummaryStore } from "../store/loginSummary"
|
||||
|
||||
const userStore = useUserStore()
|
||||
const configStore = useConfigStore()
|
||||
const authStore = useAuthModalStore()
|
||||
const loginSummaryStore = useLoginSummaryStore()
|
||||
|
||||
const {
|
||||
loginModalOpen,
|
||||
@@ -68,7 +66,6 @@ async function submit() {
|
||||
if (!msg.value) {
|
||||
authStore.closeLoginModal()
|
||||
await userStore.getMyProfile()
|
||||
loginSummaryStore.open()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -20,6 +20,8 @@ export interface WebSocketMessage {
|
||||
export interface WebSocketConfig {
|
||||
/** WebSocket 路径(如 '/ws/submission/') */
|
||||
path: string
|
||||
/** 完整 URL;提供后覆盖 PUBLIC_WS_URL + path */
|
||||
url?: string
|
||||
/** 最大重连次数,默认 5 */
|
||||
maxReconnectAttempts?: number
|
||||
/** 重连延迟(毫秒),默认 1000 */
|
||||
@@ -59,7 +61,8 @@ export class BaseWebSocket<T extends WebSocketMessage = WebSocketMessage> {
|
||||
public status: Ref<ConnectionStatus> = ref<ConnectionStatus>("disconnected")
|
||||
|
||||
constructor(config: WebSocketConfig) {
|
||||
this.url = `${import.meta.env.PUBLIC_WS_URL}/${config.path}/`
|
||||
this.url =
|
||||
config.url ?? `${import.meta.env.PUBLIC_WS_URL}/${config.path}/`
|
||||
|
||||
this.maxReconnectAttempts = config.maxReconnectAttempts ?? 5
|
||||
this.reconnectDelay = config.reconnectDelay ?? 1000
|
||||
@@ -300,9 +303,13 @@ export interface SubmissionUpdate extends WebSocketMessage {
|
||||
* 提交 WebSocket 连接管理类
|
||||
*/
|
||||
class SubmissionWebSocket extends BaseWebSocket<SubmissionUpdate> {
|
||||
private pendingSubmissionId = ""
|
||||
|
||||
constructor() {
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"
|
||||
super({
|
||||
path: "submission",
|
||||
url: `${protocol}//${window.location.host}/ws2/submissions`,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -310,12 +317,24 @@ class SubmissionWebSocket extends BaseWebSocket<SubmissionUpdate> {
|
||||
* 订阅特定提交的更新
|
||||
*/
|
||||
subscribe(submissionId: string) {
|
||||
this.pendingSubmissionId = submissionId
|
||||
const success = this.send({
|
||||
type: "subscribe",
|
||||
submission_id: submissionId,
|
||||
})
|
||||
if (!success) {
|
||||
console.error("[WebSocket] 订阅失败: 连接未就绪")
|
||||
if (success) this.pendingSubmissionId = ""
|
||||
}
|
||||
|
||||
protected onConnected() {
|
||||
if (!this.pendingSubmissionId) return
|
||||
const submissionId = this.pendingSubmissionId
|
||||
if (
|
||||
this.send({
|
||||
type: "subscribe",
|
||||
submission_id: submissionId,
|
||||
})
|
||||
) {
|
||||
this.pendingSubmissionId = ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user