package task import ( "fmt" "gitee.ltd/lxh/logger/log" jsoniter "github.com/json-iterator/go" "golang.org/x/exp/slices" "strings" "time" "wireguard-ui/component" "wireguard-ui/global/client" "wireguard-ui/model" "wireguard-ui/service" "wireguard-ui/utils" ) type NetworkClientImpl interface { ClientOfflineNotify() error // 客户端离线通知 } type networkClient struct{} func NetworkClient() NetworkClientImpl { return networkClient{} } // ClientOfflineNotify // @description: 客户端离线通知 // @receiver c // @return error func (c networkClient) ClientOfflineNotify() error { // 查询出所有配置了离线通知的客户端 var clients []model.Client if err := client.DB.Where("offline_monitoring = ?", 1).Find(&clients).Error; err != nil { return err } if len(clients) <= 0 { return nil } // 开始扫描已经链接过的客户端 connectedPeers, err := component.Wireguard().GetClients() if err != nil { log.Errorf("获取已连接客户端失败: %v", err.Error()) return err } // 查询一下通知配置 code, err := service.Setting().GetByCode("WECHAT_NOTIFY") if err != nil { log.Errorf("获取微信通知配置失败: %v", err.Error()) return err } for _, peer := range connectedPeers { var clientName string if !slices.ContainsFunc(clients, func(cli model.Client) bool { isExist := peer.PublicKey.String() == jsoniter.Get([]byte(cli.Keys), "publicKey").ToString() if isExist { clientName = cli.Name } return isExist }) { continue } // 如果存在,判断离线时间 if time.Since(peer.LastHandshakeTime).Minutes() < 3 { var ipAllocation string for _, iaip := range peer.AllowedIPs { ipAllocation += iaip.String() + "," } // 去除一下最右边的逗号 if len(ipAllocation) > 0 { ipAllocation = strings.TrimRight(ipAllocation, ",") } // 已经离线,发送通知 msg := fmt.Sprintf(` [离线通知] 客户端名称 : %v 客户端IP : %v 最后在线时间 : %v `, clientName, ipAllocation, peer.LastHandshakeTime.Format("2006-01-02 15:04:05")) err := utils.WechatNotify(code).SendTextMessage(msg) if err != nil { log.Errorf("微信消息[%v]通知失败: %v", msg, err.Error()) continue } } } return nil }