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 { 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> => { const response = await request.get>( "/contests", { params } ); return response; }, // 获取比赛详情 getDetail: async (id: number): Promise => { const response = await request.get(`/contests/${id}`); return response; }, // 创建比赛 create: async (data: CreateContestForm): Promise => { const response = await request.post("/contests", data); return response; }, // 更新比赛 update: async (id: number, data: UpdateContestForm): Promise => { const response = await request.patch(`/contests/${id}`, data); return response; }, // 发布/撤回比赛 publish: async ( id: number, contestState: "unpublished" | "published" ): Promise => { const response = await request.patch( `/contests/${id}/publish`, { contestState } ); return response; }, // 删除比赛 delete: async (id: number): Promise => { return await request.delete(`/contests/${id}`); }, }; // 附件管理 export const attachmentsApi = { // 获取比赛附件列表 getList: async (contestId: number): Promise => { const response = await request.get( `/contests/attachments/contest/${contestId}` ); return response; }, // 创建附件 create: async (data: CreateAttachmentForm): Promise => { const response = await request.post( "/contests/attachments", data ); return response; }, // 删除附件 delete: async (id: number): Promise => { return await request.delete(`/contests/attachments/${id}`); }, }; // 评审规则 export const reviewRulesApi = { // 获取评审规则 getByContest: async (contestId: number): Promise => { const response = await request.get( `/contests/review-rules/contest/${contestId}` ); return response; }, // 创建评审规则 create: async (data: CreateReviewRuleForm): Promise => { const response = await request.post( "/contests/review-rules", data ); return response; }, // 更新评审规则 update: async ( contestId: number, data: Partial ): Promise => { const response = await request.patch( `/contests/review-rules/contest/${contestId}`, data ); return response; }, }; // 报名管理 export const registrationsApi = { // 获取报名列表 getList: async ( params: QueryRegistrationParams ): Promise> => { const response = await request.get< any, PaginationResponse >("/contests/registrations", { params }); return response; }, // 获取报名详情 getDetail: async (id: number): Promise => { const response = await request.get( `/contests/registrations/${id}` ); return response; }, // 创建报名 create: async ( data: CreateRegistrationForm ): Promise => { const response = await request.post( "/contests/registrations", data ); return response; }, // 审核报名 review: async ( id: number, data: ReviewRegistrationForm ): Promise => { const response = await request.patch( `/contests/registrations/${id}/review`, data ); return response; }, // 删除报名 delete: async (id: number): Promise => { return await request.delete(`/contests/registrations/${id}`); }, }; // 团队管理 export const teamsApi = { // 获取团队列表 getList: async (contestId: number): Promise => { const response = await request.get( `/contests/teams/contest/${contestId}` ); return response; }, // 获取团队详情 getDetail: async (id: number): Promise => { const response = await request.get( `/contests/teams/${id}` ); return response; }, // 创建团队 create: async (data: CreateTeamForm): Promise => { const response = await request.post( "/contests/teams", data ); return response; }, // 更新团队 update: async ( id: number, data: Partial ): Promise => { const response = await request.patch( `/contests/teams/${id}`, data ); return response; }, // 邀请成员 inviteMember: async ( teamId: number, data: InviteMemberForm ): Promise => { const response = await request.post( `/contests/teams/${teamId}/members`, data ); return response; }, // 移除成员 removeMember: async (teamId: number, userId: number): Promise => { return await request.delete( `/contests/teams/${teamId}/members/${userId}` ); }, // 删除团队 delete: async (id: number): Promise => { return await request.delete(`/contests/teams/${id}`); }, }; // 作品管理 export const worksApi = { // 获取作品列表 getList: async ( params: QueryWorkParams ): Promise> => { const response = await request.get>( "/contests/works", { params } ); return response; }, // 获取作品详情 getDetail: async (id: number): Promise => { const response = await request.get( `/contests/works/${id}` ); return response; }, // 提交作品 submit: async (data: SubmitWorkForm): Promise => { const response = await request.post( "/contests/works/submit", data ); return response; }, // 获取作品版本列表 getVersions: async (registrationId: number): Promise => { const response = await request.get( `/contests/works/registration/${registrationId}/versions` ); return response; }, // 删除作品 delete: async (id: number): Promise => { return await request.delete(`/contests/works/${id}`); }, }; // 评审管理 export const reviewsApi = { // 分配作品给评委 assignWork: async ( contestId: number, data: AssignWorkForm ): Promise => { const response = await request.post( `/contests/reviews/assign?contestId=${contestId}`, data ); return response; }, // 评分 score: async (data: CreateScoreForm): Promise => { const response = await request.post( "/contests/reviews/score", data ); return response; }, // 更新评分 updateScore: async ( scoreId: number, data: Partial ): Promise => { const response = await request.patch( `/contests/reviews/score/${scoreId}`, data ); return response; }, // 获取分配给当前评委的作品 getAssignedWorks: async ( contestId: number ): Promise => { const response = await request.get( `/contests/reviews/assigned?contestId=${contestId}` ); return response; }, // 获取作品评分列表 getWorkScores: async (workId: number): Promise => { const response = await request.get( `/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 => { const response = await request.get( `/contests/notices/contest/${contestId}` ); return response; }, // 获取公告详情 getDetail: async (id: number): Promise => { const response = await request.get( `/contests/notices/${id}` ); return response; }, // 创建公告 create: async (data: CreateNoticeForm): Promise => { const response = await request.post( "/contests/notices", data ); return response; }, // 更新公告 update: async ( id: number, data: Partial ): Promise => { const response = await request.patch( `/contests/notices/${id}`, data ); return response; }, // 删除公告 delete: async (id: number): Promise => { return await request.delete(`/contests/notices/${id}`); }, }; // 评委管理 export const judgesApi = { // 获取评委列表 getList: async (contestId: number): Promise => { const response = await request.get( `/contests/judges/contest/${contestId}` ); return response; }, // 获取评委详情 getDetail: async (id: number): Promise => { const response = await request.get( `/contests/judges/${id}` ); return response; }, // 添加评委 create: async (data: CreateJudgeForm): Promise => { const response = await request.post( "/contests/judges", data ); return response; }, // 更新评委 update: async ( id: number, data: Partial ): Promise => { const response = await request.patch( `/contests/judges/${id}`, data ); return response; }, // 删除评委 delete: async (id: number): Promise => { return await request.delete(`/contests/judges/${id}`); }, };