commit 74aeed3b7e3fa740ca45c4b12c0157b5a8beec46 Author: oldsheeppp Date: Thu Oct 24 23:11:29 2024 +0800 update diff --git a/Code/backend/README.md b/Code/backend/README.md new file mode 100644 index 0000000..e69de29 diff --git a/Code/backend/cmd/config/config.go b/Code/backend/cmd/config/config.go new file mode 100644 index 0000000..2009d6d --- /dev/null +++ b/Code/backend/cmd/config/config.go @@ -0,0 +1,44 @@ +package config + +import ( + "encoding/json" + "fmt" + "os" + "path/filepath" +) + +type Configuration struct { + Port int `json:"backendport"` + Name string `json:"name"` + Database string `json:"database"` + PicturePath string `json:"picturePath"` +} + +var AllConfig *Configuration + +func InitConfig() { + cfg, _ := loadConfig() + AllConfig = &cfg +} + +func loadConfig() (Configuration, error) { + + dir, err1 := os.Getwd() + if err1 != nil { + fmt.Println(err1) + return Configuration{}, err1 + } + projectPath := filepath.Join(dir, "../../") + filespath := filepath.Join(projectPath, "cmd/config/config.json") + file, err := os.ReadFile(filespath) + + if err != nil { + return Configuration{}, err + } + var cfg Configuration + err = json.Unmarshal(file, &cfg) + if err != nil { + return Configuration{}, err + } + return cfg, nil +} diff --git a/Code/backend/cmd/config/config.json b/Code/backend/cmd/config/config.json new file mode 100644 index 0000000..ad60087 --- /dev/null +++ b/Code/backend/cmd/config/config.json @@ -0,0 +1,6 @@ +{ + "backendport": 8080, + "name": "node1", + "database": "initqwe", + "picPath": "/home/backend/picture" +} \ No newline at end of file diff --git a/Code/backend/cmd/manager/database.yaml b/Code/backend/cmd/manager/database.yaml new file mode 100644 index 0000000..fd1c10b --- /dev/null +++ b/Code/backend/cmd/manager/database.yaml @@ -0,0 +1,5 @@ +mysql: + username: root + password: + url: 127.0.0.1:3300 + databasename: intelligent_monitoring diff --git a/Code/backend/cmd/manager/main.go b/Code/backend/cmd/manager/main.go new file mode 100644 index 0000000..99978f2 --- /dev/null +++ b/Code/backend/cmd/manager/main.go @@ -0,0 +1,42 @@ +package main + +import ( + "go_backend/cmd/config" + "go_backend/internal/api" + "go_backend/internal/dbs" + scheduledtask "go_backend/internal/scheduled_task" + "go_backend/internal/utils" + "strconv" + + "github.com/gin-gonic/gin" + "github.com/robfig/cron/v3" +) + +func main() { + + config.InitConfig() + + if config.AllConfig.Database == "init" || config.AllConfig.Database == "Init" { + println("init!!!!!!") + dbs.GenerateModel() + } + + r := gin.Default() + + r.Use(utils.Cors()) + + api.GetAllCameras(r.Group("")) + api.CreateNode(r.Group("")) + api.ModifyNode(r.Group("")) + api.CreateDetectionRecord(r.Group("")) + api.GetDetectionRecord(r.Group("")) + api.GetTrajectoryRecordList(r.Group("")) + println(config.AllConfig.Port) + + c := cron.New() + c.AddFunc("@every 1m", scheduledtask.MergeTrajectory) + c.Start() + + // _ = r.Run(":" + strconv.Itoa(config.AllConfig.Port)) + _ = r.Run(":" + strconv.Itoa(8080)) +} diff --git a/Code/backend/go.mod b/Code/backend/go.mod new file mode 100644 index 0000000..0be2ee8 --- /dev/null +++ b/Code/backend/go.mod @@ -0,0 +1,64 @@ +module go_backend + +go 1.20 + +require ( + github.com/gin-gonic/gin v1.10.0 + github.com/robfig/cron/v3 v3.0.1 + github.com/spf13/viper v1.19.0 + gorm.io/driver/mysql v1.4.4 + gorm.io/gen v0.3.26 + gorm.io/gorm v1.25.11 + gorm.io/plugin/dbresolver v1.5.0 +) + +require ( + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.20.0 // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect + github.com/goccy/go-json v0.10.2 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/sagikazarmark/locafero v0.4.0 // indirect + github.com/sagikazarmark/slog-shim v0.1.0 // indirect + github.com/sourcegraph/conc v0.3.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.6.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.6.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.9.0 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.23.0 // indirect + golang.org/x/exp v0.0.0-20230905200255-921286631fa9 // indirect + golang.org/x/mod v0.14.0 // indirect + golang.org/x/net v0.25.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/text v0.15.0 // indirect + golang.org/x/tools v0.17.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 + gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c // indirect + gorm.io/hints v1.1.0 // indirect +) diff --git a/Code/backend/go.sum b/Code/backend/go.sum new file mode 100644 index 0000000..75cbea7 --- /dev/null +++ b/Code/backend/go.sum @@ -0,0 +1,171 @@ +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= +github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.20.0 h1:K9ISHbSaI0lyB2eWMPJo+kOS/FBExVwjEviJTixqxL8= +github.com/go-playground/validator/v10 v10.20.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= +github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= +github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= +github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= +github.com/microsoft/go-mssqldb v0.17.0 h1:Fto83dMZPnYv1Zwx5vHHxpNraeEaUlQ/hhHLgZiaenE= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= +github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= +github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= +github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= +github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= +github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= +github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= +go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g= +golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= +golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc= +golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps= +google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= +google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c h1:jWdr7cHgl8c/ua5vYbR2WhSp+NQmzhsj0xoY3foTzW8= +gorm.io/datatypes v1.1.1-0.20230130040222-c43177d3cf8c/go.mod h1:SH2K9R+2RMjuX1CkCONrPwoe9JzVv2hkQvEu4bXGojE= +gorm.io/driver/mysql v1.4.3/go.mod h1:sSIebwZAVPiT+27jK9HIwvsqOGKx3YMPmrA3mBJR10c= +gorm.io/driver/mysql v1.4.4 h1:MX0K9Qvy0Na4o7qSC/YI7XxqUw5KDw01umqgID+svdQ= +gorm.io/driver/mysql v1.4.4/go.mod h1:BCg8cKI+R0j/rZRQxeKis/forqRwRSYOR8OM3Wo6hOM= +gorm.io/driver/postgres v1.4.5 h1:mTeXTTtHAgnS9PgmhN2YeUbazYpLhUI1doLnw42XUZc= +gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8= +gorm.io/driver/sqlite v1.4.3 h1:HBBcZSDnWi5BW3B3rwvVTc510KGkBkexlOg0QrmLUuU= +gorm.io/driver/sqlserver v1.4.1 h1:t4r4r6Jam5E6ejqP7N82qAJIJAht27EGT41HyPfXRw0= +gorm.io/gen v0.3.26 h1:sFf1j7vNStimPRRAtH4zz5NiHM+1dr6eA9aaRdplyhY= +gorm.io/gen v0.3.26/go.mod h1:a5lq5y3w4g5LMxBcw0wnO6tYUCdNutWODq5LrIt75LE= +gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0= +gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= +gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= +gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= +gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw= +gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y= +gorm.io/plugin/dbresolver v1.5.0 h1:XVHLxh775eP0CqVh3vcfJtYqja3uFl5Wr3cKlY8jgDY= +gorm.io/plugin/dbresolver v1.5.0/go.mod h1:l4Cn87EHLEYuqUncpEeTC2tTJQkjngPSD+lo8hIvcT0= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/Code/backend/internal/api/camera.go b/Code/backend/internal/api/camera.go new file mode 100644 index 0000000..dfb28ef --- /dev/null +++ b/Code/backend/internal/api/camera.go @@ -0,0 +1,158 @@ +package api + +import ( + "fmt" + "github.com/gin-gonic/gin" + "go_backend/internal/dbs" + "go_backend/internal/model" + "go_backend/internal/utils" + "time" +) + +type CameraVO struct { + ID int32 `json:"id"` + CameraID string `json:"camera_id"` + DisplayName string `json:"display_name"` + ParentCategoryID []int `json:"parent_category_id"` + ViewPriority int32 `json:"view_priority"` + Status string `json:"status"` + Type string `json:"type"` + IPAddress string `json:"ip_address"` + IsDeleted bool `json:"is_deleted"` + CreateTime time.Time `json:"create_time"` + DeletedTime time.Time `json:"deleted_time"` + UpdateTime time.Time `json:"update_time"` + ChildVO []*CameraVO `json:"child"` +} + +func GetAllCameras(router *gin.RouterGroup) { + router.GET("/camerasList", func(c *gin.Context) { + cameras := make([]model.Camera, 0) + db := dbs.GetGormDB() + db.Find(&cameras) + + cameraMap := make(map[int][]model.Camera) + + for _, camera := range cameras { + cameraMap[int(camera.ViewPriority)] = append(cameraMap[(int(camera.ViewPriority))], camera) + } + + cameraVOList := make([]*CameraVO, 0) + level := 0 + + cameraRecord := make(map[int]*CameraVO) + + for priority, cameraArray := range cameraMap { + if priority == 0 { + for _, camera := range cameraArray { + vo := transVO(camera) + cameraVOList = append(cameraVOList, &vo) + cameraRecord[int(camera.ID)] = &vo + } + level += 1 + continue + } + + if priority == level { + tempRecord := make(map[int]*CameraVO) + + for _, camera := range cameraArray { + vo := transVO(camera) + parentId := vo.ParentCategoryID[len(vo.ParentCategoryID)-1] + if pointer, exists := cameraRecord[parentId]; exists { + pointer.ChildVO = append(pointer.ChildVO, &vo) + utils.PrintSlice(vo.ParentCategoryID) + newParent := make([]int, 0) + utils.PrintSlice(pointer.ParentCategoryID) + for _, id := range pointer.ParentCategoryID { + newParent = append(newParent, id) + } + newParent = append(newParent, parentId) + vo.ParentCategoryID = newParent + tempRecord[int(vo.ID)] = &vo + } + } + cameraRecord = tempRecord + level += 1 + } + } + Success(c, cameraVOList) + }) +} + +type Node struct { + ParentID int `json:"parent_id"` + DisplayName string `json:"display_name"` + Ip string `json:"ip"` +} + +func CreateNode(router *gin.RouterGroup) { + router.POST("/camera/addNode", func(c *gin.Context) { + var req Node + err := c.ShouldBindJSON(&req) + if err != nil { + fmt.Println("ctx.ShouldBindJSON err: ", err) + c.JSON(400, gin.H{"error": err.Error()}) + return + } + println("nihao", req.ParentID) + newNode := model.Camera{ + ParentCategoryID: int32(req.ParentID), + DisplayName: req.DisplayName, + IPAddress: req.Ip, + } + db := dbs.GetGormDB() + result := db.Create(&newNode) + + Success(c, result) + }) +} + +type ModifyNodeData struct { + Id int `json:"id"` + DisplayName string `json:"display_name"` + Ip string `json:"ip"` +} + +func ModifyNode(router *gin.RouterGroup) { + router.POST("/camera/modify", func(c *gin.Context) { + var req ModifyNodeData + err := c.ShouldBindJSON(&req) + if err != nil { + fmt.Println("ctx.ShouldBindJSON err: ", err) + c.JSON(400, gin.H{"error": err.Error()}) + return + } + node := model.Camera{ + ID: int32(req.Id), + IPAddress: req.Ip, + } + if req.DisplayName != "" { + node.DisplayName = req.DisplayName + } + db := dbs.GetGormDB() + result := db.Updates(&node) + + Success(c, result) + }) +} + +func transVO(camera model.Camera) CameraVO { + vo := CameraVO{ + ID: camera.ID, + CameraID: camera.CameraID, + DisplayName: camera.DisplayName, + ParentCategoryID: make([]int, 1), + ViewPriority: camera.ViewPriority, + Status: camera.Status, + Type: camera.Type, + IPAddress: camera.IPAddress, + IsDeleted: camera.IsDeleted, + CreateTime: camera.CreateTime, + DeletedTime: camera.DeletedTime, + UpdateTime: camera.UpdateTime, + ChildVO: make([]*CameraVO, 0), + } + vo.ParentCategoryID[0] = int(camera.ParentCategoryID) + return vo +} diff --git a/Code/backend/internal/api/messages.go b/Code/backend/internal/api/messages.go new file mode 100644 index 0000000..a90e5f8 --- /dev/null +++ b/Code/backend/internal/api/messages.go @@ -0,0 +1,32 @@ +package api + +const ( + ErrUnexpected Message = iota + 1 + ErrBadRequest + ErrSaveFailed + ErrDeleteFailed + ErrAlreadyExists + ErrNotFound + ErrUnauthorized + ErrForbidden + ErrEntityNotFound + ErrInternalServer + MsgChangesSaved +) + +var Messages = MessageMap{ + // Error messages: + ErrUnexpected: "Unexpected error, please try again", + ErrBadRequest: "Invalid request", + ErrSaveFailed: "Changes could not be saved", + ErrDeleteFailed: "Could not be deleted", + ErrAlreadyExists: "Duplicated key, item already exists", + ErrNotFound: "Record not found", + ErrUnauthorized: "Unauthorized", + ErrForbidden: "Permission denied", + ErrEntityNotFound: "Entity not found", + ErrInternalServer: "Internal server error", + + // Info and confirmation messages: + MsgChangesSaved: "Changes successfully saved", +} diff --git a/Code/backend/internal/api/msg.go b/Code/backend/internal/api/msg.go new file mode 100644 index 0000000..e519b8b --- /dev/null +++ b/Code/backend/internal/api/msg.go @@ -0,0 +1,27 @@ +package api + +import ( + "errors" + "fmt" + "strings" +) + +type Message int +type MessageMap map[Message]string + +// msgParams replaces message params with the actual values. +func msgParams(msg string, params ...interface{}) string { + if strings.Contains(msg, "%") { + msg = fmt.Sprintf(msg, params...) + } + + return msg +} + +func Msg(id Message, params ...interface{}) string { + return msgParams(Messages[id], params...) +} + +func ErrorMsg(id Message, params ...interface{}) error { + return errors.New(Msg(id, params...)) +} diff --git a/Code/backend/internal/api/personDetectionRecord.go b/Code/backend/internal/api/personDetectionRecord.go new file mode 100644 index 0000000..0d85ffd --- /dev/null +++ b/Code/backend/internal/api/personDetectionRecord.go @@ -0,0 +1,197 @@ +package api + +import ( + "bytes" + "encoding/base64" + "fmt" + "github.com/gin-gonic/gin" + "go_backend/cmd/config" + "go_backend/internal/dbs" + "go_backend/internal/model" + "gorm.io/gorm" + "image" + "image/png" + "net/url" + "os" + "path/filepath" + "strconv" + "time" +) + +type page struct { + Limit int `form:"limit" json:"limit"` + Offset int `form:"offset" json:"offset"` +} + +type detectionReturnParam struct { + TotalNum int64 `json:"totalNum"` + DetectionRecord []DetectionVO `json:"detectionRecord"` +} + +func GetDetectionRecord(router *gin.RouterGroup) { + router.GET("/detection/List", func(c *gin.Context) { + limit, _ := strconv.Atoi(c.Query("limit")) + offset, _ := strconv.Atoi(c.Query("offset")) + // 计算跳过的记录数 + skipRecord := (offset - 1) * limit + detectionRecords := make([]model.PersonDetectionRecord, 0) + db := dbs.GetGormDB() + db.Limit(limit).Offset(skipRecord).Find(&detectionRecords) + detectionVOS := make([]DetectionVO, 0) + // 根据每条记录搜索对应的摄像头 + for _, record := range detectionRecords { + var cameras []model.Camera + result := db.Model(model.Camera{}). + Where("camera_id = ?", record.CameraID). + Find(&cameras) + if result.Error != nil { + fmt.Println(result.Error) + return + } + if len(cameras) > 1 { + fmt.Println("对应摄像头id ", record.CameraID, " 超过一个") + } + address := mergeAddress(cameras[0], db) + detectionVOS = append(detectionVOS, transToDetectionVO(record, address)) + } + + var count int64 + db.Model(model.PersonDetectionRecord{}).Count(&count) + Success(c, detectionReturnParam{ + TotalNum: count, + DetectionRecord: detectionVOS, + }) + }) +} + +func mergeAddress(cameraTarget model.Camera, db *gorm.DB) string { + var addressArray []string + var address string + var temp = cameraTarget + for { + addressArray = append(addressArray, temp.DisplayName) + if temp.ParentCategoryID == 0 { + break + } + var temp1 model.Camera + db.Model(model.Camera{}). + Where("id = ? ", temp.ParentCategoryID). + Find(&temp1) + temp = temp1 + } + // 组织成xxx-xxx的形式 + for i := len(addressArray) - 1; i >= 1; i-- { + address += addressArray[i] + address += "-" + } + return address + addressArray[0] +} + +type DetectionVO struct { + ID int64 `json:"id"` + PersonId int32 `json:"person_id"` + AlarmType string `json:"alarm_type"` + PersonType string `json:"person_type"` + DetectTime string `json:"detect_time"` + IpAddress string `json:"ip_address"` + Address string `json:"address"` + ProcessStatus string `json:"process_status"` + TrajectoryDetectionID int64 `json:"trajectory_detection_id"` +} + +func transToDetectionVO(record model.PersonDetectionRecord, address string) DetectionVO { + parsedUrl, err := url.Parse(record.Address) + if err != nil { + fmt.Println("Error parsing URL:", err) + } + ip := parsedUrl.Path + return DetectionVO{ + ID: record.ID, + PersonId: record.PersonID, + AlarmType: record.AlarmType, + PersonType: record.PersonType, + DetectTime: record.DetectTime.Format("2006-01-02 15:04:05"), + IpAddress: ip, + Address: address, + ProcessStatus: record.ProcessStatus, + TrajectoryDetectionID: record.TrajectoryDetectionID, + } +} + +type recordInfo struct { + PersonType string `form:"personType" json:"personType"` + PersonId int `form:"personId" json:"personId"` + TimeStamp int64 `form:"timestamp" json:"timestamp"` + Picture string `form:"picture" json:"picture"` + CameraIP string `form:"cameraIP" json:"cameraIP"` +} + +func CreateDetectionRecord(router *gin.RouterGroup) { + router.GET("/detection/create", func(c *gin.Context) { + var req recordInfo + err := c.ShouldBindJSON(&req) + if err != nil { + fmt.Println("ctx.ShouldBindJSON err: ", err) + c.JSON(400, gin.H{"error": err.Error()}) + return + } + + // 用base64解码图片数据 + decodedData, err := base64.StdEncoding.DecodeString(req.Picture) + + timestamp := req.TimeStamp + tm := time.Unix(timestamp, 0) + dir := filepath.Join(config.AllConfig.PicturePath, tm.Format("2006"), + tm.Format("01"), tm.Format("02"), + tm.Format("03"), tm.Format("04")) + + // 创建文件来保存图片,图片名字为personType-cameraip-time-personid + fileName := fmt.Sprintf("%s.%s.%s.%s.png", req.PersonType, req.CameraIP, tm.Second(), tm.Format("20240102150405")) + // 创建目录 + err = os.MkdirAll(dir, os.ModePerm) + if err != nil { + fmt.Println("创建目录出错:", err) + return + } + + filePath := filepath.Join(dir, fileName) + // 创建文件 + file, err := os.Create(filePath) + if err != nil { + fmt.Println("创建文件出错:", err) + return + } + defer file.Close() + // 使用PNG格式保存图片 + img, _, err := image.Decode(bytes.NewReader(decodedData)) + if err != nil { + fmt.Println("读取图片出错:", err) + return + } + err = png.Encode(file, img) + if err != nil { + fmt.Println("保存图片出错:", err) + return + } + + var cameras []model.Camera + dbs.GetGormDB().Model(model.PersonDetectionRecord{}). + Where("ip_address like ?", "%"+req.CameraIP+"%"). + Find(&cameras) + + if len(cameras) != 1 { + fmt.Println("该ip对应的摄像头大于1个:", req.CameraIP) + return + } + + newRecord := model.PersonDetectionRecord{ + PersonType: req.PersonType, + Address: req.CameraIP, + DetectTime: tm, + CameraID: string(cameras[0].ID), + } + dbs.GetGormDB().Model(model.PersonDetectionRecord{}).Create(&newRecord) + + Success(c, "success") + }) +} diff --git a/Code/backend/internal/api/response.go b/Code/backend/internal/api/response.go new file mode 100644 index 0000000..467bcc4 --- /dev/null +++ b/Code/backend/internal/api/response.go @@ -0,0 +1,67 @@ +package api + +import ( + "net/http" + "strings" + + "github.com/gin-gonic/gin" +) + +const ( + CodeSuccess = 200 +) + +type Response struct { + Code int `json:"code"` + Err string `json:"errMsg,omitempty"` + Data interface{} `json:"data,omitempty"` + IsSuccess bool `json:"isSuccess"` + RequestID string `json:"requestID,omitempty"` +} + +func (r Response) String() string { + return r.Err +} + +func (r Response) LowerString() string { + return strings.ToLower(r.String()) +} + +func (r Response) Error() string { + return r.Err +} + +func (r Response) Success() bool { + return r.Err == "" && r.Code < 400 +} + +func NewResponse(code int, id Message, params ...interface{}) Response { + return Response{Code: code, Err: Msg(id, params...)} +} + +func Success(c *gin.Context, data interface{}) { + response := Response{ + Code: CodeSuccess, + Data: data, + IsSuccess: true, + } + c.JSON(http.StatusOK, response) +} + +func SuccessBool(c *gin.Context, data interface{}, success bool) { + response := Response{ + Code: CodeSuccess, + Data: data, + IsSuccess: success, + } + c.JSON(http.StatusOK, response) +} + +func SuccessYAML(c *gin.Context, data interface{}) { + response := Response{ + Code: CodeSuccess, + Data: data, + IsSuccess: true, + } + c.YAML(http.StatusOK, response) +} diff --git a/Code/backend/internal/api/trajectoryRecord.go b/Code/backend/internal/api/trajectoryRecord.go new file mode 100644 index 0000000..4e65239 --- /dev/null +++ b/Code/backend/internal/api/trajectoryRecord.go @@ -0,0 +1,30 @@ +package api + +import ( + "github.com/gin-gonic/gin" + "go_backend/internal/dbs" + "go_backend/internal/model" +) + +func GetTrajectoryRecordList(router *gin.RouterGroup) { + router.GET("/trajectoryList", func(c *gin.Context) { + + trajectories := make([]model.TrajectoryDetectionRecord, 0) + db := dbs.GetGormDB() + db.Find(&trajectories) + + Success(c, trajectories) + }) +} + +func GetTargetTrajectory(router *gin.RouterGroup) { + router.GET("/trajectory", func(c *gin.Context) { + id := c.Query("id") + var tra model.TrajectoryDetectionRecord + db := dbs.GetGormDB() + db.Where("id = ? ", id). + Find(&tra) + + Success(c, tra) + }) +} diff --git a/Code/backend/internal/dbs/database.yaml b/Code/backend/internal/dbs/database.yaml new file mode 100644 index 0000000..a5f63a7 --- /dev/null +++ b/Code/backend/internal/dbs/database.yaml @@ -0,0 +1,5 @@ +mysql: + username: root + password: + url: 127.0.0.1:3300 + databasename: intelligent_monitorings \ No newline at end of file diff --git a/Code/backend/internal/dbs/db_init.go b/Code/backend/internal/dbs/db_init.go new file mode 100644 index 0000000..301471c --- /dev/null +++ b/Code/backend/internal/dbs/db_init.go @@ -0,0 +1,100 @@ +package dbs + +import ( + "fmt" + "github.com/spf13/viper" + "gorm.io/driver/mysql" + "gorm.io/gen" + "gorm.io/gorm" +) + +var isInit = false +var mysqlUser string +var mysqlPassword string +var mysqlUrl string +var mysqlDatabase string + +func GetGormDB() (db *gorm.DB) { + var MySQLDSN string + + if !isInit { + viper.SetConfigName("database") + viper.SetConfigType("yaml") + viper.AddConfigPath("./") + + err := viper.ReadInConfig() + if err != nil { + panic(fmt.Errorf("fatal error config file: %w", err)) + } + mysqlUser = viper.GetString("mysql.username") + mysqlPassword = viper.GetString("mysql.password") + mysqlUrl = viper.GetString("mysql.url") + mysqlDatabase = viper.GetString("mysql.databasename") + isInit = true + } + + if mysqlPassword == "" || len(mysqlPassword) == 0 { + MySQLDSN = fmt.Sprintf("%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", + mysqlUser, mysqlUrl, mysqlDatabase) + } else { + MySQLDSN = fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", + mysqlUser, mysqlPassword, mysqlUrl, mysqlDatabase) + } + + db, err2 := gorm.Open(mysql.Open(MySQLDSN)) + if err2 != nil { + panic(fmt.Errorf("cannot establish db connection: %w", err2)) + } + + return +} + +func GenerateModel() { + g := gen.NewGenerator(gen.Config{ + OutPath: "../../internal/query", + }) + + g.UseDB(GetGormDB()) + g.ApplyBasic( + g.GenerateModel("cameras"), + g.GenerateModelAs("person_detection_record", "PersonDetectionRecord"), + g.GenerateModelAs("trajectory_detection_record", "TrajectoryDetectionRecord"), + g.GenerateModelAs("person", "Person")) + g.Execute() +} + +func insertlocal() { + //Create_local_component("hadoop", "3.0.0", "../../shell/init/hadoop.sh", "node1") + //Create_local_component("spark", "3.3.0", "../../shell/init/spark.sh", "node1") + //Create_local_component("hbase", "2.0.0", "../../shell/init/hbase.sh", "node1") + //Create_local_component("zookeeper", "3.7.1", "../../shell/init/zookeeper.sh", "node1") + //Create_local_component("hive", "3.1.2", "../../shell/init/hive.sh", "node1") + //Create_local_component("flink", "1.16.2", "../../shell/init/flink.sh", "node1") + //Create_local_component("streampark", "2.0.0", "../../shell/init/streampark.sh", "node1") + //Create_local_component("zeppelin", "0.10.1", "../../shell/init/zeppelin.sh", "node1") +} + +func insertK8s() { + //Create_k8s_component("hadoop", "hadoop:3.0.0") + //Create_k8s_component("spark", "spark:3.3.0") + //Create_k8s_component("hbase", "hadpp:2.0.0") + //Create_k8s_component("zookeeper", "zookeeper:3.7.1") + //Create_k8s_component("hive", "hadpp:3.1.2") + //Create_k8s_component("flink", "flink:1.16.2") + //Create_k8s_component("streampark", "streampark:2.0.0") + //Create_k8s_component("zeppelin", "zeppelin:0.10.1") +} + +func insertlocalStatus() { + //created := "created" + //node := "node1" + //Create_local_status("hadoop", created, node) + //Create_local_status("spark", created, node) + //Create_local_status("hbase", created, node) + //Create_local_status("zookeeper", created, node) + //Create_local_status("hive", created, node) + //Create_local_status("flink", created, node) + //Create_local_status("streampark", created, node) + //Create_local_status("zeppelin", created, node) + +} diff --git a/Code/backend/internal/model/cameras.gen.go b/Code/backend/internal/model/cameras.gen.go new file mode 100644 index 0000000..86325ac --- /dev/null +++ b/Code/backend/internal/model/cameras.gen.go @@ -0,0 +1,34 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNameCamera = "cameras" + +// Camera mapped from table +type Camera struct { + ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + CameraID string `gorm:"column:camera_id;comment:摄像头的id" json:"camera_id"` // 摄像头的id + DisplayName string `gorm:"column:display_name;comment:展示使用的名字" json:"display_name"` // 展示使用的名字 + ParentCategoryID int32 `gorm:"column:parent_category_id;comment:上一级的类别" json:"parent_category_id"` // 上一级的类别 + ViewPriority int32 `gorm:"column:view_priority" json:"view_priority"` + Status string `gorm:"column:status;comment:摄像头目前状态" json:"status"` // 摄像头目前状态 + Type string `gorm:"column:type;comment:类别" json:"type"` // 类别 + IPAddress string `gorm:"column:ip_address;comment:ip地址" json:"ip_address"` // ip地址 + Latitude string `gorm:"column:latitude;comment:纬度" json:"latitude"` // 纬度 + Longitude string `gorm:"column:longitude;comment:经度" json:"longitude"` // 经度 + IsDeleted bool `gorm:"column:is_deleted" json:"is_deleted"` + CreateTime time.Time `gorm:"column:create_time" json:"create_time"` + DeletedTime time.Time `gorm:"column:deleted_time" json:"deleted_time"` + UpdateTime time.Time `gorm:"column:update_time" json:"update_time"` +} + +// TableName Camera's table name +func (*Camera) TableName() string { + return TableNameCamera +} diff --git a/Code/backend/internal/model/person.gen.go b/Code/backend/internal/model/person.gen.go new file mode 100644 index 0000000..cbed747 --- /dev/null +++ b/Code/backend/internal/model/person.gen.go @@ -0,0 +1,27 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNamePerson = "person" + +// Person mapped from table +type Person struct { + ID int32 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + PersonType int32 `gorm:"column:person_type" json:"person_type"` + PersonPicURL string `gorm:"column:person_pic_url" json:"person_pic_url"` + PersonName string `gorm:"column:person_name" json:"person_name"` + IsDeleted bool `gorm:"column:is_deleted" json:"is_deleted"` + CreateTime time.Time `gorm:"column:create_time" json:"create_time"` + UpdateTime time.Time `gorm:"column:update_time" json:"update_time"` +} + +// TableName Person's table name +func (*Person) TableName() string { + return TableNamePerson +} diff --git a/Code/backend/internal/model/person_detection_record.gen.go b/Code/backend/internal/model/person_detection_record.gen.go new file mode 100644 index 0000000..4034a34 --- /dev/null +++ b/Code/backend/internal/model/person_detection_record.gen.go @@ -0,0 +1,32 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNamePersonDetectionRecord = "person_detection_record" + +// PersonDetectionRecord mapped from table +type PersonDetectionRecord struct { + ID int64 `gorm:"column:id;primaryKey;autoIncrement:true" json:"id"` + EventID string `gorm:"column:event_id" json:"event_id"` + AlarmType string `gorm:"column:alarm_type" json:"alarm_type"` + PersonType string `gorm:"column:person_type" json:"person_type"` + CameraID string `gorm:"column:camera_id" json:"camera_id"` + PersonID int32 `gorm:"column:person_id" json:"person_id"` + Address string `gorm:"column:address" json:"address"` + DetectTime time.Time `gorm:"column:detect_time" json:"detect_time"` + ProcessStatus string `gorm:"column:process_status" json:"process_status"` + TrajectoryDetectionID int64 `gorm:"column:trajectory_detection_id" json:"trajectory_detection_id"` + CreateTime time.Time `gorm:"column:create_time" json:"create_time"` + UpdateTime time.Time `gorm:"column:update_time" json:"update_time"` +} + +// TableName PersonDetectionRecord's table name +func (*PersonDetectionRecord) TableName() string { + return TableNamePersonDetectionRecord +} diff --git a/Code/backend/internal/model/trajectory_detection_record.gen.go b/Code/backend/internal/model/trajectory_detection_record.gen.go new file mode 100644 index 0000000..20c60bd --- /dev/null +++ b/Code/backend/internal/model/trajectory_detection_record.gen.go @@ -0,0 +1,29 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package model + +import ( + "time" +) + +const TableNameTrajectoryDetectionRecord = "trajectory_detection_record" + +// TrajectoryDetectionRecord mapped from table +type TrajectoryDetectionRecord struct { + ID int32 `gorm:"column:id;primaryKey" json:"id"` + PersonDetectionRecordIds string `gorm:"column:person_detection_record_ids" json:"person_detection_record_ids"` + PersonID int32 `gorm:"column:person_id" json:"person_id"` + TrajectoryLength int32 `gorm:"column:trajectory_length" json:"trajectory_length"` + Trajectory string `gorm:"column:trajectory" json:"trajectory"` + IsDeleted bool `gorm:"column:is_deleted" json:"is_deleted"` + CreateTime time.Time `gorm:"column:create_time" json:"create_time"` + UpdateTime time.Time `gorm:"column:update_time" json:"update_time"` + DeletedTime time.Time `gorm:"column:deleted_time" json:"deleted_time"` +} + +// TableName TrajectoryDetectionRecord's table name +func (*TrajectoryDetectionRecord) TableName() string { + return TableNameTrajectoryDetectionRecord +} diff --git a/Code/backend/internal/query/cameras.gen.go b/Code/backend/internal/query/cameras.gen.go new file mode 100644 index 0000000..c00f849 --- /dev/null +++ b/Code/backend/internal/query/cameras.gen.go @@ -0,0 +1,379 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "go_backend/internal/model" +) + +func newCamera(db *gorm.DB, opts ...gen.DOOption) camera { + _camera := camera{} + + _camera.cameraDo.UseDB(db, opts...) + _camera.cameraDo.UseModel(&model.Camera{}) + + tableName := _camera.cameraDo.TableName() + _camera.ALL = field.NewAsterisk(tableName) + _camera.ID = field.NewInt32(tableName, "id") + _camera.CameraID = field.NewString(tableName, "camera_id") + _camera.DisplayName = field.NewString(tableName, "display_name") + _camera.ParentCategoryID = field.NewInt32(tableName, "parent_category_id") + _camera.ViewPriority = field.NewInt32(tableName, "view_priority") + _camera.Status = field.NewString(tableName, "status") + _camera.Type = field.NewString(tableName, "type") + _camera.IPAddress = field.NewString(tableName, "ip_address") + _camera.Latitude = field.NewString(tableName, "latitude") + _camera.Longitude = field.NewString(tableName, "longitude") + _camera.IsDeleted = field.NewBool(tableName, "is_deleted") + _camera.CreateTime = field.NewTime(tableName, "create_time") + _camera.DeletedTime = field.NewTime(tableName, "deleted_time") + _camera.UpdateTime = field.NewTime(tableName, "update_time") + + _camera.fillFieldMap() + + return _camera +} + +type camera struct { + cameraDo cameraDo + + ALL field.Asterisk + ID field.Int32 + CameraID field.String // 摄像头的id + DisplayName field.String // 展示使用的名字 + ParentCategoryID field.Int32 // 上一级的类别 + ViewPriority field.Int32 + Status field.String // 摄像头目前状态 + Type field.String // 类别 + IPAddress field.String // ip地址 + Latitude field.String // 纬度 + Longitude field.String // 经度 + IsDeleted field.Bool + CreateTime field.Time + DeletedTime field.Time + UpdateTime field.Time + + fieldMap map[string]field.Expr +} + +func (c camera) Table(newTableName string) *camera { + c.cameraDo.UseTable(newTableName) + return c.updateTableName(newTableName) +} + +func (c camera) As(alias string) *camera { + c.cameraDo.DO = *(c.cameraDo.As(alias).(*gen.DO)) + return c.updateTableName(alias) +} + +func (c *camera) updateTableName(table string) *camera { + c.ALL = field.NewAsterisk(table) + c.ID = field.NewInt32(table, "id") + c.CameraID = field.NewString(table, "camera_id") + c.DisplayName = field.NewString(table, "display_name") + c.ParentCategoryID = field.NewInt32(table, "parent_category_id") + c.ViewPriority = field.NewInt32(table, "view_priority") + c.Status = field.NewString(table, "status") + c.Type = field.NewString(table, "type") + c.IPAddress = field.NewString(table, "ip_address") + c.Latitude = field.NewString(table, "latitude") + c.Longitude = field.NewString(table, "longitude") + c.IsDeleted = field.NewBool(table, "is_deleted") + c.CreateTime = field.NewTime(table, "create_time") + c.DeletedTime = field.NewTime(table, "deleted_time") + c.UpdateTime = field.NewTime(table, "update_time") + + c.fillFieldMap() + + return c +} + +func (c *camera) WithContext(ctx context.Context) *cameraDo { return c.cameraDo.WithContext(ctx) } + +func (c camera) TableName() string { return c.cameraDo.TableName() } + +func (c camera) Alias() string { return c.cameraDo.Alias() } + +func (c camera) Columns(cols ...field.Expr) gen.Columns { return c.cameraDo.Columns(cols...) } + +func (c *camera) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := c.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (c *camera) fillFieldMap() { + c.fieldMap = make(map[string]field.Expr, 14) + c.fieldMap["id"] = c.ID + c.fieldMap["camera_id"] = c.CameraID + c.fieldMap["display_name"] = c.DisplayName + c.fieldMap["parent_category_id"] = c.ParentCategoryID + c.fieldMap["view_priority"] = c.ViewPriority + c.fieldMap["status"] = c.Status + c.fieldMap["type"] = c.Type + c.fieldMap["ip_address"] = c.IPAddress + c.fieldMap["latitude"] = c.Latitude + c.fieldMap["longitude"] = c.Longitude + c.fieldMap["is_deleted"] = c.IsDeleted + c.fieldMap["create_time"] = c.CreateTime + c.fieldMap["deleted_time"] = c.DeletedTime + c.fieldMap["update_time"] = c.UpdateTime +} + +func (c camera) clone(db *gorm.DB) camera { + c.cameraDo.ReplaceConnPool(db.Statement.ConnPool) + return c +} + +func (c camera) replaceDB(db *gorm.DB) camera { + c.cameraDo.ReplaceDB(db) + return c +} + +type cameraDo struct{ gen.DO } + +func (c cameraDo) Debug() *cameraDo { + return c.withDO(c.DO.Debug()) +} + +func (c cameraDo) WithContext(ctx context.Context) *cameraDo { + return c.withDO(c.DO.WithContext(ctx)) +} + +func (c cameraDo) ReadDB() *cameraDo { + return c.Clauses(dbresolver.Read) +} + +func (c cameraDo) WriteDB() *cameraDo { + return c.Clauses(dbresolver.Write) +} + +func (c cameraDo) Session(config *gorm.Session) *cameraDo { + return c.withDO(c.DO.Session(config)) +} + +func (c cameraDo) Clauses(conds ...clause.Expression) *cameraDo { + return c.withDO(c.DO.Clauses(conds...)) +} + +func (c cameraDo) Returning(value interface{}, columns ...string) *cameraDo { + return c.withDO(c.DO.Returning(value, columns...)) +} + +func (c cameraDo) Not(conds ...gen.Condition) *cameraDo { + return c.withDO(c.DO.Not(conds...)) +} + +func (c cameraDo) Or(conds ...gen.Condition) *cameraDo { + return c.withDO(c.DO.Or(conds...)) +} + +func (c cameraDo) Select(conds ...field.Expr) *cameraDo { + return c.withDO(c.DO.Select(conds...)) +} + +func (c cameraDo) Where(conds ...gen.Condition) *cameraDo { + return c.withDO(c.DO.Where(conds...)) +} + +func (c cameraDo) Order(conds ...field.Expr) *cameraDo { + return c.withDO(c.DO.Order(conds...)) +} + +func (c cameraDo) Distinct(cols ...field.Expr) *cameraDo { + return c.withDO(c.DO.Distinct(cols...)) +} + +func (c cameraDo) Omit(cols ...field.Expr) *cameraDo { + return c.withDO(c.DO.Omit(cols...)) +} + +func (c cameraDo) Join(table schema.Tabler, on ...field.Expr) *cameraDo { + return c.withDO(c.DO.Join(table, on...)) +} + +func (c cameraDo) LeftJoin(table schema.Tabler, on ...field.Expr) *cameraDo { + return c.withDO(c.DO.LeftJoin(table, on...)) +} + +func (c cameraDo) RightJoin(table schema.Tabler, on ...field.Expr) *cameraDo { + return c.withDO(c.DO.RightJoin(table, on...)) +} + +func (c cameraDo) Group(cols ...field.Expr) *cameraDo { + return c.withDO(c.DO.Group(cols...)) +} + +func (c cameraDo) Having(conds ...gen.Condition) *cameraDo { + return c.withDO(c.DO.Having(conds...)) +} + +func (c cameraDo) Limit(limit int) *cameraDo { + return c.withDO(c.DO.Limit(limit)) +} + +func (c cameraDo) Offset(offset int) *cameraDo { + return c.withDO(c.DO.Offset(offset)) +} + +func (c cameraDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *cameraDo { + return c.withDO(c.DO.Scopes(funcs...)) +} + +func (c cameraDo) Unscoped() *cameraDo { + return c.withDO(c.DO.Unscoped()) +} + +func (c cameraDo) Create(values ...*model.Camera) error { + if len(values) == 0 { + return nil + } + return c.DO.Create(values) +} + +func (c cameraDo) CreateInBatches(values []*model.Camera, batchSize int) error { + return c.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (c cameraDo) Save(values ...*model.Camera) error { + if len(values) == 0 { + return nil + } + return c.DO.Save(values) +} + +func (c cameraDo) First() (*model.Camera, error) { + if result, err := c.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Camera), nil + } +} + +func (c cameraDo) Take() (*model.Camera, error) { + if result, err := c.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Camera), nil + } +} + +func (c cameraDo) Last() (*model.Camera, error) { + if result, err := c.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Camera), nil + } +} + +func (c cameraDo) Find() ([]*model.Camera, error) { + result, err := c.DO.Find() + return result.([]*model.Camera), err +} + +func (c cameraDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Camera, err error) { + buf := make([]*model.Camera, 0, batchSize) + err = c.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (c cameraDo) FindInBatches(result *[]*model.Camera, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return c.DO.FindInBatches(result, batchSize, fc) +} + +func (c cameraDo) Attrs(attrs ...field.AssignExpr) *cameraDo { + return c.withDO(c.DO.Attrs(attrs...)) +} + +func (c cameraDo) Assign(attrs ...field.AssignExpr) *cameraDo { + return c.withDO(c.DO.Assign(attrs...)) +} + +func (c cameraDo) Joins(fields ...field.RelationField) *cameraDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Joins(_f)) + } + return &c +} + +func (c cameraDo) Preload(fields ...field.RelationField) *cameraDo { + for _, _f := range fields { + c = *c.withDO(c.DO.Preload(_f)) + } + return &c +} + +func (c cameraDo) FirstOrInit() (*model.Camera, error) { + if result, err := c.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Camera), nil + } +} + +func (c cameraDo) FirstOrCreate() (*model.Camera, error) { + if result, err := c.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Camera), nil + } +} + +func (c cameraDo) FindByPage(offset int, limit int) (result []*model.Camera, count int64, err error) { + result, err = c.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = c.Offset(-1).Limit(-1).Count() + return +} + +func (c cameraDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = c.Count() + if err != nil { + return + } + + err = c.Offset(offset).Limit(limit).Scan(result) + return +} + +func (c cameraDo) Scan(result interface{}) (err error) { + return c.DO.Scan(result) +} + +func (c cameraDo) Delete(models ...*model.Camera) (result gen.ResultInfo, err error) { + return c.DO.Delete(models) +} + +func (c *cameraDo) withDO(do gen.Dao) *cameraDo { + c.DO = *do.(*gen.DO) + return c +} diff --git a/Code/backend/internal/query/gen.go b/Code/backend/internal/query/gen.go new file mode 100644 index 0000000..9e6b023 --- /dev/null +++ b/Code/backend/internal/query/gen.go @@ -0,0 +1,111 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + "database/sql" + + "gorm.io/gorm" + + "gorm.io/gen" + + "gorm.io/plugin/dbresolver" +) + +func Use(db *gorm.DB, opts ...gen.DOOption) *Query { + return &Query{ + db: db, + Camera: newCamera(db, opts...), + Person: newPerson(db, opts...), + PersonDetectionRecord: newPersonDetectionRecord(db, opts...), + TrajectoryDetectionRecord: newTrajectoryDetectionRecord(db, opts...), + } +} + +type Query struct { + db *gorm.DB + + Camera camera + Person person + PersonDetectionRecord personDetectionRecord + TrajectoryDetectionRecord trajectoryDetectionRecord +} + +func (q *Query) Available() bool { return q.db != nil } + +func (q *Query) clone(db *gorm.DB) *Query { + return &Query{ + db: db, + Camera: q.Camera.clone(db), + Person: q.Person.clone(db), + PersonDetectionRecord: q.PersonDetectionRecord.clone(db), + TrajectoryDetectionRecord: q.TrajectoryDetectionRecord.clone(db), + } +} + +func (q *Query) ReadDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Read)) +} + +func (q *Query) WriteDB() *Query { + return q.ReplaceDB(q.db.Clauses(dbresolver.Write)) +} + +func (q *Query) ReplaceDB(db *gorm.DB) *Query { + return &Query{ + db: db, + Camera: q.Camera.replaceDB(db), + Person: q.Person.replaceDB(db), + PersonDetectionRecord: q.PersonDetectionRecord.replaceDB(db), + TrajectoryDetectionRecord: q.TrajectoryDetectionRecord.replaceDB(db), + } +} + +type queryCtx struct { + Camera *cameraDo + Person *personDo + PersonDetectionRecord *personDetectionRecordDo + TrajectoryDetectionRecord *trajectoryDetectionRecordDo +} + +func (q *Query) WithContext(ctx context.Context) *queryCtx { + return &queryCtx{ + Camera: q.Camera.WithContext(ctx), + Person: q.Person.WithContext(ctx), + PersonDetectionRecord: q.PersonDetectionRecord.WithContext(ctx), + TrajectoryDetectionRecord: q.TrajectoryDetectionRecord.WithContext(ctx), + } +} + +func (q *Query) Transaction(fc func(tx *Query) error, opts ...*sql.TxOptions) error { + return q.db.Transaction(func(tx *gorm.DB) error { return fc(q.clone(tx)) }, opts...) +} + +func (q *Query) Begin(opts ...*sql.TxOptions) *QueryTx { + tx := q.db.Begin(opts...) + return &QueryTx{Query: q.clone(tx), Error: tx.Error} +} + +type QueryTx struct { + *Query + Error error +} + +func (q *QueryTx) Commit() error { + return q.db.Commit().Error +} + +func (q *QueryTx) Rollback() error { + return q.db.Rollback().Error +} + +func (q *QueryTx) SavePoint(name string) error { + return q.db.SavePoint(name).Error +} + +func (q *QueryTx) RollbackTo(name string) error { + return q.db.RollbackTo(name).Error +} diff --git a/Code/backend/internal/query/person.gen.go b/Code/backend/internal/query/person.gen.go new file mode 100644 index 0000000..3ffb695 --- /dev/null +++ b/Code/backend/internal/query/person.gen.go @@ -0,0 +1,351 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "go_backend/internal/model" +) + +func newPerson(db *gorm.DB, opts ...gen.DOOption) person { + _person := person{} + + _person.personDo.UseDB(db, opts...) + _person.personDo.UseModel(&model.Person{}) + + tableName := _person.personDo.TableName() + _person.ALL = field.NewAsterisk(tableName) + _person.ID = field.NewInt32(tableName, "id") + _person.PersonType = field.NewInt32(tableName, "person_type") + _person.PersonPicURL = field.NewString(tableName, "person_pic_url") + _person.PersonName = field.NewString(tableName, "person_name") + _person.IsDeleted = field.NewBool(tableName, "is_deleted") + _person.CreateTime = field.NewTime(tableName, "create_time") + _person.UpdateTime = field.NewTime(tableName, "update_time") + + _person.fillFieldMap() + + return _person +} + +type person struct { + personDo personDo + + ALL field.Asterisk + ID field.Int32 + PersonType field.Int32 + PersonPicURL field.String + PersonName field.String + IsDeleted field.Bool + CreateTime field.Time + UpdateTime field.Time + + fieldMap map[string]field.Expr +} + +func (p person) Table(newTableName string) *person { + p.personDo.UseTable(newTableName) + return p.updateTableName(newTableName) +} + +func (p person) As(alias string) *person { + p.personDo.DO = *(p.personDo.As(alias).(*gen.DO)) + return p.updateTableName(alias) +} + +func (p *person) updateTableName(table string) *person { + p.ALL = field.NewAsterisk(table) + p.ID = field.NewInt32(table, "id") + p.PersonType = field.NewInt32(table, "person_type") + p.PersonPicURL = field.NewString(table, "person_pic_url") + p.PersonName = field.NewString(table, "person_name") + p.IsDeleted = field.NewBool(table, "is_deleted") + p.CreateTime = field.NewTime(table, "create_time") + p.UpdateTime = field.NewTime(table, "update_time") + + p.fillFieldMap() + + return p +} + +func (p *person) WithContext(ctx context.Context) *personDo { return p.personDo.WithContext(ctx) } + +func (p person) TableName() string { return p.personDo.TableName() } + +func (p person) Alias() string { return p.personDo.Alias() } + +func (p person) Columns(cols ...field.Expr) gen.Columns { return p.personDo.Columns(cols...) } + +func (p *person) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := p.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (p *person) fillFieldMap() { + p.fieldMap = make(map[string]field.Expr, 7) + p.fieldMap["id"] = p.ID + p.fieldMap["person_type"] = p.PersonType + p.fieldMap["person_pic_url"] = p.PersonPicURL + p.fieldMap["person_name"] = p.PersonName + p.fieldMap["is_deleted"] = p.IsDeleted + p.fieldMap["create_time"] = p.CreateTime + p.fieldMap["update_time"] = p.UpdateTime +} + +func (p person) clone(db *gorm.DB) person { + p.personDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p person) replaceDB(db *gorm.DB) person { + p.personDo.ReplaceDB(db) + return p +} + +type personDo struct{ gen.DO } + +func (p personDo) Debug() *personDo { + return p.withDO(p.DO.Debug()) +} + +func (p personDo) WithContext(ctx context.Context) *personDo { + return p.withDO(p.DO.WithContext(ctx)) +} + +func (p personDo) ReadDB() *personDo { + return p.Clauses(dbresolver.Read) +} + +func (p personDo) WriteDB() *personDo { + return p.Clauses(dbresolver.Write) +} + +func (p personDo) Session(config *gorm.Session) *personDo { + return p.withDO(p.DO.Session(config)) +} + +func (p personDo) Clauses(conds ...clause.Expression) *personDo { + return p.withDO(p.DO.Clauses(conds...)) +} + +func (p personDo) Returning(value interface{}, columns ...string) *personDo { + return p.withDO(p.DO.Returning(value, columns...)) +} + +func (p personDo) Not(conds ...gen.Condition) *personDo { + return p.withDO(p.DO.Not(conds...)) +} + +func (p personDo) Or(conds ...gen.Condition) *personDo { + return p.withDO(p.DO.Or(conds...)) +} + +func (p personDo) Select(conds ...field.Expr) *personDo { + return p.withDO(p.DO.Select(conds...)) +} + +func (p personDo) Where(conds ...gen.Condition) *personDo { + return p.withDO(p.DO.Where(conds...)) +} + +func (p personDo) Order(conds ...field.Expr) *personDo { + return p.withDO(p.DO.Order(conds...)) +} + +func (p personDo) Distinct(cols ...field.Expr) *personDo { + return p.withDO(p.DO.Distinct(cols...)) +} + +func (p personDo) Omit(cols ...field.Expr) *personDo { + return p.withDO(p.DO.Omit(cols...)) +} + +func (p personDo) Join(table schema.Tabler, on ...field.Expr) *personDo { + return p.withDO(p.DO.Join(table, on...)) +} + +func (p personDo) LeftJoin(table schema.Tabler, on ...field.Expr) *personDo { + return p.withDO(p.DO.LeftJoin(table, on...)) +} + +func (p personDo) RightJoin(table schema.Tabler, on ...field.Expr) *personDo { + return p.withDO(p.DO.RightJoin(table, on...)) +} + +func (p personDo) Group(cols ...field.Expr) *personDo { + return p.withDO(p.DO.Group(cols...)) +} + +func (p personDo) Having(conds ...gen.Condition) *personDo { + return p.withDO(p.DO.Having(conds...)) +} + +func (p personDo) Limit(limit int) *personDo { + return p.withDO(p.DO.Limit(limit)) +} + +func (p personDo) Offset(offset int) *personDo { + return p.withDO(p.DO.Offset(offset)) +} + +func (p personDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *personDo { + return p.withDO(p.DO.Scopes(funcs...)) +} + +func (p personDo) Unscoped() *personDo { + return p.withDO(p.DO.Unscoped()) +} + +func (p personDo) Create(values ...*model.Person) error { + if len(values) == 0 { + return nil + } + return p.DO.Create(values) +} + +func (p personDo) CreateInBatches(values []*model.Person, batchSize int) error { + return p.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (p personDo) Save(values ...*model.Person) error { + if len(values) == 0 { + return nil + } + return p.DO.Save(values) +} + +func (p personDo) First() (*model.Person, error) { + if result, err := p.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.Person), nil + } +} + +func (p personDo) Take() (*model.Person, error) { + if result, err := p.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.Person), nil + } +} + +func (p personDo) Last() (*model.Person, error) { + if result, err := p.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.Person), nil + } +} + +func (p personDo) Find() ([]*model.Person, error) { + result, err := p.DO.Find() + return result.([]*model.Person), err +} + +func (p personDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.Person, err error) { + buf := make([]*model.Person, 0, batchSize) + err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (p personDo) FindInBatches(result *[]*model.Person, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return p.DO.FindInBatches(result, batchSize, fc) +} + +func (p personDo) Attrs(attrs ...field.AssignExpr) *personDo { + return p.withDO(p.DO.Attrs(attrs...)) +} + +func (p personDo) Assign(attrs ...field.AssignExpr) *personDo { + return p.withDO(p.DO.Assign(attrs...)) +} + +func (p personDo) Joins(fields ...field.RelationField) *personDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Joins(_f)) + } + return &p +} + +func (p personDo) Preload(fields ...field.RelationField) *personDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Preload(_f)) + } + return &p +} + +func (p personDo) FirstOrInit() (*model.Person, error) { + if result, err := p.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.Person), nil + } +} + +func (p personDo) FirstOrCreate() (*model.Person, error) { + if result, err := p.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.Person), nil + } +} + +func (p personDo) FindByPage(offset int, limit int) (result []*model.Person, count int64, err error) { + result, err = p.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = p.Offset(-1).Limit(-1).Count() + return +} + +func (p personDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = p.Count() + if err != nil { + return + } + + err = p.Offset(offset).Limit(limit).Scan(result) + return +} + +func (p personDo) Scan(result interface{}) (err error) { + return p.DO.Scan(result) +} + +func (p personDo) Delete(models ...*model.Person) (result gen.ResultInfo, err error) { + return p.DO.Delete(models) +} + +func (p *personDo) withDO(do gen.Dao) *personDo { + p.DO = *do.(*gen.DO) + return p +} diff --git a/Code/backend/internal/query/person_detection_record.gen.go b/Code/backend/internal/query/person_detection_record.gen.go new file mode 100644 index 0000000..65355e0 --- /dev/null +++ b/Code/backend/internal/query/person_detection_record.gen.go @@ -0,0 +1,375 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "go_backend/internal/model" +) + +func newPersonDetectionRecord(db *gorm.DB, opts ...gen.DOOption) personDetectionRecord { + _personDetectionRecord := personDetectionRecord{} + + _personDetectionRecord.personDetectionRecordDo.UseDB(db, opts...) + _personDetectionRecord.personDetectionRecordDo.UseModel(&model.PersonDetectionRecord{}) + + tableName := _personDetectionRecord.personDetectionRecordDo.TableName() + _personDetectionRecord.ALL = field.NewAsterisk(tableName) + _personDetectionRecord.ID = field.NewInt64(tableName, "id") + _personDetectionRecord.EventID = field.NewString(tableName, "event_id") + _personDetectionRecord.AlarmType = field.NewString(tableName, "alarm_type") + _personDetectionRecord.PersonType = field.NewString(tableName, "person_type") + _personDetectionRecord.CameraID = field.NewString(tableName, "camera_id") + _personDetectionRecord.PersonID = field.NewInt32(tableName, "person_id") + _personDetectionRecord.Address = field.NewString(tableName, "address") + _personDetectionRecord.DetectTime = field.NewTime(tableName, "detect_time") + _personDetectionRecord.ProcessStatus = field.NewString(tableName, "process_status") + _personDetectionRecord.TrajectoryDetectionID = field.NewInt64(tableName, "trajectory_detection_id") + _personDetectionRecord.CreateTime = field.NewTime(tableName, "create_time") + _personDetectionRecord.UpdateTime = field.NewTime(tableName, "update_time") + + _personDetectionRecord.fillFieldMap() + + return _personDetectionRecord +} + +type personDetectionRecord struct { + personDetectionRecordDo personDetectionRecordDo + + ALL field.Asterisk + ID field.Int64 + EventID field.String + AlarmType field.String + PersonType field.String + CameraID field.String + PersonID field.Int32 + Address field.String + DetectTime field.Time + ProcessStatus field.String + TrajectoryDetectionID field.Int64 + CreateTime field.Time + UpdateTime field.Time + + fieldMap map[string]field.Expr +} + +func (p personDetectionRecord) Table(newTableName string) *personDetectionRecord { + p.personDetectionRecordDo.UseTable(newTableName) + return p.updateTableName(newTableName) +} + +func (p personDetectionRecord) As(alias string) *personDetectionRecord { + p.personDetectionRecordDo.DO = *(p.personDetectionRecordDo.As(alias).(*gen.DO)) + return p.updateTableName(alias) +} + +func (p *personDetectionRecord) updateTableName(table string) *personDetectionRecord { + p.ALL = field.NewAsterisk(table) + p.ID = field.NewInt64(table, "id") + p.EventID = field.NewString(table, "event_id") + p.AlarmType = field.NewString(table, "alarm_type") + p.PersonType = field.NewString(table, "person_type") + p.CameraID = field.NewString(table, "camera_id") + p.PersonID = field.NewInt32(table, "person_id") + p.Address = field.NewString(table, "address") + p.DetectTime = field.NewTime(table, "detect_time") + p.ProcessStatus = field.NewString(table, "process_status") + p.TrajectoryDetectionID = field.NewInt64(table, "trajectory_detection_id") + p.CreateTime = field.NewTime(table, "create_time") + p.UpdateTime = field.NewTime(table, "update_time") + + p.fillFieldMap() + + return p +} + +func (p *personDetectionRecord) WithContext(ctx context.Context) *personDetectionRecordDo { + return p.personDetectionRecordDo.WithContext(ctx) +} + +func (p personDetectionRecord) TableName() string { return p.personDetectionRecordDo.TableName() } + +func (p personDetectionRecord) Alias() string { return p.personDetectionRecordDo.Alias() } + +func (p personDetectionRecord) Columns(cols ...field.Expr) gen.Columns { + return p.personDetectionRecordDo.Columns(cols...) +} + +func (p *personDetectionRecord) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := p.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (p *personDetectionRecord) fillFieldMap() { + p.fieldMap = make(map[string]field.Expr, 12) + p.fieldMap["id"] = p.ID + p.fieldMap["event_id"] = p.EventID + p.fieldMap["alarm_type"] = p.AlarmType + p.fieldMap["person_type"] = p.PersonType + p.fieldMap["camera_id"] = p.CameraID + p.fieldMap["person_id"] = p.PersonID + p.fieldMap["address"] = p.Address + p.fieldMap["detect_time"] = p.DetectTime + p.fieldMap["process_status"] = p.ProcessStatus + p.fieldMap["trajectory_detection_id"] = p.TrajectoryDetectionID + p.fieldMap["create_time"] = p.CreateTime + p.fieldMap["update_time"] = p.UpdateTime +} + +func (p personDetectionRecord) clone(db *gorm.DB) personDetectionRecord { + p.personDetectionRecordDo.ReplaceConnPool(db.Statement.ConnPool) + return p +} + +func (p personDetectionRecord) replaceDB(db *gorm.DB) personDetectionRecord { + p.personDetectionRecordDo.ReplaceDB(db) + return p +} + +type personDetectionRecordDo struct{ gen.DO } + +func (p personDetectionRecordDo) Debug() *personDetectionRecordDo { + return p.withDO(p.DO.Debug()) +} + +func (p personDetectionRecordDo) WithContext(ctx context.Context) *personDetectionRecordDo { + return p.withDO(p.DO.WithContext(ctx)) +} + +func (p personDetectionRecordDo) ReadDB() *personDetectionRecordDo { + return p.Clauses(dbresolver.Read) +} + +func (p personDetectionRecordDo) WriteDB() *personDetectionRecordDo { + return p.Clauses(dbresolver.Write) +} + +func (p personDetectionRecordDo) Session(config *gorm.Session) *personDetectionRecordDo { + return p.withDO(p.DO.Session(config)) +} + +func (p personDetectionRecordDo) Clauses(conds ...clause.Expression) *personDetectionRecordDo { + return p.withDO(p.DO.Clauses(conds...)) +} + +func (p personDetectionRecordDo) Returning(value interface{}, columns ...string) *personDetectionRecordDo { + return p.withDO(p.DO.Returning(value, columns...)) +} + +func (p personDetectionRecordDo) Not(conds ...gen.Condition) *personDetectionRecordDo { + return p.withDO(p.DO.Not(conds...)) +} + +func (p personDetectionRecordDo) Or(conds ...gen.Condition) *personDetectionRecordDo { + return p.withDO(p.DO.Or(conds...)) +} + +func (p personDetectionRecordDo) Select(conds ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Select(conds...)) +} + +func (p personDetectionRecordDo) Where(conds ...gen.Condition) *personDetectionRecordDo { + return p.withDO(p.DO.Where(conds...)) +} + +func (p personDetectionRecordDo) Order(conds ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Order(conds...)) +} + +func (p personDetectionRecordDo) Distinct(cols ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Distinct(cols...)) +} + +func (p personDetectionRecordDo) Omit(cols ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Omit(cols...)) +} + +func (p personDetectionRecordDo) Join(table schema.Tabler, on ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Join(table, on...)) +} + +func (p personDetectionRecordDo) LeftJoin(table schema.Tabler, on ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.LeftJoin(table, on...)) +} + +func (p personDetectionRecordDo) RightJoin(table schema.Tabler, on ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.RightJoin(table, on...)) +} + +func (p personDetectionRecordDo) Group(cols ...field.Expr) *personDetectionRecordDo { + return p.withDO(p.DO.Group(cols...)) +} + +func (p personDetectionRecordDo) Having(conds ...gen.Condition) *personDetectionRecordDo { + return p.withDO(p.DO.Having(conds...)) +} + +func (p personDetectionRecordDo) Limit(limit int) *personDetectionRecordDo { + return p.withDO(p.DO.Limit(limit)) +} + +func (p personDetectionRecordDo) Offset(offset int) *personDetectionRecordDo { + return p.withDO(p.DO.Offset(offset)) +} + +func (p personDetectionRecordDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *personDetectionRecordDo { + return p.withDO(p.DO.Scopes(funcs...)) +} + +func (p personDetectionRecordDo) Unscoped() *personDetectionRecordDo { + return p.withDO(p.DO.Unscoped()) +} + +func (p personDetectionRecordDo) Create(values ...*model.PersonDetectionRecord) error { + if len(values) == 0 { + return nil + } + return p.DO.Create(values) +} + +func (p personDetectionRecordDo) CreateInBatches(values []*model.PersonDetectionRecord, batchSize int) error { + return p.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (p personDetectionRecordDo) Save(values ...*model.PersonDetectionRecord) error { + if len(values) == 0 { + return nil + } + return p.DO.Save(values) +} + +func (p personDetectionRecordDo) First() (*model.PersonDetectionRecord, error) { + if result, err := p.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.PersonDetectionRecord), nil + } +} + +func (p personDetectionRecordDo) Take() (*model.PersonDetectionRecord, error) { + if result, err := p.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.PersonDetectionRecord), nil + } +} + +func (p personDetectionRecordDo) Last() (*model.PersonDetectionRecord, error) { + if result, err := p.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.PersonDetectionRecord), nil + } +} + +func (p personDetectionRecordDo) Find() ([]*model.PersonDetectionRecord, error) { + result, err := p.DO.Find() + return result.([]*model.PersonDetectionRecord), err +} + +func (p personDetectionRecordDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.PersonDetectionRecord, err error) { + buf := make([]*model.PersonDetectionRecord, 0, batchSize) + err = p.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (p personDetectionRecordDo) FindInBatches(result *[]*model.PersonDetectionRecord, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return p.DO.FindInBatches(result, batchSize, fc) +} + +func (p personDetectionRecordDo) Attrs(attrs ...field.AssignExpr) *personDetectionRecordDo { + return p.withDO(p.DO.Attrs(attrs...)) +} + +func (p personDetectionRecordDo) Assign(attrs ...field.AssignExpr) *personDetectionRecordDo { + return p.withDO(p.DO.Assign(attrs...)) +} + +func (p personDetectionRecordDo) Joins(fields ...field.RelationField) *personDetectionRecordDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Joins(_f)) + } + return &p +} + +func (p personDetectionRecordDo) Preload(fields ...field.RelationField) *personDetectionRecordDo { + for _, _f := range fields { + p = *p.withDO(p.DO.Preload(_f)) + } + return &p +} + +func (p personDetectionRecordDo) FirstOrInit() (*model.PersonDetectionRecord, error) { + if result, err := p.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.PersonDetectionRecord), nil + } +} + +func (p personDetectionRecordDo) FirstOrCreate() (*model.PersonDetectionRecord, error) { + if result, err := p.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.PersonDetectionRecord), nil + } +} + +func (p personDetectionRecordDo) FindByPage(offset int, limit int) (result []*model.PersonDetectionRecord, count int64, err error) { + result, err = p.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = p.Offset(-1).Limit(-1).Count() + return +} + +func (p personDetectionRecordDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = p.Count() + if err != nil { + return + } + + err = p.Offset(offset).Limit(limit).Scan(result) + return +} + +func (p personDetectionRecordDo) Scan(result interface{}) (err error) { + return p.DO.Scan(result) +} + +func (p personDetectionRecordDo) Delete(models ...*model.PersonDetectionRecord) (result gen.ResultInfo, err error) { + return p.DO.Delete(models) +} + +func (p *personDetectionRecordDo) withDO(do gen.Dao) *personDetectionRecordDo { + p.DO = *do.(*gen.DO) + return p +} diff --git a/Code/backend/internal/query/trajectory_detection_record.gen.go b/Code/backend/internal/query/trajectory_detection_record.gen.go new file mode 100644 index 0000000..f29331b --- /dev/null +++ b/Code/backend/internal/query/trajectory_detection_record.gen.go @@ -0,0 +1,365 @@ +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. +// Code generated by gorm.io/gen. DO NOT EDIT. + +package query + +import ( + "context" + + "gorm.io/gorm" + "gorm.io/gorm/clause" + "gorm.io/gorm/schema" + + "gorm.io/gen" + "gorm.io/gen/field" + + "gorm.io/plugin/dbresolver" + + "go_backend/internal/model" +) + +func newTrajectoryDetectionRecord(db *gorm.DB, opts ...gen.DOOption) trajectoryDetectionRecord { + _trajectoryDetectionRecord := trajectoryDetectionRecord{} + + _trajectoryDetectionRecord.trajectoryDetectionRecordDo.UseDB(db, opts...) + _trajectoryDetectionRecord.trajectoryDetectionRecordDo.UseModel(&model.TrajectoryDetectionRecord{}) + + tableName := _trajectoryDetectionRecord.trajectoryDetectionRecordDo.TableName() + _trajectoryDetectionRecord.ALL = field.NewAsterisk(tableName) + _trajectoryDetectionRecord.ID = field.NewInt32(tableName, "id") + _trajectoryDetectionRecord.PersonDetectionRecordIds = field.NewString(tableName, "person_detection_record_ids") + _trajectoryDetectionRecord.PersonID = field.NewInt32(tableName, "person_id") + _trajectoryDetectionRecord.TrajectoryLength = field.NewInt32(tableName, "trajectory_length") + _trajectoryDetectionRecord.Trajectory = field.NewString(tableName, "trajectory") + _trajectoryDetectionRecord.IsDeleted = field.NewBool(tableName, "is_deleted") + _trajectoryDetectionRecord.CreateTime = field.NewTime(tableName, "create_time") + _trajectoryDetectionRecord.UpdateTime = field.NewTime(tableName, "update_time") + _trajectoryDetectionRecord.DeletedTime = field.NewTime(tableName, "deleted_time") + + _trajectoryDetectionRecord.fillFieldMap() + + return _trajectoryDetectionRecord +} + +type trajectoryDetectionRecord struct { + trajectoryDetectionRecordDo trajectoryDetectionRecordDo + + ALL field.Asterisk + ID field.Int32 + PersonDetectionRecordIds field.String + PersonID field.Int32 + TrajectoryLength field.Int32 + Trajectory field.String + IsDeleted field.Bool + CreateTime field.Time + UpdateTime field.Time + DeletedTime field.Time + + fieldMap map[string]field.Expr +} + +func (t trajectoryDetectionRecord) Table(newTableName string) *trajectoryDetectionRecord { + t.trajectoryDetectionRecordDo.UseTable(newTableName) + return t.updateTableName(newTableName) +} + +func (t trajectoryDetectionRecord) As(alias string) *trajectoryDetectionRecord { + t.trajectoryDetectionRecordDo.DO = *(t.trajectoryDetectionRecordDo.As(alias).(*gen.DO)) + return t.updateTableName(alias) +} + +func (t *trajectoryDetectionRecord) updateTableName(table string) *trajectoryDetectionRecord { + t.ALL = field.NewAsterisk(table) + t.ID = field.NewInt32(table, "id") + t.PersonDetectionRecordIds = field.NewString(table, "person_detection_record_ids") + t.PersonID = field.NewInt32(table, "person_id") + t.TrajectoryLength = field.NewInt32(table, "trajectory_length") + t.Trajectory = field.NewString(table, "trajectory") + t.IsDeleted = field.NewBool(table, "is_deleted") + t.CreateTime = field.NewTime(table, "create_time") + t.UpdateTime = field.NewTime(table, "update_time") + t.DeletedTime = field.NewTime(table, "deleted_time") + + t.fillFieldMap() + + return t +} + +func (t *trajectoryDetectionRecord) WithContext(ctx context.Context) *trajectoryDetectionRecordDo { + return t.trajectoryDetectionRecordDo.WithContext(ctx) +} + +func (t trajectoryDetectionRecord) TableName() string { + return t.trajectoryDetectionRecordDo.TableName() +} + +func (t trajectoryDetectionRecord) Alias() string { return t.trajectoryDetectionRecordDo.Alias() } + +func (t trajectoryDetectionRecord) Columns(cols ...field.Expr) gen.Columns { + return t.trajectoryDetectionRecordDo.Columns(cols...) +} + +func (t *trajectoryDetectionRecord) GetFieldByName(fieldName string) (field.OrderExpr, bool) { + _f, ok := t.fieldMap[fieldName] + if !ok || _f == nil { + return nil, false + } + _oe, ok := _f.(field.OrderExpr) + return _oe, ok +} + +func (t *trajectoryDetectionRecord) fillFieldMap() { + t.fieldMap = make(map[string]field.Expr, 9) + t.fieldMap["id"] = t.ID + t.fieldMap["person_detection_record_ids"] = t.PersonDetectionRecordIds + t.fieldMap["person_id"] = t.PersonID + t.fieldMap["trajectory_length"] = t.TrajectoryLength + t.fieldMap["trajectory"] = t.Trajectory + t.fieldMap["is_deleted"] = t.IsDeleted + t.fieldMap["create_time"] = t.CreateTime + t.fieldMap["update_time"] = t.UpdateTime + t.fieldMap["deleted_time"] = t.DeletedTime +} + +func (t trajectoryDetectionRecord) clone(db *gorm.DB) trajectoryDetectionRecord { + t.trajectoryDetectionRecordDo.ReplaceConnPool(db.Statement.ConnPool) + return t +} + +func (t trajectoryDetectionRecord) replaceDB(db *gorm.DB) trajectoryDetectionRecord { + t.trajectoryDetectionRecordDo.ReplaceDB(db) + return t +} + +type trajectoryDetectionRecordDo struct{ gen.DO } + +func (t trajectoryDetectionRecordDo) Debug() *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Debug()) +} + +func (t trajectoryDetectionRecordDo) WithContext(ctx context.Context) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.WithContext(ctx)) +} + +func (t trajectoryDetectionRecordDo) ReadDB() *trajectoryDetectionRecordDo { + return t.Clauses(dbresolver.Read) +} + +func (t trajectoryDetectionRecordDo) WriteDB() *trajectoryDetectionRecordDo { + return t.Clauses(dbresolver.Write) +} + +func (t trajectoryDetectionRecordDo) Session(config *gorm.Session) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Session(config)) +} + +func (t trajectoryDetectionRecordDo) Clauses(conds ...clause.Expression) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Clauses(conds...)) +} + +func (t trajectoryDetectionRecordDo) Returning(value interface{}, columns ...string) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Returning(value, columns...)) +} + +func (t trajectoryDetectionRecordDo) Not(conds ...gen.Condition) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Not(conds...)) +} + +func (t trajectoryDetectionRecordDo) Or(conds ...gen.Condition) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Or(conds...)) +} + +func (t trajectoryDetectionRecordDo) Select(conds ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Select(conds...)) +} + +func (t trajectoryDetectionRecordDo) Where(conds ...gen.Condition) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Where(conds...)) +} + +func (t trajectoryDetectionRecordDo) Order(conds ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Order(conds...)) +} + +func (t trajectoryDetectionRecordDo) Distinct(cols ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Distinct(cols...)) +} + +func (t trajectoryDetectionRecordDo) Omit(cols ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Omit(cols...)) +} + +func (t trajectoryDetectionRecordDo) Join(table schema.Tabler, on ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Join(table, on...)) +} + +func (t trajectoryDetectionRecordDo) LeftJoin(table schema.Tabler, on ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.LeftJoin(table, on...)) +} + +func (t trajectoryDetectionRecordDo) RightJoin(table schema.Tabler, on ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.RightJoin(table, on...)) +} + +func (t trajectoryDetectionRecordDo) Group(cols ...field.Expr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Group(cols...)) +} + +func (t trajectoryDetectionRecordDo) Having(conds ...gen.Condition) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Having(conds...)) +} + +func (t trajectoryDetectionRecordDo) Limit(limit int) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Limit(limit)) +} + +func (t trajectoryDetectionRecordDo) Offset(offset int) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Offset(offset)) +} + +func (t trajectoryDetectionRecordDo) Scopes(funcs ...func(gen.Dao) gen.Dao) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Scopes(funcs...)) +} + +func (t trajectoryDetectionRecordDo) Unscoped() *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Unscoped()) +} + +func (t trajectoryDetectionRecordDo) Create(values ...*model.TrajectoryDetectionRecord) error { + if len(values) == 0 { + return nil + } + return t.DO.Create(values) +} + +func (t trajectoryDetectionRecordDo) CreateInBatches(values []*model.TrajectoryDetectionRecord, batchSize int) error { + return t.DO.CreateInBatches(values, batchSize) +} + +// Save : !!! underlying implementation is different with GORM +// The method is equivalent to executing the statement: db.Clauses(clause.OnConflict{UpdateAll: true}).Create(values) +func (t trajectoryDetectionRecordDo) Save(values ...*model.TrajectoryDetectionRecord) error { + if len(values) == 0 { + return nil + } + return t.DO.Save(values) +} + +func (t trajectoryDetectionRecordDo) First() (*model.TrajectoryDetectionRecord, error) { + if result, err := t.DO.First(); err != nil { + return nil, err + } else { + return result.(*model.TrajectoryDetectionRecord), nil + } +} + +func (t trajectoryDetectionRecordDo) Take() (*model.TrajectoryDetectionRecord, error) { + if result, err := t.DO.Take(); err != nil { + return nil, err + } else { + return result.(*model.TrajectoryDetectionRecord), nil + } +} + +func (t trajectoryDetectionRecordDo) Last() (*model.TrajectoryDetectionRecord, error) { + if result, err := t.DO.Last(); err != nil { + return nil, err + } else { + return result.(*model.TrajectoryDetectionRecord), nil + } +} + +func (t trajectoryDetectionRecordDo) Find() ([]*model.TrajectoryDetectionRecord, error) { + result, err := t.DO.Find() + return result.([]*model.TrajectoryDetectionRecord), err +} + +func (t trajectoryDetectionRecordDo) FindInBatch(batchSize int, fc func(tx gen.Dao, batch int) error) (results []*model.TrajectoryDetectionRecord, err error) { + buf := make([]*model.TrajectoryDetectionRecord, 0, batchSize) + err = t.DO.FindInBatches(&buf, batchSize, func(tx gen.Dao, batch int) error { + defer func() { results = append(results, buf...) }() + return fc(tx, batch) + }) + return results, err +} + +func (t trajectoryDetectionRecordDo) FindInBatches(result *[]*model.TrajectoryDetectionRecord, batchSize int, fc func(tx gen.Dao, batch int) error) error { + return t.DO.FindInBatches(result, batchSize, fc) +} + +func (t trajectoryDetectionRecordDo) Attrs(attrs ...field.AssignExpr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Attrs(attrs...)) +} + +func (t trajectoryDetectionRecordDo) Assign(attrs ...field.AssignExpr) *trajectoryDetectionRecordDo { + return t.withDO(t.DO.Assign(attrs...)) +} + +func (t trajectoryDetectionRecordDo) Joins(fields ...field.RelationField) *trajectoryDetectionRecordDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Joins(_f)) + } + return &t +} + +func (t trajectoryDetectionRecordDo) Preload(fields ...field.RelationField) *trajectoryDetectionRecordDo { + for _, _f := range fields { + t = *t.withDO(t.DO.Preload(_f)) + } + return &t +} + +func (t trajectoryDetectionRecordDo) FirstOrInit() (*model.TrajectoryDetectionRecord, error) { + if result, err := t.DO.FirstOrInit(); err != nil { + return nil, err + } else { + return result.(*model.TrajectoryDetectionRecord), nil + } +} + +func (t trajectoryDetectionRecordDo) FirstOrCreate() (*model.TrajectoryDetectionRecord, error) { + if result, err := t.DO.FirstOrCreate(); err != nil { + return nil, err + } else { + return result.(*model.TrajectoryDetectionRecord), nil + } +} + +func (t trajectoryDetectionRecordDo) FindByPage(offset int, limit int) (result []*model.TrajectoryDetectionRecord, count int64, err error) { + result, err = t.Offset(offset).Limit(limit).Find() + if err != nil { + return + } + + if size := len(result); 0 < limit && 0 < size && size < limit { + count = int64(size + offset) + return + } + + count, err = t.Offset(-1).Limit(-1).Count() + return +} + +func (t trajectoryDetectionRecordDo) ScanByPage(result interface{}, offset int, limit int) (count int64, err error) { + count, err = t.Count() + if err != nil { + return + } + + err = t.Offset(offset).Limit(limit).Scan(result) + return +} + +func (t trajectoryDetectionRecordDo) Scan(result interface{}) (err error) { + return t.DO.Scan(result) +} + +func (t trajectoryDetectionRecordDo) Delete(models ...*model.TrajectoryDetectionRecord) (result gen.ResultInfo, err error) { + return t.DO.Delete(models) +} + +func (t *trajectoryDetectionRecordDo) withDO(do gen.Dao) *trajectoryDetectionRecordDo { + t.DO = *do.(*gen.DO) + return t +} diff --git a/Code/backend/internal/scheduled_task/mergeTrajectory.go b/Code/backend/internal/scheduled_task/mergeTrajectory.go new file mode 100644 index 0000000..b5bb0d8 --- /dev/null +++ b/Code/backend/internal/scheduled_task/mergeTrajectory.go @@ -0,0 +1,157 @@ +package scheduledtask + +import ( + "encoding/json" + "fmt" + "go_backend/internal/dbs" + "go_backend/internal/model" + "log" + "sync" + "time" +) + +var ( + globalCounter int + globalLock sync.Mutex +) + +func MergeTrajectory() { + if !tryToGetLock() { + globalCounter++ + return + } + defer globalLock.Unlock() + + records := make([]model.PersonDetectionRecord, 0) + db := dbs.GetGormDB() + now := time.Now() + // 如果没获取到锁,那就顺延一分钟,下次查询时多查询一分钟的,不能漏了 + minuteCount := 2 + globalCounter + startOfPeriod := now.Add(-1 * time.Minute * time.Duration(minuteCount)) + result := db.Model(model.PersonDetectionRecord{}). + Where("create_time >= ? AND create_time <= ?", startOfPeriod, now). + Order("create_time ASC").Find(&records) + if result.Error != nil { + fmt.Println(result.Error) + return + } + globalCounter = 0 + + // 记录的是personid和personid所对应的record数组 + recordMap := make(map[int][]model.PersonDetectionRecord) + for _, record := range records { + recordMap[int(record.PersonID)] = append(recordMap[int(record.PersonID)], record) + } + // 对每一个personid对应的数组起一个协程进行处理 + var wg sync.WaitGroup + for personID, records := range recordMap { + wg.Add(1) + go func(personID int, records []model.PersonDetectionRecord) { + defer wg.Done() + processRecords(personID, records) + }(personID, records) + } + wg.Wait() + +} + +func tryToGetLock() bool { + if globalLock.TryLock() { + return true + } + return false +} + +func processRecords(personID int, records []model.PersonDetectionRecord) { + var isInited bool + + // 如果第一条记录的都没有轨迹记录,那说明该行人在此时还没有轨迹记录,需要进行初始化 + if records[0].TrajectoryDetectionID == 0 { + isInited = false + } else { + isInited = true + } + + var trajectoryRecord model.TrajectoryDetectionRecord + var trajectoryRecordArray []int + var trajectoryCameraArray []string + + if !isInited { + trajectoryRecord.PersonID = int32(personID) + trajectoryRecordArray = make([]int, 0) + trajectoryCameraArray = make([]string, 0) + } else { + trajectoryRecord, trajectoryRecordArray, trajectoryCameraArray = getTrajectoryFromDB(personID) + } + + for _, record := range records { + // 如果轨迹id不是0,说明已经有轨迹记录 + if record.TrajectoryDetectionID != 0 { + continue + } + trajectoryRecord.TrajectoryLength++ + trajectoryRecordArray = append(trajectoryRecordArray, int(record.ID)) + trajectoryCameraArray = append(trajectoryCameraArray, record.CameraID) + } + + recordStr, _ := json.Marshal(trajectoryRecordArray) + cameraStr, _ := json.Marshal(trajectoryCameraArray) + + newRecord := model.TrajectoryDetectionRecord{ + Trajectory: string(cameraStr), + PersonDetectionRecordIds: string(recordStr), + TrajectoryLength: int32(len(cameraStr))} + + // 如果没有初始化,那就create新记录,不然就update + if !isInited { + dbs.GetGormDB().Model(model.TrajectoryDetectionRecord{}).Create(&newRecord) + } else { + dbs.GetGormDB().Model(model.TrajectoryDetectionRecord{}).Where("id = ?", trajectoryRecord.ID).Updates(&newRecord) + } + + // 对每一条检测记录,更新他的轨迹记录 + for _, record := range records { + if record.TrajectoryDetectionID != 0 { + continue + } + var temp model.PersonDetectionRecord + temp.TrajectoryDetectionID = int64(newRecord.ID) + temp.ID = record.ID + dbs.GetGormDB().Model(model.PersonDetectionRecord{}).Where("id = ?", record.ID).Updates(temp) + } +} + +func getTrajectoryFromDB(id int) (model.TrajectoryDetectionRecord, []int, []string) { + var temp []model.TrajectoryDetectionRecord + var errR model.TrajectoryDetectionRecord + db := dbs.GetGormDB() + result := db.Where("id = ?", id).Find(&temp) + + if result.Error != nil { + fmt.Println(result.Error) + return errR, nil, nil + } + if len(temp) > 1 { + log.Fatalln("find more than one record which id is ", id) + return errR, nil, nil + } + + trajectoryRecord := temp[0] + + // 获取行人检测的数组 + var data []int + err := json.Unmarshal([]byte(trajectoryRecord.PersonDetectionRecordIds), &data) + if err != nil { + log.Fatalln(err) + } + trajectoryRecordArray := data + // 获取摄像头检测的轨迹数组 + var data1 []string + err = json.Unmarshal([]byte(trajectoryRecord.Trajectory), &data1) + if err != nil { + log.Fatalln(err) + } + trajectoryCameraArray := data1 + + return trajectoryRecord, trajectoryRecordArray, trajectoryCameraArray +} diff --git a/Code/backend/internal/utils/snowflake.go b/Code/backend/internal/utils/snowflake.go new file mode 100644 index 0000000..4554f3d --- /dev/null +++ b/Code/backend/internal/utils/snowflake.go @@ -0,0 +1,59 @@ +package utils + +import ( + "fmt" + "sync" + "time" +) + +const ( + epoch = int64(1609459200000) // 2021-01-01 00:00:00 的时间戳(毫秒) + workerBits = 5 + sequenceBits = 12 + maxWorkerID = -1 ^ (-1 << workerBits) + maxSequenceID = -1 ^ (-1 << sequenceBits) + workerShift = sequenceBits + timestampShift = sequenceBits + workerBits +) + +type Snowflake struct { + mu sync.Mutex + timestamp int64 + workerID int + sequenceID int +} + +func NewSnowflake(workerID int) *Snowflake { + if workerID < 0 || workerID > maxWorkerID { + panic(fmt.Sprintf("worker ID must be between 0 and %d", maxWorkerID)) + } + return &Snowflake{ + timestamp: 0, + workerID: workerID, + sequenceID: 0, + } +} + +func (s *Snowflake) NextID() int64 { + s.mu.Lock() + defer s.mu.Unlock() + + currentTime := time.Now().UnixNano() / 1000000 // 转换为毫秒 + if s.timestamp == currentTime { + s.sequenceID = (s.sequenceID + 1) & maxSequenceID + if s.sequenceID == 0 { + // 当前毫秒内的序列号用尽,等待下一毫秒 + for currentTime <= s.timestamp { + currentTime = time.Now().UnixNano() / 1000000 + } + } + } else { + s.sequenceID = 0 + } + + s.timestamp = currentTime + id := ((currentTime - epoch) << timestampShift) | + (int64(s.workerID) << workerShift) | + int64(s.sequenceID) + return id +} diff --git a/Code/backend/internal/utils/util.go b/Code/backend/internal/utils/util.go new file mode 100644 index 0000000..728ae69 --- /dev/null +++ b/Code/backend/internal/utils/util.go @@ -0,0 +1,123 @@ +package utils + +import ( + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "os/exec" + "reflect" +) + +func PrintSlice(s interface{}) { + rv := reflect.ValueOf(s) + if rv.Kind() != reflect.Slice { + fmt.Println("wrong slice") + } + + for i := 0; i < rv.Len(); i++ { + elem := rv.Index(i) + if elem.Kind() == reflect.Struct { + // 元素是结构体,打印其字段和值 + fmt.Printf("Element %d:\n", i) + for j := 0; j < elem.NumField(); j++ { + field := elem.Type().Field(j) + value := elem.Field(j) + fmt.Printf(" %s: %v\n", field.Name, value.Interface()) + } + } else { + // 元素不是结构体,直接打印 + fmt.Printf("%d: %v\n", i, elem.Interface()) + } + } +} + +// PrintStruct 打印结构体的字段和值 +func PrintStruct(s interface{}) { + rt := reflect.TypeOf(s) + rv := reflect.ValueOf(s) + + // 确保传入的是结构体 + if rt.Kind() != reflect.Struct { + fmt.Println("传入的不是一个结构体") + return + } + + // 遍历结构体的所有字段 + for i := 0; i < rt.NumField(); i++ { + field := rt.Field(i) + value := rv.Field(i) + + // 打印字段名和值 + fmt.Printf("%s: %v\n", field.Name, value.Interface()) + } +} + +// PrintStructPtr 打印通过指针传递的结构体的字段和值 +func PrintStructPtr(ptr interface{}) { + // 确保传入的是一个指针 + if reflect.TypeOf(ptr).Kind() != reflect.Ptr { + fmt.Println("传入的不是一个指针") + return + } + + // 通过指针访问结构体 + rt := reflect.TypeOf(ptr).Elem() // 获取指针指向的类型 + rv := reflect.ValueOf(ptr).Elem() // 获取指针指向的值 + + // 确保指针指向的是结构体 + if rt.Kind() != reflect.Struct { + fmt.Println("指针指向的不是一个结构体") + return + } + + // 遍历结构体的所有字段 + for i := 0; i < rt.NumField(); i++ { + field := rt.Field(i) + value := rv.Field(i) + + // 打印字段名和值 + fmt.Printf("%s: %v\n", field.Name, value.Interface()) + } +} + +func FindMaxIndex(slice []float64) int { + if len(slice) == 0 { + return -1 + } + + maxIndex := 0 + maxValue := slice[0] + + for i, v := range slice { + if v > maxValue { + maxValue = v + maxIndex = i + } + } + + return maxIndex +} + +func RunCommand(command string) error { + cmd := exec.Command("sh", "-c", command) + + return cmd.Run() +} + +func Cors() gin.HandlerFunc { + return func(c *gin.Context) { + method := c.Request.Method + origin := c.Request.Header.Get("Origin") + if origin != "" { + c.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名 + c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE") + c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization") + c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type") + c.Header("Access-Control-Allow-Credentials", "true") + } + if method == "OPTIONS" { + c.AbortWithStatus(http.StatusNoContent) + } + c.Next() + } +} diff --git a/Docs/使用教程.md b/Docs/使用教程.md new file mode 100644 index 0000000..9558689 --- /dev/null +++ b/Docs/使用教程.md @@ -0,0 +1,4 @@ +# 使用教程 + ++ 先在根目录执行go mod tidy更新依赖 ++ 然后在cmd/manager里执行go run main.go \ No newline at end of file diff --git a/智能监控项目-后端.md b/智能监控项目-后端.md new file mode 100644 index 0000000..68d015f --- /dev/null +++ b/智能监控项目-后端.md @@ -0,0 +1,4 @@ +# 智能监控项目-后端 + ++ 使用go语言编写,使用gin框架作为web框架 ++ 使用mysql数据库存储数据 \ No newline at end of file