From de37adb6dec5e9da70f9cc11b234176ee6fda986 Mon Sep 17 00:00:00 2001
From: sunty <1172534965@qq.com>
Date: 星期五, 24 五月 2024 21:04:39 +0800
Subject: [PATCH] 添加布控模块,合并person_status和snapshot_count_summary数据库等

---
 db/repository.go          |  158 ++++++-----
 cache/device.go           |   22 +
 data/prepare.go           |   31 ++
 api/analysisApi/server.go |   16 +
 go.mod                    |    5 
 rule/service.go           |  119 ++++----
 config/app.yaml           |    5 
 rule/identityEngine.go    |   80 ++++++
 config/config.go          |    7 
 task/service.go           |   72 +++++
 task/tool.go              |   28 ++
 main.go                   |   40 ++
 rule/engine.go            |  122 +++++++--
 task/engine.go            |   43 +++
 14 files changed, 579 insertions(+), 169 deletions(-)

diff --git a/api/analysisApi/server.go b/api/analysisApi/server.go
new file mode 100644
index 0000000..1192088
--- /dev/null
+++ b/api/analysisApi/server.go
@@ -0,0 +1,16 @@
+package analysisApi
+
+import (
+	"basic.com/CloudAI/protomsg.git/analysis"
+	"context"
+	"ruleModelEngine/task"
+)
+
+type Server struct {
+	analysis.UnimplementedAnalysisServiceServer
+}
+
+func (s *Server) GetCodeList(ctx context.Context, params *analysis.SendAnalysisRequest) (*analysis.EmptyResponse, error) {
+	go task.TaskAnalysisService(params.DocumentNumber)
+	return &analysis.EmptyResponse{}, nil
+}
diff --git a/cache/device.go b/cache/device.go
new file mode 100644
index 0000000..9140696
--- /dev/null
+++ b/cache/device.go
@@ -0,0 +1,22 @@
+package cache
+
+import (
+	"basic.com/valib/logger.git"
+	"ruleModelEngine/db"
+)
+
+var Device = make(map[string]db.Device)
+
+func DeviceCacheInit() error {
+	var err error
+	var Devices []db.Device
+	Devices, err = db.GetDeviceData()
+	if err != nil {
+		logger.Error("GetDeviceData", err)
+		return err
+	}
+	for _, device := range Devices {
+		Device[device.DeviceCode] = device
+	}
+	return nil
+}
diff --git a/config/app.yaml b/config/app.yaml
index f740e99..222fd03 100644
--- a/config/app.yaml
+++ b/config/app.yaml
@@ -23,4 +23,7 @@
   level: -1
   maxSize: 128
   maxBackups: 30
-  maxAge: 15
\ No newline at end of file
+  maxAge: 15
+api:
+  host: 192.168.20.115
+  port: 4101
\ No newline at end of file
diff --git a/config/config.go b/config/config.go
index ed8e823..f6ab35f 100644
--- a/config/config.go
+++ b/config/config.go
@@ -38,10 +38,16 @@
 	LogLevel string `mapstructure: "logLevel"`
 }
 
+type api struct {
+	Host string `mapstructure: "host"`
+	Port string `mapstructure: "port"`
+}
+
 var LogConf = &LogConfig{}
 var DataBase = &database{}
 var Elastic = &elastic{}
 var App = &app{}
+var Api = &api{}
 var LogBasePath string
 var LogLevel int
 
@@ -57,6 +63,7 @@
 	viper.UnmarshalKey("elastic", Elastic)
 	viper.UnmarshalKey("database", DataBase)
 	viper.UnmarshalKey("app", App)
+	viper.UnmarshalKey("api", Api)
 	viper.UnmarshalKey("log", LogConf)
 	logger.SetLevel(LogConf.Level)
 	if viper.GetString("LogBasePath") != "" {
diff --git a/data/prepare.go b/data/prepare.go
index ac6cf9a..8b0f675 100644
--- a/data/prepare.go
+++ b/data/prepare.go
@@ -7,10 +7,14 @@
 )
 
 // 璁$畻鎶撴媿澶╂暟
-func CalculateCaptureDays(details []db.CaptureDetail) int {
+func CalculateCaptureDays(details []db.CaptureDetail) (int, int) {
 	// 浣跨敤 map 鏉ュ瓨鍌ㄦ瘡澶╂槸鍚︽湁鎶撴媿璁板綍
 	captureMap := make(map[string]bool)
-	for _, detail := range details {
+	//pointDate := ""
+	//pointTime := ""
+	//pointDirection := ""
+	overnightCount := 0
+	for i, detail := range details {
 		// 瑙f瀽鎶撴媿鏃ユ湡
 		layout := "2006-01-02 15:04:05"
 		captureTime, err := time.Parse(layout, detail.CaptureDate)
@@ -18,10 +22,27 @@
 			fmt.Println("瑙f瀽鎶撴媿鏃ユ湡鏃跺嚭閿�:", err)
 			continue
 		}
+		//fmt.Println(captureTime, detail.Direction)
 		// 鑾峰彇鏃ユ湡閮ㄥ垎
 		date := captureTime.Format("2006-01-02")
+		//time := captureTime.Format("15:04:05")
 		// 鍦� map 涓爣璁拌繖涓�澶╂湁鎶撴媿璁板綍
 		captureMap[date] = true
+		if i == len(details)-1 {
+			break
+		}
+
+		// 绗竴涓獙璇佹潯浠讹細褰撳墠涓� in锛屾椂闂村湪涓嬪崍 16 鐐逛互鍚�
+		currTime, _ := time.Parse("2006-01-02 15:04:05", detail.CaptureDate)
+		if detail.Direction == "in" && currTime.Hour() >= 16 {
+			// 绗簩涓獙璇佹潯浠讹細涓嬩竴涓负 out锛屾椂闂村湪涓婂崍 5 鐐逛箣鍚� 12 鐐逛箣鍓�
+			nextDetail := details[i+1]
+			nextTime, _ := time.Parse("2006-01-02 15:04:05", nextDetail.CaptureDate)
+			nextDay := nextTime.AddDate(0, 0, -1).Format("2006-01-02")
+			if nextDetail.Direction == "out" && nextTime.Hour() >= 5 && nextTime.Hour() < 12 && nextDay == detail.CaptureDate[:10] {
+				overnightCount++
+			}
+		}
 	}
 
 	// 缁熻鏈夋姄鎷嶈褰曠殑澶╂暟
@@ -30,7 +51,7 @@
 		captureDays++
 	}
 
-	return captureDays
+	return captureDays, overnightCount
 }
 
 // 璁剧疆鐘舵��
@@ -103,7 +124,7 @@
 		person, ok := statusIndex[info.DocumentNumber]
 		if !ok {
 			// 涓嶅瓨鍦ㄥ搴旂殑浜哄憳鐘舵�佷负鏂版暟鎹�
-			filteredInfos = append(filteredInfos, db.PersonStatus{CommunityID: communityID, DocumentNumber: info.DocumentNumber, Status: info.Status, FrequentAddress: info.FrequentAddress})
+			filteredInfos = append(filteredInfos, db.PersonStatus{OrgId: info.OrgId, CommunityID: communityID, DocumentNumber: info.DocumentNumber, Status: info.Status, FrequentAddress: info.FrequentAddress})
 			continue
 		}
 
@@ -114,7 +135,7 @@
 		}
 
 		// 鏇存柊杩囨护鍚庣殑淇℃伅鍒楄〃
-		filteredInfos = append(filteredInfos, db.PersonStatus{CommunityID: communityID, DocumentNumber: info.DocumentNumber, Status: info.Status, FrequentAddress: info.FrequentAddress})
+		filteredInfos = append(filteredInfos, db.PersonStatus{OrgId: info.OrgId, CommunityID: communityID, DocumentNumber: info.DocumentNumber, Status: info.Status, FrequentAddress: info.FrequentAddress})
 
 	}
 
diff --git a/db/repository.go b/db/repository.go
index 5cdc1d8..1353cf1 100644
--- a/db/repository.go
+++ b/db/repository.go
@@ -8,12 +8,8 @@
 
 // 鏌ヨ灏忓尯琛�
 func GetCommunityIDs() ([]string, error) {
-	db, err := ConnectDB()
-	if err != nil {
-		return nil, err
-	}
-
 	// 鏌ヨ鏁版嵁
+	var db = DB
 	var communityIDs []string
 	result := db.Table("domain_unit").Where("domainType = ?", 1).Pluck("id", &communityIDs)
 	if result.Error != nil {
@@ -23,13 +19,33 @@
 	return communityIDs, nil
 }
 
+// 鏌ヨ璁惧琛�
+func GetDeviceData() ([]Device, error) {
+	// 鏌ヨ鏁版嵁
+	var db = DB
+	var device []Device
+	result := db.Table("device").Where("communityID != ?", "").Find(&device)
+	if result.Error != nil {
+		return nil, result.Error
+	}
+
+	return device, nil
+}
+
 // 鏌ヨ鍏ㄩ儴鏁版嵁
-func GetAllData() ([]PersonnelStatusRule, error) {
-	db, err := ConnectDB()
-	if err != nil {
+func GetAllTaskData() ([]Task, error) {
+	var db = DB
+	var task []Task
+	if err := db.Find(&task).Error; err != nil {
 		return nil, err
 	}
 
+	return task, nil
+}
+
+// 鏌ヨ鍏ㄩ儴鏁版嵁
+func GetAllData() ([]PersonnelStatusRule, error) {
+	var db = DB
 	var rules []PersonnelStatusRule
 	if err := db.Find(&rules).Error; err != nil {
 		return nil, err
@@ -40,18 +56,14 @@
 
 // 鏌ヨ浣忔埛鏃堕棿鏁版嵁
 func GetResidentData(status, communityID string) ([]Resident, error) {
-	db, err := ConnectDB()
-	if err != nil {
-		return nil, err
-	}
-
 	var residents []Resident
-
+	//var db = DB.Debug()
+	var db = DB
 	// 鎵ц鏌ヨ
-	rows, err := db.Table("person_status").
-		Select("person_status.documentNumber", "person_status.communityID", "snapshot_count_summary.last_appearance_time", "snapshot_count_summary.created_at").
-		Joins("INNER JOIN snapshot_count_summary ON person_status.documentNumber = snapshot_count_summary.document_number AND person_status.communityID = snapshot_count_summary.community_id").
-		Where("person_status.status = ? AND person_status.communityID = ?", status, communityID).
+	rows, err := db.Table("snapshot_count_summary").
+		Select("document_number", "community_id", "last_appearance_time", "created_at").
+		Where("status = ? AND community_id = ?", status, communityID).
+		//Where("snapshot_count_summary.created_at is not null").
 		Rows()
 	if err != nil {
 		return nil, err
@@ -61,10 +73,12 @@
 	// 閬嶅巻鏌ヨ缁撴灉
 	for rows.Next() {
 		var resident Resident
-		err := rows.Scan(&resident.DocumentNumber, &resident.CommunityID, &resident.LastAppearanceTime, &resident.CreateAt)
+		err := rows.Scan(&resident.DocumentNumber, &resident.CommunityId, &resident.LastAppearanceTime, &resident.CreateAt)
 		if err != nil {
+			logger.Error("err: ", err)
 			return nil, err
 		}
+		//fmt.Println("resident111: ", resident)
 		residents = append(residents, resident)
 	}
 	if err := rows.Err(); err != nil {
@@ -76,11 +90,7 @@
 
 // 鏌ヨ浜虹墿灞炴��
 func GetDBPersonStatusData(id string) ([]PersonStatus, error) {
-	db, err := ConnectDB()
-	if err != nil {
-		return nil, err
-	}
-
+	var db = DB
 	// 鏌ヨ鏁版嵁
 	var personStatusList []PersonStatus
 	if err := db.Table("person_status").
@@ -93,37 +103,44 @@
 	return personStatusList, nil
 }
 
-// 鏍规嵁绀惧尯id鍜屼綇鎴峰睘鎬ф煡璇綇鎴锋。妗堢紪鍙�
-func GetDocNumberFromPersonStatus(id, status string) ([]string, error) {
-	db, err := ConnectDB()
-	if err != nil {
-		return nil, err
-	}
-
+// 鏌ヨ浜虹墿骞撮緞
+func GetAgeById(id string) (int, error) {
+	var db = DB
 	// 鏌ヨ鏁版嵁
-	var personStatusList []PersonStatus
-	if err := db.Table("person_status").
-		Select("documentNumber, status, frequentAddress").
-		Where("communityID = ? AND status = ?", id, status).
-		Find(&personStatusList).Error; err != nil {
-		return nil, err
+	var age int
+	if err := db.Table("dbtablepersons").
+		Select("age").
+		Where("id = ?", id).
+		Find(&age).Error; err != nil {
+		return 0, err
 	}
 
-	docNum := make([]string, 0)
-	for _, ps := range personStatusList {
-		docNum = append(docNum, ps.DocumentNumber)
-	}
-
-	return docNum, nil
+	return age, nil
 }
+
+//// 鏍规嵁绀惧尯id鍜屼綇鎴峰睘鎬ф煡璇綇鎴锋。妗堢紪鍙�
+//func GetDocNumberFromPersonStatus(id, status string) ([]string, error) {
+//	var db = DB
+//	// 鏌ヨ鏁版嵁
+//	var personStatusList []PersonStatus
+//	if err := db.Table("person_status").
+//		Select("documentNumber, status, frequentAddress").
+//		Where("communityID = ? AND status = ?", id, status).
+//		Find(&personStatusList).Error; err != nil {
+//		return nil, err
+//	}
+//
+//	docNum := make([]string, 0)
+//	for _, ps := range personStatusList {
+//		docNum = append(docNum, ps.DocumentNumber)
+//	}
+//
+//	return docNum, nil
+//}
 
 // 鏌ヨ浜虹墿韬唤灞炴�ц〃
 func GetLabelManageIdentity(IdentityType int) ([]LabelManage, error) {
-	db, err := ConnectDB()
-	if err != nil {
-		return nil, err
-	}
-
+	var db = DB
 	// 鏌ヨ鏁版嵁
 	var labelManageIdentity []LabelManage
 	if err := db.Table("label_manage").
@@ -136,13 +153,23 @@
 	return labelManageIdentity, nil
 }
 
+// 鏍规嵁dbtablepersons琛╥d鏌ヨ鐩爣妗f骞撮緞
+func QueryAgeById(id string) (int, error) {
+	var db = DB
+	var age int
+	err := db.Table("dbtablepersons").
+		Select("age").
+		Where("id = ?", id).
+		Scan(&age).Error
+	if err != nil {
+		return 0, err
+	}
+	return age, nil
+}
+
 // UpdatePersonInfo 鏇存柊鎴栨彃鍏ュ涓汉鍛樹俊鎭�
 func UpdateMoveInout(personsMoveInout []MoveInout) error {
-	// 鏁版嵁搴撹繛鎺ヤ俊鎭�
-	db, err := ConnectDB()
-	if err != nil {
-		return err
-	}
+	var db = DB
 	// 閬嶅巻浜哄憳淇℃伅
 	for _, personMoveInout := range personsMoveInout {
 
@@ -158,6 +185,7 @@
 
 		// 濡傛灉璁板綍瀛樺湪锛屽垯鏇存柊
 		if existingPerson.DocumentNumber != "" {
+			//fmt.Println("existingPerson.DocumentNumber: ", existingPerson.DocumentNumber)
 			if existingPerson.Status != "Verified" {
 				err := db.Model(&MoveInout{}).
 					Where("document_number = ? AND community_id = ?", personMoveInout.DocumentNumber, personMoveInout.CommunityID).
@@ -180,7 +208,9 @@
 			}
 		} else {
 			// 濡傛灉璁板綍涓嶅瓨鍦紝鍒欐彃鍏ユ柊璁板綍
-			err := db.Create(&personsMoveInout).Error
+			//fmt.Println("鎻掑叆璁板綍澶辫触")
+			//fmt.Println("data", &personMoveInout)
+			err := db.Create(&personMoveInout).Error
 			if err != nil {
 				return err
 			}
@@ -193,11 +223,7 @@
 
 // UpdatePersonInfo 鏇存柊鎴栨彃鍏ュ涓汉鍛樿韩浠戒俊鎭�
 func UpdateDBPersonLabel(personsIdentity []Identity) error {
-	// 鏁版嵁搴撹繛鎺ヤ俊鎭�
-	db, err := ConnectDB()
-	if err != nil {
-		return err
-	}
+	var db = DB
 	// 閬嶅巻浜哄憳淇℃伅
 	for _, personIdentity := range personsIdentity {
 
@@ -247,17 +273,13 @@
 
 // UpdatePersonInfo 鏇存柊鎴栨彃鍏ュ涓汉鍛樹俊鎭�
 func UpdatePersonInfo(persons []PersonStatus, communityID string) error {
-	// 鏁版嵁搴撹繛鎺ヤ俊鎭�
-	db, err := ConnectDB()
-	if err != nil {
-		return err
-	}
+	var db = DB
 	// 閬嶅巻浜哄憳淇℃伅
 	for _, person := range persons {
 
 		// 妫�鏌ヨ褰曟槸鍚﹀瓨鍦�
 		var existingPerson PersonStatus
-		err := db.Where("documentNumber = ? AND communityID = ?", person.DocumentNumber, communityID).First(&existingPerson).Error
+		err := db.Where("document_number = ? AND community_id = ?", person.DocumentNumber, communityID).First(&existingPerson).Error
 		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
 			logger.Error("Query person error:", err, person.DocumentNumber, communityID)
 			//fmt.Println("asdasfasfasf")
@@ -268,10 +290,10 @@
 		// 濡傛灉璁板綍瀛樺湪锛屽垯鏇存柊
 		if existingPerson.DocumentNumber != "" {
 			err := db.Model(&PersonStatus{}).
-				Where("documentNumber = ? AND communityID = ?", person.DocumentNumber, communityID).
+				Where("document_number = ? AND community_id = ?", person.DocumentNumber, communityID).
 				Updates(map[string]interface{}{
-					"status":          person.Status,
-					"frequentAddress": person.FrequentAddress,
+					"status":           person.Status,
+					"frequent_address": person.FrequentAddress,
 				}).Error
 			if err != nil {
 				return err
diff --git a/go.mod b/go.mod
index d3cde2e..54341ae 100644
--- a/go.mod
+++ b/go.mod
@@ -11,6 +11,7 @@
 )
 
 require (
+	basic.com/CloudAI/protomsg.git v0.0.0-20240523091240-77f661e9c66f // indirect
 	basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3 // indirect
 	filippo.io/edwards25519 v1.1.0 // indirect
 	github.com/fsnotify/fsnotify v1.7.0 // indirect
@@ -39,8 +40,8 @@
 	golang.org/x/sys v0.19.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be // indirect
-	google.golang.org/grpc v1.63.2 // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
+	google.golang.org/grpc v1.64.0 // indirect
+	google.golang.org/protobuf v1.34.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )
diff --git a/main.go b/main.go
index b03808f..1fad01b 100644
--- a/main.go
+++ b/main.go
@@ -1,7 +1,16 @@
 package main
 
 import (
+	"basic.com/CloudAI/protomsg.git/analysis"
+	"google.golang.org/grpc"
+	"net"
+	"ruleModelEngine/api/analysisApi"
+	"ruleModelEngine/cache"
 	"ruleModelEngine/config"
+	"ruleModelEngine/db"
+
+	//"ruleModelEngine/task"
+
 	//"annotation_service/db"
 	"basic.com/valib/logger.git"
 	"flag"
@@ -16,7 +25,33 @@
 	var logFile = config.LogConf.Path + "annotation_service.log"
 	logger.InitLogger(logFile, config.LogConf.Level, config.LogConf.MaxSize, config.LogConf.MaxBackups, config.LogConf.MaxAge)
 	logger.Info("loginit success !")
+	dbErr := db.ConnectDB()
+	if dbErr != nil {
+		logger.Error("鏁版嵁搴撹繛鎺ュけ璐�", dbErr)
+		return
+	}
+	logger.Info("ConnectDB success !")
+	cacheErr := cache.DeviceCacheInit()
+	if cacheErr != nil {
+		logger.Error("璁惧琛ㄧ紦瀛樺け璐�", cacheErr)
+		return
+	}
+	logger.Info("cache device success !")
+}
 
+func initApiServer() {
+	ln, err := net.Listen("tcp", config.Api.Host+":"+config.Api.Port)
+	if err != nil {
+		logger.Fatal("grpc server init error: %v", err.Error())
+		//panic(fmt.Sprintf("grpc server init error: %v", err.Error()))
+	}
+	s := grpc.NewServer()
+	analysis.RegisterAnalysisServiceServer(s, &analysisApi.Server{})
+	err = s.Serve(ln)
+	if err != nil {
+		logger.Fatal("grpc server init error: %v", err.Error())
+		//panic(fmt.Sprintf("grpc server init error: %v", err.Error()))
+	}
 }
 
 func main() {
@@ -28,11 +63,12 @@
 		logger.Info("Executing immediately...")
 		rule.ExecuteTask()
 	}
-
+	//task.TaskAnalysisService("3407b20e-6343-4832-88fa-a8e986552532")
+	//go initApiServer()
+	//return
 	now := time.Now()
 	next := time.Date(now.Year(), now.Month(), now.Day()+1, 1, 0, 0, 0, now.Location())
 	duration := next.Sub(now)
-
 	timer := time.NewTimer(duration)
 	logger.Info("The program has started and will execute at one o'clock in the early morning every night.")
 	for {
diff --git a/rule/engine.go b/rule/engine.go
index 9409760..8bbb953 100644
--- a/rule/engine.go
+++ b/rule/engine.go
@@ -2,7 +2,6 @@
 
 import (
 	"basic.com/valib/logger.git"
-	"errors"
 	"fmt"
 	"math"
 	"ruleModelEngine/db"
@@ -56,11 +55,13 @@
 				status = "Confirmed"
 			}
 		}
-
+		if status == "" {
+			continue
+		}
 		//fmt.Println("status: ", status)
 		moveInout = append(moveInout, db.MoveInout{
 			DocumentNumber: resident.DocumentNumber,
-			CommunityID:    resident.CommunityID,
+			CommunityID:    resident.CommunityId,
 			MoveInDate:     createdAt,           // 瀛樺偍骞存湀鏃�
 			MoveOutDate:    &lastAppearanceDate, // 瀛樺偍骞存湀鏃�
 			MoveType:       moveType,
@@ -71,18 +72,18 @@
 	return moveInout
 }
 
-func ProcessRuleEngine(personInfos []db.CaptureInfo, ruleInfo []db.PersonnelStatusRule, cmmunityID string) (bool, error) {
-	ruleInfoCheck := checkRuleValidity(ruleInfo)
-	if ruleInfoCheck == false {
-		logger.Error("瑙勫垯搴撴暟鎹紓甯�")
-		return false, errors.New("瑙勫垯搴撴暟鎹紓甯�")
-	}
-	fmt.Println("娓呮礂鍓嶏細 ", len(personInfos))
-	logger.Info("瑙勫垯绠楁硶鎵ц瀹屾瘯锛侊紒锛�")
-	return true, nil
-}
+//func ProcessRuleEngine(personInfos []db.CaptureInfo, ruleInfo []db.PersonnelStatusRule, cmmunityID string) (bool, error) {
+//	ruleInfoCheck := checkRuleValidity(ruleInfo)
+//	if ruleInfoCheck == false {
+//		logger.Error("瑙勫垯搴撴暟鎹紓甯�")
+//		return false, errors.New("瑙勫垯搴撴暟鎹紓甯�")
+//	}
+//	fmt.Println("娓呮礂鍓嶏細 ", len(personInfos))
+//	logger.Info("瑙勫垯绠楁硶鎵ц瀹屾瘯锛侊紒锛�")
+//	return true, nil
+//}
 
-func CreateLinearModel(personInfos []db.CaptureInfo, communityID string, threshold float64, validDays int) ([]db.Identity, []db.CaptureInfo) {
+func CreateLinearModel(personInfos []db.CaptureInfo, communityID string, threshold float64, validDays int, labelId int) ([]db.Identity, []db.CaptureInfo) {
 	identity := make([]db.Identity, 0)
 	captureInfo := make([]db.CaptureInfo, 0)
 	for _, info := range personInfos {
@@ -116,7 +117,7 @@
 				identity = append(identity, db.Identity{
 					CommunityID:    communityID,
 					DocumentNumber: info.DocumentNumber,
-					LabelId:        3,
+					LabelId:        labelId,
 					ExpireTime:     GetCurrentDateAddDaysTimestamp(validDays)})
 				continue
 			}
@@ -149,26 +150,32 @@
 	fmt.Println(addrData)
 }
 
-func CreateProcessModel(personInfos []db.CaptureInfo, days int) {
-	timeTOIndex := getIndexForTime(24 * 60)
-	dateTOIndex := getIndexForDate(days)
-	//fmt.Println(dateTOIndex)
-	inModelMatrix := make([][]int, days)
-	for i := range inModelMatrix {
-		inModelMatrix[i] = make([]int, 24*60)
+func CreateProcessModel(personInfos []db.CaptureInfo, days int, communityID string, labelManage []db.LabelManage) []db.Identity {
+	labelIndexMap := make(map[string]int)
+	for index, labelManageInfo := range labelManage {
+		labelIndexMap[labelManageInfo.Name] = index
 	}
-	outModelMatrix := make([][]int, days)
-	for i := range outModelMatrix {
-		outModelMatrix[i] = make([]int, 24*60)
-	}
+	identity := make([]db.Identity, 0)
 	for _, info := range personInfos {
+		timeTOIndex := getIndexForTime(24 * 60)
+		dateTOIndex := getIndexForDate(days)
+		//fmt.Println(dateTOIndex)
+		inModelMatrix := make([][]int, days)
+		for i := range inModelMatrix {
+			inModelMatrix[i] = make([]int, 24*60)
+		}
+		outModelMatrix := make([][]int, days)
+		for i := range outModelMatrix {
+			outModelMatrix[i] = make([]int, 24*60)
+		}
 		//fmt.Println("info: ", info)
 		for _, captureInfo := range info.CaptureDetail {
 			captrueDateTime := captureInfo.CaptureDate
 			dateTimeObj, err := time.Parse("2006-01-02 15:04:05", captrueDateTime)
 			if err != nil {
 				logger.Error("Parse time error", err)
-				return
+				continue
+				//return n/**/il, err
 			}
 			if isWeekend(dateTimeObj) {
 				continue
@@ -184,9 +191,66 @@
 				continue
 			}
 		}
+		countMaxRows, colS, colE := CountMaxRows(outModelMatrix, 30, 30)
+		logger.Info("瑙勫緥鍑哄嫟鏃堕棿娈碉細", colS, colE, "\t娆℃暟: ", countMaxRows)
+		if countMaxRows >= 10 {
+			if info.Age <= 22 && info.Age >= 7 {
+				lIndex := labelIndexMap["瀛︾敓"]
+				identity = append(identity, db.Identity{
+					CommunityID:    communityID,
+					DocumentNumber: info.DocumentNumber,
+					LabelId:        labelManage[lIndex].Id,
+					ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+			} else if info.Age >= 23 && info.Age <= 60 {
+				lIndex := labelIndexMap["涓婄彮鏃�"]
+				identity = append(identity, db.Identity{
+					CommunityID:    communityID,
+					DocumentNumber: info.DocumentNumber,
+					LabelId:        labelManage[lIndex].Id,
+					ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+			} else if info.Age > 60 {
+				lIndex := labelIndexMap["绂婚��浼戜汉鍛�"]
+				identity = append(identity, db.Identity{
+					CommunityID:    communityID,
+					DocumentNumber: info.DocumentNumber,
+					LabelId:        labelManage[lIndex].Id,
+					ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+			}
+			//fmt.Println("涓婄彮鏃�", info.DocumentNumber, info.Age, countMaxRows, colS, colE)
+		} else {
+			countMaxRows, colS, colE := CountMaxRows(inModelMatrix, 30, 30)
+			logger.Info("瑙勫緥鍑哄嫟鏃堕棿娈碉細", colS, colE, "\t娆℃暟: ", countMaxRows)
+			if countMaxRows >= 10 {
+				if info.Age <= 22 && info.Age >= 7 {
+					lIndex := labelIndexMap["瀛︾敓"]
+					identity = append(identity, db.Identity{
+						CommunityID:    communityID,
+						DocumentNumber: info.DocumentNumber,
+						LabelId:        labelManage[lIndex].Id,
+						ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+				} else if info.Age >= 23 && info.Age <= 60 {
+					lIndex := labelIndexMap["涓婄彮鏃�"]
+					identity = append(identity, db.Identity{
+						CommunityID:    communityID,
+						DocumentNumber: info.DocumentNumber,
+						LabelId:        labelManage[lIndex].Id,
+						ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+				} else if info.Age > 60 {
+					lIndex := labelIndexMap["绂婚��浼戜汉鍛�"]
+					identity = append(identity, db.Identity{
+						CommunityID:    communityID,
+						DocumentNumber: info.DocumentNumber,
+						LabelId:        labelManage[lIndex].Id,
+						ExpireTime:     GetCurrentDateAddDaysTimestamp(labelManage[lIndex].ValidDays)})
+				}
+				//fmt.Println("涓婄彮鏃�", info.DocumentNumber, info.Age, countMaxRows, colS, colE)
+			}
+		}
+
+		//fmt.Println("outModelMatrix: ", outModelMatrix)
+		//fmt.Println("inModelMatrix: ", inModelMatrix)
 	}
-	fmt.Println(outModelMatrix)
-	fmt.Println(inModelMatrix)
+	return identity
 }
 
 // 璁$畻涓�闃跺鏁�
diff --git a/rule/identityEngine.go b/rule/identityEngine.go
new file mode 100644
index 0000000..ef2dd8c
--- /dev/null
+++ b/rule/identityEngine.go
@@ -0,0 +1,80 @@
+package rule
+
+import (
+	"math/rand"
+	"time"
+)
+
+// 婊戝潡缁勪欢-鍒濆鍖栧苟鎺у埗姒傜巼璧嬪��1鐨勪簩缁存暟缁�
+func initializeArrayWithProbability(rows, cols int, probability float64) [][]int {
+	array := make([][]int, rows)
+	rand.Seed(time.Now().UnixNano()) // 浣跨敤褰撳墠鏃堕棿浣滀负闅忔満鏁扮瀛�
+
+	for i := range array {
+		array[i] = make([]int, cols)
+		for j := range array[i] {
+			// 鐢熸垚0鍒�99涔嬮棿鐨勯殢鏈烘暟锛屽鏋滃皬浜庣瓑浜庢鐜�*100锛屽垯璧嬪�间负1
+			if rand.Intn(100) <= int(probability*100) {
+				array[i][j] = 1
+			}
+		}
+	}
+	return array
+}
+
+// 婊戝潡缁勪欢-缁熻婊戝姩绐楀彛鍐呭�间负1鐨勫厓绱犳暟閲�
+func countOnesInWindow(window [][]int) int {
+	count := 0
+	for _, row := range window {
+		for _, val := range row {
+			if val == 1 {
+				count++
+				break // 涓�鏃︽壘鍒颁竴涓厓绱犱负1锛岃烦鍑哄唴灞傚惊鐜�
+			}
+		}
+	}
+	return count
+}
+
+// 婊戝潡缁勪欢-缁熻婊戝姩绐楀彛鍐呰嚦灏戞湁涓�涓厓绱犱负1鐨勮鏁�
+func countRowsWithOneInWindow(window [][]int) int {
+	count := 0
+	for _, row := range window {
+		for _, val := range row {
+			if val == 1 {
+				count++
+				break // 涓�鏃︽壘鍒颁竴涓厓绱犱负1锛岃烦鍑哄唴灞傚惊鐜�
+			}
+		}
+	}
+	return count
+}
+
+// 婊戝潡缁勪欢-缁熻鏈�楂樿鏁颁互鍙婃粦鍧楀潗鏍�
+func CountMaxRows(modelMatrix [][]int, windowRows, windowCols int) (int, int, int) {
+	maxRowCountWindowCols := 0
+	maxRowCount := 0
+	// 缁熻婊戝姩绐楀彛鍐呭�间负1鐨勫厓绱犳暟閲忓拰鑷冲皯鏈変竴涓厓绱犱负1鐨勮鏁�
+	for i := 0; i <= 1440-windowCols; i++ {
+		window := make([][]int, windowRows)
+		for j := range window {
+			window[j] = modelMatrix[j][i : i+windowCols]
+		}
+		//onesCount := countOnesInWindow(window)
+		rowsWithOneCount := countRowsWithOneInWindow(window)
+		if rowsWithOneCount == 0 {
+			continue
+		}
+		if rowsWithOneCount > maxRowCount {
+			maxRowCount = rowsWithOneCount
+			maxRowCountWindowCols = i
+		}
+
+		//fmt.Printf("浠庣 %d 鍒楀埌绗� %d 鍒楋紝鍊间负1鐨勫厓绱犳暟閲忎负锛�%d锛岃嚦灏戞湁涓�涓厓绱犱负1鐨勮鏁颁负锛�%d\n", i, i+windowCols-1, onesCount, rowsWithOneCount)
+	}
+	//fmt.Println("documentNumber: ", info.DocumentNumber)
+	//fmt.Println("maxRowCount: ", maxRowCount)
+	//fmt.Println("maxRowCountWindowCols: ", maxRowCountWindowCols, maxRowCountWindowCols+windowCols-1)
+
+	return maxRowCount, maxRowCountWindowCols, maxRowCountWindowCols + windowCols - 1
+}
diff --git a/rule/service.go b/rule/service.go
index 4de8888..6294c83 100644
--- a/rule/service.go
+++ b/rule/service.go
@@ -7,67 +7,28 @@
 	"ruleModelEngine/db"
 )
 
-//func PrintFilteredPersonnelInfo(filteredPersonnelInfo []db.PersonnelInfo) {
-//	for _, pi := range filteredPersonnelInfo {
-//		fmt.Printf("DocumentNumber: %s\n", pi.DocumentNumber)
-//		fmt.Printf("TotalCaptureCount: %d\n", pi.TotalCaptureCount)
-//		fmt.Printf("TotalCaptureDays: %d\n", pi.TotalCaptureDays)
-//		fmt.Printf("PersonnelStatus: %s\n", pi.PersonnelStatus)
 //
-//		fmt.Println("CaptureDetails:")
-//		for _, cd := range pi.CaptureDetails {
-//			fmt.Printf("  Date: %s\n", cd.Date)
-//			fmt.Printf("  TotalCaptureCount: %d\n", cd.TotalCaptureCount)
-//			fmt.Println("  Captures:")
-//			for _, c := range cd.Captures {
-//				fmt.Printf("    DataTime: %s\n", c.DataTime)
-//				fmt.Printf("    Location: %s\n", c.Location)
+//// 妫�鏌ヨ鍒欒〃涔﹀惁瀛樺湪寮傚父
+//func checkRuleValidity(rules []db.PersonnelStatusRule) bool {
+//	for i := 0; i < len(rules); i++ {
+//		for j := i + 1; j < len(rules); j++ {
+//			ruleI := rules[i]
+//			ruleJ := rules[j]
+//			//fmt.Println(ruleI.DetectionDaysStart,ruleI.DetectionDaysEnd)
+//			//fmt.Println(ruleJ.DetectionDaysStart,ruleJ.DetectionDaysEnd)
+//			if (ruleI.DetectionDaysStart <= ruleJ.DetectionDaysEnd && ruleI.DetectionDaysStart >= ruleJ.DetectionDaysStart) ||
+//				(ruleI.DetectionDaysEnd <= ruleJ.DetectionDaysEnd && ruleI.DetectionDaysEnd >= ruleJ.DetectionDaysStart) ||
+//				(ruleI.DetectionDaysStart <= ruleJ.DetectionDaysStart && ruleI.DetectionDaysEnd >= ruleJ.DetectionDaysEnd) {
+//				return false
 //			}
 //		}
-//		fmt.Println()
 //	}
+//	return true
 //}
-
-// 璁$畻甯哥敤鍦板潃
-//func assignFrequentAddress(personnelInfo []db.PersonnelInfo) []db.PersonnelInfo {
-//	for i := range personnelInfo {
-//		addressCounts := make(map[string]int)
-//		var maxAddress string
-//		maxCount := 0
-//		for _, detail := range personnelInfo[i].CaptureDetails {
-//			for _, capture := range detail.Captures {
-//				addressCounts[capture.Location]++
-//				if addressCounts[capture.Location] > maxCount {
-//					maxCount = addressCounts[capture.Location]
-//					maxAddress = capture.Location
-//				}
-//			}
-//		}
-//		personnelInfo[i].FrequentAddress = maxAddress
-//	}
-//	return personnelInfo
-//}
-
-// 妫�鏌ヨ鍒欒〃涔﹀惁瀛樺湪寮傚父
-func checkRuleValidity(rules []db.PersonnelStatusRule) bool {
-	for i := 0; i < len(rules); i++ {
-		for j := i + 1; j < len(rules); j++ {
-			ruleI := rules[i]
-			ruleJ := rules[j]
-			//fmt.Println(ruleI.DetectionDaysStart,ruleI.DetectionDaysEnd)
-			//fmt.Println(ruleJ.DetectionDaysStart,ruleJ.DetectionDaysEnd)
-			if (ruleI.DetectionDaysStart <= ruleJ.DetectionDaysEnd && ruleI.DetectionDaysStart >= ruleJ.DetectionDaysStart) ||
-				(ruleI.DetectionDaysEnd <= ruleJ.DetectionDaysEnd && ruleI.DetectionDaysEnd >= ruleJ.DetectionDaysStart) ||
-				(ruleI.DetectionDaysStart <= ruleJ.DetectionDaysStart && ruleI.DetectionDaysEnd >= ruleJ.DetectionDaysEnd) {
-				return false
-			}
-		}
-	}
-	return true
-}
 
 // 鎵ц绋嬪簭鍏ュ彛
 func ExecuteTask() {
+	//return
 	ruleInfo, err := db.GetAllData()
 	if err != nil {
 		logger.Error("GetAllData Error", err)
@@ -78,13 +39,18 @@
 	if err != nil {
 		logger.Error("GetCommunityIDs Error", err)
 	}
+	labeManage, err := db.GetLabelManageIdentity(2)
+	if err != nil {
+		logger.Error("GetDBPersonStatusData Error", err)
+	}
+	//fmt.Println(labeManage)
 	for _, communityID := range communityIDs {
+		//涓囧叏绀惧尯
+		//if communityID != "50010101010000001001" {
+		//	continue
+		//}
 		//鏌ヨ绀惧尯鍐呬汉鍛樻。妗堬紝鏂逛究鏁版嵁鏇存柊
 		personStatus, err := db.GetDBPersonStatusData(communityID)
-		if err != nil {
-			logger.Error("GetDBPersonStatusData Error", err)
-		}
-		labeManage, err := db.GetLabelManageIdentity(2)
 		if err != nil {
 			logger.Error("GetDBPersonStatusData Error", err)
 		}
@@ -94,13 +60,35 @@
 		//鎸夌ぞ鍖篿d鏌ヨ杩戜竴涓湀es鏁版嵁
 		captureInfos, err := db.Query1MDataByCommunityId(communityID)
 		//fmt.Println("captureInfos: ", captureInfos)
+		//residentCount := 0
 		for i := range captureInfos {
-			captureDays := data.CalculateCaptureDays(captureInfos[i].CaptureDetail)
+			//fmt.Println(captureInfos[i].DocumentNumber)
+			captureDays, overnightCount := data.CalculateCaptureDays(captureInfos[i].CaptureDetail)
 			captureInfos[i].CaptureDays = captureDays
-			//fmt.Println("璇ヤ汉鍛樺嚭鐜板ぉ鏁颁负", captureInfos[i].CaptureDays)
+			captureInfos[i].OvernightStays = overnightCount
+
+			//if captureInfos[i].CaptureDays <= 10 && captureInfos[i].OvernightStays >= 1 {
+			//	fmt.Println(captureInfos[i].DocumentNumber)
+			//	fmt.Println("璇ヤ汉鍛樺嚭鐜板ぉ鏁颁负", captureInfos[i].CaptureDays)
+			//	fmt.Println("璇ヤ汉鍛樿繃澶滃ぉ鏁颁负", captureInfos[i].OvernightStays)
+			//}
+
 			captureInfos[i].Status = data.SetStatus(captureDays, ruleInfo)
+			if captureInfos[i].OvernightStays >= 5 && (captureInfos[i].CaptureDays <= 14 && captureInfos[i].CaptureDays >= 5) {
+				captureInfos[i].Status = "resident"
+			}
+			//if captureInfos[i].Status == "resident" {
+			//	residentCount++
+			//}
+			age, err := db.QueryAgeById(captureInfos[i].DocumentNumber)
+			if err != nil {
+				logger.Error("QueryAgeById ERROR", err)
+			}
+			captureInfos[i].Age = age
 			data.SetFrequentAddress(&captureInfos[i])
+			//fmt.Println("captureInfos[i].Age: ", captureInfos[i].Age)
 		}
+		//fmt.Println("residentCount: ", residentCount)
 		if err != nil {
 			logger.Error("MatchAllTargets Error", err)
 		}
@@ -111,7 +99,7 @@
 		for _, identity := range labeManage {
 			switch identity.Name {
 			case "鏈嶅姟浜哄憳":
-				identity, attribute := CreateLinearModel(captureInfos, communityID, 2.68, identity.ValidDays)
+				identity, attribute := CreateLinearModel(captureInfos, communityID, 2.68, identity.ValidDays, identity.Id)
 				errIdentity := db.UpdateDBPersonLabel(identity)
 				if errIdentity != nil {
 					logger.Error("UpdateDBPersonLabel Error", errIdentity)
@@ -120,7 +108,11 @@
 
 			}
 		}
-		//CreateProcessModel(captureInfos, 30)
+		identity := CreateProcessModel(captureInfos, 30, communityID, labeManage)
+		errIdentity := db.UpdateDBPersonLabel(identity)
+		if errIdentity != nil {
+			logger.Error("UpdateDBPersonLabel Error", errIdentity)
+		}
 		//continue
 		//fmt.Println("captureInfos: ", captureInfos)
 		postCaptureInfos := data.ProcessData(captureInfos, personStatus, ruleInfo, communityID)
@@ -132,10 +124,14 @@
 		}
 
 		resident, DocNumberErr := db.GetResidentData("resident", communityID)
+		//fmt.Println(resident)
+		//return
 		if DocNumberErr != nil {
 			logger.Error("GetDocNumberFromPersonStatus Error: ", DocNumberErr)
 		}
+
 		//fmt.Println(resident)
+		//fmt.Println("resident: ", resident)
 		mio := processResidentStatus(resident)
 		//fmt.Println("mip: ", mio)
 		UpdateMoveInoutErr := db.UpdateMoveInout(mio)
@@ -143,5 +139,4 @@
 			logger.Error("UpdateMoveInoutErr Error: ", UpdateMoveInoutErr)
 		}
 	}
-
 }
diff --git a/task/engine.go b/task/engine.go
new file mode 100644
index 0000000..9ec9330
--- /dev/null
+++ b/task/engine.go
@@ -0,0 +1,43 @@
+package task
+
+import (
+	"basic.com/valib/logger.git"
+	"ruleModelEngine/cache"
+	"ruleModelEngine/db"
+)
+
+func UnderageClimbingToRooftop(taskPerson db.TaskPerson) bool {
+	age, err := db.GetAgeById(taskPerson.DocumentNumber)
+	if err != nil {
+		logger.Error("GetAgeById: ", err)
+		return false
+	}
+	floor, _ := extractFloorNumber(taskPerson.Floor)
+	if age <= 16 && floor == cache.Device[taskPerson.CameraId].MaxBuildingFloor && taskPerson.TargetType == "body" {
+		return true
+	}
+	return false
+}
+func UnderageEnteringCommercialBuilding(taskPerson db.TaskPerson) bool {
+	age, err := db.GetAgeById(taskPerson.DocumentNumber)
+	if err != nil {
+		logger.Error("GetAgeById: ", err)
+		return false
+	}
+	//floor, _ := extractFloorNumber(taskPerson.Floor)
+	if age <= 16 && taskPerson.TargetType == "face" && cache.Device[taskPerson.CameraId].BuildingType == db.BuildingTypeMixedUse {
+		return true
+	}
+	return false
+}
+func ClimbingFloorsIllegally(taskPerson db.TaskPerson) bool {
+
+	return true
+}
+func EnteringButNotLeaving(taskPerson db.TaskPerson) bool {
+
+	return true
+}
+func registeredAddressNotMatchActualResidence(taskPerson db.TaskPerson) bool {
+	return true
+}
diff --git a/task/service.go b/task/service.go
new file mode 100644
index 0000000..2f807ad
--- /dev/null
+++ b/task/service.go
@@ -0,0 +1,72 @@
+package task
+
+import (
+	"basic.com/valib/logger.git"
+	"fmt"
+	"ruleModelEngine/cache"
+	"ruleModelEngine/db"
+	"time"
+)
+
+type alarmRule struct {
+	ruleId   int
+	ruleText string
+}
+
+func TaskAnalysisService(id string) {
+	alarmRules := make([]alarmRule, 0)
+	time.Sleep(time.Second * 2)
+	var taskPerson db.TaskPerson
+	var err error
+	for i := 0; i <= 2; i++ {
+		taskPerson, err = db.QueryById(id)
+		if err != nil {
+			logger.Error("QueryById Error", err)
+		}
+		if taskPerson.Id != "" {
+			break
+		}
+		time.Sleep(time.Second * 15)
+	}
+	fmt.Println("personInfo: ", taskPerson)
+	fmt.Println("device: ", cache.Device)
+	tasks, err := db.GetAllTaskData()
+	if err != nil {
+		logger.Error("GetAllTaskData Error", err)
+	}
+	fmt.Println(tasks)
+
+	for _, task := range tasks {
+		switch task.Name {
+		case "鏈垚骞村嚭椤舵ゼ":
+			flag := UnderageClimbingToRooftop(taskPerson)
+			if flag == true {
+				alarmRules = append(alarmRules, alarmRule{ruleId: task.Id, ruleText: task.Name})
+			}
+		case "鏈垚骞村叆鍟嗕綇妤�":
+			flag := UnderageEnteringCommercialBuilding(taskPerson)
+			if flag == true {
+				alarmRules = append(alarmRules, alarmRule{ruleId: task.Id, ruleText: task.Name})
+			}
+		case "绐滄ゼ":
+			flag := ClimbingFloorsIllegally(taskPerson)
+			if flag == true {
+				alarmRules = append(alarmRules, alarmRule{ruleId: task.Id, ruleText: task.Name})
+			}
+		case "鍙繘涓嶅嚭":
+			flag := EnteringButNotLeaving(taskPerson)
+			if flag == true {
+				alarmRules = append(alarmRules, alarmRule{ruleId: task.Id, ruleText: task.Name})
+			}
+		case "鐢充綇涓嶄竴":
+			flag := registeredAddressNotMatchActualResidence(taskPerson)
+			if flag == true {
+				alarmRules = append(alarmRules, alarmRule{ruleId: task.Id, ruleText: task.Name})
+			}
+		default:
+			continue
+
+		}
+	}
+
+}
diff --git a/task/tool.go b/task/tool.go
new file mode 100644
index 0000000..0f3aca9
--- /dev/null
+++ b/task/tool.go
@@ -0,0 +1,28 @@
+package task
+
+import (
+	"fmt"
+	"regexp"
+	"strconv"
+)
+
+func extractFloorNumber(input string) (int, error) {
+	// 瀹氫箟鍖归厤妤煎眰鏁板瓧鐨勬鍒欒〃杈惧紡
+	re := regexp.MustCompile(`-?\d+`)
+
+	// 鏌ユ壘绗竴涓尮閰嶇殑妤煎眰鏁板瓧
+	matches := re.FindStringSubmatch(input)
+
+	// 濡傛灉鎵惧埌鍖归厤鐨勬ゼ灞傛暟瀛�
+	if len(matches) > 0 {
+		// 灏嗗尮閰嶇殑妤煎眰鏁板瓧杞崲涓烘暣鏁�
+		floorNumber, err := strconv.Atoi(matches[0])
+		if err != nil {
+			return 0, err
+		}
+		return floorNumber, nil
+	}
+
+	// 濡傛灉鏈壘鍒板尮閰嶇殑妤煎眰鏁板瓧锛屽垯杩斿洖閿欒
+	return 0, fmt.Errorf("No floor number found in input: %s", input)
+}

--
Gitblit v1.8.0