旧 Django 后端 2026-08-26 下线、回滚路径作废,代码里还留着几处以它为前提的
死代码和过期注释。
- PUBLIC_WS_URL / PUBLIC_OJ_URL 全部删除。BaseWebSocket 的
`${PUBLIC_WS_URL}/${path}/` fallback 是 Channels 时代的写法,而三个子类
早就各自传 url,等于永不执行;config.vue 里 PUBLIC_OJ_URL 只是个会被
getWebsiteConfig() 立刻覆盖、且指着 :8000 的假初值。WebSocketConfig.path
随之去掉,url 改成必填。
- vite.config:删掉 /api2、/ws2 的迁移期注释,换成还成立的约束(代理这三段
要和 docker/Caddyfile 同步);newBackend 改名 backend。
- 六处 “回滚时旧后端还要读” 换成真实理由:snake_case 保留的结论不变,但因为
判题机按这套键名写、存量 JSONB 就是这形状。
- CLAUDE.md:数据库一节开头「不写迁移 + 先想清楚回滚」与下一节的 drizzle
migration 自相矛盾,改掉;判题状态码不再要求同步到 OnlineJudge,理由换成
历史 submission.result 和沙箱用的就是这套编码。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,7 @@ interface Props {
|
||||
|
||||
/**
|
||||
* ACM 助手行。`acInfo` 的**内容**是 acm_contest_rank.submission_info 的 JSONB 原文,
|
||||
* 键名保持 snake_case —— 回滚时旧后端还要读。
|
||||
* 键名保持 snake_case —— 判题写进去的就是这套键名,见 utils/types.ts 的 SubmissionInfo。
|
||||
*/
|
||||
type HelperItem = Omit<AcmHelperItem, "acInfo"> & {
|
||||
acInfo: SubmissionInfo
|
||||
|
||||
@@ -117,7 +117,7 @@ const abnormalServers = computed(() =>
|
||||
)
|
||||
|
||||
const websiteConfig = reactive<WebsiteConfig>({
|
||||
websiteBaseUrl: import.meta.env.PUBLIC_OJ_URL,
|
||||
websiteBaseUrl: "",
|
||||
websiteName: "判题狗",
|
||||
websiteNameShortcut: "判题狗",
|
||||
websiteFooter: "所有权归属于徐越,感谢青岛大学开源 OJ 系统,感谢开源社区",
|
||||
|
||||
2
apps/web/src/env.d.ts
vendored
2
apps/web/src/env.d.ts
vendored
@@ -3,12 +3,10 @@
|
||||
interface ImportMetaEnv {
|
||||
readonly PUBLIC_ENV: string
|
||||
readonly PUBLIC_MAXKB_URL: string
|
||||
readonly PUBLIC_OJ_URL: string
|
||||
readonly PUBLIC_CODE_URL: string
|
||||
readonly PUBLIC_JUDGE0_URL: string
|
||||
readonly PUBLIC_ICONIFY_URL: string
|
||||
readonly PUBLIC_SIGNALING_URL: string
|
||||
readonly PUBLIC_WS_URL: string
|
||||
}
|
||||
|
||||
interface ImportMeta {
|
||||
|
||||
@@ -18,10 +18,8 @@ export interface WebSocketMessage {
|
||||
* WebSocket 配置
|
||||
*/
|
||||
export interface WebSocketConfig {
|
||||
/** WebSocket 路径(如 '/ws/submission/') */
|
||||
path: string
|
||||
/** 完整 URL;提供后覆盖 PUBLIC_WS_URL + path */
|
||||
url?: string
|
||||
/** 完整 URL。后端只认 /ws/submissions 和 /ws/config 两条,按当前页面的协议与 host 拼 */
|
||||
url: string
|
||||
/** 最大重连次数,默认 5 */
|
||||
maxReconnectAttempts?: number
|
||||
/** 重连延迟(毫秒),默认 1000 */
|
||||
@@ -61,7 +59,7 @@ export class BaseWebSocket<T extends WebSocketMessage = WebSocketMessage> {
|
||||
public status: Ref<ConnectionStatus> = ref<ConnectionStatus>("disconnected")
|
||||
|
||||
constructor(config: WebSocketConfig) {
|
||||
this.url = config.url ?? `${import.meta.env.PUBLIC_WS_URL}/${config.path}/`
|
||||
this.url = config.url
|
||||
|
||||
this.maxReconnectAttempts = config.maxReconnectAttempts ?? 5
|
||||
this.reconnectDelay = config.reconnectDelay ?? 1000
|
||||
@@ -306,10 +304,7 @@ class SubmissionWebSocket extends BaseWebSocket<SubmissionUpdate> {
|
||||
|
||||
constructor() {
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"
|
||||
super({
|
||||
path: "submission",
|
||||
url: `${protocol}//${window.location.host}/ws/submissions`,
|
||||
})
|
||||
super({ url: `${protocol}//${window.location.host}/ws/submissions` })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,7 +382,8 @@ export function useSubmissionWebSocket(
|
||||
*
|
||||
* class NotificationWebSocket extends BaseWebSocket<NotificationMessage> {
|
||||
* constructor() {
|
||||
* super({ path: 'notification' })
|
||||
* const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:'
|
||||
* super({ url: `${protocol}//${window.location.host}/ws/notifications` })
|
||||
* }
|
||||
* }
|
||||
*
|
||||
@@ -448,10 +444,7 @@ export interface FlowchartEvaluationUpdate extends WebSocketMessage {
|
||||
class FlowchartWebSocket extends BaseWebSocket<FlowchartEvaluationUpdate> {
|
||||
constructor() {
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"
|
||||
super({
|
||||
path: "flowchart",
|
||||
url: `${protocol}//${window.location.host}/ws/submissions`,
|
||||
})
|
||||
super({ url: `${protocol}//${window.location.host}/ws/submissions` })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -518,10 +511,7 @@ export interface ConfigUpdate extends WebSocketMessage {
|
||||
class ConfigWebSocket extends BaseWebSocket<ConfigUpdate> {
|
||||
constructor() {
|
||||
const protocol = window.location.protocol === "https:" ? "wss:" : "ws:"
|
||||
super({
|
||||
path: "config",
|
||||
url: `${protocol}//${window.location.host}/ws/config`,
|
||||
})
|
||||
super({ url: `${protocol}//${window.location.host}/ws/config` })
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -19,7 +19,8 @@ import type {
|
||||
|
||||
/**
|
||||
* 个人主页数据。`acmProblemsStatus` 的**内容**保持 snake_case ——
|
||||
* 它是 user_profile.acm_problems_status 的 JSONB 原文,回滚时旧后端还要读。
|
||||
* 它是 user_profile.acm_problems_status 的 JSONB 原文,库里存量数据就是这套键名,
|
||||
* 改名等于要把全部历史行迁一遍。
|
||||
*/
|
||||
export type Profile = Omit<UserProfile, "user" | "acmProblemsStatus"> & {
|
||||
user: SessionUser
|
||||
@@ -281,7 +282,7 @@ interface Info {
|
||||
|
||||
/**
|
||||
* 判题产出的统计。**键名保持 snake_case** —— 这是 submission.statistic_info
|
||||
* JSONB 的原文,判题机写进去、回滚时旧后端还要读,不能跟着响应字段一起改名。
|
||||
* JSONB 的原文,判题机按这套键名写进去,不能跟着响应字段一起改名。
|
||||
*/
|
||||
export interface StatisticInfo {
|
||||
score?: number
|
||||
@@ -368,7 +369,7 @@ export type BlankContest = Omit<
|
||||
|
||||
/**
|
||||
* acm_contest_rank.submission_info 的 JSONB 内容。**键名保持 snake_case** ——
|
||||
* 判题写进去、回滚时旧后端还要读,不能跟着响应字段一起改名。
|
||||
* 判题按这套键名写进去,历史比赛的榜单行也是这个形状,不能跟着响应字段一起改名。
|
||||
*/
|
||||
export interface SubmissionInfo {
|
||||
is_ac: boolean
|
||||
@@ -380,7 +381,7 @@ export interface SubmissionInfo {
|
||||
|
||||
/**
|
||||
* 榜单行。`submissionInfo` 的**内容**仍是 snake_case —— 它是 acm_contest_rank
|
||||
* 表的 JSONB 原文,回滚时旧后端还要读,见 SubmissionInfo。
|
||||
* 表的 JSONB 原文,见 SubmissionInfo。
|
||||
*/
|
||||
export type ContestRank = Omit<
|
||||
import("@oj2/contract").ContestRankItem,
|
||||
|
||||
Reference in New Issue
Block a user