845 lines
20 KiB
TypeScript
845 lines
20 KiB
TypeScript
|
|
import request from "@/utils/request";
|
||
|
|
import type { PaginationParams, PaginationResponse } from "@/types/api";
|
||
|
|
|
||
|
|
// ==================== 比赛相关类型 ====================
|
||
|
|
export interface Contest {
|
||
|
|
id: number;
|
||
|
|
contestName: string;
|
||
|
|
contestType: "individual" | "team";
|
||
|
|
contestState: "unpublished" | "published";
|
||
|
|
startTime: string;
|
||
|
|
endTime: string;
|
||
|
|
address?: string;
|
||
|
|
content?: string;
|
||
|
|
contestTenants?: number[];
|
||
|
|
coverUrl?: string;
|
||
|
|
posterUrl?: string;
|
||
|
|
contactName?: string;
|
||
|
|
contactPhone?: string;
|
||
|
|
contactQrcode?: string;
|
||
|
|
organizers?: string[];
|
||
|
|
coOrganizers?: string[];
|
||
|
|
sponsors?: string[];
|
||
|
|
registerStartTime: string;
|
||
|
|
registerEndTime: string;
|
||
|
|
registerState?: string;
|
||
|
|
submitRule: "once" | "resubmit";
|
||
|
|
submitStartTime: string;
|
||
|
|
submitEndTime: string;
|
||
|
|
reviewRuleId?: number;
|
||
|
|
reviewStartTime: string;
|
||
|
|
reviewEndTime: string;
|
||
|
|
resultPublishTime?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
attachments?: ContestAttachment[];
|
||
|
|
reviewRule?: ContestReviewRule;
|
||
|
|
_count?: {
|
||
|
|
registrations: number;
|
||
|
|
works: number;
|
||
|
|
teams: number;
|
||
|
|
judges: number;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateContestForm {
|
||
|
|
contestName: string;
|
||
|
|
contestType: "individual" | "team";
|
||
|
|
startTime: string;
|
||
|
|
endTime: string;
|
||
|
|
address?: string;
|
||
|
|
content?: string;
|
||
|
|
contestTenants?: number[];
|
||
|
|
coverUrl?: string;
|
||
|
|
posterUrl?: string;
|
||
|
|
contactName?: string;
|
||
|
|
contactPhone?: string;
|
||
|
|
contactQrcode?: string;
|
||
|
|
organizers?: string[];
|
||
|
|
coOrganizers?: string[];
|
||
|
|
sponsors?: string[];
|
||
|
|
registerStartTime: string;
|
||
|
|
registerEndTime: string;
|
||
|
|
submitRule?: "once" | "resubmit";
|
||
|
|
submitStartTime: string;
|
||
|
|
submitEndTime: string;
|
||
|
|
reviewStartTime: string;
|
||
|
|
reviewEndTime: string;
|
||
|
|
resultPublishTime?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface UpdateContestForm extends Partial<CreateContestForm> {
|
||
|
|
contestState?: "unpublished" | "published";
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface QueryContestParams extends PaginationParams {
|
||
|
|
contestName?: string;
|
||
|
|
contestState?: "unpublished" | "published";
|
||
|
|
contestType?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 附件相关类型 ====================
|
||
|
|
export interface ContestAttachment {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
fileName: string;
|
||
|
|
fileUrl: string;
|
||
|
|
format?: string;
|
||
|
|
fileType?: string;
|
||
|
|
size?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateAttachmentForm {
|
||
|
|
contestId: number;
|
||
|
|
fileName: string;
|
||
|
|
fileUrl: string;
|
||
|
|
format?: string;
|
||
|
|
fileType?: string;
|
||
|
|
size?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 评审规则相关类型 ====================
|
||
|
|
export interface ContestReviewRule {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
ruleName: string;
|
||
|
|
dimensions: any;
|
||
|
|
calculationRule: "average" | "max" | "min" | "weighted";
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateReviewRuleForm {
|
||
|
|
contestId: number;
|
||
|
|
ruleName: string;
|
||
|
|
dimensions: any;
|
||
|
|
calculationRule?: "average" | "max" | "min" | "weighted";
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 报名相关类型 ====================
|
||
|
|
export interface ContestRegistration {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
tenantId: number;
|
||
|
|
registrationType?: "individual" | "team";
|
||
|
|
teamId?: number;
|
||
|
|
teamName?: string;
|
||
|
|
userId: number;
|
||
|
|
accountNo: string;
|
||
|
|
accountName: string;
|
||
|
|
role?: string;
|
||
|
|
registrationState: "pending" | "passed" | "rejected" | "withdrawn";
|
||
|
|
registrant?: number;
|
||
|
|
registrationTime: string;
|
||
|
|
reason?: string;
|
||
|
|
operator?: number;
|
||
|
|
operationDate?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
contest?: Contest;
|
||
|
|
user?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
};
|
||
|
|
team?: ContestTeam;
|
||
|
|
_count?: {
|
||
|
|
works: number;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateRegistrationForm {
|
||
|
|
contestId: number;
|
||
|
|
registrationType: "individual" | "team";
|
||
|
|
teamId?: number;
|
||
|
|
userId: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ReviewRegistrationForm {
|
||
|
|
registrationState: "pending" | "passed" | "rejected" | "withdrawn";
|
||
|
|
reason?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface QueryRegistrationParams extends PaginationParams {
|
||
|
|
contestId?: number;
|
||
|
|
registrationState?: "pending" | "passed" | "rejected" | "withdrawn";
|
||
|
|
registrationType?: string;
|
||
|
|
userId?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 团队相关类型 ====================
|
||
|
|
export interface ContestTeam {
|
||
|
|
id: number;
|
||
|
|
tenantId: number;
|
||
|
|
contestId: number;
|
||
|
|
teamName: string;
|
||
|
|
leaderUserId: number;
|
||
|
|
maxMembers?: number;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
leader?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
};
|
||
|
|
members?: ContestTeamMember[];
|
||
|
|
contest?: Contest;
|
||
|
|
_count?: {
|
||
|
|
members: number;
|
||
|
|
registrations: number;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ContestTeamMember {
|
||
|
|
id: number;
|
||
|
|
tenantId: number;
|
||
|
|
teamId: number;
|
||
|
|
userId: number;
|
||
|
|
role: "leader" | "member" | "mentor";
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
user?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateTeamForm {
|
||
|
|
contestId: number;
|
||
|
|
teamName: string;
|
||
|
|
leaderUserId: number;
|
||
|
|
maxMembers?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface InviteMemberForm {
|
||
|
|
userId: number;
|
||
|
|
role?: "leader" | "member" | "mentor";
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 作品相关类型 ====================
|
||
|
|
export interface ContestWork {
|
||
|
|
id: number;
|
||
|
|
tenantId: number;
|
||
|
|
contestId: number;
|
||
|
|
registrationId: number;
|
||
|
|
workNo?: string;
|
||
|
|
title: string;
|
||
|
|
description?: string;
|
||
|
|
files?: string[];
|
||
|
|
version: number;
|
||
|
|
isLatest: boolean;
|
||
|
|
status: "submitted" | "locked" | "reviewing" | "rejected" | "accepted";
|
||
|
|
submitTime: string;
|
||
|
|
submitterUserId?: number;
|
||
|
|
submitterAccountNo?: string;
|
||
|
|
submitSource: string;
|
||
|
|
previewUrl?: string;
|
||
|
|
aiModelMeta?: any;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
contest?: Contest;
|
||
|
|
registration?: ContestRegistration;
|
||
|
|
attachments?: ContestWorkAttachment[];
|
||
|
|
_count?: {
|
||
|
|
scores: number;
|
||
|
|
assignments: number;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ContestWorkAttachment {
|
||
|
|
id: number;
|
||
|
|
tenantId: number;
|
||
|
|
contestId: number;
|
||
|
|
workId: number;
|
||
|
|
fileName: string;
|
||
|
|
fileUrl: string;
|
||
|
|
format?: string;
|
||
|
|
fileType?: string;
|
||
|
|
size?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface SubmitWorkForm {
|
||
|
|
registrationId: number;
|
||
|
|
title: string;
|
||
|
|
description?: string;
|
||
|
|
files?: string[];
|
||
|
|
previewUrl?: string;
|
||
|
|
aiModelMeta?: any;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface QueryWorkParams extends PaginationParams {
|
||
|
|
contestId?: number;
|
||
|
|
registrationId?: number;
|
||
|
|
status?: "submitted" | "locked" | "reviewing" | "rejected" | "accepted";
|
||
|
|
title?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 评审相关类型 ====================
|
||
|
|
export interface ContestWorkJudgeAssignment {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
workId: number;
|
||
|
|
judgeId: number;
|
||
|
|
assignmentTime: string;
|
||
|
|
status: "assigned" | "reviewing" | "completed";
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
work?: ContestWork;
|
||
|
|
judge?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
};
|
||
|
|
scores?: ContestWorkScore[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ContestWorkScore {
|
||
|
|
id: number;
|
||
|
|
tenantId: number;
|
||
|
|
contestId: number;
|
||
|
|
workId: number;
|
||
|
|
assignmentId: number;
|
||
|
|
judgeId: number;
|
||
|
|
judgeName: string;
|
||
|
|
dimensionScores: any;
|
||
|
|
totalScore: number;
|
||
|
|
comments?: string;
|
||
|
|
scoreTime: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
work?: ContestWork;
|
||
|
|
judge?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface AssignWorkForm {
|
||
|
|
workId: number;
|
||
|
|
judgeIds: number[];
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateScoreForm {
|
||
|
|
workId: number;
|
||
|
|
assignmentId: number;
|
||
|
|
dimensionScores: any;
|
||
|
|
totalScore: number;
|
||
|
|
comments?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 公告相关类型 ====================
|
||
|
|
export interface ContestNotice {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
title: string;
|
||
|
|
content: string;
|
||
|
|
noticeType: "system" | "manual" | "urgent";
|
||
|
|
priority: number;
|
||
|
|
publishTime?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
contest?: Contest;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateNoticeForm {
|
||
|
|
contestId: number;
|
||
|
|
title: string;
|
||
|
|
content: string;
|
||
|
|
noticeType?: "system" | "manual" | "urgent";
|
||
|
|
priority?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== 评委相关类型 ====================
|
||
|
|
export interface ContestJudge {
|
||
|
|
id: number;
|
||
|
|
contestId: number;
|
||
|
|
judgeId: number;
|
||
|
|
specialty?: string;
|
||
|
|
weight?: number;
|
||
|
|
description?: string;
|
||
|
|
creator?: number;
|
||
|
|
modifier?: number;
|
||
|
|
createTime?: string;
|
||
|
|
modifyTime?: string;
|
||
|
|
validState?: number;
|
||
|
|
contest?: Contest;
|
||
|
|
judge?: {
|
||
|
|
id: number;
|
||
|
|
username: string;
|
||
|
|
nickname: string;
|
||
|
|
email?: string;
|
||
|
|
};
|
||
|
|
_count?: {
|
||
|
|
assignedContestWorks: number;
|
||
|
|
scoredContestWorks: number;
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CreateJudgeForm {
|
||
|
|
contestId: number;
|
||
|
|
judgeId: number;
|
||
|
|
specialty?: string;
|
||
|
|
weight?: number;
|
||
|
|
description?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
// ==================== API 函数 ====================
|
||
|
|
|
||
|
|
// 比赛管理
|
||
|
|
export const contestsApi = {
|
||
|
|
// 获取比赛列表
|
||
|
|
getList: async (
|
||
|
|
params: QueryContestParams
|
||
|
|
): Promise<PaginationResponse<Contest>> => {
|
||
|
|
const response = await request.get<any, PaginationResponse<Contest>>(
|
||
|
|
"/contests",
|
||
|
|
{ params }
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取比赛详情
|
||
|
|
getDetail: async (id: number): Promise<Contest> => {
|
||
|
|
const response = await request.get<any, Contest>(`/contests/${id}`);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建比赛
|
||
|
|
create: async (data: CreateContestForm): Promise<Contest> => {
|
||
|
|
const response = await request.post<any, Contest>("/contests", data);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新比赛
|
||
|
|
update: async (id: number, data: UpdateContestForm): Promise<Contest> => {
|
||
|
|
const response = await request.patch<any, Contest>(`/contests/${id}`, data);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 发布/撤回比赛
|
||
|
|
publish: async (
|
||
|
|
id: number,
|
||
|
|
contestState: "unpublished" | "published"
|
||
|
|
): Promise<Contest> => {
|
||
|
|
const response = await request.patch<any, Contest>(
|
||
|
|
`/contests/${id}/publish`,
|
||
|
|
{ contestState }
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除比赛
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 附件管理
|
||
|
|
export const attachmentsApi = {
|
||
|
|
// 获取比赛附件列表
|
||
|
|
getList: async (contestId: number): Promise<ContestAttachment[]> => {
|
||
|
|
const response = await request.get<any, ContestAttachment[]>(
|
||
|
|
`/contests/attachments/contest/${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建附件
|
||
|
|
create: async (data: CreateAttachmentForm): Promise<ContestAttachment> => {
|
||
|
|
const response = await request.post<any, ContestAttachment>(
|
||
|
|
"/contests/attachments",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除附件
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/attachments/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 评审规则
|
||
|
|
export const reviewRulesApi = {
|
||
|
|
// 获取评审规则
|
||
|
|
getByContest: async (contestId: number): Promise<ContestReviewRule> => {
|
||
|
|
const response = await request.get<any, ContestReviewRule>(
|
||
|
|
`/contests/review-rules/contest/${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建评审规则
|
||
|
|
create: async (data: CreateReviewRuleForm): Promise<ContestReviewRule> => {
|
||
|
|
const response = await request.post<any, ContestReviewRule>(
|
||
|
|
"/contests/review-rules",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新评审规则
|
||
|
|
update: async (
|
||
|
|
contestId: number,
|
||
|
|
data: Partial<CreateReviewRuleForm>
|
||
|
|
): Promise<ContestReviewRule> => {
|
||
|
|
const response = await request.patch<any, ContestReviewRule>(
|
||
|
|
`/contests/review-rules/contest/${contestId}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 报名管理
|
||
|
|
export const registrationsApi = {
|
||
|
|
// 获取报名列表
|
||
|
|
getList: async (
|
||
|
|
params: QueryRegistrationParams
|
||
|
|
): Promise<PaginationResponse<ContestRegistration>> => {
|
||
|
|
const response = await request.get<
|
||
|
|
any,
|
||
|
|
PaginationResponse<ContestRegistration>
|
||
|
|
>("/contests/registrations", { params });
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取报名详情
|
||
|
|
getDetail: async (id: number): Promise<ContestRegistration> => {
|
||
|
|
const response = await request.get<any, ContestRegistration>(
|
||
|
|
`/contests/registrations/${id}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建报名
|
||
|
|
create: async (
|
||
|
|
data: CreateRegistrationForm
|
||
|
|
): Promise<ContestRegistration> => {
|
||
|
|
const response = await request.post<any, ContestRegistration>(
|
||
|
|
"/contests/registrations",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 审核报名
|
||
|
|
review: async (
|
||
|
|
id: number,
|
||
|
|
data: ReviewRegistrationForm
|
||
|
|
): Promise<ContestRegistration> => {
|
||
|
|
const response = await request.patch<any, ContestRegistration>(
|
||
|
|
`/contests/registrations/${id}/review`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除报名
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/registrations/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 团队管理
|
||
|
|
export const teamsApi = {
|
||
|
|
// 获取团队列表
|
||
|
|
getList: async (contestId: number): Promise<ContestTeam[]> => {
|
||
|
|
const response = await request.get<any, ContestTeam[]>(
|
||
|
|
`/contests/teams/contest/${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取团队详情
|
||
|
|
getDetail: async (id: number): Promise<ContestTeam> => {
|
||
|
|
const response = await request.get<any, ContestTeam>(
|
||
|
|
`/contests/teams/${id}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建团队
|
||
|
|
create: async (data: CreateTeamForm): Promise<ContestTeam> => {
|
||
|
|
const response = await request.post<any, ContestTeam>(
|
||
|
|
"/contests/teams",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新团队
|
||
|
|
update: async (
|
||
|
|
id: number,
|
||
|
|
data: Partial<CreateTeamForm>
|
||
|
|
): Promise<ContestTeam> => {
|
||
|
|
const response = await request.patch<any, ContestTeam>(
|
||
|
|
`/contests/teams/${id}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 邀请成员
|
||
|
|
inviteMember: async (
|
||
|
|
teamId: number,
|
||
|
|
data: InviteMemberForm
|
||
|
|
): Promise<ContestTeamMember> => {
|
||
|
|
const response = await request.post<any, ContestTeamMember>(
|
||
|
|
`/contests/teams/${teamId}/members`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 移除成员
|
||
|
|
removeMember: async (teamId: number, userId: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(
|
||
|
|
`/contests/teams/${teamId}/members/${userId}`
|
||
|
|
);
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除团队
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/teams/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 作品管理
|
||
|
|
export const worksApi = {
|
||
|
|
// 获取作品列表
|
||
|
|
getList: async (
|
||
|
|
params: QueryWorkParams
|
||
|
|
): Promise<PaginationResponse<ContestWork>> => {
|
||
|
|
const response = await request.get<any, PaginationResponse<ContestWork>>(
|
||
|
|
"/contests/works",
|
||
|
|
{ params }
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取作品详情
|
||
|
|
getDetail: async (id: number): Promise<ContestWork> => {
|
||
|
|
const response = await request.get<any, ContestWork>(
|
||
|
|
`/contests/works/${id}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 提交作品
|
||
|
|
submit: async (data: SubmitWorkForm): Promise<ContestWork> => {
|
||
|
|
const response = await request.post<any, ContestWork>(
|
||
|
|
"/contests/works/submit",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取作品版本列表
|
||
|
|
getVersions: async (registrationId: number): Promise<ContestWork[]> => {
|
||
|
|
const response = await request.get<any, ContestWork[]>(
|
||
|
|
`/contests/works/registration/${registrationId}/versions`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除作品
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/works/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 评审管理
|
||
|
|
export const reviewsApi = {
|
||
|
|
// 分配作品给评委
|
||
|
|
assignWork: async (
|
||
|
|
contestId: number,
|
||
|
|
data: AssignWorkForm
|
||
|
|
): Promise<ContestWorkJudgeAssignment[]> => {
|
||
|
|
const response = await request.post<any, ContestWorkJudgeAssignment[]>(
|
||
|
|
`/contests/reviews/assign?contestId=${contestId}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 评分
|
||
|
|
score: async (data: CreateScoreForm): Promise<ContestWorkScore> => {
|
||
|
|
const response = await request.post<any, ContestWorkScore>(
|
||
|
|
"/contests/reviews/score",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新评分
|
||
|
|
updateScore: async (
|
||
|
|
scoreId: number,
|
||
|
|
data: Partial<CreateScoreForm>
|
||
|
|
): Promise<ContestWorkScore> => {
|
||
|
|
const response = await request.patch<any, ContestWorkScore>(
|
||
|
|
`/contests/reviews/score/${scoreId}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取分配给当前评委的作品
|
||
|
|
getAssignedWorks: async (
|
||
|
|
contestId: number
|
||
|
|
): Promise<ContestWorkJudgeAssignment[]> => {
|
||
|
|
const response = await request.get<any, ContestWorkJudgeAssignment[]>(
|
||
|
|
`/contests/reviews/assigned?contestId=${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取作品评分列表
|
||
|
|
getWorkScores: async (workId: number): Promise<ContestWorkScore[]> => {
|
||
|
|
const response = await request.get<any, ContestWorkScore[]>(
|
||
|
|
`/contests/reviews/work/${workId}/scores`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 计算最终得分
|
||
|
|
calculateFinalScore: async (
|
||
|
|
workId: number
|
||
|
|
): Promise<{
|
||
|
|
finalScore: number;
|
||
|
|
scoreCount: number;
|
||
|
|
calculationRule: string;
|
||
|
|
}> => {
|
||
|
|
const response = await request.get<
|
||
|
|
any,
|
||
|
|
{ finalScore: number; scoreCount: number; calculationRule: string }
|
||
|
|
>(`/contests/reviews/work/${workId}/final-score`);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 公告管理
|
||
|
|
export const noticesApi = {
|
||
|
|
// 获取公告列表
|
||
|
|
getList: async (contestId: number): Promise<ContestNotice[]> => {
|
||
|
|
const response = await request.get<any, ContestNotice[]>(
|
||
|
|
`/contests/notices/contest/${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取公告详情
|
||
|
|
getDetail: async (id: number): Promise<ContestNotice> => {
|
||
|
|
const response = await request.get<any, ContestNotice>(
|
||
|
|
`/contests/notices/${id}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 创建公告
|
||
|
|
create: async (data: CreateNoticeForm): Promise<ContestNotice> => {
|
||
|
|
const response = await request.post<any, ContestNotice>(
|
||
|
|
"/contests/notices",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新公告
|
||
|
|
update: async (
|
||
|
|
id: number,
|
||
|
|
data: Partial<CreateNoticeForm>
|
||
|
|
): Promise<ContestNotice> => {
|
||
|
|
const response = await request.patch<any, ContestNotice>(
|
||
|
|
`/contests/notices/${id}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除公告
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/notices/${id}`);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
// 评委管理
|
||
|
|
export const judgesApi = {
|
||
|
|
// 获取评委列表
|
||
|
|
getList: async (contestId: number): Promise<ContestJudge[]> => {
|
||
|
|
const response = await request.get<any, ContestJudge[]>(
|
||
|
|
`/contests/judges/contest/${contestId}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 获取评委详情
|
||
|
|
getDetail: async (id: number): Promise<ContestJudge> => {
|
||
|
|
const response = await request.get<any, ContestJudge>(
|
||
|
|
`/contests/judges/${id}`
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 添加评委
|
||
|
|
create: async (data: CreateJudgeForm): Promise<ContestJudge> => {
|
||
|
|
const response = await request.post<any, ContestJudge>(
|
||
|
|
"/contests/judges",
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 更新评委
|
||
|
|
update: async (
|
||
|
|
id: number,
|
||
|
|
data: Partial<CreateJudgeForm>
|
||
|
|
): Promise<ContestJudge> => {
|
||
|
|
const response = await request.patch<any, ContestJudge>(
|
||
|
|
`/contests/judges/${id}`,
|
||
|
|
data
|
||
|
|
);
|
||
|
|
return response;
|
||
|
|
},
|
||
|
|
|
||
|
|
// 删除评委
|
||
|
|
delete: async (id: number): Promise<void> => {
|
||
|
|
return await request.delete<any, void>(`/contests/judges/${id}`);
|
||
|
|
},
|
||
|
|
};
|