chore: 同步本地 v9 整改与运营能力

This commit is contained in:
weijuesen
2026-08-17 21:43:26 +08:00
parent 9a426039b7
commit d205d4845b
58 changed files with 4042 additions and 115 deletions
+35 -2
View File
@@ -29,7 +29,9 @@ func RegisterBiosecurityRoutes(rg *gin.RouterGroup, db *gorm.DB) {
func listSeedSources(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
q := db.Model(&model.SeedSource{})
q := db.Model(&model.SeedSource{}).
Joins("LEFT JOIN batches b ON b.id = seed_sources.batch_id")
q = applyRoomScope(q, c, "b.room_id")
if batch := c.Query("batchId"); batch != "" {
q = q.Where("batch_id = ?", batch)
}
@@ -62,6 +64,12 @@ func createSeedSource(db *gorm.DB) gin.HandlerFunc {
return
}
}
if body.BatchID != nil && !requireObjectAccess(c, db, "batch", *body.BatchID) {
return
}
if body.ParentID != nil && !requireObjectAccess(c, db, "seed_source", *body.ParentID) {
return
}
source := model.SeedSource{
PublicID: randomPublicID(),
BatchID: body.BatchID,
@@ -96,6 +104,9 @@ func createSeedSource(db *gorm.DB) gin.HandlerFunc {
func updateSeedSource(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
if !requireObjectAccess(c, db, "seed_source", c.Param("id")) {
return
}
var source model.SeedSource
if db.Where("id = ?", c.Param("id")).First(&source).Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "seed source not found"})
@@ -168,7 +179,10 @@ func updateSeedSource(db *gorm.DB) gin.HandlerFunc {
func listDisinfectionRecords(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
q := db.Model(&model.DisinfectionRecord{})
q := db.Model(&model.DisinfectionRecord{}).
Joins("LEFT JOIN rooms r ON r.id = disinfection_records.room_id").
Joins("LEFT JOIN batches b ON b.id = disinfection_records.batch_id")
q = applyRoomScope(q, c, "COALESCE(r.id, b.room_id)")
if room := c.Query("roomId"); room != "" {
q = q.Where("room_id = ?", room)
}
@@ -215,6 +229,13 @@ func createDisinfectionRecord(db *gorm.DB) gin.HandlerFunc {
c.JSON(http.StatusBadRequest, gin.H{"error": "batchId 不是合法的 UUID"})
return
}
if body.RoomID != nil && !canAccessRoom(db, c, body.RoomID) {
c.JSON(http.StatusForbidden, gin.H{"error": "无权在该蚕房下创建消毒记录"})
return
}
if body.BatchID != nil && !requireObjectAccess(c, db, "batch", *body.BatchID) {
return
}
if err := db.Create(&body).Error; err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "创建消毒记录失败"})
return
@@ -225,6 +246,9 @@ func createDisinfectionRecord(db *gorm.DB) gin.HandlerFunc {
func updateDisinfectionRecord(db *gorm.DB) gin.HandlerFunc {
return func(c *gin.Context) {
if !requireObjectAccess(c, db, "disinfection_record", c.Param("id")) {
return
}
var record model.DisinfectionRecord
if db.Where("id = ?", c.Param("id")).First(&record).Error != nil {
c.JSON(http.StatusNotFound, gin.H{"error": "disinfection record not found"})
@@ -284,6 +308,9 @@ func issueQR(db *gorm.DB) gin.HandlerFunc {
c.JSON(http.StatusBadRequest, gin.H{"error": "entityType/entityId 无效"})
return
}
if !requireObjectAccess(c, db, body.EntityType, body.EntityID) {
return
}
if !entityExists(db, body.EntityType, body.EntityID) {
c.JSON(http.StatusNotFound, gin.H{"error": "二维码关联实体不存在"})
return
@@ -333,6 +360,12 @@ func resolveQR(db *gorm.DB) gin.HandlerFunc {
c.JSON(http.StatusNotFound, gin.H{"error": "二维码关联实体不存在"})
return
}
if roomID, ok := objectRoomID(db, link.EntityType, link.EntityID); ok {
if !canAccessRoom(db, c, roomID) {
c.JSON(http.StatusForbidden, gin.H{"error": "无权访问该二维码关联实体"})
return
}
}
c.JSON(http.StatusOK, gin.H{
"entityType": link.EntityType,
"publicId": link.PublicID,