feat: system manager.

This commit is contained in:
2026-04-29 08:41:23 +08:00
parent ea44ea0153
commit 77e7a612fc
6 changed files with 590 additions and 0 deletions
+159
View File
@@ -0,0 +1,159 @@
package controllers
import (
"errors"
"hr_receiver/config"
"hr_receiver/models"
"net/http"
"strconv"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
)
type KindergartenAdminController struct {
DB *gorm.DB
}
type kindergartenPayload struct {
Address string `json:"address"`
Name string `json:"name"`
RegionID uint32 `json:"regionId"`
}
func NewKindergartenAdminController() *KindergartenAdminController {
return &KindergartenAdminController{DB: config.DB}
}
func (kc *KindergartenAdminController) List(c *gin.Context) {
var items []models.Kindergarten
query := kc.DB.Model(&models.Kindergarten{}).Order("region_id ASC, id ASC")
if keyword := strings.TrimSpace(c.Query("keyword")); keyword != "" {
likeValue := "%" + keyword + "%"
query = query.Where("name LIKE ? OR address LIKE ?", likeValue, likeValue)
}
if err := query.Find(&items).Error; err != nil {
writeError(c, http.StatusInternalServerError, "failed to query kindergartens")
return
}
writeSuccess(c, http.StatusOK, "query success", items)
}
func (kc *KindergartenAdminController) Create(c *gin.Context) {
var payload kindergartenPayload
if err := c.ShouldBindJSON(&payload); err != nil {
writeError(c, http.StatusBadRequest, err.Error())
return
}
if err := validateKindergartenPayload(payload); err != nil {
writeError(c, http.StatusBadRequest, err.Error())
return
}
record := models.Kindergarten{
Address: strings.TrimSpace(payload.Address),
Name: strings.TrimSpace(payload.Name),
RegionID: payload.RegionID,
}
if err := kc.DB.Create(&record).Error; err != nil {
writeKindergartenDBError(c, err)
return
}
writeSuccess(c, http.StatusCreated, "create success", record)
}
func (kc *KindergartenAdminController) Update(c *gin.Context) {
record, err := kc.findByID(c.Param("id"))
if err != nil {
respondKindergartenLookupError(c, err)
return
}
var payload kindergartenPayload
if err := c.ShouldBindJSON(&payload); err != nil {
writeError(c, http.StatusBadRequest, err.Error())
return
}
if err := validateKindergartenPayload(payload); err != nil {
writeError(c, http.StatusBadRequest, err.Error())
return
}
record.Name = strings.TrimSpace(payload.Name)
record.Address = strings.TrimSpace(payload.Address)
record.RegionID = payload.RegionID
if err := kc.DB.Save(&record).Error; err != nil {
writeKindergartenDBError(c, err)
return
}
writeSuccess(c, http.StatusOK, "update success", record)
}
func (kc *KindergartenAdminController) Delete(c *gin.Context) {
record, err := kc.findByID(c.Param("id"))
if err != nil {
respondKindergartenLookupError(c, err)
return
}
var bindings int64
if err := kc.DB.Model(&models.UserRegionBinding{}).Where("region_id = ?", record.RegionID).Count(&bindings).Error; err != nil {
writeError(c, http.StatusInternalServerError, "failed to check user bindings")
return
}
if bindings > 0 {
writeError(c, http.StatusConflict, "current kindergarten is bound to users")
return
}
if err := kc.DB.Delete(&record).Error; err != nil {
writeError(c, http.StatusInternalServerError, "failed to delete kindergarten")
return
}
writeSuccess(c, http.StatusOK, "delete success", nil)
}
func (kc *KindergartenAdminController) findByID(id string) (models.Kindergarten, error) {
var record models.Kindergarten
numericID, err := strconv.ParseUint(strings.TrimSpace(id), 10, 64)
if err != nil {
return record, gorm.ErrRecordNotFound
}
if err := kc.DB.First(&record, numericID).Error; err != nil {
return record, err
}
return record, nil
}
func validateKindergartenPayload(payload kindergartenPayload) error {
if strings.TrimSpace(payload.Name) == "" {
return errors.New("name is required")
}
if strings.TrimSpace(payload.Address) == "" {
return errors.New("address is required")
}
if payload.RegionID == 0 {
return errors.New("regionId is required")
}
return nil
}
func respondKindergartenLookupError(c *gin.Context, err error) {
if errors.Is(err, gorm.ErrRecordNotFound) {
writeError(c, http.StatusNotFound, "kindergarten not found")
return
}
writeError(c, http.StatusInternalServerError, "failed to query kindergarten")
}
func writeKindergartenDBError(c *gin.Context, err error) {
if strings.Contains(strings.ToLower(err.Error()), "unique") {
writeError(c, http.StatusConflict, "regionId already has a kindergarten")
return
}
writeError(c, http.StatusInternalServerError, "failed to persist kindergarten")
}