115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type signRequest struct {
|
|
NodeID string `json:"node_id"`
|
|
LongName string `json:"long_name"`
|
|
ShortName string `json:"short_name"`
|
|
SignText string `json:"sign_text"`
|
|
SignTime string `json:"sign_time"`
|
|
}
|
|
|
|
func registerAdminSignRoutes(r gin.IRouter, store *store) {
|
|
r.GET("/signs", func(c *gin.Context) {
|
|
opts, ok := parseListOptions(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
rows, err := store.ListSigns(opts)
|
|
if err != nil {
|
|
writeListResponse(c, rows, opts, err, signDTO)
|
|
return
|
|
}
|
|
total, err := store.CountSigns(opts)
|
|
writeListResponseWithTotal(c, rows, opts, total, err, signDTO)
|
|
})
|
|
r.POST("/signs", func(c *gin.Context) {
|
|
var req signRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid sign request"})
|
|
return
|
|
}
|
|
signTime, ok := parseSignRequestTime(c, req.SignTime)
|
|
if !ok {
|
|
return
|
|
}
|
|
row, err := store.CreateSign(req.NodeID, nullableString(req.LongName), nullableString(req.ShortName), req.SignText, signTime)
|
|
writeSignMutationResponse(c, http.StatusCreated, row, err)
|
|
})
|
|
r.PUT("/signs/:id", func(c *gin.Context) {
|
|
id, ok := parseSignID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
var req signRequest
|
|
if err := c.ShouldBindJSON(&req); err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid sign request"})
|
|
return
|
|
}
|
|
signTime, ok := parseSignRequestTime(c, req.SignTime)
|
|
if !ok {
|
|
return
|
|
}
|
|
row, err := store.UpdateSign(id, req.NodeID, nullableString(req.LongName), nullableString(req.ShortName), req.SignText, signTime)
|
|
writeSignMutationResponse(c, http.StatusOK, row, err)
|
|
})
|
|
r.DELETE("/signs/:id", func(c *gin.Context) {
|
|
id, ok := parseSignID(c)
|
|
if !ok {
|
|
return
|
|
}
|
|
err := store.DeleteSign(id)
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "sign record not found"})
|
|
return
|
|
}
|
|
if err != nil {
|
|
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(http.StatusOK, gin.H{"status": "ok"})
|
|
})
|
|
}
|
|
|
|
func parseSignID(c *gin.Context) (uint64, bool) {
|
|
id, err := strconv.ParseUint(c.Param("id"), 10, 64)
|
|
if err != nil || id == 0 {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid sign id"})
|
|
return 0, false
|
|
}
|
|
return id, true
|
|
}
|
|
|
|
func parseSignRequestTime(c *gin.Context, value string) (time.Time, bool) {
|
|
if value == "" {
|
|
return time.Time{}, true
|
|
}
|
|
parsed, err := time.Parse(time.RFC3339, value)
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid sign_time: use RFC3339"})
|
|
return time.Time{}, false
|
|
}
|
|
return parsed, true
|
|
}
|
|
|
|
func writeSignMutationResponse(c *gin.Context, status int, row *signRecord, err error) {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
c.JSON(http.StatusNotFound, gin.H{"error": "sign record not found"})
|
|
return
|
|
}
|
|
if err != nil {
|
|
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
|
|
return
|
|
}
|
|
c.JSON(status, gin.H{"item": signDTO(*row)})
|
|
}
|