| | |
| | | LastDirection string // 最后一次抓拍 |
| | | MaxAge int // 年龄 |
| | | MinAge int // 年龄 |
| | | StartTime int64 // 起始时间 |
| | | Task *db.ModelTask |
| | | } |
| | | |
| | |
| | | m.AlarmType = task.AlarmType |
| | | m.KeyPersonType = task.PersonType |
| | | m.PersonLabel = task.PersonLabel |
| | | m.StartTime = task.BeginTime.Unix() |
| | | |
| | | for _, v := range task.Rules { |
| | | if v.Alias == "disappearTime" { |
| | |
| | | m.LastDirection = val |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | logger.Debugf("DisappearModel init finish ...task id:%s, name:%s, rule:%+v\n", task.ID, task.Name, m) |
| | | logger.Debugf("DisappearModel init finish ...task id:%s, name:%s, rule:%+v", task.ID, task.Name, m) |
| | | |
| | | if m.DisappearTime == 0 { |
| | | logger.Warnf("invalid parameters. task id:%s, name:%s\n", task.ID, task.Name) |
| | | logger.Warnf("invalid parameters. task id:%s, name:%s", task.ID, task.Name) |
| | | return errors.New("invalid parameters") |
| | | } |
| | | |
| | | return nil |
| | | } |
| | | |
| | | type PersonInfo struct { |
| | | DocumentNumber string `json:"document_number"` |
| | | CommunityId string `json:"community_id"` |
| | | OrgId string `json:"org_id"` |
| | | PersonName string `json:"person_name"` |
| | | IdCard string `json:"id_card"` |
| | | LastAppearanceTime int64 `json:"last_appearance_time"` |
| | | LastDirection string `json:"last_direction"` |
| | | LastLocation string `json:"last_location"` |
| | | } |
| | | |
| | | func (m *DisappearModel) Run() error { |
| | | results := make([]*db.ModelTaskResults, 0) |
| | | var ageFilter, labelFilter, keyFilter, lastFilter []PersonInfo |
| | | |
| | | if m.MinAge == 0 && m.PersonLabel == "" && m.KeyPersonType == "" { |
| | | err := db.GetDB().Raw(` |
| | | SELECT |
| | | s.document_number, |
| | | s.community_id, |
| | | s.org_id, |
| | | p.person_name, |
| | | p.id_card, |
| | | s.last_appearance_time, |
| | | s.last_direction, |
| | | s.last_location |
| | | FROM |
| | | snapshot_count_summary AS s |
| | | JOIN person AS p ON p.id = s.document_number |
| | | WHERE |
| | | s.last_appearance_time > ? |
| | | `, m.StartTime).Scan(&lastFilter).Error |
| | | if err != nil { |
| | | logger.Warnf(err.Error()) |
| | | } |
| | | |
| | | if len(lastFilter) == 0 { |
| | | return fmt.Errorf("no results found that match the condition %+v", m.Task.Rules) |
| | | } |
| | | |
| | | logger.Debugf("task %s match default result %d", m.Task.Name, len(lastFilter)) |
| | | } |
| | | |
| | | if m.MinAge > 0 { |
| | | err := db.GetDB().Raw(` |
| | |
| | | s.community_id, |
| | | s.org_id, |
| | | p.person_name, |
| | | p.id_card , |
| | | p.id_card, |
| | | s.last_appearance_time, |
| | | s.last_direction, |
| | | s.last_location |
| | | s.last_location |
| | | FROM |
| | | snapshot_count_summary AS s |
| | | JOIN person AS p ON p.id = s.document_number |
| | | WHERE |
| | | s.STATUS = 'resident' |
| | | AND p.id_card != "" |
| | | s.last_appearance_time > ? |
| | | AND p.id_card != "" |
| | | AND TIMESTAMPDIFF( |
| | | YEAR, |
| | | STR_TO_DATE( CASE WHEN LENGTH( id_card ) = 18 THEN SUBSTRING( id_card, 7, 8 ) ELSE NULL END, '%Y%m%d' ), |
| | | CURDATE( ) >= ? |
| | | AND TIMESTAMPDIFF( |
| | | CURDATE( ) |
| | | ) >= ? |
| | | AND TIMESTAMPDIFF( |
| | | YEAR, |
| | | STR_TO_DATE( CASE WHEN LENGTH( id_card ) = 18 THEN SUBSTRING( id_card, 7, 8 ) ELSE NULL END, '%Y%m%d' ), |
| | | CURDATE( ) <= ? |
| | | `, m.MinAge, m.MaxAge).Scan(&ageFilter).Error |
| | | CURDATE( ) |
| | | ) <= ? |
| | | `, m.StartTime, m.MinAge, m.MaxAge).Scan(&ageFilter).Error |
| | | if err != nil { |
| | | logger.Warnf(err.Error()) |
| | | } |
| | |
| | | return fmt.Errorf("no results found that match the age condition %s - %s", m.MinAge, m.MaxAge) |
| | | } |
| | | |
| | | logger.Debugf("match age result %d", len(ageFilter)) |
| | | logger.Debugf("task %s match age result %d", m.Task.Name, len(ageFilter)) |
| | | } |
| | | |
| | | if m.PersonLabel != "" { |
| | |
| | | JOIN person AS p ON p.id = s.document_number |
| | | JOIN person_label AS l ON p.id = l.person_id |
| | | WHERE |
| | | l.label_id IN ? |
| | | `, labels).Scan(&labelFilter).Error |
| | | s.last_appearance_time > ? |
| | | AND l.label_id IN ? |
| | | `, m.StartTime, labels).Scan(&labelFilter).Error |
| | | if err != nil { |
| | | logger.Warnf(err.Error()) |
| | | } |
| | |
| | | return fmt.Errorf("no results found that match the label condition %s", m.PersonLabel) |
| | | } |
| | | |
| | | logger.Debugf("match label result %d", len(labelFilter)) |
| | | logger.Debugf("task %s match label result %d", m.Task.Name, len(labelFilter)) |
| | | } |
| | | |
| | | // 合并一下条件 |
| | |
| | | JOIN person AS p ON p.id = s.document_number |
| | | JOIN key_person AS k ON k.id_card = p.id_card |
| | | WHERE |
| | | s.key_status = 1 |
| | | s.last_appearance_time > ? |
| | | AND s.key_status = 1 |
| | | AND p.id_card != "" |
| | | AND k.person_type IN ? |
| | | `, keyTypes).Scan(&keyFilter).Error |
| | | `, m.StartTime, keyTypes).Scan(&keyFilter).Error |
| | | if err != nil { |
| | | logger.Warnf(err.Error()) |
| | | } |
| | | |
| | | logger.Debugf("match key person result %d", len(keyFilter)) |
| | | logger.Debugf("task %s match key person result %d", m.Task.Name, len(keyFilter)) |
| | | |
| | | if len(lastFilter) > 0 { |
| | | lastFilter = intersectPersonInfo(lastFilter, keyFilter) |
| | | } else { |
| | | lastFilter = keyFilter |
| | | } |
| | | } |
| | | |
| | | if len(lastFilter) > 0 { |
| | | lastFilter = intersectPersonInfo(lastFilter, keyFilter) |
| | | } else { |
| | | lastFilter = keyFilter |
| | | } |
| | | logger.Debugf("task %s last result %d", m.Task.Name, len(lastFilter)) |
| | | |
| | | logger.Debugf("last result %d", len(lastFilter)) |
| | | var personIds = make(map[string]struct{}, 0) |
| | | for _, p := range lastFilter { |
| | | if len(m.AreaIds) > 0 { |
| | | _, o1 := m.AreaIds[p.CommunityId] |
| | | _, o2 := m.AreaIds[p.OrgId] |
| | | if !o1 && !o2 { |
| | | if !o1 { |
| | | continue |
| | | } |
| | | } |
| | |
| | | if isOlderThanGivenHours(p.LastAppearanceTime, m.DisappearTime) { |
| | | result := &db.ModelTaskResults{ |
| | | Title: m.Task.Name, |
| | | Event: m.Task.Name, |
| | | Event: m.eventFormat(p.LastAppearanceTime, p.LastDirection), |
| | | ModelID: m.Task.ModelID, |
| | | ModelTaskID: m.Task.ID, |
| | | CommunityId: p.CommunityId, |
| | |
| | | FirstPersonID: p.DocumentNumber, |
| | | } |
| | | |
| | | // 同一个人报警一次 |
| | | if _, ok := personIds[p.DocumentNumber]; ok { |
| | | continue |
| | | } else { |
| | | personIds[p.DocumentNumber] = struct{}{} |
| | | } |
| | | |
| | | results = append(results, result) |
| | | } |
| | | } |
| | | |
| | | logger.Debugf("task %s last filter result %d", m.Task.Name, len(results)) |
| | | return service.SaveTaskResults(results) |
| | | } |
| | | |
| | | func (m *DisappearModel) KeepAlive() error { |
| | | db.GetDB().Model(m.Task).Where("id = ?", m.Task.ID).Update("last_run_time", time.Now()) |
| | | return nil |
| | | } |
| | | |
| | | func (m *DisappearModel) Shutdown() error { |
| | |
| | | // 判断时间戳是否早于该时间 |
| | | return timestampTime.Before(timeThreshold) |
| | | } |
| | | |
| | | func (m *DisappearModel) eventFormat(lastAppearTime int64, lastDirection string) string { |
| | | lastTime := time.Unix(lastAppearTime, 0) |
| | | currentTime := time.Now() |
| | | |
| | | duration := currentTime.Sub(lastTime) |
| | | |
| | | // 输出时间差的小时数 |
| | | var durationStr = "小时" |
| | | hours := duration.Hours() |
| | | if hours > 24 { |
| | | hours = hours / 24 |
| | | durationStr = "天" |
| | | } |
| | | |
| | | var direction string |
| | | var reverse = "未出现" |
| | | if lastDirection == "in" { |
| | | direction = "进" |
| | | reverse = "未出" |
| | | } else if lastDirection == "out" { |
| | | direction = "出" |
| | | reverse = "未归" |
| | | } |
| | | |
| | | return fmt.Sprintf("%s%s,持续%.1f%s%s", lastTime.Format("2006-01-02 15:04:05"), direction, hours, durationStr, reverse) |
| | | } |