Files
gb-cms/api/api_system.go
2025-11-29 13:50:31 +08:00

274 lines
9.5 KiB
Go

package api
import (
"fmt"
"gb-cms/common"
"gb-cms/dao"
"gb-cms/log"
"gb-cms/stack"
"gopkg.in/ini.v1"
"net/http"
"strconv"
"strings"
"sync"
)
var (
setConfigLock sync.Mutex
)
type BaseConfig struct {
APIAuth bool `json:"APIAuth"`
AckTimeout int `json:"AckTimeout"`
AllowStreamStartByURL bool `json:"AllowStreamStartByURL"`
BlackIPList string `json:"BlackIPList"`
BlackUAList string `json:"BlackUAList"`
Captcha bool `json:"Captcha"`
DevicePassword string `json:"DevicePassword"`
DropChannelType string `json:"DropChannelType"`
GlobalChannelAudio bool `json:"GlobalChannelAudio"`
GlobalChannelShared bool `json:"GlobalChannelShared"`
GlobalDeviceAlarmSubscribeInterval int `json:"GlobalDeviceAlarmSubscribeInterval"`
GlobalDeviceCatalogSubscribeInterval int `json:"GlobalDeviceCatalogSubscribeInterval"`
GlobalDevicePTZSubscribeInterval int `json:"GlobalDevicePTZSubscribeInterval"`
GlobalDevicePositionSubscribeInterval int `json:"GlobalDevicePositionSubscribeInterval"`
HTTPSCertFile string `json:"HTTPSCertFile"`
HTTPSKeyFile string `json:"HTTPSKeyFile"`
HTTPSPort int `json:"HTTPSPort"`
Host string `json:"Host"`
KeepaliveTimeout int `json:"KeepaliveTimeout"`
LiveStreamAuth bool `json:"LiveStreamAuth"`
MapCenter string `json:"MapCenter"`
MapEnable bool `json:"MapEnable"`
MediaTransport string `json:"MediaTransport"`
MediaTransportMode string `json:"MediaTransportMode"`
Port int `json:"Port"`
PreferStreamFmt string `json:"PreferStreamFmt"`
Realm string `json:"Realm"`
SIPLog bool `json:"SIPLog"`
Serial string `json:"Serial"`
TimeServer string `json:"TimeServer"`
}
func (api *ApiServer) OnGetBaseConfig(_ *Empty, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
setupType := common.String2SetupType(common.Config.DeviceDefaultMediaTransport)
ip, ua := dao.BlacklistManager.ToStrings()
v := BaseConfig{
APIAuth: true,
AckTimeout: common.Config.InviteTimeout,
AllowStreamStartByURL: false,
BlackIPList: ip,
BlackUAList: ua,
Captcha: false,
DevicePassword: common.Config.Password,
DropChannelType: common.Config.GlobalDropChannelType,
GlobalChannelAudio: true,
GlobalChannelShared: false,
GlobalDeviceAlarmSubscribeInterval: common.Config.SubAlarmGlobalInterval,
GlobalDeviceCatalogSubscribeInterval: common.Config.SubCatalogGlobalInterval,
GlobalDevicePTZSubscribeInterval: common.Config.SubPTZGlobalInterval,
GlobalDevicePositionSubscribeInterval: common.Config.SubPositionGlobalInterval,
HTTPSCertFile: "",
HTTPSKeyFile: "",
HTTPSPort: 0,
Host: common.Config.PublicIP,
KeepaliveTimeout: common.Config.AliveExpires,
LiveStreamAuth: true,
MapCenter: "",
MapEnable: false,
MediaTransport: setupType.Transport(),
MediaTransportMode: setupType.String(),
Port: common.Config.SipPort,
PreferStreamFmt: common.Config.PreferStreamFmt,
Realm: common.Config.Realm,
SIPLog: false,
Serial: common.Config.SipID,
TimeServer: "",
}
return v, nil
}
func (api *ApiServer) OnSetBaseConfig(baseConfig *BaseConfig, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
if len(baseConfig.Serial) != 20 {
return nil, fmt.Errorf("serial must be 20 characters long")
} else if len(baseConfig.Realm) == 0 {
return nil, fmt.Errorf("realm must be 10 characters long")
} else if baseConfig.Port == 0 {
return nil, fmt.Errorf("port must be greater than 0")
}
setConfigLock.Lock()
defer setConfigLock.Unlock()
// 黑名单
ipList := strings.Split(baseConfig.BlackIPList, ",")
uaList := strings.Split(baseConfig.BlackUAList, ",")
err := dao.Blacklist.Replace(ipList, uaList)
if err != nil {
log.Sugar.Errorf("更新黑名单失败: %s", err.Error())
return nil, err
}
iniConfig, err := ini.Load("./config.ini")
if err != nil {
return nil, err
}
var sipChanged bool
var changed bool
if baseConfig.Serial != common.Config.SipID {
// 更新sip id
iniConfig.Section("sip").Key("id").SetValue(baseConfig.Serial)
sipChanged = true
}
if baseConfig.Realm != common.Config.Realm {
// 更新realm
iniConfig.Section("sip").Key("realm").SetValue(baseConfig.Realm)
changed = true
}
if baseConfig.Port != common.Config.SipPort {
// 更新端口
iniConfig.Section("sip").Key("port").SetValue(strconv.Itoa(baseConfig.Port))
sipChanged = true
}
if baseConfig.Host != common.Config.PublicIP {
// 更新host
iniConfig.Section("sip").Key("public_ip").SetValue(baseConfig.Host)
sipChanged = true
}
if baseConfig.DevicePassword != common.Config.Password {
// 更新设备密码
iniConfig.Section("sip").Key("password").SetValue(baseConfig.DevicePassword)
changed = true
}
// 更新优先流格式
if baseConfig.PreferStreamFmt != common.Config.PreferStreamFmt {
iniConfig.Section("sip").Key("prefer_stream_fmt").SetValue(baseConfig.PreferStreamFmt)
changed = true
}
// 更新订阅间隔
if baseConfig.GlobalDeviceAlarmSubscribeInterval != common.Config.SubAlarmGlobalInterval {
iniConfig.Section("sip").Key("sub_alarm_global_interval").SetValue(strconv.Itoa(baseConfig.GlobalDeviceAlarmSubscribeInterval))
changed = true
}
if baseConfig.GlobalDeviceCatalogSubscribeInterval != common.Config.SubCatalogGlobalInterval {
iniConfig.Section("sip").Key("sub_catalog_global_interval").SetValue(strconv.Itoa(baseConfig.GlobalDeviceCatalogSubscribeInterval))
changed = true
}
if baseConfig.GlobalDevicePTZSubscribeInterval != common.Config.SubPTZGlobalInterval {
iniConfig.Section("sip").Key("sub_ptz_global_interval").SetValue(strconv.Itoa(baseConfig.GlobalDevicePTZSubscribeInterval))
changed = true
}
if baseConfig.GlobalDevicePositionSubscribeInterval != common.Config.SubPositionGlobalInterval {
iniConfig.Section("sip").Key("sub_position_global_interval").SetValue(strconv.Itoa(baseConfig.GlobalDevicePositionSubscribeInterval))
changed = true
}
// 更新全局过滤通道类型
if baseConfig.DropChannelType != common.Config.GlobalDropChannelType {
iniConfig.Section("sip").Key("global_drop_channel_type").SetValue(baseConfig.DropChannelType)
changed = true
var codes []string
if baseConfig.DropChannelType != "" {
codes = strings.Split(baseConfig.DropChannelType, ",")
}
err = dao.Channel.DropChannel("", codes, nil)
if err != nil {
log.Sugar.Errorf("更新全局过滤通道类型失败: %s", err.Error())
return nil, err
}
}
// 更新默认媒体传输方式
var setup = "udp"
if strings.ToLower(baseConfig.MediaTransport) == "udp" {
} else if strings.ToLower(baseConfig.MediaTransportMode) == "passive" {
setup = "passive"
} else if strings.ToLower(baseConfig.MediaTransportMode) == "active" {
setup = "active"
}
if setup != common.Config.DeviceDefaultMediaTransport {
iniConfig.Section("sip").Key("device_default_media_transport").SetValue(setup)
changed = true
}
if !changed && !sipChanged {
return "OK", nil
}
err = iniConfig.SaveTo("./config.ini")
if err != nil {
return nil, err
}
var newConfig *common.Config_
newConfig, err = common.ParseConfig("./config.ini")
if err != nil {
return nil, err
}
// ip库只在启动时加载
newConfig.IP2RegionEnable = common.Config.IP2RegionEnable
newConfig.IP2RegionDBPath = common.Config.IP2RegionDBPath
// 重启sip服务
if sipChanged {
log.Sugar.Infof("重启sip服务器 port: %d", baseConfig.Port)
if err = stack.RestartSipStack(newConfig); err != nil {
return nil, err
}
}
common.Config = newConfig
return "OK", nil
}
func (api *ApiServer) OnLogList(q *QueryDeviceChannel, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
if q.Limit < 1 {
q.Limit = 10
}
v := struct {
LogCount int
LogList interface{}
LogRegion bool
LogReserveDays int
}{
LogRegion: common.Config.IP2RegionEnable,
LogReserveDays: common.Config.LogReserveDays,
}
query, i, err := dao.Log.Query(q.Limit, (q.Start/q.Limit)+1, q.Keyword, q.Sort, q.Order, q.Method, q.StartTime, q.EndTime)
if err != nil {
log.Sugar.Errorf("查询操作日志失败: %s", err.Error())
return nil, err
}
v.LogCount = i
v.LogList = query
return &v, err
}
func (api *ApiServer) OnLogClear(_ *Empty, _ http.ResponseWriter, _ *http.Request) (interface{}, error) {
if err := dao.Log.Clear(); err != nil {
log.Sugar.Errorf("清除操作日志失败: %s", err.Error())
return nil, err
}
return "OK", nil
}