Commit 77c4d68d authored by Yechang's avatar Yechang
Browse files

feat: similarity

parent 665b1b36
Loading
Loading
Loading
Loading
Loading
+110 −2
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ import _ from "lodash";
import type { PageServerLoad } from "./$types";
import { error, redirect, type Actions } from "@sveltejs/kit";
import { db } from "$lib/server/db";
import { createJudgementByHTTP, SlotType } from "$lib/server/oj";

export const load = (async ({ parent, params }) => {
    const data = await parent();
@@ -121,7 +122,114 @@ export const load = (async ({ parent, params }) => {


export const actions = {
    default: async (event) => {
    default: async ({ params }) => {
        const problemId = _.toNumber(params.problemId)
        const problem = await db.problem.findUnique({ where: { id: problemId } })
        if (_.isNil(problem) || _.isNil(problem.gradeGroupId)) {
            error(404);
        }

        // get all students in this class
        const students = await db.classesOnUsers.findMany({
            where: {
                classId: problem.classId,
                role: 'STUDENT'
            },
            include: {
                user: {
                    select: {
                        sustechId: true
                    },
                }
            },
            orderBy: {
                user: {
                    sustechId: 'asc'
                }
            }
        })
        const studentIds = students.map(student => student.user.sustechId).filter(id => !_.isNil(id))

        // get all entries with groups and records
        const group = await db.gradeGroup.findUnique({
            where: {
                id: problem.gradeGroupId
            },
            include: {
                records: {
                    include: {
                        student: {
                            select: { sustechId: true }
                        }
                    },
                    orderBy: { id: 'asc' }
                }
            }
        });
        if (_.isNil(group)) {
            redirect(302, '/')
        }

        const { strategy, records } = group;
        const strategyFn = {
            MAX: _.max<number>,
            MIN: _.min<number>,
            LAST: _.last<number>
        }[strategy]

        const userRecords = _.groupBy(
            records.filter(record => !_.isNil(record.student.sustechId)),
            record => record.student.sustechId
        )
        const _userScores = _.entries(userRecords).map(([sustechId, records]) => {
            const score = strategyFn(records.map((record) => record.grade)) || 0;
            return {
                [sustechId]: score
            }
        })
        const userScores = _.merge({}, ..._userScores)

        const users: {
            [sustechId: string]: number
        } = _.fromPairs(
            studentIds.map(studentId => [studentId, 0])
        )

        studentIds.forEach(studentId => {
            const score = userScores[studentId] || 0
            users[studentId] = score
        });

        const submissions = await db.submission.findMany({
            where: { problemId },
            include: {
                submitter: true,
                feedback: true
            }
        })

        const involvedSubmissions = submissions.filter(submission => {
            const { feedback, submitter } = submission;
            if (_.isNil(feedback)) {
                return false
            }
            const { sustechId } = submitter
            if (_.isNil(sustechId)) {
                return false
            }
            if (!(sustechId in users)) {
                return false
            }
            const targetScore = users[sustechId]

            const finalScore = feedback.score;

            return finalScore == targetScore
        })

        await createJudgementByHTTP("similarity", [{
            type: SlotType.S3_DIR,
            keys: involvedSubmissions.map(s => s.volumeId)
        }]);
    }
} satisfies Actions; 
 No newline at end of file