This commit is contained in:
2026-06-30 13:08:18 +07:00
parent 795726aea5
commit 1c2bfde005
18 changed files with 1504 additions and 90 deletions

View File

@@ -919,12 +919,13 @@ func GetStudentExamPaperFilesHandler(db *gorm.DB) fiber.Handler {
resList = append(resList, fiber.Map{
"id": r.ID,
"fileName": r.FileName,
"url": fmt.Sprintf("/api/student/exam/download?studentRkId=%d&kind=resource&fileId=%d", studentID, r.ID),
"url": fmt.Sprintf("/api/student/exam/download?studentRkId=%d&kind=resource&fileId=%d&view=1", studentID, r.ID),
"downloadUrl": fmt.Sprintf("/api/student/exam/download?studentRkId=%d&kind=resource&fileId=%d", studentID, r.ID),
})
}
return c.JSON(fiber.Map{
"paperTitle": info.Paper.Title,
"pdfUrl": fmt.Sprintf("/api/student/exam/download?studentRkId=%d&kind=pdf", studentID),
"pdfUrl": fmt.Sprintf("/api/student/exam/download?studentRkId=%d&kind=pdf&view=1", studentID),
"resources": resList,
})
}
@@ -941,19 +942,61 @@ func DownloadStudentExamFileHandler(db *gorm.DB) fiber.Handler {
if info == nil || info.Enrollment.PaperSentAt == nil || info.Paper == nil {
return c.Status(403).JSON(fiber.Map{"error": "Không có quyền"})
}
inline := c.Query("view") == "1" || c.Query("inline") == "1"
kind := c.Query("kind", "pdf")
if kind == "pdf" {
return c.Download(info.Paper.PdfPath, filepath.Base(info.Paper.PdfPath))
name := filepath.Base(info.Paper.PdfPath)
if inline {
return sendExamFileInline(c, info.Paper.PdfPath, name)
}
return c.Download(info.Paper.PdfPath, name)
}
fileID, _ := strconv.ParseUint(c.Query("fileId", "0"), 10, 64)
var res models.ExamPaperResource
if err := db.Where("id = ? AND exam_paper_id = ?", fileID, info.Paper.ID).First(&res).Error; err != nil {
return c.Status(404).JSON(fiber.Map{"error": "File không tồn tại"})
}
if inline && examFileCanViewInline(res.FileName) {
return sendExamFileInline(c, res.FilePath, res.FileName)
}
return c.Download(res.FilePath, res.FileName)
}
}
func examFileCanViewInline(fileName string) bool {
switch strings.ToLower(filepath.Ext(fileName)) {
case ".pdf", ".png", ".jpg", ".jpeg", ".gif", ".webp", ".txt":
return true
default:
return false
}
}
func examViewMimeType(fileName string) string {
switch strings.ToLower(filepath.Ext(fileName)) {
case ".pdf":
return "application/pdf"
case ".png":
return "image/png"
case ".jpg", ".jpeg":
return "image/jpeg"
case ".gif":
return "image/gif"
case ".webp":
return "image/webp"
case ".txt":
return "text/plain; charset=utf-8"
default:
return "application/octet-stream"
}
}
func sendExamFileInline(c *fiber.Ctx, filePath, fileName string) error {
c.Set("Content-Type", examViewMimeType(fileName))
c.Set("Content-Disposition", fmt.Sprintf("inline; filename=%q", fileName))
return c.SendFile(filePath)
}
// POST /api/student/exam/submit — multipart zip
func SubmitStudentExamHandler(db *gorm.DB) fiber.Handler {
return func(c *fiber.Ctx) error {

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

View File

@@ -0,0 +1,28 @@
{
"version": 1,
"exportedAt": "2026-06-29T08:03:38.6066807Z",
"profiles": [
{
"id": "4e08fbd2-15ff-4f37-ba79-44d9f633a248",
"name": "Gà Chill",
"createdAt": "2026-06-27T03:50:45.9698419Z",
"updatedAt": "2026-06-29T01:46:39.7112252Z",
"sshHost": "103.245.236.191",
"sshPort": 22,
"sshUser": "Administrator",
"sshPassword": "pass@123123aA@",
"remoteDbHost": "127.0.0.1",
"remoteDbPort": 1433,
"dbUser": "sa",
"dbPassword": "123123aA@",
"dbTank41": "Db_Tank41",
"dbTank": "Db_Tank",
"dbMember": "Db_Member",
"remoteRequestHost": "127.0.0.1",
"remoteRequestPort": 81,
"resourceUrl": "https://resource.gunnychill.net",
"deployRoot": "C:\\Gunny",
"devRootXml": "E:\\gunny3"
}
]
}