feat(teacher-bff): 添加考试作业成绩聚合端点
env.ts 新增 CoreEduServiceUrl teacher.service 新增 listExamsByClass/listHomeworkByClass/listGradesByExam 三个聚合方法 teacher.controller 暴露 3 个 GET 端点: /teacher/classes/:classId/exams /teacher/classes/:classId/homework /teacher/exams/:examId/grades 验证: 3 端点全部 200 返回 core-edu 数据
This commit is contained in:
@@ -1,11 +1,12 @@
|
|||||||
import { z } from 'zod';
|
import { z } from "zod";
|
||||||
|
|
||||||
const envSchema = z.object({
|
const envSchema = z.object({
|
||||||
PORT: z.string().default('3003'),
|
PORT: z.string().default("3003"),
|
||||||
IamServiceUrl: z.string().url().default('http://localhost:3002'),
|
IamServiceUrl: z.string().url().default("http://localhost:3002"),
|
||||||
ClassesServiceUrl: z.string().url().default('http://localhost:3001'),
|
ClassesServiceUrl: z.string().url().default("http://localhost:3001"),
|
||||||
LOG_LEVEL: z.string().default('info'),
|
CoreEduServiceUrl: z.string().url().default("http://localhost:3004"),
|
||||||
NODE_ENV: z.string().default('development'),
|
LOG_LEVEL: z.string().default("info"),
|
||||||
|
NODE_ENV: z.string().default("development"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export type Env = z.infer<typeof envSchema>;
|
export type Env = z.infer<typeof envSchema>;
|
||||||
@@ -13,11 +14,14 @@ export type Env = z.infer<typeof envSchema>;
|
|||||||
export function loadEnv(): Env {
|
export function loadEnv(): Env {
|
||||||
const result = envSchema.safeParse({
|
const result = envSchema.safeParse({
|
||||||
...process.env,
|
...process.env,
|
||||||
IamServiceUrl: process.env.IAM_SERVICE_URL || 'http://localhost:3002',
|
IamServiceUrl: process.env.IAM_SERVICE_URL || "http://localhost:3002",
|
||||||
ClassesServiceUrl: process.env.CLASSES_SERVICE_URL || 'http://localhost:3001',
|
ClassesServiceUrl:
|
||||||
|
process.env.CLASSES_SERVICE_URL || "http://localhost:3001",
|
||||||
|
CoreEduServiceUrl:
|
||||||
|
process.env.CORE_EDU_SERVICE_URL || "http://localhost:3004",
|
||||||
});
|
});
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error('Invalid env: ' + JSON.stringify(result.error.flatten()));
|
throw new Error("Invalid env: " + JSON.stringify(result.error.flatten()));
|
||||||
}
|
}
|
||||||
return result.data;
|
return result.data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,10 @@
|
|||||||
import { Controller, Get, Req, UnauthorizedException } from "@nestjs/common";
|
import {
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
Param,
|
||||||
|
Req,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from "@nestjs/common";
|
||||||
import type { Request } from "express";
|
import type { Request } from "express";
|
||||||
import { TeacherService } from "./teacher.service.js";
|
import { TeacherService } from "./teacher.service.js";
|
||||||
|
|
||||||
@@ -25,4 +31,25 @@ export class TeacherController {
|
|||||||
const data = await this.service.getViewports(userId);
|
const data = await this.service.getViewports(userId);
|
||||||
return { success: true as const, data };
|
return { success: true as const, data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 聚合:班级下的考试列表(core-edu)
|
||||||
|
@Get("classes/:classId/exams")
|
||||||
|
async listExamsByClass(@Param("classId") classId: string) {
|
||||||
|
const data = await this.service.listExamsByClass(classId);
|
||||||
|
return { success: true as const, data };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聚合:班级下的作业列表(core-edu)
|
||||||
|
@Get("classes/:classId/homework")
|
||||||
|
async listHomeworkByClass(@Param("classId") classId: string) {
|
||||||
|
const data = await this.service.listHomeworkByClass(classId);
|
||||||
|
return { success: true as const, data };
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聚合:考试下的成绩列表(core-edu)
|
||||||
|
@Get("exams/:examId/grades")
|
||||||
|
async listGradesByExam(@Param("examId") examId: string) {
|
||||||
|
const data = await this.service.listGradesByExam(examId);
|
||||||
|
return { success: true as const, data };
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -49,4 +49,43 @@ export class TeacherService {
|
|||||||
};
|
};
|
||||||
return json.data ?? [];
|
return json.data ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 聚合班级下的考试列表(core-edu)
|
||||||
|
async listExamsByClass(classId: string): Promise<unknown> {
|
||||||
|
const res = await fetch(
|
||||||
|
`${env.CoreEduServiceUrl}/exams/class/${encodeURIComponent(classId)}`,
|
||||||
|
{ headers: { "x-user-id": "bff" } },
|
||||||
|
);
|
||||||
|
if (!res.ok) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const json = (await res.json()) as { success: boolean; data?: unknown };
|
||||||
|
return json.data ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聚合班级下的作业列表(core-edu)
|
||||||
|
async listHomeworkByClass(classId: string): Promise<unknown> {
|
||||||
|
const res = await fetch(
|
||||||
|
`${env.CoreEduServiceUrl}/homework/class/${encodeURIComponent(classId)}`,
|
||||||
|
{ headers: { "x-user-id": "bff" } },
|
||||||
|
);
|
||||||
|
if (!res.ok) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const json = (await res.json()) as { success: boolean; data?: unknown };
|
||||||
|
return json.data ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 聚合考试下的成绩列表(core-edu)
|
||||||
|
async listGradesByExam(examId: string): Promise<unknown> {
|
||||||
|
const res = await fetch(
|
||||||
|
`${env.CoreEduServiceUrl}/grades/exam/${encodeURIComponent(examId)}`,
|
||||||
|
{ headers: { "x-user-id": "bff" } },
|
||||||
|
);
|
||||||
|
if (!res.ok) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const json = (await res.json()) as { success: boolean; data?: unknown };
|
||||||
|
return json.data ?? [];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user