package controllers import ( "basic.com/valib/logger.git" "net/http" "regexp" "strconv" "webserver/extend/code" "webserver/extend/config" "webserver/extend/sys" "webserver/extend/util" "webserver/middlewares/auth" "webserver/service" "basic.com/dbapi.git" "github.com/gin-gonic/gin" ) type SysSetController struct { } type LocalConfigVo struct { Id string `json:"id"` AlarmIp string `json:"alarm_ip,omitempty" example:"192.168.1.182"` AlarmPort int `json:"alarm_port,omitempty" example:"22122"` AlarmThresholdType int `json:"alarm_threshold_type"` //报警阈值类型设置:1:按最高分,2:按阈值以上 AlarmThreshold int `json:"alarm_threshold"` //报警阈值 WebPicIp string `json:"web_pic_ip,omitempty" example:""` WebPicPort int `json:"web_pic_port,omitempty" example:"22122"` EsPicIp string `json:"es_pic_ip,omitempty" example:""` EsPicPort int `json:"es_pic_port,omitempty" example:"22122"` CutMaxDuration int `json:"cut_max_duration,omitempty" example:"20"` CutMinDuration int `json:"cut_min_duration,omitempty" example:"5"` ServerId string `json:"server_id,omitempty" example:"分析设备id"` ServerName string `json:"server_name,omitempty" example:"分析设备名称"` ServerType int `json:"server_type,omitempty" example:"1"` Reserved string `json:"reserved,omitempty" example:"1"` RealMax int `json:"real_max"` //实时处理的最大路数 } type ResourceConfigVo struct { IpType int `json:"ipType"` //0:本机ip,1:漂移ip ServiceIp string `json:"serviceIp"` //外部服务ip Domain string `json:"domain"` //域名 FilePort int `json:"filePort"` } type Gb28181ConfigVo struct { Id string `json:"Id"` ServerIp string `json:"ServerIp" example:"国标服务器IP"` ServerPort int `json:"ServerPort" example:"平台服务端口:7060"` PublicId string `json:"PublicId" example:"平台服务Id"` GbServerPort int `json:"GbServerPort" example:"国标服务端口:8060"` IsAuth bool `json:"IsAuth" example:"是否开启鉴权:true"` Password string `json:"Password" example:"密码"` UpdateTime string `json:"UpdateTime"` } type SysClockConfigVo struct { TimeZone string `json:"timeZone" example:"时区"` NTP bool `json:"ntp" example:"NTP校时"` NTPServer string `json:"ntpServer" example:"NTP服务器地址"` Interval int `json:"interval" example:"自动校时间隔"` NewTime string `json:"newTime" example:"手动指定时间"` } // @Security ApiKeyAuth // @Summary 存储信息查询 // @Description 存储信息查询 // @Accept json // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/alarmServerShow [GET] func (sset SysSetController) AlarmServerShow(c *gin.Context) { var api dbapi.SysSetApi b, sysconf := api.GetServerInfo() if b { util.ResponseFormat(c, code.Success, sysconf) } else { util.ResponseFormat(c, code.ComError, "查询失败") } } // @Security ApiKeyAuth // @Summary 存储信息修改 // @Description 存储信息修改 // @Accept json // @Produce json // @Tags sysset // @Param config body controllers.LocalConfigVo true "报警和存储信息数据" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/alarmEdit [POST] func (sset SysSetController) AlarmEdit(c *gin.Context) { var args LocalConfigVo err := c.BindJSON(&args) if err != nil { util.ResponseFormat(c, code.RequestParamError, "参数有误") return } var api dbapi.SysSetApi paramBody := util.Struct2Map(args) b, data := api.AlarmEdit(paramBody) if b { util.ResponseFormat(c, code.Success, data) } else { util.ResponseFormat(c, code.ComError, "保存失败") } } // @Security ApiKeyAuth // @Summary 存储信息修改 // @Description 存储信息修改 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/videoLenShow [GET] func (sset SysSetController) VideoLenShow(c *gin.Context) { var api dbapi.SysSetApi b, sysconf := api.GetServerInfo() if b { resData := make(map[string]int32, 0) resData["max_video_len"] = sysconf.CutMaxDuration resData["min_video_len"] = sysconf.CutMinDuration // 存在则修改 util.ResponseFormat(c, code.Success, resData) } else { util.ResponseFormat(c, code.ComError, "查询失败") } } // @Security ApiKeyAuth // @Summary 视频截取时长修改 // @Description 视频截取时长信息 // @Accept x-www-form-urlencoded // @Produce json // @Tags sysset // @Param min_video_len formData string true "视频截取最短时长" // @Param max_video_len formData string true "视频截取最长时长" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/videoLenEdit [POST] func (sset SysSetController) VideoLenEdit(c *gin.Context) { /*min_video_len := c.Query("min_video_len") //查询请求URL后面的参数 max_video_len := c.PostForm("max_video_len") //从表单中查询参数*/ //POST和PUT主体参数优先于URL查询字符串值。 max_video_len := c.Request.FormValue("max_video_len") min_video_len := c.Request.FormValue("min_video_len") var api dbapi.SysSetApi b, data := api.VideoLenEdit(max_video_len, min_video_len) if b { util.ResponseFormat(c, code.UpdateSuccess, data) } else { util.ResponseFormat(c, code.ComError, "保存失败") } } // @Security ApiKeyAuth // @Summary 获取分析设备信息 // @Description 分析设备信息 // @Accept json // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/getDevInfo [GET] func (sset SysSetController) GetDevInfo(c *gin.Context) { var api dbapi.SysSetApi b, sysconf := api.GetServerInfo() resData := make(map[string]interface{}, 0) if !b { // 查询是否存在 util.ResponseFormat(c, code.ServiceInsideError, "查询失败") } else { resData["server_id"] = sysconf.GetServerId() resData["server_name"] = sysconf.GetServerName() resData["server_port"] = sys.GetNginxListenPort() ipv4, mask, _ := sys.GetLocalIP(config.Server.NetworkAdapter) gateway, _ := sys.GetDefaultRoute(config.Server.NetworkAdapter) dns, _ := sys.GetDnsServer() resData["ip"] = ipv4 resData["subMask"] = mask resData["gateway"] = gateway resData["dns"] = dns resData["min_video_len"] = sysconf.CutMinDuration resData["max_video_len"] = sysconf.CutMaxDuration resData["alarm_ip"] = sysconf.AlarmIp resData["alarm_port"] = sysconf.AlarmPort resData["web_pic_ip"] = sysconf.WebPicIp resData["web_pic_port"] = sysconf.WebPicPort resData["es_pic_ip"] = sysconf.EsPicIp resData["es_pic_port"] = sysconf.EsPicPort resData["deviceNum"] = config.Server.DeviceNum resData["deviceType"] = config.Server.DeviceType resData["deviceSerialNum"] = config.Server.DeviceSerialNum resData["masterVersion"] = config.Server.MasterVersion resData["webVersion"] = config.Server.WebVersion resData["channelCount"] = config.Server.ChannelCount resData["diskCount"] = config.Server.DiskCount util.ResponseFormat(c, code.Success, resData) } } // @Security ApiKeyAuth // saveDevInfo dev_id dev_name // @Summary 保存视频分析设备信息 // @Description 分析设备信息 // @Accept x-www-form-urlencoded // @Produce json // @Tags sysset // @Param dev_name formData string true "分析设备名称" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/saveDevInfo [POST] func (sset SysSetController) SaveDevInfo(c *gin.Context) { var api dbapi.SysSetApi paramBody := map[string]interface{}{ "serverName": c.PostForm("server_name"), "ip": c.PostForm("ip"), "subMask": c.PostForm("subMask"), "gateway": c.PostForm("gateway"), "dns": c.PostForm("dns"), } b, data := api.SaveServerInfo(paramBody) logger.Debug("isOk b:",b, "data:", data) if b { // 查询是否存在 util.ResponseFormat(c, code.Success, data) } else { // 存在及修改 不存在 即添加 util.ResponseFormat(c, code.ComError, "保存失败") } } // @Security ApiKeyAuth // @Summary GB28181设置查询 // @Description GB28181设置信息查询 // @Accept json // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/gb28181ConfigShow [GET] func (sset SysSetController) Gb28181ConfigShow(c *gin.Context) { var api dbapi.SysSetApi b, data := api.Gb28181ConfigShow() if b { util.ResponseFormat(c, code.Success, data) } else { util.ResponseFormat(c, code.ComError, "查询失败") } } // @Security ApiKeyAuth // @Summary GB28181设置信息修改 // @Description GB28181设置修改 // @Accept json // @Produce json // @Tags sysset // @Param config body controllers.Gb28181ConfigVo true "GB28181设置数据" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/gb28181ConfigEdit [POST] func (sset SysSetController) Gb28181ConfigEdit(c *gin.Context) { var args Gb28181ConfigVo err := c.BindJSON(&args) if err != nil { util.ResponseFormat(c, code.RequestParamError, "参数有误") return } var api dbapi.SysSetApi paramBody := util.Struct2Map(args) b, data := api.Gb28181ConfigEdit(paramBody) if b { util.ResponseFormat(c, code.UpdateSuccess, data) } else { util.ResponseFormat(c, code.ComError, "更新失败") } } // @Security ApiKeyAuth // @Summary 获取时间配置 // @Description 系统时间配置信息 // @Accept json // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/clockInfo [GET] func (sset SysSetController) GetClockinfo(c *gin.Context) { resData := make(map[string]interface{}, 0) resData["time_zone"], resData["local_time"] = sys.TimeZone() resData["ntp"], resData["ntp_server"], resData["interval"] = sys.NTPConfig() util.ResponseFormat(c, code.Success, resData) } // @Security ApiKeyAuth // @Summary 测试同步时间 // @Description 测试同步时间服务器是否可用 // @Produce json // @Tags sysset // @Param server query string true "时间服务器ip" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/ntpTest [GET] func (sset SysSetController) TestNTPServer(c *gin.Context) { ntpServer := c.Query("server") if root := sys.CheckRootPermissions(); !root { util.ResponseFormat(c, code.ServiceInsideError, "服务器没有修改时间的权限") return } isConn := sys.RunNTPDate(ntpServer) if !isConn { util.ResponseFormat(c, code.RequestParamError, "NTP服务器不可用") return } util.ResponseFormat(c, code.Success, "") } // @Security ApiKeyAuth // @Summary 设置系统时间 // @Description 校正系统时间 // @Accept json // @Produce json // @Tags sysset // @Param config body controllers.SysClockConfigVo true "校时信息" // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/updateClock [POST] func (sset SysSetController) SetSysClock(c *gin.Context) { var args SysClockConfigVo err := c.BindJSON(&args) if err != nil { util.ResponseFormat(c, code.RequestParamError, "参数有误") return } if args.TimeZone != "CST" && args.TimeZone != "UTC" { if r := sys.SetTimeZone(args.TimeZone); !r { util.ResponseFormat(c, code.RequestParamError, "时区参数错误") return } } if !args.NTP { if r := sys.SetLocalTime(args.NewTime); !r { util.ResponseFormat(c, code.RequestParamError, "指定的时间参数错误") return } } else { if r := sys.EnableNTPCron(args.NTPServer, args.Interval); !r { util.ResponseFormat(c, code.RequestParamError, "指定的服务器地址错误") return } } util.ResponseFormat(c, code.UpdateSuccess, "配置成功") } // @Security ApiKeyAuth // @Summary 查询系统运行信息 // @Description 获取当前系统的运行状态,CPU, GPU, 内存等 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/sysinfo [GET] func (sset SysSetController) GetSysInfo(c *gin.Context) { info := sys.GetSysInfo() util.ResponseFormat(c, code.UpdateSuccess, info) } // @Security ApiKeyAuth // @Summary 查询系统状态阈值设置 // @Description 获取当前系统的运行状态,CPU, GPU, 内存的阈值配置 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/sysThresholds [GET] func (sset SysSetController) GetSysThresholds(c *gin.Context) { util.ResponseFormat(c, code.UpdateSuccess, config.Server.SysThresholds) } // @Security ApiKeyAuth // @Summary 重启系统 // @Description 重启操作系统 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/reboot [GET] func (sset SysSetController) RebootOS(c *gin.Context) { if isOk, msg := sys.Reboot(); !isOk { util.ResponseFormat(c, code.UpdateFail, msg) return } util.ResponseFormat(c, code.Success, "正在重启") } // @Summary 获取定时重启 // @Description 获取定时重启任务的配置规则 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/rebootTask [GET] func (sset SysSetController) GetRebootTask(c *gin.Context) { _, msg := sys.ReadRebootTaskInCrontab() util.ResponseFormat(c, code.Success, msg) } // @Summary 设置定时重启 // @Description 设置定时重启任务的配置规则 // @Accept x-www-form-urlencoded // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"目录结构数据", success:true}" // @Failure 500 {string} json "{"code":500, msg:"返回错误信息", success:false}" // @Router /data/api-v/sysset/rebootTask [POST] func (sset SysSetController) SetRebootTask(c *gin.Context) { task := c.PostForm("task") if len(task) < 1 { sys.CleanRebootTask() util.ResponseFormat(c, code.Success, "配置成功") return } regEx := `^([0-9*]+\s){4}[0-9*]+$` if r, _ := regexp.MatchString(regEx, task); !r { util.ResponseFormat(c, code.RequestParamError, "参数错误") return } if r := sys.UpdateRebootTask(task); !r { util.ResponseFormat(c, code.UpdateFail, "配置失败") return } util.ResponseFormat(c, code.Success, "配置成功") } // @Security ApiKeyAuth // @Summary 获取存储对外服务信息 // @Description 获取存储对外服务信息 // @Produce json // @Tags sysset // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/getResourceConfig [get] func (sset SysSetController) GetResourceConfig(c *gin.Context) { var sysApi dbapi.SysSetApi b,d := sysApi.GetResourceConfig() if b { util.ResponseFormat(c,code.Success,map[string]interface{}{ "ipType":d.IpType, "serviceIp": d.ServiceIp, "domain": d.Domain, "filePort": d.FilePort, }) } else { util.ResponseFormat(c,code.ComError,"") } } // @Security ApiKeyAuth // @Summary 存储对外服务信息 // @Description 存储对外服务信息 // @Accept json // @Produce json // @Tags sysset // @Param reqBoby body controllers.ResourceConfigVo true "post请求,json参数" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/saveResourceConfig [post] func (sset SysSetController) SaveResourceConfig(c *gin.Context) { var reqBody ResourceConfigVo c.BindJSON(&reqBody) if reqBody.ServiceIp == "" && reqBody.Domain == "" { util.ResponseFormat(c, code.RequestParamError, "") return } var sysApi dbapi.SysSetApi paramBody := util.Struct2Map(reqBody) if b, _ := sysApi.SaveResourceConfig(paramBody); b { util.ResponseFormat(c, code.Success, "") } else { util.ResponseFormat(c, code.ComError, "") } } // @Summary 系统更新包上传(分块检查) // @Description 系统更新包上传(分块检查) // @Accept multipart/form-data // @Produce json // @Tags sysset // @Param chunkNumber formData int true "当前是第几个分块" // @Param chunkSize formData int true "每一块的大小" // @Param currentChunkSize formData int true "当前块的大小" // @Param identifier formData string true "整个文件的唯一标识,目前是md5" // @Param filename formData string true "文件名称" // @Param relativePath formData string true "文件在客户端电脑的路径" // @Param totalChunks formData int true "文件总块数" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/patchUpdate [get] func (sset SysSetController) PatchUpdateCheck(c *gin.Context) { authDriver := auth.GenerateAuthDriver() userM := (*authDriver).User(c) if userM ==nil { util.ResponseFormat(c,code.TokenNotFound,"登录过期,请登录") return } chunkNumber, e1 := strconv.Atoi(c.Request.FormValue("chunkNumber")) chunkSize, e2 := strconv.Atoi(c.Request.FormValue("chunkSize")) currentChunkSize, e3 := strconv.Atoi(c.Request.FormValue("currentChunkSize")) identifier := c.Request.FormValue("identifier") filename := c.Request.FormValue("filename") relativePath := c.Request.FormValue("relativePath") totalChunks, e5 := strconv.Atoi(c.Request.FormValue("totalChunks")) if identifier == "" || e1 != nil || e2 != nil || e3 != nil || e5 !=nil { util.ResponseFormat(c,code.RequestParamError,"参数有误") return } var arg = service.FileChunkCheckVo { UserId: userM["id"].(string), FileName: filename, Identifier: identifier, RelativePath: relativePath, TotalChunks: totalChunks, ChunkNumber: chunkNumber, ChunkSize: chunkSize, CurrentChunkSize:currentChunkSize, } var sv service.SysService if b := sv.CheckUpdateFile(&arg);b { c.String(http.StatusOK,"found") } else { c.String(http.StatusNoContent,"") } } // @Security ApiKeyAuth // @Summary 系统更新包上传 // @Description 系统更新包上传 // @Accept multipart/form-data // @Produce json // @Tags sysset // @Param chunkNumber formData int true "当前是第几个分块" // @Param chunkSize formData int true "每一块的大小" // @Param currentChunkSize formData int true "当前块的大小" // @Param totalSize formData string true "文件总大小" // @Param identifier formData string true "整个文件的唯一标识,目前是md5" // @Param filename formData string true "文件名称" // @Param relativePath formData string true "文件在客户端电脑的路径" // @Param totalChunks formData int true "文件总块数" // @Param file formData file true "文件分片内容" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/patchUpdate [post] func (sset SysSetController) PatchUpdate(c *gin.Context) { authDriver := auth.GenerateAuthDriver() userM := (*authDriver).User(c) if userM == nil { util.ResponseFormat(c, code.TokenNotFound, "登录过期,请登录") return } chunkNumber, e1 := strconv.Atoi(c.Request.FormValue("chunkNumber")) chunkSize, e2 := strconv.Atoi(c.Request.FormValue("chunkSize")) currentChunkSize, e3 := strconv.Atoi(c.Request.FormValue("currentChunkSize")) totalSize, e4 := strconv.ParseInt(c.Request.FormValue("totalSize"), 10, 64) identifier := c.Request.FormValue("identifier") filename := c.Request.FormValue("filename") relativePath := c.Request.FormValue("relativePath") totalChunks, e5 := strconv.Atoi(c.Request.FormValue("totalChunks")) file, header, e6 := c.Request.FormFile("file") if identifier == "" || e1 != nil || e2 != nil || e3 != nil || e4 != nil || e5 != nil || e6 != nil { util.ResponseFormat(c, code.RequestParamError, "参数有误") return } var arg = service.FileUploadVo{ UserId: userM["id"].(string), FileName: filename, Identifier: identifier, RelativePath: relativePath, TotalSize: totalSize, TotalChunks: totalChunks, ChunkNumber: chunkNumber, ChunkSize: chunkSize, CurrentChunkSize: currentChunkSize, File: &file, Header: header, } var sv service.SysService if b,_ := sv.PatchUpload(&arg); b { util.ResponseFormat(c, code.Success, "") } else { util.ResponseFormat(c, code.ComError, "") } } // @Security ApiKeyAuth // @Summary 开始升级 // @Description 开始升级 // @Accept multipart/form-data // @Produce json // @Tags sysset // @Param identifier formData string true "整个文件的唯一标识,目前是md5" // @Param filename formData string true "文件名称" // @Success 200 {string} json "{"code":200, msg:"", success:true}" // @Failure 500 {string} json "{"code":500, msg:"", success:false}" // @Router /data/api-v/sysset/upgrade [post] func (sset SysSetController) Upgrade(c *gin.Context) { identifier := c.Request.FormValue("identifier") filename := c.Request.FormValue("filename") if identifier == "" || filename == "" { util.ResponseFormat(c,code.RequestParamError,"") return } var sv service.SysService if b,err := sv.Upgrade(identifier, filename);b { util.ResponseFormat(c,code.UpgradeSuccess,"升级成功") } else { util.ResponseFormat(c,code.UpgradeFail,err.Error()) } }