Go + Vue 管理台:Agent 隧道、域名反代、IP 安全、访客验证与监控大盘。 Gitea Actions CI 多架构镜像;纯 Go SQLite、无 CGO Docker 构建。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
package store
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
func (s *Store) ListVisitors() ([]User, error) {
|
||||
var users []User
|
||||
err := s.db.Where("role = ?", "visitor").Order("id asc").Find(&users).Error
|
||||
return users, err
|
||||
}
|
||||
|
||||
func (s *Store) ListResourceVisitorIDs(resourceType string, resourceID uint) ([]uint, error) {
|
||||
var bindings []ResourceVisitor
|
||||
err := s.db.Where("resource_type = ? AND resource_id = ?", resourceType, resourceID).
|
||||
Order("user_id asc").Find(&bindings).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ids := make([]uint, len(bindings))
|
||||
for i, b := range bindings {
|
||||
ids[i] = b.UserID
|
||||
}
|
||||
return ids, nil
|
||||
}
|
||||
|
||||
func (s *Store) SetResourceVisitors(resourceType string, resourceID uint, userIDs []uint) error {
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Where("resource_type = ? AND resource_id = ?", resourceType, resourceID).
|
||||
Delete(&ResourceVisitor{}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
for _, uid := range userIDs {
|
||||
rv := ResourceVisitor{
|
||||
ResourceType: resourceType,
|
||||
ResourceID: resourceID,
|
||||
UserID: uid,
|
||||
}
|
||||
if err := tx.Create(&rv).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) DeleteResourceVisitors(resourceType string, resourceID uint) error {
|
||||
return s.db.Where("resource_type = ? AND resource_id = ?", resourceType, resourceID).
|
||||
Delete(&ResourceVisitor{}).Error
|
||||
}
|
||||
|
||||
func (s *Store) ListAllResourceVisitors() ([]ResourceVisitor, error) {
|
||||
var items []ResourceVisitor
|
||||
err := s.db.Order("resource_type, resource_id, user_id").Find(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
const MaxVisitorAccessLogsPerUser = 200
|
||||
|
||||
func (s *Store) AppendVisitorAccessLog(entry *VisitorAccessLog) error {
|
||||
return s.db.Transaction(func(tx *gorm.DB) error {
|
||||
if err := tx.Create(entry).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
var keepIDs []uint
|
||||
if err := tx.Model(&VisitorAccessLog{}).Where("user_id = ?", entry.UserID).
|
||||
Order("id desc").Limit(MaxVisitorAccessLogsPerUser).Pluck("id", &keepIDs).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if len(keepIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return tx.Where("user_id = ? AND id NOT IN ?", entry.UserID, keepIDs).
|
||||
Delete(&VisitorAccessLog{}).Error
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Store) ListVisitorAccessLogs(userID uint, limit int) ([]VisitorAccessLog, error) {
|
||||
if limit <= 0 || limit > MaxVisitorAccessLogsPerUser {
|
||||
limit = MaxVisitorAccessLogsPerUser
|
||||
}
|
||||
var items []VisitorAccessLog
|
||||
err := s.db.Where("user_id = ?", userID).
|
||||
Order("id desc").Limit(limit).Find(&items).Error
|
||||
return items, err
|
||||
}
|
||||
|
||||
func (s *Store) DeleteVisitorAccessLogs(userID uint) error {
|
||||
return s.db.Where("user_id = ?", userID).Delete(&VisitorAccessLog{}).Error
|
||||
}
|
||||
Reference in New Issue
Block a user