Files
bl/login/internal/cmd/robot_group_config.go
xinian 79c014f9cd
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
fix: 修正技能效果索引与实现逻辑
2026-03-31 03:42:46 +08:00

173 lines
3.5 KiB
Go

package cmd
import (
"encoding/json"
"os"
"path/filepath"
"sort"
"sync"
)
const (
robotGroupConfigFile = "robot_groups.json"
robotBlacklistFile = "robot_blacklist.json"
)
type robotGroupConfig struct {
NotifyGroupIDs []int64 `json:"notify_group_ids"`
ManageGroupIDs []int64 `json:"manage_group_ids"`
}
type robotBlacklist struct {
UserIDs []int64 `json:"user_ids"`
}
var robotBlacklistMu sync.Mutex
func loadRobotGroupConfig() robotGroupConfig {
path := resolveRobotConfigPath(robotGroupConfigFile)
ensureRobotConfigFile(path, []byte("{\n \"notify_group_ids\": [],\n \"manage_group_ids\": []\n}\n"))
var cfg robotGroupConfig
data, err := os.ReadFile(path)
if err != nil {
return cfg
}
if err = json.Unmarshal(data, &cfg); err != nil {
return robotGroupConfig{}
}
cfg.NotifyGroupIDs = normalizeInt64IDs(cfg.NotifyGroupIDs)
cfg.ManageGroupIDs = normalizeInt64IDs(cfg.ManageGroupIDs)
return cfg
}
func loadRobotBlacklist() robotBlacklist {
path := resolveRobotConfigPath(robotBlacklistFile)
ensureRobotConfigFile(path, []byte("{\n \"user_ids\": []\n}\n"))
var cfg robotBlacklist
data, err := os.ReadFile(path)
if err != nil {
return cfg
}
if err = json.Unmarshal(data, &cfg); err != nil {
return robotBlacklist{}
}
cfg.UserIDs = normalizeInt64IDs(cfg.UserIDs)
return cfg
}
func saveRobotBlacklist(cfg robotBlacklist) error {
path := resolveRobotConfigPath(robotBlacklistFile)
cfg.UserIDs = normalizeInt64IDs(cfg.UserIDs)
ensureRobotConfigFile(path, []byte("{\n \"user_ids\": []\n}\n"))
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
data = append(data, '\n')
return os.WriteFile(path, data, 0o644)
}
func addRobotBlacklistUser(userID int64) error {
if userID <= 0 {
return nil
}
robotBlacklistMu.Lock()
defer robotBlacklistMu.Unlock()
cfg := loadRobotBlacklist()
for _, id := range cfg.UserIDs {
if id == userID {
return nil
}
}
cfg.UserIDs = append(cfg.UserIDs, userID)
return saveRobotBlacklist(cfg)
}
func removeRobotBlacklistUser(userID int64) error {
if userID <= 0 {
return nil
}
robotBlacklistMu.Lock()
defer robotBlacklistMu.Unlock()
cfg := loadRobotBlacklist()
ids := make([]int64, 0, len(cfg.UserIDs))
for _, id := range cfg.UserIDs {
if id != userID {
ids = append(ids, id)
}
}
cfg.UserIDs = ids
return saveRobotBlacklist(cfg)
}
func isRobotBlacklisted(userID int64) bool {
if userID <= 0 {
return false
}
cfg := loadRobotBlacklist()
for _, id := range cfg.UserIDs {
if id == userID {
return true
}
}
return false
}
func resolveRobotConfigPath(name string) string {
candidates := []string{
filepath.Join("public", "config", name),
filepath.Join("..", "public", "config", name),
filepath.Join("..", "..", "public", "config", name),
}
for _, candidate := range candidates {
if _, err := os.Stat(candidate); err == nil {
return candidate
}
}
return candidates[0]
}
func ensureRobotConfigFile(path string, fallback []byte) {
if _, err := os.Stat(path); err == nil {
return
}
_ = os.MkdirAll(filepath.Dir(path), 0o755)
_ = os.WriteFile(path, fallback, 0o644)
}
func normalizeInt64IDs(ids []int64) []int64 {
uniq := make(map[int64]struct{}, len(ids))
for _, id := range ids {
if id > 0 {
uniq[id] = struct{}{}
}
}
res := make([]int64, 0, len(uniq))
for id := range uniq {
res = append(res, id)
}
sort.Slice(res, func(i, j int) bool {
return res[i] < res[j]
})
return res
}
func isConfiguredGroup(groupID int64, groups []int64) bool {
for _, id := range groups {
if id == groupID {
return true
}
}
return false
}