Initialize AutoLibrary website with Gitea deployment

This commit is contained in:
KenanZhu committed 2026-11-04 09:59:06 +08:00
commit 18216953e7
101 files changed
+12581

No files matched your search

@@ -0,0 +1,310 @@
package bulletins_handler
import (
"log"
"net/http"
"strconv"
"time"
"autolibrary.top/webserver/utils"
"autolibrary.top/webserver/backend/database/bulletins_database"
"autolibrary.top/webserver/backend/models/bulletins_model"
"github.com/gin-gonic/gin"
)
/*
These handlers are used to manage bulletins.
*/
// GET /bulletins?date={yyyy-MM-dd}&time={HH:mm:ss}&range_hour={0<number}
//
// This handler regard the given 'date' and 'time' in Shanghai(+8:00) time zone.
func GetBulletins(c *gin.Context) {
dateStr := c.Query("date")
timeStr := c.Query("time")
rangeHourStr := c.Query("range_hour")
loc := utils.ShanghaiLocation
// Default to current date_time and range
if dateStr == "" {
dateStr = utils.NowInShanghai().Format("2006-01-02")
}
if timeStr == "" {
timeStr = "00:00:00"
}
if rangeHourStr == "" {
rangeHourStr = "24"
}
dateTimeStr := dateStr + " " + timeStr
dateTime, err := utils.ParseInShanghai("2006-01-02 15:04:05", dateTimeStr)
if err != nil {
log.Printf("[E] GET > try to get bulletins, but got invalid (date=%s, time=%s, tz=%s) parameters: %v", dateStr, timeStr, loc.String(), err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "GET > try to get bulletins, but got invalid parameters: 'date' or 'time'",
"data": nil,
})
return
}
rangeHours, err := strconv.Atoi(rangeHourStr)
if err != nil {
log.Printf("[E] GET > try to get bulletins, but got invalid (range_hour=%s) parameter: %v", rangeHourStr, err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "GET > try to get bulletins, but got invalid parameter: 'range_hour'",
"data": nil,
})
return
}
startOfDateTime := dateTime
endOfDateTime := startOfDateTime.Add(time.Duration(rangeHours)*time.Hour)
startOfDateTimeStr := startOfDateTime.Format(time.RFC3339)
endOfDateTimeStr := endOfDateTime.Format(time.RFC3339)
var bulletins []bulletins_model.Bulletin
result := bulletins_database.DB.Where(
"date_time >= ? AND date_time < ? AND is_deleted = ?", startOfDateTime, endOfDateTime, false,
).Find(&bulletins)
if result.Error != nil {
log.Printf("[E] GET > occur an error when get bulletins from %s to %s: %v", startOfDateTimeStr, endOfDateTimeStr, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "GET > occur an error when get bulletins",
"data": nil,
})
return
}
var deleteIds []int64
result = bulletins_database.DB.Model(bulletins_model.Bulletin{}).Where(
"date_time >= ? AND date_time < ? AND is_deleted = ?", startOfDateTime, endOfDateTime, true,
).Pluck("id", &deleteIds)
if result.Error != nil {
log.Printf("[E] GET > occur an error when get bulletins from %s to %s: %v", startOfDateTimeStr, endOfDateTimeStr, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "GET > occur an error when get bulletins",
"data": nil,
})
return
}
data := gin.H{
"bulletins": bulletins,
"delete_ids": deleteIds,
}
log.Printf("[I] GET > get bulletins from %s to %s successfully", startOfDateTimeStr, endOfDateTimeStr)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "GET > get bulletins successful",
"data": data,
})
}
// GET /bulletins/:id
func GetBulletinByID(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Printf("[E] GET > try to get bulletin, but got invalid id parameter: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "GET > try to get bulletin, but got invalid id",
"data": nil,
})
return
}
var bulletin bulletins_model.Bulletin
result := bulletins_database.DB.Where("is_deleted = ?", false).First(&bulletin, id)
if result.Error != nil {
log.Printf("[E] GET > bulletin (id=%d) can not found: %v", id, result.Error)
c.JSON(http.StatusNotFound, gin.H{
"code": http.StatusNotFound,
"msg": "GET > bulletin can not found",
"data": nil,
})
return
}
log.Printf("[I] GET > get bulletin (id=%d) successfully", id)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "GET > get bulletin successful",
"data": bulletin,
})
}
// POST /bulletins
func PostBulletin(c *gin.Context) {
var bulletin bulletins_model.Bulletin
if err := c.ShouldBindJSON(&bulletin); err != nil {
log.Printf("[E] POST > try to create bulletin, but got invalid request data: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "POST > try to create bulletin, but got invalid request data",
"data": nil,
})
return
}
bulletin.CreateAt = utils.NowInShanghai()
// set default value to make sure the bulletin is not edited and not deleted before
// get into the database
bulletin.IsEdited = false
bulletin.IsDeleted = false
result := bulletins_database.DB.Create(&bulletin)
if result.Error != nil {
log.Printf("[E] POST > occur an error when create bulletin: %v", result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "POST > occur an error when create bulletin",
"data": nil,
})
return
}
dataTimeStr := bulletin.DateTime.Format(time.RFC3339)
id := strconv.FormatUint(uint64(bulletin.ID), 10)
log.Printf("[I] POST > create bulletin (id=%s, date_time=%s) successful", id, dataTimeStr)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "POST > create bulletin successful",
"data": bulletin,
})
}
// PUT /bulletins/:id
func PutBulletinByID(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Printf("[E] PUT > try to update bulletin, but got invalid id parameter: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "PUT > try to update bulletin, but got invalid id",
"data": nil,
})
return
}
var updateBulletin bulletins_model.Bulletin
if err := c.ShouldBindJSON(&updateBulletin); err != nil {
log.Printf("[E] PUT > try to update bulletin, but got invalid request data: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "PUT > try to update bulletin, but got invalid request data",
"data": nil,
})
return
}
var existingBulletin bulletins_model.Bulletin
result := bulletins_database.DB.Where("is_deleted = ?", false).First(&existingBulletin, id)
if result.Error != nil {
log.Printf("[E] PUT > bulletin (id=%d) can not found: %v", id, result.Error)
c.JSON(http.StatusNotFound, gin.H{
"code": http.StatusNotFound,
"msg": "PUT > bulletin can not found",
"data": nil,
})
return
}
// keep the original date time
updateBulletin.DateTime = existingBulletin.DateTime
// set last edit time to current time
updateBulletin.LastEditAt = utils.NowInShanghai()
// set is edited to true
updateBulletin.IsEdited = true
result = bulletins_database.DB.Model(&existingBulletin).Where("id = ?", id).Updates(updateBulletin)
if result.Error != nil {
log.Printf("[E] PUT > occur an error when update bulletin (id=%d): %v", id, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "PUT > occur an error when update bulletin",
"data": nil,
})
return
}
// post check after update
var updatedBulletin bulletins_model.Bulletin
if result = bulletins_database.DB.Where("is_deleted = ?", false).First(&updatedBulletin, id); result.Error == nil {
log.Printf("[I] PUT > update bulletin (id=%d) successful", id)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "PUT > update bulletin successful",
"data": updatedBulletin,
})
} else {
log.Printf("[E] PUT > update successful but failed to retrieve updated bulletin (id=%d): %v", id, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "PUT > update successful but failed to retrieve updated bulletin",
"data": nil,
})
}
}
// DELETE /bulletins/:id
func DeleteBulletinByID(c *gin.Context) {
id, err := strconv.Atoi(c.Param("id"))
if err != nil {
log.Printf("[E] DELETE > try to delete bulletin, but got invalid id: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"msg": "DELETE > try to delete bulletin, but got invalid id",
"data": nil,
})
return
}
// soft delete, actually is a update operation
var existingBulletin bulletins_model.Bulletin
result := bulletins_database.DB.Where("is_deleted = ?", false).First(&existingBulletin, id)
if result.Error != nil {
log.Printf("[E] DELETE > bulletin (id=%d) can not found: %v", id, result.Error)
c.JSON(http.StatusNotFound, gin.H{
"code": http.StatusNotFound,
"msg": "DELETE > bulletin can not found",
"data": nil,
})
return
}
// set is_deleted to true
existingBulletin.IsDeleted = true
result = bulletins_database.DB.Model(&existingBulletin).Where("id = ?", id).Updates(existingBulletin)
if result.Error != nil {
log.Printf("[E] DELETE > occur an error when soft delete bulletin (id=%d): %v", id, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "DELETE > occur an error when soft delete bulletin",
"data": nil,
})
return
}
// post check after soft delete
var deletedBulletin bulletins_model.Bulletin
if result = bulletins_database.DB.Where("is_deleted = ?", true).First(&deletedBulletin, id); result.Error == nil {
log.Printf("[I] DELETE > soft delete bulletin (id=%d) successful", id)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"msg": "DELETE > soft delete bulletin successful",
"data": deletedBulletin,
})
} else {
log.Printf("[E] DELETE > soft delete successful but failed to retrieve deleted bulletin (id=%d): %v", id, result.Error)
c.JSON(http.StatusInternalServerError, gin.H{
"code": http.StatusInternalServerError,
"msg": "DELETE > soft delete successful but failed to retrieve deleted bulletin",
"data": nil,
})
}
}