package parking import ( "errors" "fmt" "net/url" "strings" "wails-app/internal/dao" "wails-app/internal/global" ) // CameraStreamOption 是工作台使用的安全摄像头信息,不包含用户名和密码。 type CameraStreamOption struct { DeviceCode string `json:"device_code"` DeviceName string `json:"device_name"` ChannelID uint `json:"channel_id"` ChannelCode string `json:"channel_code"` ChannelName string `json:"channel_name"` Protocol string `json:"protocol"` PlayURL string `json:"play_url"` SnapshotURL string `json:"snapshot_url"` Status string `json:"status"` Online bool `json:"online"` } // ListCameraStreams 返回启用摄像头的浏览器播放配置,并按通道绑定到道闸设备。 func (s *PassageService) ListCameraStreams() ([]CameraStreamOption, error) { if global.GVA_DB == nil { return nil, errors.New("数据库未初始化") } var cameras []dao.Camera if err := global.GVA_DB.Preload("BoundChannel").Where("is_active = ?", true). Order("device_name ASC").Find(&cameras).Error; err != nil { return nil, err } options := make([]CameraStreamOption, 0, len(cameras)) for _, camera := range cameras { protocol := camera.StreamProtocol if protocol == "" { protocol = "webrtc" } playURL := camera.StreamURL systemConversionEnabled := strings.ToLower(strings.TrimSpace(global.GVA_CONFIG.Camera.ConversionMode)) != "edge" if systemConversionEnabled && isSystemMJPEG(protocol) { token := issueCameraStreamToken(camera.DeviceCode) prefix := global.GVA_CONFIG.System.RouterPrefix if prefix == "" { prefix = "/api" } playURL = fmt.Sprintf("%s/parking/camera/stream/%s/%s", strings.TrimRight(prefix, "/"), url.PathEscape(camera.DeviceCode), token) protocol = "mjpeg" } else if isSystemMJPEG(protocol) { // 切到 edge 模式后,沿用数据库中的 StreamURL(由边缘或外部媒体网关提供)。 protocol = "webrtc" } status := camera.Status if status == "" { status = "offline" } options = append(options, CameraStreamOption{ DeviceCode: camera.DeviceCode, DeviceName: camera.DeviceName, ChannelID: camera.ChannelID, ChannelCode: cameraChannelCode(camera.BoundChannel), ChannelName: cameraChannelName(camera.BoundChannel), Protocol: protocol, PlayURL: playURL, SnapshotURL: camera.SnapshotURL, Status: status, Online: camera.Status == "online" || camera.Status == "connected", }) } return options, nil } func cameraChannelCode(channel *dao.Channel) string { if channel == nil { return "" } return channel.ChannelCode } func cameraChannelName(channel *dao.Channel) string { if channel == nil { return "" } return channel.ChannelName }