This commit is contained in:
@@ -68,6 +68,7 @@ func AutoMigrate(db *gorm.DB) error {
|
||||
&models.SystemSetting{},
|
||||
&models.GuideLink{},
|
||||
&models.AppDownload{},
|
||||
&models.AppGuide{},
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
129
server/internal/handlers/handlers_app_guides.go
Normal file
129
server/internal/handlers/handlers_app_guides.go
Normal file
@@ -0,0 +1,129 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"server/internal/models"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
// GET /api/public/app-guides
|
||||
func ListAppGuidesPublicHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
var guides []models.AppGuide
|
||||
if err := db.Order("created_at desc").Find(&guides).Error; err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Không thể tải danh sách tài liệu hướng dẫn"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"data": guides})
|
||||
}
|
||||
}
|
||||
|
||||
// GET /api/app-guides
|
||||
func ListAppGuidesHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
var guides []models.AppGuide
|
||||
if err := db.Order("created_at desc").Find(&guides).Error; err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Không thể tải danh sách tài liệu hướng dẫn"})
|
||||
}
|
||||
return c.JSON(fiber.Map{"data": guides})
|
||||
}
|
||||
}
|
||||
|
||||
// POST /api/app-guides
|
||||
func CreateAppGuideHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
if !isSuperAdmin(c) {
|
||||
return c.Status(403).JSON(fiber.Map{"error": "Bạn không có quyền thực hiện chức năng này"})
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
var req Request
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid request body"})
|
||||
}
|
||||
if req.Title == "" || req.URL == "" {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Tiêu đề và đường dẫn không được để trống"})
|
||||
}
|
||||
|
||||
guide := models.AppGuide{
|
||||
Title: req.Title,
|
||||
URL: req.URL,
|
||||
}
|
||||
if err := db.Create(&guide).Error; err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Lưu tài liệu hướng dẫn thất bại"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"ok": true, "data": guide})
|
||||
}
|
||||
}
|
||||
|
||||
// PUT /api/app-guides/:id
|
||||
func UpdateAppGuideHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
if !isSuperAdmin(c) {
|
||||
return c.Status(403).JSON(fiber.Map{"error": "Bạn không có quyền thực hiện chức năng này"})
|
||||
}
|
||||
|
||||
idParam := c.Params("id")
|
||||
id, err := strconv.ParseUint(idParam, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid ID"})
|
||||
}
|
||||
|
||||
var guide models.AppGuide
|
||||
if err := db.First(&guide, uint(id)).Error; err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "Không tìm thấy tài liệu hướng dẫn"})
|
||||
}
|
||||
|
||||
type Request struct {
|
||||
Title string `json:"title"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
var req Request
|
||||
if err := c.BodyParser(&req); err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid request body"})
|
||||
}
|
||||
if req.Title == "" || req.URL == "" {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Tiêu đề và đường dẫn không được để trống"})
|
||||
}
|
||||
|
||||
guide.Title = req.Title
|
||||
guide.URL = req.URL
|
||||
|
||||
if err := db.Save(&guide).Error; err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Cập nhật tài liệu hướng dẫn thất bại"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"ok": true, "data": guide})
|
||||
}
|
||||
}
|
||||
|
||||
// DELETE /api/app-guides/:id
|
||||
func DeleteAppGuideHandler(db *gorm.DB) fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
if !isSuperAdmin(c) {
|
||||
return c.Status(403).JSON(fiber.Map{"error": "Bạn không có quyền thực hiện chức năng này"})
|
||||
}
|
||||
|
||||
idParam := c.Params("id")
|
||||
id, err := strconv.ParseUint(idParam, 10, 32)
|
||||
if err != nil {
|
||||
return c.Status(400).JSON(fiber.Map{"error": "Invalid ID"})
|
||||
}
|
||||
|
||||
var guide models.AppGuide
|
||||
if err := db.First(&guide, uint(id)).Error; err != nil {
|
||||
return c.Status(404).JSON(fiber.Map{"error": "Không tìm thấy tài liệu hướng dẫn"})
|
||||
}
|
||||
|
||||
if err := db.Delete(&guide).Error; err != nil {
|
||||
return c.Status(500).JSON(fiber.Map{"error": "Xóa tài liệu hướng dẫn thất bại"})
|
||||
}
|
||||
|
||||
return c.JSON(fiber.Map{"ok": true})
|
||||
}
|
||||
}
|
||||
@@ -212,4 +212,15 @@ type AppDownload struct {
|
||||
|
||||
func (AppDownload) TableName() string { return "app_downloads" }
|
||||
|
||||
// AppGuide đại diện cho tài liệu/video hướng dẫn ứng dụng dành cho sinh viên
|
||||
type AppGuide struct {
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
Title string `gorm:"column:title;size:512;not null" json:"title"`
|
||||
URL string `gorm:"column:url;size:1024;not null" json:"url"`
|
||||
}
|
||||
|
||||
func (AppGuide) TableName() string { return "app_guides" }
|
||||
|
||||
|
||||
|
||||
@@ -109,6 +109,7 @@ func main() {
|
||||
|
||||
api.Get("/public/app-downloads", handlers.ListAppDownloadsPublicHandler(gormDB))
|
||||
api.Get("/public/guide-links", handlers.ListGuideLinksPublicHandler(gormDB))
|
||||
api.Get("/public/app-guides", handlers.ListAppGuidesPublicHandler(gormDB))
|
||||
|
||||
// Management — yêu cầu đăng nhập staff
|
||||
staff := api.Group("", middleware.RequireStaff())
|
||||
@@ -215,6 +216,11 @@ func main() {
|
||||
staff.Put("/app-downloads/:id", handlers.UpdateAppDownloadHandler(gormDB))
|
||||
staff.Delete("/app-downloads/:id", handlers.DeleteAppDownloadHandler(gormDB))
|
||||
|
||||
staff.Get("/app-guides", handlers.ListAppGuidesHandler(gormDB))
|
||||
staff.Post("/app-guides", handlers.CreateAppGuideHandler(gormDB))
|
||||
staff.Put("/app-guides/:id", handlers.UpdateAppGuideHandler(gormDB))
|
||||
staff.Delete("/app-guides/:id", handlers.DeleteAppGuideHandler(gormDB))
|
||||
|
||||
go func() {
|
||||
ticker := time.NewTicker(30 * time.Second)
|
||||
defer ticker.Stop()
|
||||
|
||||
Reference in New Issue
Block a user