2个文件已添加
19个文件已修改
2511 ■■■■■ 已修改文件
api-gateway/auth/auth.go 276 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api-gateway/models/base.go 78 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-common/models/Record.go 1029 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-common/models/task.go 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-service/controllers/camera.go 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-service/main.go 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
camera-service/models/milvus.go 126 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
chanmanage-service/models/camera.go 151 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/controllers/eventPush.go 98 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/controllers/pushSet.go 179 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/main.go 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/models/eventPush.go 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/mqtt/config.go 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/mqtt/mqtt.go 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/service/eventPushService.go 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
push-service/vo/eventPush.go 88 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
search-service/main.go 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
sysinfo-service/service/psutil.go 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/bhome_msg_dev/bhome_msg_dev.pb.go 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/controllers/dictionary.go 118 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
system-service/service/devInfoSync.go 50 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
api-gateway/auth/auth.go
@@ -1,138 +1,138 @@
package auth
import (
    "github.com/gin-gonic/gin"
    "net/http"
    "strings"
    "sync"
    "vamicro/extend/util"
)
const (
    TokenKey = "abc123456789"
)
type Auth interface {
    Check(c *gin.Context)bool
    User(c *gin.Context)map[string]interface{}
    Login(http *http.Request,w http.ResponseWriter,user map[string]interface{})interface{}
    Logout(http *http.Request,w http.ResponseWriter) bool
}
func GenerateAuthDriver() *Auth {
    var authDriver Auth
    authDriver = NewJwtAuthDriver()
    return &authDriver
}
var outUserM = make(map[string]string,0)
var lock sync.RWMutex
func SetOutUser(userId string) {
    lock.Lock()
    defer lock.Unlock()
    outUserM[userId] = userId
}
func OutUser(userId string) bool {
    lock.Lock()
    defer lock.Unlock()
    if _,ok := outUserM[userId];ok{
        return true
    }
    return false
}
func RemoveOutUser(userId string) {
    lock.Lock()
    defer lock.Unlock()
    if _,ok := outUserM[userId];ok{
        delete(outUserM,userId)
    }
}
var noTokenUrls = []string{
    "/data/api-v/gb28181/findAreaByParentId",
    "/data/api-v/sysinit/getInitInfo",
    "/data/api-v/sysinit/savePassword",
    "/data/api-v/sysinit/networkList",
    "/data/api-v/sysinit/initNetwork",
    "/data/api-v/sysinit/saveRegInfo",
    "/data/api-v/sysinit/getRegInfo",
    "/data/api-u/sys/logout",
}
func AuthHandler() gin.HandlerFunc {
    return func(c *gin.Context) {
        urlPath := c.Request.URL.Path
        if strings.Contains(urlPath,"/data/api-") &&
            !strings.Contains(urlPath,"login") &&
            !strings.Contains(urlPath, "/data/api-v/license") &&
            !strings.Contains(urlPath, "/data/api-v/info/") &&
            !util.ArrayContains(noTokenUrls, urlPath) &&
            !strings.Contains(urlPath, "/data/api-v/token") {
            //Oauth2检查
            token,err := Oauth2Serv.ValidationBearerToken(c.Request)
            if nil == err {
                if !CheckAcl(urlPath) {
                    c.JSON(401, gin.H{
                        "code": 401,
                        "success": false,
                        "msg": "接口暂未开放",
                        "data": "",
                    })
                    c.Abort()
                    return
                }
                c.Request.Header.Set("Login_user_id", token.GetUserID())
                c.Next()
                //fmt.Print(token.GetUserID())
                return
            } else {
                //fmt.Println(err.Error())
            }
            jwtDriver :=NewJwtAuthDriver()
            if !jwtDriver.Check(c) {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            userM := (*jwtDriver).User(c)
            if userM == nil {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            userId := userM["id"].(string)
            if OutUser(userId) {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            c.Request.Header.Set("Login_user_id", userId)
            c.Next()
        } else {
            c.Next()
        }
    }
}
func GetCurUser(c *gin.Context)map[string]interface{}{
    return (*GenerateAuthDriver()).User(c)
}
package auth
import (
    "github.com/gin-gonic/gin"
    "net/http"
    "strings"
    "sync"
    "vamicro/extend/util"
)
const (
    TokenKey = "abc123456789"
)
type Auth interface {
    Check(c *gin.Context)bool
    User(c *gin.Context)map[string]interface{}
    Login(http *http.Request,w http.ResponseWriter,user map[string]interface{})interface{}
    Logout(http *http.Request,w http.ResponseWriter) bool
}
func GenerateAuthDriver() *Auth {
    var authDriver Auth
    authDriver = NewJwtAuthDriver()
    return &authDriver
}
var outUserM = make(map[string]string,0)
var lock sync.RWMutex
func SetOutUser(userId string) {
    lock.Lock()
    defer lock.Unlock()
    outUserM[userId] = userId
}
func OutUser(userId string) bool {
    lock.Lock()
    defer lock.Unlock()
    if _,ok := outUserM[userId];ok{
        return true
    }
    return false
}
func RemoveOutUser(userId string) {
    lock.Lock()
    defer lock.Unlock()
    if _,ok := outUserM[userId];ok{
        delete(outUserM,userId)
    }
}
var noTokenUrls = []string{
    "/data/api-v/gb28181/findAreaByParentId",
    "/data/api-v/sysinit/getInitInfo",
    "/data/api-v/sysinit/savePassword",
    "/data/api-v/sysinit/networkList",
    "/data/api-v/sysinit/initNetwork",
    "/data/api-v/sysinit/saveRegInfo",
    "/data/api-v/sysinit/getRegInfo",
    "/data/api-u/sys/logout",
}
func AuthHandler() gin.HandlerFunc {
    return func(c *gin.Context) {
        urlPath := c.Request.URL.Path
        if strings.Contains(urlPath,"/data/api-") &&
            !strings.Contains(urlPath,"login") &&
            !strings.Contains(urlPath, "/data/api-v/license") &&
            !strings.Contains(urlPath, "/data/api-v/info/") &&
            !util.ArrayContains(noTokenUrls, urlPath) &&
            !strings.Contains(urlPath, "/data/api-v/token") {
            //Oauth2检查
            token,err := Oauth2Serv.ValidationBearerToken(c.Request)
            if nil == err {
                if !CheckAcl(urlPath) {
                    c.JSON(401, gin.H{
                        "code": 401,
                        "success": false,
                        "msg": "接口暂未开放",
                        "data": "",
                    })
                    c.Abort()
                    return
                }
                c.Request.Header.Set("Login_user_id", token.GetUserID())
                c.Next()
                //fmt.Print(token.GetUserID())
                return
            } else {
                //fmt.Println(err.Error())
            }
            jwtDriver :=NewJwtAuthDriver()
            if !jwtDriver.Check(c) {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            userM := (*jwtDriver).User(c)
            if userM == nil {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            userId := userM["id"].(string)
            if OutUser(userId) {
                c.JSON(401, gin.H{
                    "code": 401,
                    "success": false,
                    "msg": "请求未携带Token,无权访问",
                    "data": "",
                })
                c.Abort()
                return
            }
            c.Request.Header.Set("Login_user_id", userId)
            c.Next()
        } else {
            c.Next()
        }
    }
}
func GetCurUser(c *gin.Context)map[string]interface{}{
    return (*GenerateAuthDriver()).User(c)
}
api-gateway/models/base.go
@@ -1,39 +1,39 @@
package models
import (
    "gopkg.in/ini.v1"
)
type PathConfig struct {
    BasePath      string `json:"basePath"`
    DecodeUrl     string `json:"decodeUrl"`
    SmartUrl      string `json:"smartUrl"`
    MilvusUrl     string `json:"milvusUrl"`
    WvpToken      string `json:"wvpToken"`
    WvpUrl        string `json:"wvpUrl"`
    ZlmediaKitUrl string `json:"zlmediaKitUrl"`
    SqlitePath    string `json:"sqlitePath"`
}
func GetBasePath() string {
    cfg, _ := ini.Load("config.ini")
    // 读取默认分区
    basePath := cfg.Section("setting").Key("basepath").String()
    return basePath
}
func GetConfig() PathConfig {
    config := PathConfig{}
    cfg, _ := ini.Load("config.ini")
    // 读取默认分区
    config.DecodeUrl = cfg.Section("setting").Key("decodeBaseUrl").String()
    config.BasePath = cfg.Section("setting").Key("basepath").String()
    config.SmartUrl = cfg.Section("setting").Key("smartUrl").String()
    config.MilvusUrl = cfg.Section("setting").Key("milvusUrl").String()
    config.WvpToken = cfg.Section("setting").Key("wvpToken").String()
    config.WvpUrl = cfg.Section("setting").Key("wvpUrl").String()
    config.ZlmediaKitUrl = cfg.Section("setting").Key("zlmediaKitUrl").String()
    config.SqlitePath = cfg.Section("setting").Key("sqlitePath").String()
    return config
}
package models
import (
    "gopkg.in/ini.v1"
)
type PathConfig struct {
    BasePath      string `json:"basePath"`
    DecodeUrl     string `json:"decodeUrl"`
    SmartUrl      string `json:"smartUrl"`
    MilvusUrl     string `json:"milvusUrl"`
    WvpToken      string `json:"wvpToken"`
    WvpUrl        string `json:"wvpUrl"`
    ZlmediaKitUrl string `json:"zlmediaKitUrl"`
    SqlitePath    string `json:"sqlitePath"`
}
func GetBasePath() string {
    cfg, _ := ini.Load("config.ini")
    // 读取默认分区
    basePath := cfg.Section("setting").Key("basepath").String()
    return basePath
}
func GetConfig() PathConfig {
    config := PathConfig{}
    cfg, _ := ini.Load("config.ini")
    // 读取默认分区
    config.DecodeUrl = cfg.Section("setting").Key("decodeBaseUrl").String()
    config.BasePath = cfg.Section("setting").Key("basepath").String()
    config.SmartUrl = cfg.Section("setting").Key("smartUrl").String()
    config.MilvusUrl = cfg.Section("setting").Key("milvusUrl").String()
    config.WvpToken = cfg.Section("setting").Key("wvpToken").String()
    config.WvpUrl = cfg.Section("setting").Key("wvpUrl").String()
    config.ZlmediaKitUrl = cfg.Section("setting").Key("zlmediaKitUrl").String()
    config.SqlitePath = cfg.Section("setting").Key("sqlitePath").String()
    return config
}
camera-common/models/Record.go
@@ -1,512 +1,517 @@
package models
import (
    "context"
    "fmt"
    "math"
    "sort"
    "strconv"
    "strings"
    "time"
    "github.com/milvus-io/milvus-sdk-go/v2/entity"
)
// DataOperator 数据操作相关方法
type DataOperator struct {
    client *MilvusClient
}
// NewDataOperator 创建数据操作器
func NewDataOperator(client *MilvusClient) *DataOperator {
    return &DataOperator{client: client}
}
type PicWidHei struct {
    PicW int `json:"picW"`
    PicH int `json:"picH"`
}
// 统计查询
type StaticRecord struct {
    Id                 string                    `json:"id"`
    TaskId             []int64                   `json:"task_id"`
    RuleId             []int64                   `json:"rule_id"`
    EventLevelId       []int64                   `json:"event_level_id"`
    VideoPointId       int64                     `json:"video_point_id"`
    DetectId           []int64                   `json:"detect_id"`
    VideoName          string                    `json:"video_name"`
    TaskNames          []TaskOption              `json:"task_names"`
    CheckNames         []CheckOption             `json:"check_names"`
    RuleNames          []RuleOption              `json:"rule_names"`
    EventLevels        []DictOption              `json:"event_levels"`
    KnowledgeDocuments []KnowledgeDocumentOption `json:"knowledge_documents"`
    ImagePath          string                    `json:"image_path"`
    VideoPath          string                    `json:"video_path"`
    DetectTime         string                    `json:"detect_time"`
    IsWarning          int64                     `json:"is_warning"`
    ZhDescClass        string                    `json:"zh_desc_class"`
    TaskName           string                    `json:"task_name"`
    EventLevelName     string                    `json:"event_level_name"`
    DetectNum          int64                     `json:"detect_num"`
    Suggestion         string                    `json:"suggestion"`
    RiskDescription    string                    `json:"risk_description"`
    KnowledgeId        []int64                   `json:"knowledge_id"`
    IsDesc             int64                     `json:"is_desc"`
    CameraId           string                    `json:"cameraId"`
    CameraName         string                    `json:"cameraName"`
    CameraAddr         string                    `json:"cameraAddr"`
    PicDate            string                    `json:"picDate"`
    PicId              int64                     `json:"picId"`
    PicMaxUrl          []string                  `json:"picMaxUrl"`
    PicSrcUrl          []string                  `json:"picSrcUrl"`
    PicWH              PicWidHei                 `json:"picWH"`
    SdkName            string                    `json:"sdkName"`
    Content            string                    `json:"content"`
    AlarmRules         []AlarmRule               `json:"alarmRules"`
    LikeDate           string                    `json:"likeDate"`
    ShowLabels         string                    `json:"showLabels"`
    OtherLabels        string                    `json:"otherLabels"`
    VideoUrl           string                    `json:"videoUrl"`
    AnalyServerId      string                    `json:"analyServerId"`
    AnalyServerName    string                    `json:"analyServerName"`
    AnalyServerIp      string                    `json:"analyServerIp"`
    ClusterId          string                    `json:"clusterId"`
    IsAlarm            bool                      `json:"isAlarm"`
    IsAckAlarm         bool                      `json:"isAckAlarm"`
    IsCollect          bool                      `json:"isCollect"`
    IsDelete           bool                      `json:"isDelete"`
    BaseInfo           []*BaseCompareInfo        `json:"baseInfo"`
    TargetInfo         []TargetInfo              `json:"targetInfo"`
    FileId             string                    `json:"fileId"`     // 数据栈文件id
    DataSource         string                    `json:"dataSource"` // 数据来源:摄像机, 数据栈
}
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
type Points struct {
    TopLeft     Point `json:"topLeft"`
    BottomRight Point `json:"bottomRight"`
}
type BaseCompareInfo struct {
    TableId      string  `json:"tableId"`
    TableName    string  `json:"tableName"`
    BwType       string  `json:"bwType"`
    CompareScore float64 `json:"compareScore"`
    TargetId     string  `json:"targetId"`
    TargetName   string  `json:"targetName"`
    TargetPicUrl string  `json:"targetPicUrl"`
    MonitorLevel string  `json:"monitorLevel"`
    Content      string  `json:"content"`
    DbLabel      string  `json:"labels"`
}
type TargetInfo struct {
    TargetId        string  `json:"targetId"`
    AreaId          string  `json:"areaId"`
    AreaName        string  `json:"areaName"`
    TargetScore     float64 `json:"targetScore"`
    TargetType      string  `json:"targetType"`
    Feature         string  `json:"feature"`
    PicSmUrl        string  `json:"picSmUrl"`
    TargetLocation  Points  `json:"targetLocation"`
    BelongsTargetID string  `json:"belongsTargetId"`
    Attribute       string  `json:"attribute"`
}
type AlarmRule struct {
    AlarmLevel   string `db:"alarmLevel" json:"alarmLevel"`
    DefenceState bool   `db:"defenceState" json:"defenceState"`
    GroupId      string `db:"groupId" json:"groupId"`
    LinkInfo     string `db:"linkInfo" json:"linkInfo"`
    RuleText     string `db:"ruleText" json:"ruleText"`
}
type TaskOption struct {
    TaskId   int64  `db:"task_id" json:"taskId"`
    TaskName string `db:"task_name" json:"taskName"`
}
type CheckOption struct {
    TaskId   int64  `db:"task_id" json:"taskId,omitempty"`
    CheckId  int64  `db:"check_id" json:"checkId"`
    FileName string `db:"file_name" json:"fileName"`
}
type RuleOption struct {
    TaskId   int64  `db:"task_id" json:"taskId,omitempty"`
    RuleId   int64  `db:"rule_id" json:"ruleId"`
    FileName string `db:"file_name" json:"fileName"`
}
// 字典
type DictOption struct {
    DictId    int64  `db:"dict_id" json:"dictId"`
    DictName  string `db:"dict_name" json:"dictName"`
    DictValue string `db:"dict_value" json:"dictValue"`
    DictType  string `db:"dict_type" json:"dictType"`
}
// 知识库
type KnowledgeDocumentOption struct {
    Id      string `db:"id" json:"id"`
    Title   string `db:"title" json:"title"`
    KnowId  int64  `db:"know_id" json:"know_id"`
    FileUrl string `db:"title" json:"file_url"`
}
// Pagination 分页信息
type Pagination struct {
    Page      int `json:"page"`      // 当前页码
    PageSize  int `json:"pageSize"`  // 每页大小
    Total     int `json:"total"`     // 总记录数
    TotalPage int `json:"totalPage"` // 总页数
}
// PaginatedResult 分页结果
type PaginatedResult struct {
    Items      []StaticRecord `json:"list"`
    Pagination Pagination     `json:"pagination"`
}
type PaginatedResult2 struct {
    Items      map[string]interface{} `json:"list"`
    Pagination Pagination             `json:"pagination"`
}
// 记录
type RecordReq struct {
    Ids      []string `json:"ids"`
    VideoIds []string `json:"treeNodes"`
    TaskIds  []int64  `json:"taskIds`
    TaskName []string `json:"taskName"`
    Warning  int64    `json:"warning`
    Page     int64    `json:"page"`
    PageSize int64    `json:"pageSize"`
}
// 根据分页取数据
func GetWithPage(collectionName string, pageNum int64, pageSize int64, filter string) (*PaginatedResult, error) {
    if pageNum < 1 {
        pageNum = 1
    }
    if pageSize < 1 {
        pageSize = 10
    }
    if dbClient == nil {
        return nil, nil
    }
    dataOp := &DataOperator{client: dbClient}
    fmt.Println(filter)
    records, err := dataOp.queryWithPagination(collectionName, filter, pageNum, pageSize)
    if err != nil {
        return nil, err
    }
    return records, nil
}
// 转换数据
func convertResultToMap(result []entity.Column) []StaticRecord {
    if len(result) == 0 {
        return nil
    }
    count := result[0].Len()
    var records []StaticRecord
    for i := 0; i < count; i++ {
        record := StaticRecord{}
        for _, field := range result {
            switch field.Name() {
            case "id":
                IdColumn := field.(*entity.ColumnInt64).Data()
                if len(IdColumn) > 0 {
                    record.Id = strconv.FormatInt(IdColumn[i], 10)
                }
            case "task_id":
                TaskIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(TaskIdColumn) > 0 {
                    record.TaskId = TaskIdColumn[i]
                }
            case "rule_id":
                RuleIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(RuleIdColumn) > 0 {
                    record.RuleId = RuleIdColumn[i]
                }
            case "event_level_id":
                EventLevelIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(EventLevelIdColumn) > 0 {
                    record.EventLevelId = EventLevelIdColumn[i]
                }
            case "video_point_id":
                VideoPointIdColumn := field.(*entity.ColumnInt64).Data()
                if len(VideoPointIdColumn) > 0 {
                    record.VideoPointId = VideoPointIdColumn[i]
                }
            case "detect_id":
                DetectIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(DetectIdColumn) > 0 {
                    record.DetectId = DetectIdColumn[i]
                }
            case "image_path":
                ImagePathColumn := field.(*entity.ColumnVarChar).Data()
                if len(ImagePathColumn) > 0 {
                    record.ImagePath = ImagePathColumn[i]
                }
            case "video_path":
                VideoPathColumn := field.(*entity.ColumnVarChar).Data()
                if len(VideoPathColumn) > 0 {
                    record.VideoPath = VideoPathColumn[i]
                }
            case "zh_desc_class":
                zhColumn := field.(*entity.ColumnVarChar).Data()
                if len(zhColumn) > 0 {
                    record.ZhDescClass = zhColumn[i]
                }
            case "task_name":
                TNColumn := field.(*entity.ColumnVarChar).Data()
                if len(TNColumn) > 0 {
                    record.TaskName = TNColumn[i]
                }
            case "event_level_name":
                EVColumn := field.(*entity.ColumnVarChar).Data()
                if len(EVColumn) > 0 {
                    record.EventLevelName = EVColumn[i]
                }
            case "is_desc":
                descColumn := field.(*entity.ColumnInt64).Data()
                if len(descColumn) > 0 {
                    record.IsDesc = descColumn[i]
                }
            case "detect_num":
                DEColumn := field.(*entity.ColumnInt64).Data()
                if len(DEColumn) > 0 {
                    record.DetectNum = DEColumn[i]
                }
            case "is_waning":
                warnColumn := field.(*entity.ColumnInt64).Data()
                if len(warnColumn) > 0 {
                    record.IsWarning = warnColumn[i]
                }
            case "detect_time":
                DetectTimeColumn := field.(*entity.ColumnVarChar).Data()
                if len(DetectTimeColumn) > 0 {
                    record.DetectTime = DetectTimeColumn[i]
                }
            case "knowledge_id":
                KnowledgeIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(KnowledgeIdColumn) > 0 {
                    record.KnowledgeId = KnowledgeIdColumn[i]
                }
            case "suggestion":
                SuggestionColumn := field.(*entity.ColumnVarChar).Data()
                if len(SuggestionColumn) > 0 {
                    record.Suggestion = SuggestionColumn[i]
                }
            case "risk_description":
                RiskDescriptionColumn := field.(*entity.ColumnVarChar).Data()
                if len(RiskDescriptionColumn) > 0 {
                    record.RiskDescription = RiskDescriptionColumn[i]
                }
            }
        }
        records = append(records, record)
    }
    return records
}
// 分页查询
func (do *DataOperator) queryWithPagination(collectionName string, filterExpr string, pageNum int64, pageSize int64) (*PaginatedResult, error) {
    ctx := context.Background()
    // 计算偏移量
    //offset := (pageNum - 1) * pageSize
    // 构建查询表达式(Milvus 2.1+ 支持 limit/offset)
    //queryExpr := fmt.Sprintf("%s limit %d offset %d", filterExpr, pageSize, offset)
    total, err := do.getTotalCount(collectionName, filterExpr)
    if err != nil {
        return nil, err
    }
    // 计算总页数
    totalPages := int(math.Ceil(float64(total) / float64(pageSize)))
    // 执行查询
    result, err := do.client.client.Query(
        ctx,
        collectionName,
        []string{}, // 所有分区
        filterExpr,
        []string{"rule_id", "task_id", "is_waning", "zh_desc_class", "task_name", "event_level_name", "detect_num",
            "event_level_id", "video_point_id", "detect_id", "image_path",
            "video_path", "detect_time", "knowledge_id", "risk_description", "suggestion", "id", "is_desc"}, // 返回所有字段
        // client.WithLimit(pageSize),
        // client.WithOffset(offset),
    )
    if err != nil {
        return nil, fmt.Errorf("分页查询失败: %v", err)
    }
    lists := convertResultToMap(result)
    layout := "2006-01-02 15:04:05.999999"
    var temp1 time.Time
    var temp2 time.Time
    //排序
    sort.Slice(lists, func(i, j int) bool {
        //return lists[i].DetectTime > lists[j].:DetectTime
        temp1, _ = time.Parse(layout, lists[i].DetectTime)
        temp2, _ = time.Parse(layout, lists[j].DetectTime)
        return temp1.After(temp2)
    })
    items := Paginate(lists, int(pageNum), int(pageSize))
    return &PaginatedResult{
        Items: items,
        Pagination: Pagination{
            Page:      int(pageNum),
            PageSize:  int(pageSize),
            Total:     int(total),
            TotalPage: totalPages,
        },
    }, nil
}
// 分页数据
func Paginate(data []StaticRecord, page, pageSize int) []StaticRecord {
    start := (page - 1) * pageSize
    if start >= len(data) {
        return nil
    }
    end := start + pageSize
    if end > len(data) {
        end = len(data)
    }
    return data[start:end]
}
// 统计数量
func (do *DataOperator) getTotalCount(collectionName string, filterExpr string) (int64, error) {
    result, err := do.client.client.Query(
        context.Background(),
        collectionName,
        []string{},
        filterExpr,
        []string{"count(*)"},
    )
    if err != nil {
        return 0, err
    }
    return result[0].(*entity.ColumnInt64).Data()[0], nil
}
// 根据id获取任务
func GetTaskByIds(ids []int64) (items []TaskOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select task_id,task_name from mal_smart_task where task_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据id获取视频
func GetVideoById(vid int64) (video Camera, err error) {
    // 如果返回的是指针,需要初始化
    sqlStr := "select id,name,alias,type,addr,rtsp,is_running,run_type,run_enable FROM cameras where video_id=?"
    if err := db.Raw(sqlStr, vid).Scan(&video).Error; err != nil {
        return Camera{}, err
    }
    return
}
// 根据id获取检测内容
func GetCheckByIds(ids []int64) (items []CheckOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select check_id,file_name from mal_check_content where check_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据id获取规则
func GetRuleByIds(ids []int64) (items []RuleOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select rule_id,file_name from mal_warning_rule where rule_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 获取事件
func GetEventByIds(ids []int64) (items []DictOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select dict_id,dict_name,dict_value from mal_dict_type where dict_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据知识库id查数据
func GetKnowledgeDocumentByIds(ids []int64) (items []KnowledgeDocumentOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `SELECT id, know_id, file_name as title FROM mal_knowledge_document where id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据知识库id查数据
func GetCameraIds(ids []string) (items []CameraDto, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select id,name,alias,type,addr,rtsp,is_running,run_type,run_enable,video_id FROM cameras where id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
package models
import (
    "context"
    "fmt"
    "math"
    "sort"
    "strconv"
    "strings"
    "time"
    "github.com/milvus-io/milvus-sdk-go/v2/entity"
)
// DataOperator 数据操作相关方法
type DataOperator struct {
    client *MilvusClient
}
// NewDataOperator 创建数据操作器
func NewDataOperator(client *MilvusClient) *DataOperator {
    return &DataOperator{client: client}
}
type PicWidHei struct {
    PicW int `json:"picW"`
    PicH int `json:"picH"`
}
// 统计查询
type StaticRecord struct {
    Id                 string                    `json:"id"`
    TaskId             []int64                   `json:"task_id"`
    RuleId             []int64                   `json:"rule_id"`
    EventLevelId       []int64                   `json:"event_level_id"`
    VideoPointId       int64                     `json:"video_point_id"`
    DetectId           []int64                   `json:"detect_id"`
    VideoName          string                    `json:"video_name"`
    TaskNames          []TaskOption              `json:"task_names"`
    CheckNames         []CheckOption             `json:"check_names"`
    RuleNames          []RuleOption              `json:"rule_names"`
    EventLevels        []DictOption              `json:"event_levels"`
    KnowledgeDocuments []KnowledgeDocumentOption `json:"knowledge_documents"`
    ImagePath          string                    `json:"image_path"`
    VideoPath          string                    `json:"video_path"`
    DetectTime         string                    `json:"detect_time"`
    IsWarning          int64                     `json:"is_warning"`
    ZhDescClass        string                    `json:"zh_desc_class"`
    TaskName           string                    `json:"task_name"`
    EventLevelName     string                    `json:"event_level_name"`
    DetectNum          int64                     `json:"detect_num"`
    Suggestion         string                    `json:"suggestion"`
    RiskDescription    string                    `json:"risk_description"`
    KnowledgeId        []int64                   `json:"knowledge_id"`
    IsDesc             int64                     `json:"is_desc"`
    CameraId           string                    `json:"cameraId"`
    CameraName         string                    `json:"cameraName"`
    CameraAddr         string                    `json:"cameraAddr"`
    PicDate            string                    `json:"picDate"`
    PicId              int64                     `json:"picId"`
    PicMaxUrl          []string                  `json:"picMaxUrl"`
    PicSrcUrl          []string                  `json:"picSrcUrl"`
    PicWH              PicWidHei                 `json:"picWH"`
    SdkName            string                    `json:"sdkName"`
    Content            string                    `json:"content"`
    AlarmRules         []AlarmRule               `json:"alarmRules"`
    LikeDate           string                    `json:"likeDate"`
    ShowLabels         string                    `json:"showLabels"`
    OtherLabels        string                    `json:"otherLabels"`
    VideoUrl           string                    `json:"videoUrl"`
    AnalyServerId      string                    `json:"analyServerId"`
    AnalyServerName    string                    `json:"analyServerName"`
    AnalyServerIp      string                    `json:"analyServerIp"`
    ClusterId          string                    `json:"clusterId"`
    IsAlarm            bool                      `json:"isAlarm"`
    IsAckAlarm         bool                      `json:"isAckAlarm"`
    IsCollect          bool                      `json:"isCollect"`
    IsDelete           bool                      `json:"isDelete"`
    BaseInfo           []*BaseCompareInfo        `json:"baseInfo"`
    TargetInfo         []TargetInfo              `json:"targetInfo"`
    FileId             string                    `json:"fileId"`     // 数据栈文件id
    DataSource         string                    `json:"dataSource"` // 数据来源:摄像机, 数据栈
}
type Point struct {
    X float64 `json:"x"`
    Y float64 `json:"y"`
}
type Points struct {
    TopLeft     Point `json:"topLeft"`
    BottomRight Point `json:"bottomRight"`
}
type BaseCompareInfo struct {
    TableId      string  `json:"tableId"`
    TableName    string  `json:"tableName"`
    BwType       string  `json:"bwType"`
    CompareScore float64 `json:"compareScore"`
    TargetId     string  `json:"targetId"`
    TargetName   string  `json:"targetName"`
    TargetPicUrl string  `json:"targetPicUrl"`
    MonitorLevel string  `json:"monitorLevel"`
    Content      string  `json:"content"`
    DbLabel      string  `json:"labels"`
}
type TargetInfo struct {
    TargetId        string  `json:"targetId"`
    AreaId          string  `json:"areaId"`
    AreaName        string  `json:"areaName"`
    TargetScore     float64 `json:"targetScore"`
    TargetType      string  `json:"targetType"`
    Feature         string  `json:"feature"`
    PicSmUrl        string  `json:"picSmUrl"`
    TargetLocation  Points  `json:"targetLocation"`
    BelongsTargetID string  `json:"belongsTargetId"`
    Attribute       string  `json:"attribute"`
}
type AlarmRule struct {
    AlarmLevel   string `db:"alarmLevel" json:"alarmLevel"`
    DefenceState bool   `db:"defenceState" json:"defenceState"`
    GroupId      string `db:"groupId" json:"groupId"`
    LinkInfo     string `db:"linkInfo" json:"linkInfo"`
    RuleText     string `db:"ruleText" json:"ruleText"`
}
type TaskOption struct {
    TaskId   int64  `db:"task_id" json:"taskId"`
    TaskName string `db:"task_name" json:"taskName"`
}
type CheckOption struct {
    TaskId   int64  `db:"task_id" json:"taskId,omitempty"`
    CheckId  int64  `db:"check_id" json:"checkId"`
    FileName string `db:"file_name" json:"fileName"`
}
type RuleOption struct {
    TaskId   int64  `db:"task_id" json:"taskId,omitempty"`
    RuleId   int64  `db:"rule_id" json:"ruleId"`
    FileName string `db:"file_name" json:"fileName"`
}
// 字典
type DictOption struct {
    DictId    int64  `db:"dict_id" json:"dictId"`
    DictName  string `db:"dict_name" json:"dictName"`
    DictValue string `db:"dict_value" json:"dictValue"`
    DictType  string `db:"dict_type" json:"dictType"`
}
// 知识库
type KnowledgeDocumentOption struct {
    Id      string `db:"id" json:"id"`
    Title   string `db:"title" json:"title"`
    KnowId  int64  `db:"know_id" json:"know_id"`
    FileUrl string `db:"title" json:"file_url"`
}
// Pagination 分页信息
type Pagination struct {
    Page      int `json:"page"`      // 当前页码
    PageSize  int `json:"pageSize"`  // 每页大小
    Total     int `json:"total"`     // 总记录数
    TotalPage int `json:"totalPage"` // 总页数
}
// PaginatedResult 分页结果
type PaginatedResult struct {
    Items      []StaticRecord `json:"list"`
    Pagination Pagination     `json:"pagination"`
}
type PaginatedResult2 struct {
    Items      map[string]interface{} `json:"list"`
    Pagination Pagination             `json:"pagination"`
}
// 记录
type RecordReq struct {
    Ids      []string `json:"ids"`
    VideoIds []string `json:"treeNodes"`
    TaskIds  []int64  `json:"taskIds`
    TaskName []string `json:"taskName"`
    Warning  int64    `json:"warning`
    Page     int64    `json:"page"`
    PageSize int64    `json:"pageSize"`
}
// 根据分页取数据
func GetWithPage(collectionName string, pageNum int64, pageSize int64, filter string) (*PaginatedResult, error) {
    if pageNum < 1 {
        pageNum = 1
    }
    if pageSize < 1 {
        pageSize = 10
    }
    if dbClient == nil {
        return nil, nil
    }
    dataOp := &DataOperator{client: dbClient}
    fmt.Println(filter)
    records, err := dataOp.queryWithPagination(collectionName, filter, pageNum, pageSize)
    if err != nil {
        return nil, err
    }
    return records, nil
}
// 转换数据
func convertResultToMap(result []entity.Column) []StaticRecord {
    if len(result) == 0 {
        return nil
    }
    count := result[0].Len()
    var records []StaticRecord
    for i := 0; i < count; i++ {
        record := StaticRecord{}
        for _, field := range result {
            switch field.Name() {
            case "id":
                IdColumn := field.(*entity.ColumnInt64).Data()
                if len(IdColumn) > 0 {
                    record.Id = strconv.FormatInt(IdColumn[i], 10)
                }
            case "task_id":
                TaskIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(TaskIdColumn) > 0 {
                    record.TaskId = TaskIdColumn[i]
                }
            case "rule_id":
                RuleIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(RuleIdColumn) > 0 {
                    record.RuleId = RuleIdColumn[i]
                }
            case "event_level_id":
                EventLevelIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(EventLevelIdColumn) > 0 {
                    record.EventLevelId = EventLevelIdColumn[i]
                }
            case "video_point_id":
                VideoPointIdColumn := field.(*entity.ColumnInt64).Data()
                if len(VideoPointIdColumn) > 0 {
                    record.VideoPointId = VideoPointIdColumn[i]
                }
            case "video_point_name":
                VideoPointColumn := field.(*entity.ColumnVarChar).Data()
                if len(VideoPointColumn) > 0 {
                    record.CameraName = VideoPointColumn[i]
                }
            case "detect_id":
                DetectIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(DetectIdColumn) > 0 {
                    record.DetectId = DetectIdColumn[i]
                }
            case "image_path":
                ImagePathColumn := field.(*entity.ColumnVarChar).Data()
                if len(ImagePathColumn) > 0 {
                    record.ImagePath = ImagePathColumn[i]
                }
            case "video_path":
                VideoPathColumn := field.(*entity.ColumnVarChar).Data()
                if len(VideoPathColumn) > 0 {
                    record.VideoPath = VideoPathColumn[i]
                }
            case "zh_desc_class":
                zhColumn := field.(*entity.ColumnVarChar).Data()
                if len(zhColumn) > 0 {
                    record.ZhDescClass = zhColumn[i]
                }
            case "task_name":
                TNColumn := field.(*entity.ColumnVarChar).Data()
                if len(TNColumn) > 0 {
                    record.TaskName = TNColumn[i]
                }
            case "event_level_name":
                EVColumn := field.(*entity.ColumnVarChar).Data()
                if len(EVColumn) > 0 {
                    record.EventLevelName = EVColumn[i]
                }
            case "is_desc":
                descColumn := field.(*entity.ColumnInt64).Data()
                if len(descColumn) > 0 {
                    record.IsDesc = descColumn[i]
                }
            case "detect_num":
                DEColumn := field.(*entity.ColumnInt64).Data()
                if len(DEColumn) > 0 {
                    record.DetectNum = DEColumn[i]
                }
            case "is_waning":
                warnColumn := field.(*entity.ColumnInt64).Data()
                if len(warnColumn) > 0 {
                    record.IsWarning = warnColumn[i]
                }
            case "detect_time":
                DetectTimeColumn := field.(*entity.ColumnVarChar).Data()
                if len(DetectTimeColumn) > 0 {
                    record.DetectTime = DetectTimeColumn[i]
                }
            case "knowledge_id":
                KnowledgeIdColumn := field.(*entity.ColumnInt64Array).Data()
                if len(KnowledgeIdColumn) > 0 {
                    record.KnowledgeId = KnowledgeIdColumn[i]
                }
            case "suggestion":
                SuggestionColumn := field.(*entity.ColumnVarChar).Data()
                if len(SuggestionColumn) > 0 {
                    record.Suggestion = SuggestionColumn[i]
                }
            case "risk_description":
                RiskDescriptionColumn := field.(*entity.ColumnVarChar).Data()
                if len(RiskDescriptionColumn) > 0 {
                    record.RiskDescription = RiskDescriptionColumn[i]
                }
            }
        }
        records = append(records, record)
    }
    return records
}
// 分页查询
func (do *DataOperator) queryWithPagination(collectionName string, filterExpr string, pageNum int64, pageSize int64) (*PaginatedResult, error) {
    ctx := context.Background()
    // 计算偏移量
    //offset := (pageNum - 1) * pageSize
    // 构建查询表达式(Milvus 2.1+ 支持 limit/offset)
    //queryExpr := fmt.Sprintf("%s limit %d offset %d", filterExpr, pageSize, offset)
    total, err := do.getTotalCount(collectionName, filterExpr)
    if err != nil {
        return nil, err
    }
    // 计算总页数
    totalPages := int(math.Ceil(float64(total) / float64(pageSize)))
    // 执行查询
    result, err := do.client.client.Query(
        ctx,
        collectionName,
        []string{}, // 所有分区
        filterExpr,
        []string{"rule_id", "task_id", "is_waning", "zh_desc_class", "task_name", "event_level_name", "detect_num",
            "event_level_id", "video_point_id", "detect_id", "image_path",
            "video_path", "detect_time", "knowledge_id", "risk_description", "suggestion", "id", "is_desc"}, // 返回所有字段
        // client.WithLimit(pageSize),
        // client.WithOffset(offset),
    )
    if err != nil {
        return nil, fmt.Errorf("分页查询失败: %v", err)
    }
    lists := convertResultToMap(result)
    layout := "2006-01-02 15:04:05.999999"
    var temp1 time.Time
    var temp2 time.Time
    //排序
    sort.Slice(lists, func(i, j int) bool {
        //return lists[i].DetectTime > lists[j].:DetectTime
        temp1, _ = time.Parse(layout, lists[i].DetectTime)
        temp2, _ = time.Parse(layout, lists[j].DetectTime)
        return temp1.After(temp2)
    })
    items := Paginate(lists, int(pageNum), int(pageSize))
    return &PaginatedResult{
        Items: items,
        Pagination: Pagination{
            Page:      int(pageNum),
            PageSize:  int(pageSize),
            Total:     int(total),
            TotalPage: totalPages,
        },
    }, nil
}
// 分页数据
func Paginate(data []StaticRecord, page, pageSize int) []StaticRecord {
    start := (page - 1) * pageSize
    if start >= len(data) {
        return nil
    }
    end := start + pageSize
    if end > len(data) {
        end = len(data)
    }
    return data[start:end]
}
// 统计数量
func (do *DataOperator) getTotalCount(collectionName string, filterExpr string) (int64, error) {
    result, err := do.client.client.Query(
        context.Background(),
        collectionName,
        []string{},
        filterExpr,
        []string{"count(*)"},
    )
    if err != nil {
        return 0, err
    }
    return result[0].(*entity.ColumnInt64).Data()[0], nil
}
// 根据id获取任务
func GetTaskByIds(ids []int64) (items []TaskOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select task_id,task_name from mal_smart_task where task_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据id获取视频
func GetVideoById(vid int64) (video Camera, err error) {
    // 如果返回的是指针,需要初始化
    sqlStr := "select id,name,alias,type,addr,rtsp,is_running,run_type,run_enable FROM cameras where video_id=?"
    if err := db.Raw(sqlStr, vid).Scan(&video).Error; err != nil {
        return Camera{}, err
    }
    return
}
// 根据id获取检测内容
func GetCheckByIds(ids []int64) (items []CheckOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select check_id,file_name from mal_check_content where check_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据id获取规则
func GetRuleByIds(ids []int64) (items []RuleOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select rule_id,file_name from mal_warning_rule where rule_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 获取事件
func GetEventByIds(ids []int64) (items []DictOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select dict_id,dict_name,dict_value from mal_dict_type where dict_id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据知识库id查数据
func GetKnowledgeDocumentByIds(ids []int64) (items []KnowledgeDocumentOption, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `SELECT id, know_id, file_name as title FROM mal_knowledge_document where id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
// 根据知识库id查数据
func GetCameraIds(ids []string) (items []CameraDto, err error) {
    placeholders := make([]string, len(ids))
    args := make([]interface{}, len(ids))
    for i, id := range ids {
        placeholders[i] = "?"
        args[i] = id
    }
    sqlStr := `select id,name,alias,type,addr,rtsp,is_running,run_type,run_enable,video_id FROM cameras where id in (` + strings.Join(placeholders, ",") + `)`
    if err := db.Raw(sqlStr, args...).Scan(&items).Error; err != nil {
        return nil, err
    }
    return
}
camera-common/models/task.go
@@ -12,6 +12,12 @@
    TaskName string `db:"task_name" json:"taskName"`
}
type TaskAggregate struct {
    ID       int64  `gorm:"column:task_id" json:"id"`
    Name     string `gorm:"column:task_name"  json:"name"`
    IsDelete int8   `json:"isDelete"`
}
type TaskM struct {
    TaskId          int64  `db:"task_id" json:"taskId"`
    TaskName        string `db:"task_name" json:"taskName"`
@@ -44,3 +50,18 @@
    }
    return
}
// 查询列表数据
func GetAllTask() (items []TaskAggregate, err error) {
    // 主查询SQL
    sqlStr := fmt.Sprintf(`
        SELECT task_id, task_name
        FROM  mal_smart_task
        ORDER BY task_id DESC
    `)
    if err := db.Raw(sqlStr).Scan(&items).Error; err != nil {
        fmt.Println(err.Error())
        return nil, err
    }
    return
}
camera-service/controllers/camera.go
@@ -1139,6 +1139,8 @@
            Content:         v.CameraName,
            PicDate:         v.PicDate,
            LikeDate:        v.LikeDate,
            VideoName:       v.CameraName,
            CameraAddr:      v.CameraName,
        }
        //任务名称
@@ -1146,9 +1148,9 @@
        temp.TaskNames = items
        //视频内容
        items4, _ := models.GetVideoById(v.VideoPointId)
        temp.VideoName = items4.Name
        temp.CameraAddr = items4.Addr
        // items4, _ := models.GetVideoById(v.VideoPointId)
        // temp.VideoName = items4.Name
        // temp.CameraAddr = items4.Addr
        //检查内容
        items2, _ := models.GetCheckByIds(v.DetectId)
@@ -1211,3 +1213,14 @@
    return &bhomeclient.Reply{Success: true, Msg: "获取成功", Data: tasks}
}
// 获取所有
func (cc CameraController) GetAllTasks(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    //绑定json和结构体
    var tasks []models.TaskAggregate
    tasks, _ = models.GetAllTask()
    return &bhomeclient.Reply{Success: true, Msg: "获取成功", Data: tasks}
}
camera-service/main.go
@@ -133,6 +133,8 @@
    //获取任务根据摄像机ids
    funcMap[urlPrefix+"/camera/getTasks"] = cc.GetTasks
    funcMap[urlPrefix+"/task/aggregateTaskList"] = cc.GetAllTasks
    var pubTopics []string
    for key, _ := range funcMap {
        pubTopics = append(pubTopics, key)
camera-service/models/milvus.go
@@ -1,63 +1,63 @@
package models
import (
    "context"
    "fmt"
    "log"
    "vamicro/api-gateway/models"
    commonModels "vamicro/camera-common/models"
    "github.com/milvus-io/milvus-sdk-go/v2/client"
)
var dbClient *MilvusClient
// MilvusClient 封装Milvus操作的结构体
type MilvusClient struct {
    client client.Client
}
// NewMilvusClient 创建Milvus客户端
func NewMilvusClient(ctx context.Context, addr string) (*MilvusClient, error) {
    milvusClient, err := client.NewGrpcClient(ctx, addr)
    if err != nil {
        return nil, fmt.Errorf("failed to connect to Milvus: %v", err)
    }
    return &MilvusClient{client: milvusClient}, nil
}
// Close 关闭连接
func (m *MilvusClient) Close() error {
    return m.client.Close()
}
// 初始化milvus
func InitVectorDb() {
    // 连接到Milvus服务器
    ctx := context.Background()
    //milvusClient, err := NewMilvusClient(ctx, "192.168.1.232:19530")
    config := models.GetConfig()
    url := config.MilvusUrl
    milvusClient, err := NewMilvusClient(ctx, url)
    if err != nil {
        log.Fatal("Failed to connect to Milvus:", err)
    }
    //defer milvusClient.client.Close()
    fmt.Println("Successfully connected to Milvus")
    //初始化
    dbClient = milvusClient
    commonModels.SetClientDB(dbClient.client)
}
// GetDB ...
func GetDBCient() *MilvusClient {
    return dbClient
}
func CloseDBClient() {
    dbClient.Close()
}
package models
import (
    "context"
    "fmt"
    "log"
    "vamicro/api-gateway/models"
    commonModels "vamicro/camera-common/models"
    "github.com/milvus-io/milvus-sdk-go/v2/client"
)
var dbClient *MilvusClient
// MilvusClient 封装Milvus操作的结构体
type MilvusClient struct {
    client client.Client
}
// NewMilvusClient 创建Milvus客户端
func NewMilvusClient(ctx context.Context, addr string) (*MilvusClient, error) {
    milvusClient, err := client.NewGrpcClient(ctx, addr)
    if err != nil {
        return nil, fmt.Errorf("failed to connect to Milvus: %v", err)
    }
    return &MilvusClient{client: milvusClient}, nil
}
// Close 关闭连接
func (m *MilvusClient) Close() error {
    return m.client.Close()
}
// 初始化milvus
func InitVectorDb() {
    // 连接到Milvus服务器
    ctx := context.Background()
    //milvusClient, err := NewMilvusClient(ctx, "192.168.1.232:19530")
    config := models.GetConfig()
    url := config.MilvusUrl
    milvusClient, err := NewMilvusClient(ctx, url)
    if err != nil {
        log.Fatal("Failed to connect to Milvus:", err)
    }
    //defer milvusClient.client.Close()
    fmt.Println("Successfully connected to Milvus")
    //初始化
    dbClient = milvusClient
    commonModels.SetClientDB(dbClient.client)
}
// GetDB ...
func GetDBCient() *MilvusClient {
    return dbClient
}
func CloseDBClient() {
    dbClient.Close()
}
chanmanage-service/models/camera.go
@@ -1,76 +1,75 @@
package models
import (
    "fmt"
    "strings"
    "vamicro/camera-common/models"
)
// 查询列表数据
func GetListTask(ids []string) (items []models.TaskM, err error) {
    //idList := strings.Join(ids, ",")
    idList := "'" + strings.Join(ids, "','") + "'"
    // 主查询SQL
    //sqlStr := `select c.task_id, c.task_name from mal_task_video_link a left join mal_smart_task c on a.task_id = c.task_id where a.video_id in(?) ORDER BY a.task_id desc`
    sqlStr := fmt.Sprintf(`
        SELECT c.task_id, c.task_name,c.task_description,b.dict_value as event_name
        FROM mal_task_video_link a
        LEFT JOIN mal_smart_task c ON a.task_id = c.task_id
        LEFT JOIN mal_dict_type b ON b.dict_id = c.event_level
        WHERE a.video_id IN (%s)
        ORDER BY a.task_id DESC
    `, idList)
    if err := db2.Raw(sqlStr).Scan(&items).Error; err != nil {
        fmt.Println(err.Error())
        return nil, err
    }
    return
}
func GetAllRule() map[int64]string {
    var items []models.RuleOption
    sqlStr := `
        SELECT a.file_name,a.rule_id,b.task_id
        FROM mal_warning_rule a
        LEFT JOIN mal_task_rule_link b ON a.rule_id = b.rule_id
        WHERE task_id>0
        group BY a.rule_id
    `
    if err := db2.Raw(sqlStr).Scan(&items).Error; err != nil {
        fmt.Println(err.Error())
        return nil
    }
    ruleMap := make(map[int64]string)
    for _, d2 := range items {
        if d2.TaskId > 0 {
            ruleMap[d2.TaskId] = d2.FileName
        }
    }
    return ruleMap
}
type VideoLink struct {
    ID      int    `gorm:"column:id"       json:"id"`
    VideoId string `gorm:"column:video_id" json:"videoId"`
    TaskId  int    `gorm:"column:task_id"  json:"taskId"`
}
func GetTasks() map[string][]interface{} {
    var lists []VideoLink
    sqlStr := `select id,video_id,task_id from mal_task_video_link`
    if err := db2.Raw(sqlStr).Scan(&lists).Error; err != nil {
        fmt.Println(err.Error())
        return nil
    }
    checkMap := make(map[string][]interface{})
    for _, d2 := range lists {
        if d2.VideoId != "" {
            checkMap[d2.VideoId] = append(checkMap[d2.VideoId], d2)
        }
    }
    return checkMap
}
package models
import (
    "fmt"
    "strings"
    "vamicro/camera-common/models"
)
// 查询列表数据
func GetListTask(ids []string) (items []models.TaskM, err error) {
    //idList := strings.Join(ids, ",")
    idList := "'" + strings.Join(ids, "','") + "'"
    // 主查询SQL
    //sqlStr := `select c.task_id, c.task_name from mal_task_video_link a left join mal_smart_task c on a.task_id = c.task_id where a.video_id in(?) ORDER BY a.task_id desc`
    sqlStr := fmt.Sprintf(`
        SELECT c.task_id, c.task_name,c.task_description,b.dict_value as event_name
        FROM mal_task_video_link a
        LEFT JOIN mal_smart_task c ON a.task_id = c.task_id
        LEFT JOIN mal_dict_type b ON b.dict_id = c.event_level
        WHERE a.video_id IN (%s)
        ORDER BY a.task_id DESC
    `, idList)
    if err := db2.Raw(sqlStr).Scan(&items).Error; err != nil {
        fmt.Println(err.Error())
        return nil, err
    }
    return
}
func GetAllRule() map[int64]string {
    var items []models.RuleOption
    sqlStr := `
        SELECT a.file_name,a.rule_id,b.task_id
        FROM mal_warning_rule a
        LEFT JOIN mal_task_rule_link b ON a.rule_id = b.rule_id
        WHERE task_id>0
    `
    if err := db2.Raw(sqlStr).Scan(&items).Error; err != nil {
        fmt.Println(err.Error())
        return nil
    }
    ruleMap := make(map[int64]string)
    for _, d2 := range items {
        if d2.TaskId > 0 {
            ruleMap[d2.TaskId] = d2.FileName
        }
    }
    return ruleMap
}
type VideoLink struct {
    ID      int    `gorm:"column:id"       json:"id"`
    VideoId string `gorm:"column:video_id" json:"videoId"`
    TaskId  int    `gorm:"column:task_id"  json:"taskId"`
}
func GetTasks() map[string][]interface{} {
    var lists []VideoLink
    sqlStr := `select id,video_id,task_id from mal_task_video_link`
    if err := db2.Raw(sqlStr).Scan(&lists).Error; err != nil {
        fmt.Println(err.Error())
        return nil
    }
    checkMap := make(map[string][]interface{})
    for _, d2 := range lists {
        if d2.VideoId != "" {
            checkMap[d2.VideoId] = append(checkMap[d2.VideoId], d2)
        }
    }
    return checkMap
}
push-service/controllers/eventPush.go
@@ -1,16 +1,18 @@
package controllers
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/logger.git"
    "encoding/json"
    "vamicro/push-service/models"
    "vamicro/push-service/mqtt"
    "vamicro/push-service/service"
    "vamicro/push-service/vo"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/logger.git"
)
type EventPushController struct {
}
// @Summary 事件推送保存
// @Description 事件推送保存
@@ -19,16 +21,16 @@
// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
// @Router /data/api-v/eventPush/save [post]
func (epc EventPushController) Save(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
func (epc EventPushController) Save(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var saveBody vo.EventPushVo
    if err := c.BindJSON(&saveBody);err !=nil {
        return &bhomeclient.Reply{ Success: false, Msg: "参数有误"}
    if err := c.BindJSON(&saveBody); err != nil {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    sv := service.NewEventPushService(h.Bk)
    if sv.Save(&saveBody) {
        return &bhomeclient.Reply{ Success: true, Data: saveBody }
        return &bhomeclient.Reply{Success: true, Data: saveBody}
    } else {
        return &bhomeclient.Reply{ Success: false, Msg: "保存失败"}
        return &bhomeclient.Reply{Success: false, Msg: "保存失败"}
    }
}
@@ -41,19 +43,19 @@
// @Success 200 {string} json "{"code":200, success:true, msg:"", data:""}"
// @Failure 500 {string} json "{"code":500, success:false, msg:"",data:""}"
// @Router /data/api-v/eventPush/findByEventTopic [get]
func (epc EventPushController) FindByEventTopic(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply{
func (epc EventPushController) FindByEventTopic(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    topic := c.Query("topic")
    childType := c.Query("type")
    if topic == ""{
        return &bhomeclient.Reply{ Success: false, Msg: "参数有误"}
    if topic == "" {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    sv := service.NewEventPushService(h.Bk)
    list, err := sv.FindByEventTopic(topic, childType)
    if err == nil {
        return &bhomeclient.Reply{ Success: true, Data: list }
        return &bhomeclient.Reply{Success: true, Data: list}
    } else {
        return &bhomeclient.Reply{ Success: false, Msg: err.Error() }
        return &bhomeclient.Reply{Success: false, Msg: err.Error()}
    }
}
@@ -68,11 +70,11 @@
func (epc EventPushController) FindAll(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    name := c.Query("name")
    sv := service.NewEventPushService(h.Bk)
    flag,data := sv.FindAll(name)
    flag, data := sv.FindAll(name)
    if flag {
        return &bhomeclient.Reply{ Success: true, Data: data }
    } else{
        return &bhomeclient.Reply{ Success: false, Msg: "查询失败"}
        return &bhomeclient.Reply{Success: true, Data: data}
    } else {
        return &bhomeclient.Reply{Success: false, Msg: "查询失败"}
    }
}
@@ -80,7 +82,7 @@
func (epc EventPushController) FindAllDetails(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    sv := service.NewEventPushService(h.Bk)
    data := sv.FindAllDetails()
    return &bhomeclient.Reply{ Success: true, Data: data }
    return &bhomeclient.Reply{Success: true, Data: data}
}
// @Summary 事件推送编辑
@@ -94,22 +96,22 @@
func (epc EventPushController) GetById(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    id := c.Query("id")
    logger.Debug("id:", id)
    if id == ""{
        return &bhomeclient.Reply{ Success: false, Msg: "参数有误"}
    if id == "" {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    sv := service.NewEventPushService(h.Bk)
    flag,data := sv.GetById(id)
    flag, data := sv.GetById(id)
    logger.Debug("getByID FLAG:", flag, " data:", data)
    if flag {
        return &bhomeclient.Reply{ Success: true, Data: data}
    } else{
        return &bhomeclient.Reply{ Success:false, Msg: "查询失败"}
        return &bhomeclient.Reply{Success: true, Data: data}
    } else {
        return &bhomeclient.Reply{Success: false, Msg: "查询失败"}
    }
}
type ChangeStatusVo struct {
    Id string `json:"id"`
    Enable bool `json:"enable"`
    Id     string `json:"id"`
    Enable bool   `json:"enable"`
}
// @Summary 改变enable状态
@@ -123,14 +125,34 @@
func (epc EventPushController) ChangeStatus(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var statusBody ChangeStatusVo
    err := c.BindJSON(&statusBody)
    if err !=nil {
        return &bhomeclient.Reply{ Success: false, Msg: "参数有误"}
    if err != nil {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    sv := service.NewEventPushService(h.Bk)
    if sv.ChangeStatus(statusBody.Id,statusBody.Enable){
        return &bhomeclient.Reply{ Success:true, Msg: "修改成功"}
    if sv.ChangeStatus(statusBody.Id, statusBody.Enable) {
        //消息提醒
        var epE models.EventPush
        epE.GetById(statusBody.Id)
        //udp推送
        if epE.PushType == 1 {
            msg := map[string]string{
                "type":   "change", // 注意逗号
                "status": "",       // 最后一个元素也需要逗号(Go 语法要求)
                "id":     statusBody.Id,
            }
            if statusBody.Enable {
                msg["status"] = "start"
            } else {
                msg["status"] = "stop"
            }
            jsonStr, _ := json.Marshal(msg)
            go mqtt.Client.Publish(mqtt.MQTT_CONFIG_TOPIC, jsonStr)
        }
        return &bhomeclient.Reply{Success: true, Msg: "修改成功"}
    } else {
        return &bhomeclient.Reply{ Success:false, Msg: "修改失败"}
        return &bhomeclient.Reply{Success: false, Msg: "修改失败"}
    }
}
@@ -145,13 +167,13 @@
// @Router /data/api-v/eventPush/delete [post]
func (epc EventPushController) Delete(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    id := c.PostForm("id")
    if id ==""{
        return &bhomeclient.Reply{ Success: false, Msg: "参数有误"}
    if id == "" {
        return &bhomeclient.Reply{Success: false, Msg: "参数有误"}
    }
    sv := service.NewEventPushService(h.Bk)
    if sv.DeleteById(id){
        return &bhomeclient.Reply{ Success:true, Msg: "删除成功"}
    if sv.DeleteById(id) {
        return &bhomeclient.Reply{Success: true, Msg: "删除成功"}
    } else {
        return &bhomeclient.Reply{ Success:false, Msg: "删除失败"}
        return &bhomeclient.Reply{Success: false, Msg: "删除失败"}
    }
}
}
push-service/controllers/pushSet.go
@@ -1,10 +1,11 @@
package controllers
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/logger.git"
    "vamicro/config"
    "vamicro/push-service/vo"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/logger.git"
)
type PushSetController struct {
@@ -31,23 +32,37 @@
        Alias:   "camInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "cameraId", Name: "摄像机ID", Alias: "cameraId"},
            {Checked: true, Id: "cameraName", Name: "摄像机名称", Alias: "cameraName"},
            {Checked: true, Id: "cameraAddr", Name: "摄像机地址", Alias: "cameraAddr"},
            {Checked: true, Id: "camera_id", Name: "摄像机ID", Alias: "camera_id"},
            {Checked: true, Id: "camera_name", Name: "摄像机名称", Alias: "camera_name"},
            {Checked: true, Id: "camera_addr", Name: "摄像机地址", Alias: "camera_addr"},
        },
    }
    sceneInfoSet := vo.PushSetMenu{
        Id:      "alarmRules", //报警规则
        Name:    "场景信息",
        Alias:   "alarmRules",
    // sceneInfoSet := vo.PushSetMenu{
    //     Id:      "alarmRules", //报警规则
    //     Name:    "场景信息",
    //     Alias:   "alarmRules",
    //     Checked: true,
    //     Children: []vo.PushSetMenu{
    //         {Checked: true, Id: "taskId", Name: "场景ID", Alias: "taskId"},
    //         {Checked: true, Id: "taskName", Name: "场景名称", Alias: "taskName"},
    //         {Checked: true, Id: "alarmRules.#.alarmLevel", Name: "事件等级", Alias: "alarmLevel"},
    //         {Checked: true, Id: "alarmRules.#.ruleText", Name: "场景描述", Alias: "groupText"},
    //         {Checked: true, Id: "alarmRules.#.linkInfo", Name: "联动信息", Alias: "linkInfo"},
    //         {Checked: true, Id: "alarmRules.#.groupId", Name: "报警规则组id", Alias: "groupId"},
    //     },
    // }
    taskInfoSet := vo.PushSetMenu{
        Id:      "aiTasks", //ai任务
        Name:    "任务信息",
        Alias:   "aiTasks",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "taskId", Name: "场景ID", Alias: "taskId"},
            {Checked: true, Id: "taskName", Name: "场景名称", Alias: "taskName"},
            {Checked: true, Id: "alarmRules.#.alarmLevel", Name: "事件等级", Alias: "alarmLevel"},
            {Checked: true, Id: "alarmRules.#.ruleText", Name: "场景描述", Alias: "groupText"},
            {Checked: true, Id: "alarmRules.#.linkInfo", Name: "联动信息", Alias: "linkInfo"},
            {Checked: true, Id: "alarmRules.#.groupId", Name: "报警规则组id", Alias: "groupId"},
            {Checked: true, Id: "task_id", Name: "任务id", Alias: "task_id"},
            {Checked: true, Id: "task_name", Name: "任务名称", Alias: "task_name"},
            {Checked: true, Id: "event_level", Name: "事件等级", Alias: "event_level"},
            {Checked: true, Id: "working_time", Name: "时间段", Alias: "working_time"},
            {Checked: true, Id: "rules", Name: "任务描述", Alias: "rules"},
            {Checked: true, Id: "task_description", Name: "备注", Alias: "task_description"},
        },
    }
    serverSet := vo.PushSetMenu{
@@ -56,9 +71,9 @@
        Alias:   "serverInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "analyServerId", Name: "设备ID", Alias: "analyServerId"},
            {Checked: true, Id: "analyServerIp", Name: "设备IP", Alias: "analyServerIp"},
            {Checked: true, Id: "analyServerName", Name: "设备名称", Alias: "analyServerName"},
            {Checked: true, Id: "analy_server_id", Name: "设备ID", Alias: "analy_server_id"},
            {Checked: true, Id: "analy_server_ip", Name: "设备IP", Alias: "analy_server_ip"},
            {Checked: true, Id: "analy_server_name", Name: "设备名称", Alias: "analy_server_name"},
        },
    }
    dataSet := vo.PushSetMenu{
@@ -68,76 +83,68 @@
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "id", Name: "主键ID", Alias: "id"},
            {Checked: true, Id: "isDelete", Name: "是否删除", Alias: "isDelete"},
            {Checked: true, Id: "likeDate", Name: "比对时间", Alias: "likeDate"},
            {Checked: true, Id: "picDate", Name: "抓拍时间", Alias: "picDate"},
            {Checked: true, Id: "updateTime", Name: "更新时间", Alias: "updateTime"},
            {Checked: true, Id: "picMaxUrl", Name: "告警全景图地址", Alias: "picMaxUrl"},
            {Checked: true, Id: "picSrcUrl", Name: "原始全景图地址", Alias: "picSrcUrl"},
            {Checked: true, Id: "picId", Name: "图片ID", Alias: "picId"},
            {Checked: true, Id: "picWH.picH", Name: "图片高", Alias: "picH"},
            {Checked: true, Id: "picWH.picW", Name: "图片宽", Alias: "picW"},
            {Checked: true, Id: "sdkName", Name: "sdk类型", Alias: "sdkName"},
            {Checked: true, Id: "videoUrl", Name: "录像地址", Alias: "videoUrl"},
            {Checked: true, Id: "content", Name: "场景名称", Alias: "content"},
            {Checked: true, Id: "linkTag", Name: "联动任务标志", Alias: "linkTag"},
            {Checked: true, Id: "otherLabels", Name: "其他标签", Alias: "otherLebels"},
            {Checked: true, Id: "showLabels", Name: "算法标签", Alias: "showLabels"},
            {Checked: true, Id: "version", Name: "索引版本", Alias: "version"},
            {Checked: true, Id: "isAlarm", Name: "是否报警", Alias: "isAlarm"},
            {Checked: true, Id: "detect_time", Name: "创建时间", Alias: "detect_time"},
            {Checked: true, Id: "zh_desc_class", Name: "中文描述", Alias: "zh_desc_class"},
            {Checked: true, Id: "image_path", Name: "图像地址", Alias: "image_path"},
            {Checked: true, Id: "video_path", Name: "录像地址", Alias: "video_path"},
            {Checked: true, Id: "event_level_name", Name: "事件等级", Alias: "event_level_name"},
            {Checked: true, Id: "suggestion", Name: "处理建议", Alias: "suggestion"},
            {Checked: true, Id: "risk_description", Name: "隐患描述", Alias: "risk_description"},
            {Checked: true, Id: "is_warning", Name: "是否预警", Alias: "is_warning"},
        },
    }
    detectAreaSet := vo.PushSetMenu{
        Id:      "detectAreaInfo",
        Name:    "检测区域",
        Alias:   "detectAreaInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "targetInfo.#.areaId", Name: "检测区域id", Alias: "areaId"},
            {Checked: true, Id: "targetInfo.#.areaName", Name: "检测区域名称", Alias: "areaName"},
        },
    }
    targetSet := vo.PushSetMenu{
        Id:      "targetInfo",
        Name:    "目标",
        Alias:   "targetInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "targetInfo.#.attribute", Name: "算法属性", Alias: "attribute"},
            {Checked: true, Id: "targetInfo.#.targetLocation", Name: "目标坐标", Alias: "targetLocation"},
            {Checked: true, Id: "targetInfo.#.targetScore", Name: "目标置信度", Alias: "targetScore"},
            {Checked: true, Id: "targetInfo.#.targetType", Name: "目标类别", Alias: "targetType"},
        },
    }
    dtSet := vo.PushSetMenu{
        Id:      "tableInfo",
        Name:    "底库信息",
        Alias:   "tableInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "baseInfo.#.tableId", Name: "底库ID", Alias: "tableId"},
            {Checked: true, Id: "baseInfo.#.tableName", Name: "底库名称", Alias: "tableName"},
            {Checked: true, Id: "baseInfo.#.bwType", Name: "黑白名单", Alias: "bwType"},
            {Checked: true, Id: "baseInfo.#.targetPicUrl", Name: "目标抓拍图片", Alias: "targetPicUrl"},
            {Checked: true, Id: "baseInfo.#.compareScore", Name: "相似度", Alias: "compareScore"},
            {Checked: true, Id: "baseInfo.#.content", Name: "内容", Alias: "content"},
        },
    }
    dbpInfo := vo.PushSetMenu{
        Id:      "baseInfo",
        Name:    "底库人员信息",
        Alias:   "baseInfo",
        Checked: true,
        Children: []vo.PushSetMenu{
            {Checked: true, Id: "baseInfo.#.targetId", Name: "目标ID", Alias: "targetId"},
            {Checked: true, Id: "baseInfo.#.targetName", Name: "姓名", Alias: "targetName"},
            {Checked: true, Id: "baseInfo.#.sex", Name: "性别", Alias: "sex"},
            {Checked: true, Id: "baseInfo.#.idCard", Name: "身份证号", Alias: "idCard"},
            {Checked: true, Id: "baseInfo.#.phoneNum", Name: "手机号", Alias: "phoneNum"},
            {Checked: true, Id: "baseInfo.#.monitorLevel", Name: "人员等级", Alias: "monitorLevel"},
        },
    }
    set = append(set, camInfoSet, sceneInfoSet, serverSet, dataSet, detectAreaSet, targetSet, dtSet, dbpInfo)
    // detectAreaSet := vo.PushSetMenu{
    //     Id:      "detectAreaInfo",
    //     Name:    "检测区域",
    //     Alias:   "detectAreaInfo",
    //     Checked: true,
    //     Children: []vo.PushSetMenu{
    //         {Checked: true, Id: "targetInfo.#.areaId", Name: "检测区域id", Alias: "areaId"},
    //         {Checked: true, Id: "targetInfo.#.areaName", Name: "检测区域名称", Alias: "areaName"},
    //     },
    // }
    // targetSet := vo.PushSetMenu{
    //     Id:      "targetInfo",
    //     Name:    "目标",
    //     Alias:   "targetInfo",
    //     Checked: true,
    //     Children: []vo.PushSetMenu{
    //         {Checked: true, Id: "targetInfo.#.attribute", Name: "算法属性", Alias: "attribute"},
    //         {Checked: true, Id: "targetInfo.#.targetLocation", Name: "目标坐标", Alias: "targetLocation"},
    //         {Checked: true, Id: "targetInfo.#.targetScore", Name: "目标置信度", Alias: "targetScore"},
    //         {Checked: true, Id: "targetInfo.#.targetType", Name: "目标类别", Alias: "targetType"},
    //     },
    // }
    // dtSet := vo.PushSetMenu{
    //     Id:      "tableInfo",
    //     Name:    "底库信息",
    //     Alias:   "tableInfo",
    //     Checked: true,
    //     Children: []vo.PushSetMenu{
    //         {Checked: true, Id: "baseInfo.#.tableId", Name: "底库ID", Alias: "tableId"},
    //         {Checked: true, Id: "baseInfo.#.tableName", Name: "底库名称", Alias: "tableName"},
    //         {Checked: true, Id: "baseInfo.#.bwType", Name: "黑白名单", Alias: "bwType"},
    //         {Checked: true, Id: "baseInfo.#.targetPicUrl", Name: "目标抓拍图片", Alias: "targetPicUrl"},
    //         {Checked: true, Id: "baseInfo.#.compareScore", Name: "相似度", Alias: "compareScore"},
    //         {Checked: true, Id: "baseInfo.#.content", Name: "内容", Alias: "content"},
    //     },
    // }
    // dbpInfo := vo.PushSetMenu{
    //     Id:      "baseInfo",
    //     Name:    "底库人员信息",
    //     Alias:   "baseInfo",
    //     Checked: true,
    //     Children: []vo.PushSetMenu{
    //         {Checked: true, Id: "baseInfo.#.targetId", Name: "目标ID", Alias: "targetId"},
    //         {Checked: true, Id: "baseInfo.#.targetName", Name: "姓名", Alias: "targetName"},
    //         {Checked: true, Id: "baseInfo.#.sex", Name: "性别", Alias: "sex"},
    //         {Checked: true, Id: "baseInfo.#.idCard", Name: "身份证号", Alias: "idCard"},
    //         {Checked: true, Id: "baseInfo.#.phoneNum", Name: "手机号", Alias: "phoneNum"},
    //         {Checked: true, Id: "baseInfo.#.monitorLevel", Name: "人员等级", Alias: "monitorLevel"},
    //     },
    // }
    // set = append(set, camInfoSet, sceneInfoSet, serverSet, dataSet, detectAreaSet, targetSet, dtSet, dbpInfo)
    set = append(set, camInfoSet, taskInfoSet, serverSet, dataSet)
    return &bhomeclient.Reply{Success: true, Data: set}
}
push-service/main.go
@@ -1,10 +1,6 @@
package main
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "basic.com/valib/version.git"
    "context"
    "flag"
    "os"
@@ -13,15 +9,22 @@
    "vamicro/config"
    "vamicro/push-service/controllers"
    "vamicro/push-service/models"
    "vamicro/push-service/mqtt"
    "vamicro/push-service/service"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    vaversion "basic.com/valib/version.git"
    "github.com/go-basic/uuid"
)
var (
    procName = service.ProcName
    proc = &bhomeclient.ProcInfo{
    proc     = &bhomeclient.ProcInfo{
        Name: procName, //进程名称
        ID: procName, //进程id
        Info: "", //进程的描述信息,用于区分同一进程名称下多个进程
        ID:   procName, //进程id
        Info: "",       //进程的描述信息,用于区分同一进程名称下多个进程
    }
    env = flag.String("e", "pro", "")
)
@@ -32,20 +35,24 @@
    config.Init(*env)
    // 日志初始化
    var logFile = config.LogConf.Path + "vamicro-"+procName+".log"
    var logFile = config.LogConf.Path + "vamicro-" + procName + ".log"
    logger.InitLogger(logFile, config.LogConf.Level, config.LogConf.MaxSize, config.LogConf.MaxBackups, config.LogConf.MaxAge)
    logger.Info("log init success !")
}
func main(){
func main() {
    models.Init()
    defer models.CloseDB()
    //初始化mqtt
    mqtt.LoadConfig()
    mqtt.Client.Init(mqtt.Options.Broker, "smart-ai-helmet-manager"+uuid.New(), mqtt.Options.Username, mqtt.Options.Password)
    ctx, cancel := context.WithCancel(context.Background())
    fm, pubTopics := initFuncMap()
    var reg = &bhomeclient.RegisterInfo {
        Proc: *proc,
        Channel: nil,
    var reg = &bhomeclient.RegisterInfo{
        Proc:     *proc,
        Channel:  nil,
        PubTopic: pubTopics,
        SubTopic: []string{},
    }
@@ -54,7 +61,7 @@
    signal.Notify(q, os.Interrupt, os.Kill, syscall.SIGTERM)
    ms, err := bhomeclient.NewMicroNode(ctx, q, config.Server.AnalyServerId, reg, logger.Debug)
    if err !=nil {
    if err != nil {
        return
    }
@@ -68,10 +75,12 @@
    ms.DeRegister()
    cancel()
    ms.Free()
}
const urlPrefix = "/data/api-v"
func initFuncMap() (map[string]bhomeclient.MicroFunc,[]string) {
func initFuncMap() (map[string]bhomeclient.MicroFunc, []string) {
    funcMap := make(map[string]bhomeclient.MicroFunc)
    ec := new(controllers.EventPushController)
    psc := new(controllers.PushSetController)
@@ -85,8 +94,8 @@
    funcMap[urlPrefix+"/eventPush/getPushSet"] = psc.GetPushSet
    var pubTopics []string
    for key,_ := range funcMap {
    for key, _ := range funcMap {
        pubTopics = append(pubTopics, key)
    }
    return funcMap, pubTopics
}
}
push-service/models/eventPush.go
@@ -3,6 +3,7 @@
type EventPush struct {
    Id           string `gorm:"primary_key;column:id" json:"id"`
    Name         string `gorm:"column:name" json:"name"`
    PushType     int    `gorm:"column:push_type" json:"push_type"`
    TimeStart    string `gorm:"column:time_start" json:"time_start"`
    TimeEnd      string `gorm:"column:time_end" json:"time_end"`
    IsSatisfyAll bool   `gorm:"column:is_satisfy_all" json:"is_satisfy_all"`
push-service/mqtt/config.go
New file
@@ -0,0 +1,62 @@
package mqtt
import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "os"
    "github.com/go-basic/uuid"
)
type Config struct {
    Broker   string `json:"broker"`
    ClientId string `json:"client_id"`
    Username string `json:"username"`
    Password string `json:"password"`
}
const configPath = "/opt/vasystem/config/mqtt.conf"
const MQTT_CONFIG_TOPIC = "smartai/config"
var Options Config
func LoadConfig() {
    if !pathExists(configPath) {
        SaveConfig()
    } else {
        file, _ := os.Open(configPath)
        defer file.Close()
        fd := json.NewDecoder(file)
        fd.Decode(&Options)
        fmt.Printf("%v\n", Options)
    }
}
func SaveConfig() {
    Options = Config{
        "192.168.1.235:1883",
        "smart-ai-helmet-manager" + uuid.New(),
        "admin",
        "admin",
    }
    bytes, err := json.Marshal(Options)
    if err == nil {
        ioutil.WriteFile(configPath, bytes, 0744)
    }
}
func pathExists(path string) bool {
    _, err := os.Stat(path)
    if err == nil {
        return true
    }
    fmt.Printf("%v", err.Error())
    return false
}
push-service/mqtt/mqtt.go
New file
@@ -0,0 +1,87 @@
package mqtt
import (
    "fmt"
    MQTT "github.com/eclipse/paho.mqtt.golang"
)
type MQTTClient struct {
    Broker   string
    ClientId string
    Username string
    Passwd   string
    Mqtt     MQTT.Client
}
var Client *MQTTClient
func init() {
    Client = &MQTTClient{}
}
type mqLog struct {
}
func (l *mqLog) Println(v ...interface{}) {
    fmt.Println(v...)
}
func (l *mqLog) Printf(format string, v ...interface{}) {
    fmt.Println(fmt.Sprintf(format, v...))
}
func (m *MQTTClient) Init(brokerAddr, clientId, username, password string) {
    m.Broker = brokerAddr
    m.ClientId = clientId
    m.Username = username
    m.Passwd = password
    opts := MQTT.NewClientOptions().AddBroker(brokerAddr)
    opts.SetClientID(clientId)
    opts.SetUsername(username)
    opts.SetPassword(password)
    opts.SetAutoReconnect(false)
    hl := mqLog{}
    MQTT.ERROR   = &hl
    MQTT.CRITICAL= &hl
    MQTT.WARN    = &hl
    MQTT.DEBUG   = &hl
    m.Mqtt = MQTT.NewClient(opts)
fmt.Println("connectRetry:", opts.ConnectRetry)
    if token := m.Mqtt.Connect(); token.Wait() && token.Error() != nil {
        panic(token.Error())
        // fmt.Println(token.Error())
    }
}
func (m *MQTTClient) Subscribe(topic string, sub chan<- MQTT.Message) {
    fmt.Println("start subscribing...")
    subToken := m.Mqtt.Subscribe(
        topic,
        0,
        func(client MQTT.Client, msg MQTT.Message) {
            sub <- msg
        })
    if subToken.Wait() && subToken.Error() != nil {
        fmt.Println(subToken.Error())
    }
}
func (m *MQTTClient) Publish(topic string, msg interface{}) {
    if m.Mqtt.IsConnected() {
        token := m.Mqtt.Publish(topic, 0, false, msg)
        if token.Wait() && token.Error() != nil {
            fmt.Println(token.Error())
        }
    } else {
        fmt.Println("mqtt client reconneted")
        if token := m.Mqtt.Connect(); token.Wait() && token.Error() != nil {
            fmt.Println(token.Error())
        }
    }
}
push-service/service/eventPushService.go
@@ -1,16 +1,18 @@
package service
import (
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "encoding/json"
    "errors"
    "github.com/satori/go.uuid"
    "vamicro/extend/util"
    "vamicro/push-service/models"
    "vamicro/push-service/vo"
    sysModel "vamicro/system-service/models"
    "basic.com/pubsub/protomsg.git"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    uuid "github.com/satori/go.uuid"
)
type EventPushService struct {
@@ -82,10 +84,12 @@
    } else { //新增
        if er > 0 {
            err = errors.New("名称不允许重复")
            logger.Debug(err)
            return false
        }
        eventPushE.Id = uuid.NewV4().String()
        if err = tx.Table("event_push").Create(&eventPushE).Error; err != nil {
            logger.Debug(err)
            return false
        }
    }
@@ -101,6 +105,7 @@
            EventPushId: eventPushE.Id,
        }
        if err = tx.Table("event_push_server").Create(&ipPortE).Error; err != nil {
            logger.Debug(err)
            return false
        }
    }
@@ -109,18 +114,24 @@
            Id:          uuid.NewV4().String(),
            Enable:      urlVo.Enable,
            Url:         urlVo.Url,
            ServerIp:    urlVo.ServerIp,
            Port:        urlVo.Port,
            Type:        models.PUSH_URL_TYPE,
            EventPushId: eventPushE.Id,
        }
        if err = tx.Table("event_push_server").Create(&urlE).Error; err != nil {
            logger.Debug(err)
            return false
        }
    }
    logger.Debug("hhhhhhh")
    for _, rule := range body.Rules {
        rule.Id = uuid.NewV4().String()
        rule.EventPushId = eventPushE.Id
        if err = tx.Table("event_push_rule").Create(&rule).Error; err != nil {
            logger.Debug(err)
            return false
        }
    }
@@ -265,8 +276,10 @@
                    })
                } else if pushServer.Type == models.PUSH_URL_TYPE {
                    resultVo.Urls = append(resultVo.Urls, vo.EventUrlVo{
                        Enable: pushServer.Enable,
                        Url:    pushServer.Url,
                        Enable:   pushServer.Enable,
                        Url:      pushServer.Url,
                        ServerIp: pushServer.ServerIp,
                        Port:     pushServer.Port,
                    })
                }
            }
push-service/vo/eventPush.go
@@ -7,49 +7,52 @@
)
type EventPushVo struct {
    Id                 string                     `json:"id"`
    Name             string                     `json:"name"`
    TimeStart         string                     `json:"time_start"`
    TimeEnd         string                     `json:"time_end"`
    IsSatisfyAll     bool                     `json:"is_satisfy_all"`
    RuleText         string                     `json:"rule_text"`
    Enable             bool                     `json:"enable"`
    LinkType         string                     `json:"link_type"`
    LinkDevice         string                     `json:"link_device"`
    Id           string `json:"id"`
    Name         string `json:"name"`
    PushType     int    `json:"push_type"`
    TimeStart    string `json:"time_start"`
    TimeEnd      string `json:"time_end"`
    IsSatisfyAll bool   `json:"is_satisfy_all"`
    RuleText     string `json:"rule_text"`
    Enable       bool   `json:"enable"`
    LinkType     string `json:"link_type"`
    LinkDevice   string `json:"link_device"`
    IpPorts         []EventPushServerPortVo `json:"ip_ports"`
    Urls             []EventUrlVo             `json:"urls"`
    Rules             []models.EventPushRule     `json:"rules"`
    IpPorts []EventPushServerPortVo `json:"ip_ports"`
    Urls    []EventUrlVo            `json:"urls"`
    Rules   []models.EventPushRule  `json:"rules"`
    FiltRename         map[string]string        `json:"filtRename"`
    PushSet         []PushSetMenu             `json:"push_set"`
    FiltRename map[string]string `json:"filtRename"`
    PushSet    []PushSetMenu     `json:"push_set"`
}
type PushSetMenu struct {
    Id             string                 `json:"id"`
    Name         string                 `json:"name"`
    Checked     bool                 `json:"checked"`
    Alias         string                 `json:"alias"`
    Children     []PushSetMenu        `json:"children"`
    Id       string        `json:"id"`
    Name     string        `json:"name"`
    Checked  bool          `json:"checked"`
    Alias    string        `json:"alias"`
    Children []PushSetMenu `json:"children"`
}
type EventPushServerPortVo struct {
    ServerIp string `json:"server_ip"`
    Port int `json:"port"`
    Enable bool `json:"enable"`
    Port     int    `json:"port"`
    Enable   bool   `json:"enable"`
}
type EventUrlVo struct {
    Url string `json:"url"`
    Enable bool `json:"enable"`
    Url      string `json:"url"`
    ServerIp string `json:"server_ip"`
    Port     int    `json:"port"`
    Enable   bool   `json:"enable"`
}
func (epv *EventPushVo) SetFiltRename() {
    epv.FiltRename = make(map[string]string)
    if epv.PushSet != nil {
        for _,set := range epv.PushSet {
            if set.Children !=nil {
                for _,child := range set.Children {
        for _, set := range epv.PushSet {
            if set.Children != nil {
                for _, child := range set.Children {
                    if child.Checked {
                        prefix := ""
                        idx := strings.LastIndex(child.Id, ".")
@@ -65,34 +68,36 @@
}
func (epv *EventPushVo) CopyToEventPush() models.EventPush {
    d,_ := json.Marshal(epv.PushSet)
    d, _ := json.Marshal(epv.PushSet)
    return models.EventPush{
        Id:epv.Id,
        Name:epv.Name,
        TimeStart:epv.TimeStart,
        TimeEnd:epv.TimeEnd,
        IsSatisfyAll:epv.IsSatisfyAll,
        RuleText:epv.RuleText,
        Enable:epv.Enable,
        LinkType:epv.LinkType,
        LinkDevice:epv.LinkDevice,
        PushSet: string(d),
        Id:           epv.Id,
        Name:         epv.Name,
        TimeStart:    epv.TimeStart,
        TimeEnd:      epv.TimeEnd,
        IsSatisfyAll: epv.IsSatisfyAll,
        RuleText:     epv.RuleText,
        Enable:       epv.Enable,
        PushType:     epv.PushType,
        LinkType:     epv.LinkType,
        LinkDevice:   epv.LinkDevice,
        PushSet:      string(d),
    }
}
func (epv *EventPushVo) CopyFromEventPush(epE *models.EventPush){
func (epv *EventPushVo) CopyFromEventPush(epE *models.EventPush) {
    epv.Id = epE.Id
    epv.Name = epE.Name
    epv.TimeStart = epE.TimeStart
    epv.TimeEnd = epE.TimeEnd
    epv.IsSatisfyAll = epE.IsSatisfyAll
    epv.PushType = epE.PushType
    epv.RuleText = epE.RuleText
    epv.Enable = epE.Enable
    epv.LinkType = epE.LinkType
    epv.LinkDevice = epE.LinkDevice
    if epE.PushSet != "" {
        var set []PushSetMenu
        if err := json.Unmarshal([]byte(epE.PushSet), &set);err == nil {
        if err := json.Unmarshal([]byte(epE.PushSet), &set); err == nil {
            epv.PushSet = set
        } else {
            epv.PushSet = make([]PushSetMenu, 0)
@@ -102,8 +107,7 @@
    }
}
type KeyValueVo struct {
    Value string `json:"value"`
    Name string `json:"name"`
}
    Name  string `json:"name"`
}
search-service/main.go
@@ -1,10 +1,6 @@
package main
import (
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "basic.com/valib/version.git"
    "context"
    "flag"
    "os"
@@ -12,6 +8,11 @@
    "syscall"
    "vamicro/config"
    "vamicro/search-service/controllers"
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    vaversion "basic.com/valib/version.git"
)
var (
@@ -71,7 +72,7 @@
func initFuncMap() (map[string]bhomeclient.MicroFunc, []string) {
    funcMap := make(map[string]bhomeclient.MicroFunc)
    sc := new(controllers.EsSearchController)
    tc := new(controllers.TaskController)
    // tc := new(controllers.TaskController)
    funcMap[urlPrefix+"/dbperson/faceExtract"] = sc.FaceExtract
    funcMap[urlPrefix+"/dbperson/searchByPhoto"] = sc.SearchByPhoto
@@ -79,7 +80,7 @@
    funcMap[urlPrefix+"/es/esSearch"] = sc.PostEsSearch
    funcMap[urlPrefix+"/es/tagList"] = sc.PostEsTagList
    funcMap[urlPrefix+"/es/taskList"] = sc.PostEsTaskList
    funcMap[urlPrefix+"/task/aggregateTaskList"] = tc.AggregateTaskList
    // funcMap[urlPrefix+"/task/aggregateTaskList"] = tc.AggregateTaskList
    funcMap[urlPrefix+"/es/collect"] = sc.Collect
    funcMap[urlPrefix+"/es/deleteById"] = sc.PostEsDelete
    funcMap[urlPrefix+"/es/signMisreport"] = sc.SignMisreport
sysinfo-service/service/psutil.go
@@ -33,9 +33,35 @@
        Stat.Mem = *meminfo
    }
    // Gpu
    // agxGpuProcIface := "/sys/devices/gpu.0/load"
    // if Exists(agxGpuProcIface) {
    //     fd, err1 := os.Open(agxGpuProcIface)
    //     if err1 == nil {
    //         var load int64
    //         fmt.Fscanf(fd, "%d", &load)
    //         // 模拟nvidia库的输出
    //         Stat.Gpu = append(Stat.Gpu, gogpu.GpuUnitInfo{
    //             GpuMemoryTotal: 1000,
    //             GpuMemoryUsed:  load,
    //         })
    //         fd.Close()
    //     }
    // } else {
    //     if gpuInfo, err := gogpu.Info(); err == nil {
    //         sort.Sort(gogpu.GPURank(gpuInfo.Info))
    //         Stat.Gpu = Stat.Gpu[0:0]
    //         for _, v := range gpuInfo.Info {
    //             Stat.Gpu = append(Stat.Gpu, v)
    //         }
    //     }
    // }
    // Gpu
    agxGpuProcIface := "/sys/devices/gpu.0/load"
    if _, err := os.Stat(agxGpuProcIface); !os.IsExist(err) {
    if Exists(agxGpuProcIface){
        fd, err1 := os.Open(agxGpuProcIface)
        if err1 == nil {
            var load int64
@@ -136,3 +162,14 @@
    return Stat
}
func Exists(path string) bool {
    _, err := os.Stat(path) //os.Stat获取文件信息
    if err != nil {
        if os.IsExist(err) {
            return true
        }
        return false
    }
    return true
}
system-service/bhome_msg_dev/bhome_msg_dev.pb.go
@@ -5,10 +5,11 @@
import (
    fmt "fmt"
    proto "github.com/gogo/protobuf/proto"
    io "io"
    math "math"
    math_bits "math/bits"
    proto "github.com/gogo/protobuf/proto"
)
// Reference imports to suppress errors if they are not otherwise used.
@@ -1589,7 +1590,8 @@
            return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
        }
    }
    panic("unreachable")
    // panic("unreachable")
    return 0, nil
}
var (
system-service/controllers/dictionary.go
@@ -8,36 +8,37 @@
    "basic.com/valib/bhomeclient.git"
    "basic.com/valib/bhomedbapi.git"
    "basic.com/valib/logger.git"
    "github.com/satori/go.uuid"
    uuid "github.com/satori/go.uuid"
)
type DictionaryController struct {
}
type DicTypeVo struct {
    Type string                  `json:"type"`
    Dics []DicWithChildren         `json:"dics"`
    Type string            `json:"type"`
    Dics []DicWithChildren `json:"dics"`
}
type DicWithChildren struct {
    models.Dictionary
    Children     []DicWithChildren     `json:"children"`
    Children []DicWithChildren `json:"children"`
}
type DicList []DicWithChildren
func (dl DicList) Len()int {
func (dl DicList) Len() int {
    return len(dl)
}
func (dl DicList) Swap(i,j int) {
    dl[i],dl[j] = dl[j],dl[i]
func (dl DicList) Swap(i, j int) {
    dl[i], dl[j] = dl[j], dl[i]
}
func (dl DicList) Less(i,j int) bool {
func (dl DicList) Less(i, j int) bool {
    return dl[i].Sort < dl[j].Sort
}
func recursiveChildren(parentId string, allList *[]models.Dictionary) []DicWithChildren {
    var children = make([]DicWithChildren, 0)
    for _,d := range *allList {
    for _, d := range *allList {
        if d.ParentId == parentId {
            dwc := DicWithChildren{}
            dwc.Dictionary = d
@@ -70,7 +71,7 @@
    resMap := make(map[string]DicList, 0)
    wg := &sync.WaitGroup{}
    wg.Add(4)
    wg.Add(2)
    go func() {
        defer wg.Done()
        for _, dic := range allDics {
@@ -102,47 +103,47 @@
            }
        }
    }()
    //人员底库
    personTableList := make(DicList, 0)
    var tableApi bhomedbapi.DbTableApi
    go func() {
        defer wg.Done()
        personTables, dtErr := tableApi.FindAllDbTablesByType("0", "person")
        if dtErr == nil && personTables != nil {
            for idx, t := range personTables {
                dwc := DicWithChildren{}
                dwc.Dictionary = models.Dictionary{
                    Value: t.Id,
                    Name:  t.TableName,
                    Sort:  idx + 1,
                }
                personTableList = append(personTableList, dwc)
            }
        }
    }()
    // 车辆底库
    carTableList := make(DicList, 0)
    go func() {
        defer wg.Done()
        carTables, _ := tableApi.FindAllDbTablesByType("0", "car")
        if carTables != nil {
            for idx, t := range carTables {
                dwc := DicWithChildren{}
                dwc.Dictionary = models.Dictionary{
                    Value: t.Id,
                    Name:  t.TableName,
                    Sort:  idx + 1,
                }
                carTableList = append(carTableList, dwc)
            }
        }
    }()
    // //人员底库
    // personTableList := make(DicList, 0)
    // var tableApi bhomedbapi.DbTableApi
    // go func() {
    //     defer wg.Done()
    //     personTables, dtErr := tableApi.FindAllDbTablesByType("0", "person")
    //     if dtErr == nil && personTables != nil {
    //         for idx, t := range personTables {
    //             dwc := DicWithChildren{}
    //             dwc.Dictionary = models.Dictionary{
    //                 Value: t.Id,
    //                 Name:  t.TableName,
    //                 Sort:  idx + 1,
    //             }
    //             personTableList = append(personTableList, dwc)
    //         }
    //     }
    // }()
    // // 车辆底库
    // carTableList := make(DicList, 0)
    // go func() {
    //     defer wg.Done()
    //     carTables, _ := tableApi.FindAllDbTablesByType("0", "car")
    //     if carTables != nil {
    //         for idx, t := range carTables {
    //             dwc := DicWithChildren{}
    //             dwc.Dictionary = models.Dictionary{
    //                 Value: t.Id,
    //                 Name:  t.TableName,
    //                 Sort:  idx + 1,
    //             }
    //             carTableList = append(carTableList, dwc)
    //         }
    //     }
    // }()
    wg.Wait()
    resMap["time_rule"] = timeList
    resMap["compareBase"] = personTableList
    resMap["compareCarBase"] = carTableList
    // resMap["compareBase"] = personTableList
    // resMap["compareCarBase"] = carTableList
    for k, dList := range resMap {
        v := dList
@@ -164,7 +165,7 @@
func (controller DictionaryController) FindByParentId(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    parentId := c.Query("parentId")
    if parentId == "" {
        return &bhomeclient.Reply{ Msg: "参数有误"}
        return &bhomeclient.Reply{Msg: "参数有误"}
    }
    var model models.Dictionary
    if flag, err := model.SelectById(parentId); !flag && err == nil {
@@ -174,20 +175,19 @@
                Value: "",
                Name:  "空",
            }
            return &bhomeclient.Reply{ Success: true, Data: []models.Dictionary{empty} }
            return &bhomeclient.Reply{Success: true, Data: []models.Dictionary{empty}}
        } else {
            dics, err := model.FindByParentId(parentId)
            if err != nil {
                return &bhomeclient.Reply{ Msg: "查询失败"}
                return &bhomeclient.Reply{Msg: "查询失败"}
            } else {
                return &bhomeclient.Reply{ Success:true, Data: dics }
                return &bhomeclient.Reply{Success: true, Data: dics}
            }
        }
    } else {
        return &bhomeclient.Reply{ Msg: "查询失败"}
        return &bhomeclient.Reply{Msg: "查询失败"}
    }
}
// @Summary 根据type查找字典列表
// @Description  根据type查找字典列表
@@ -200,14 +200,14 @@
func (controller DictionaryController) ListByType(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    typ := c.Query("type")
    if typ == "" {
        return &bhomeclient.Reply{ Msg: "参数有误"}
        return &bhomeclient.Reply{Msg: "参数有误"}
    }
    var model models.Dictionary
    dics, err := model.FindByType(typ)
    if err == nil {
        return &bhomeclient.Reply{ Success:true, Data: dics }
        return &bhomeclient.Reply{Success: true, Data: dics}
    } else {
        return &bhomeclient.Reply{ Msg: "查询失败"}
        return &bhomeclient.Reply{Msg: "查询失败"}
    }
}
@@ -223,7 +223,7 @@
func (controller DictionaryController) Save(h *bhomeclient.WrapperHandler, c *bhomeclient.Request) *bhomeclient.Reply {
    var model models.Dictionary
    if err := c.BindJSON(&model); err != nil {
        return &bhomeclient.Reply{ Msg: "参数有误"}
        return &bhomeclient.Reply{Msg: "参数有误"}
    }
    var flag bool
    if model.Id == "" {
@@ -234,8 +234,8 @@
    }
    if !flag {
        return &bhomeclient.Reply{ Msg: "保存失败"}
        return &bhomeclient.Reply{Msg: "保存失败"}
    } else {
        return &bhomeclient.Reply{ Success:true, Msg: "保存成功"}
        return &bhomeclient.Reply{Success: true, Msg: "保存成功"}
    }
}
system-service/service/devInfoSync.go
@@ -155,30 +155,30 @@
    if diff {
        // 同步设备信息到商城
        if util.GetShopUrl() != "" {
            body := util.Struct2Map(i)
            url := "http://" + util.GetShopUrl() + "/data/api-d/device/syncDevToCloud"
            header := map[string]string{
                "Authorization": token,
            }
            data, err := util.DoPostRequest(url, util.CONTENT_TYPE_JSON, body, nil, header, 10*time.Second)
            if err != nil {
                logger.Error("send devInfo to cloud err:", err)
                return
            }
            logger.Debug("syncDevToCloud result:", string(data))
            var result bhomedbapi.Result
            err = json.Unmarshal(data, &result)
            if err != nil {
                logger.Error("unmarshal err:", err)
                return
            }
            if result.Success {
                lstSync = &i
            } else {
                logger.Error("syncDevToCloud result:", result)
            }
        }
        // if util.GetShopUrl() != "" {
        //     body := util.Struct2Map(i)
        //     url := "http://" + util.GetShopUrl() + "/data/api-d/device/syncDevToCloud"
        //     header := map[string]string{
        //         "Authorization": token,
        //     }
        //     data, err := util.DoPostRequest(url, util.CONTENT_TYPE_JSON, body, nil, header, 10*time.Second)
        //     if err != nil {
        //         logger.Error("send devInfo to cloud err:", err)
        //         return
        //     }
        //     logger.Debug("syncDevToCloud result:", string(data))
        //     var result bhomedbapi.Result
        //     err = json.Unmarshal(data, &result)
        //     if err != nil {
        //         logger.Error("unmarshal err:", err)
        //         return
        //     }
        //     if result.Success {
        //         lstSync = &i
        //     } else {
        //         logger.Error("syncDevToCloud result:", result)
        //     }
        // }
        //查看是否有管理节点管理着此台设备
        syncToDevManager(i)
@@ -289,7 +289,7 @@
    return nil
}
//计算持续时长
// 计算持续时长
func timeSpan(startTime time.Time) string {
    sp := time.Since(startTime)
    day := strconv.Itoa(int(sp.Hours() / 24))      //天数