| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233 |
- package devices
- import (
- "encoding/json"
- "fmt"
- "github.com/gin-gonic/gin"
- "go.uber.org/zap"
- "io"
- "os"
- "path/filepath"
- "server/dao"
- "server/global"
- "server/model/common/response"
- "server/model/devices"
- "server/utils/cache"
- "strconv"
- "strings"
- "time"
- )
- type CameraApi struct {
- }
- // DeviceEndianHeartbeat 摄像头心跳
- func (ca *CameraApi) DeviceEndianHeartbeat(c *gin.Context) {
- var info devices.CameraEndianHeartbeatRequest
- if err := c.ShouldBindJSON(&info); err != nil {
- global.GVA_LOG.Error("DeviceEndianHeartbeat === ", zap.Error(err))
- response.FailWithMessage("参数错误", c)
- return
- }
- cache.UpdateDeviceState(info.SerialNum, 1)
- resp := devices.CameraEndianHeartbeatResponse{
- ReturnCode: 0,
- PushEventPic: true,
- }
- response.OkWithData(resp, c)
- }
- func (ca *CameraApi) DeviceEndianEvent(c *gin.Context) {
- // 步骤1:解析 multipart/form-data 表单(包含EventInfo和图片文件)
- var form devices.CameraEventForm
- if err := c.ShouldBind(&form); err != nil {
- global.GVA_LOG.Error("表单解析失败", zap.Error(err))
- response.FailWithMessage("表单格式错误:"+err.Error(), c)
- return
- }
- // 步骤2:处理EventInfo.json文件(原有逻辑)
- file, err := form.EventInfo.Open()
- if err != nil {
- global.GVA_LOG.Error("打开EventInfo文件失败", zap.Error(err))
- response.FailWithMessage("读取事件文件失败:"+err.Error(), c)
- return
- }
- defer file.Close()
- fileContent, err := io.ReadAll(file)
- if err != nil {
- global.GVA_LOG.Error("读取EventInfo文件内容失败", zap.Error(err))
- response.FailWithMessage("解析事件文件失败:"+err.Error(), c)
- return
- }
- var eventReq devices.CameraEndianEventRequest
- if err := json.Unmarshal(fileContent, &eventReq); err != nil {
- global.GVA_LOG.Error("JSON解析失败", zap.Error(err), zap.String("content", string(fileContent)))
- response.FailWithMessage("事件数据格式错误:"+err.Error(), c)
- return
- }
- //if eventReq.EventType != "Alarm" {
- // global.GVA_LOG.Info("事件处理完成", zap.Any("event", eventReq))
- // response.OkWithData(devices.CameraEndianEventResponse{
- // ReturnCode: 0,
- // }, c)
- // return
- //}
- // 步骤3:新增逻辑 - 处理图片文件(form.Files)
- var savedFiles string // 记录成功保存的图片路径
- if form.File != nil {
- // 遍历所有上传的图片
- // 3.1 打开图片文件
- imgFile, err := form.File.Open()
- if err != nil {
- global.GVA_LOG.Warn("打开图片文件失败", zap.String("filename", form.File.Filename), zap.Error(err))
- return // 跳过当前文件,处理下一个
- }
- defer imgFile.Close()
- // 3.2 读取图片内容
- imgBytes, err := io.ReadAll(imgFile)
- if err != nil {
- global.GVA_LOG.Warn("读取图片内容失败", zap.String("filename", form.File.Filename), zap.Error(err))
- return
- }
- // 3.3 简单校验图片类型(可选,根据需求调整)
- if !isImageFile(form.File.Filename) {
- global.GVA_LOG.Warn("非图片文件,跳过处理", zap.String("filename", form.File.Filename))
- return
- }
- // 3.4 保存图片到本地(实际项目可改为上传OSS/云存储)
- savePath, err := saveImageToLocal(eventReq.SerialNum, form.File.Filename, imgBytes)
- if err != nil {
- global.GVA_LOG.Warn("保存图片失败", zap.String("filename", form.File.Filename), zap.Error(err))
- }
- savedFiles = savePath
- }
- // 步骤4:返回响应(包含事件信息和图片处理结果)
- resp := devices.CameraEndianEventResponse{
- ReturnCode: 0,
- }
- global.GVA_LOG.Info("事件处理完成", zap.Any("event", eventReq), zap.String("saved_files", savedFiles))
- response.OkWithData(resp, c)
- }
- // 辅助函数:判断是否为图片文件(通过文件名后缀)
- func isImageFile(filename string) bool {
- ext := strings.ToLower(filepath.Ext(filename))
- switch ext {
- case ".jpg", ".jpeg", ".png", ".bmp", ".gif":
- return true
- default:
- return false
- }
- }
- // 辅助函数:保存图片到本地目录
- func saveImageToLocal(serialNum, filename string, data []byte) (string, error) {
- // 构建保存路径:./uploads/{设备序列号}/{日期}/filename
- dateDir := time.Now().Format("20060102")
- saveDir := filepath.Join("./uploads", serialNum, dateDir)
- if err := os.MkdirAll(saveDir, 0755); err != nil {
- return "", fmt.Errorf("创建保存目录失败:%w", err)
- }
- // 生成唯一文件名(避免重名)
- uniqueName := fmt.Sprintf("%s_%s", time.Now().Format("150405"), filename)
- savePath := filepath.Join(saveDir, uniqueName)
- // 写入文件
- if err := os.WriteFile(savePath, data, 0644); err != nil {
- return "", fmt.Errorf("写入文件失败:%w", err)
- }
- return savePath, nil
- }
- //---------------------------------------------------------------------------------------------------------------------
- func (ca *CameraApi) QueryAllCameras(c *gin.Context) {
- cameras, err := cameraService.QueryAllCameras()
- if err != nil {
- global.GVA_LOG.Error("查询失败", zap.Error(err))
- response.FailWithMessage("查询失败", c)
- return
- }
- response.OkWithData(cameras, c)
- }
- func (ca *CameraApi) QueryCameraList(c *gin.Context) {
- var info devices.SearchCamera
- if err := c.ShouldBind(&info); err != nil {
- global.GVA_LOG.Error("参数错误", zap.Error(err))
- response.FailWithMessage("参数错误", c)
- return
- }
- list, total, err := cameraService.QueryCameraList(info)
- if err != nil {
- global.GVA_LOG.Error("查询失败", zap.Error(err))
- response.FailWithMessage("查询失败", c)
- return
- }
- response.OkWithDetailed(response.PageResult{
- List: list,
- Total: total,
- Page: info.Page,
- PageSize: info.PageSize,
- }, "获取成功", c)
- }
- func (ca *CameraApi) CreateCamera(c *gin.Context) {
- var camera dao.Camera
- if err := c.ShouldBind(&camera); err != nil {
- global.GVA_LOG.Error("参数错误", zap.Error(err))
- response.FailWithMessage("参数错误", c)
- return
- }
- if err := cameraService.CreateCamera(camera); err != nil {
- global.GVA_LOG.Error("新增失败", zap.Error(err))
- response.FailWithMessage("新增失败", c)
- return
- }
- response.OkWithMessage("新增成功", c)
- }
- func (ca *CameraApi) UpdateCamera(c *gin.Context) {
- var camera dao.Camera
- if err := c.ShouldBind(&camera); err != nil {
- global.GVA_LOG.Error("参数错误", zap.Error(err))
- response.FailWithMessage("参数错误", c)
- return
- }
- if err := cameraService.UpdateCamera(camera); err != nil {
- global.GVA_LOG.Error("更新失败", zap.Error(err))
- response.FailWithMessage("更新失败", c)
- return
- }
- response.OkWithMessage("更新成功", c)
- }
- func (ca *CameraApi) DeleteCamera(c *gin.Context) {
- id, err := strconv.Atoi(c.Query("id"))
- if err != nil {
- response.FailWithMessage("参数错误", c)
- return
- }
- if err := cameraService.DeleteCamera(id); err != nil {
- global.GVA_LOG.Error("删除失败", zap.Error(err))
- response.FailWithMessage("删除失败", c)
- return
- }
- response.OkWithMessage("删除成功", c)
- }
|