Forráskód Böngészése

Merge remote-tracking branch 'origin/master'

2545307760@qq.com 2 napja
szülő
commit
afdde04d98

+ 1 - 1
server/config.yaml

@@ -172,7 +172,7 @@ qiniu:
 redis:
     addr: 127.0.0.1:6379
     password: ""
-    db: 0
+    db: 4
     useCluster: false
     clusterAddrs:
         - 172.21.0.3:7000

+ 33 - 24
server/dao/device.go

@@ -7,18 +7,20 @@ import (
 
 type Device struct {
 	global.GVA_MODEL
-	Sn           string        `json:"sn" gorm:"comment:设备sn"`
-	Name         string        `json:"name" gorm:"comment:名称"`
-	Address      string        `json:"address" gorm:"comment:设备地址"`
-	TaskTime     uint          `json:"taskTime" gorm:"comment:采集时间"`
-	WaitTime     uint          `json:"waitTime" gorm:"comment:延迟时间"`
-	RadarId      int8          `json:"radarId" gorm:"comment:雷达id"`
-	SerialId     int8          `json:"serialId" gorm:"comment:串口id"`
-	Genre        int           `json:"genre" gorm:"index;comment:类型id"`
-	DeviceGenre  DeviceGenre   `json:"deviceGenre" gorm:"foreignKey:Genre;"`
-	TunnelId     int           `json:"tunnelId" gorm:"column:tunnel_id"`
-	Tunnel       Tunnel        `json:"tunnel" gorm:"foreignKey:TunnelId"`
-	DeviceRelays []DeviceRelay `json:"deviceRelays" gorm:"foreignKey:DeviceId"`
+	Sn                string              `json:"sn" gorm:"comment:设备sn"`
+	Name              string              `json:"name" gorm:"comment:名称"`
+	State             bool                `json:"state" gorm:"comment:设备状态"`
+	Address           string              `json:"address" gorm:"comment:设备地址"`
+	TaskTime          uint                `json:"taskTime" gorm:"comment:采集时间"`
+	WaitTime          uint                `json:"waitTime" gorm:"comment:延迟时间"`
+	RadarId           int8                `json:"radarId" gorm:"comment:雷达id"`
+	SerialId          int8                `json:"serialId" gorm:"comment:串口id"`
+	Genre             int                 `json:"genre" gorm:"index;comment:类型id"`
+	DeviceGenre       DeviceGenre         `json:"deviceGenre" gorm:"foreignKey:Genre;"`
+	TunnelId          int                 `json:"tunnelId" gorm:"column:tunnel_id"`
+	Tunnel            Tunnel              `json:"tunnel" gorm:"foreignKey:TunnelId"`
+	DeviceRelays      []DeviceRelay       `json:"deviceRelays" gorm:"foreignKey:DeviceSn;references:Sn"`
+	InductanceDetails []InductanceDetails `json:"inductanceDetails" gorm:"foreignKey:DeviceSn;references:Sn"`
 }
 
 func (Device) TableName() string {
@@ -75,30 +77,37 @@ func QueryDeviceByTunnelSnAndRadarId(sn string, id int) (device Device, err erro
 	return
 }
 
+func QueryDGDeviceByTunnelSn(tunnelSn string) (device Device, err error) {
+	err = global.GVA_DB.Model(&Device{}).
+		Where("genre = 7 AND tunnel_sn = ?", tunnelSn).
+		First(&device).Error
+	return
+}
+
 func (d Device) CreateDevice() error {
 	return global.GVA_DB.Transaction(func(tx *gorm.DB) error {
 		err := tx.Create(&d).Error
 		if err != nil {
 			return err
 		}
-		if d.Genre != 6 {
-			return nil
-		}
-		var deviceRelays []DeviceRelay
-		for i := 1; i <= 4; i++ {
-			relay := DeviceRelay{
-				RelayID:  i,
-				DeviceId: int(d.ID),
-				State:    false,
+		if d.Genre == 6 {
+			var deviceRelays []DeviceRelay
+			for i := 1; i <= 4; i++ {
+				relay := DeviceRelay{
+					RelayID:  i,
+					DeviceSn: d.Sn,
+					State:    false,
+				}
+				deviceRelays = append(deviceRelays, relay)
 			}
-			deviceRelays = append(deviceRelays, relay)
+			return tx.Create(&deviceRelays).Error
 		}
-		return tx.Create(&deviceRelays).Error
+		return nil
 	})
 }
 
 func (d Device) UpdateDevice() error {
-	return global.GVA_DB.Where("id = ?", d.ID).Updates(&d).Error
+	return global.GVA_DB.Debug().Where("id = ?", d.ID).Updates(&d).Error
 }
 
 func DeleteDevice(id int) error {

+ 46 - 7
server/dao/device_relay.go

@@ -1,18 +1,57 @@
 package dao
 
-import "server/global"
+import (
+	"context"
+	"encoding/json"
+	"fmt"
+	"server/global"
+)
 
 type DeviceRelay struct {
-	ID       int  `json:"id"`
-	RelayID  int  `json:"relayId" gorm:"comment:回路id"`
-	DeviceId int  `json:"deviceId" gorm:"comment:设备id"`
-	State    bool `json:"state" gorm:"comment:设备状态"`
+	ID       int    `json:"id"`
+	RelayID  int    `json:"relayId" gorm:"comment:回路id"`
+	DeviceSn string `json:"deviceSn" gorm:"comment:设备Sn"`
+	State    bool   `json:"state" gorm:"comment:设备状态"`
 }
 
 func (DeviceRelay) TableName() string {
 	return "device_relay"
 }
 
-func UpdateRelayState(deviceId, relayId int, state bool) error {
-	return global.GVA_DB.Model(&DeviceRelay{}).Debug().Where("device_id = ? AND relay_id = ?", deviceId, relayId).Update("state", state).Error
+func QueryRelayBySn(sn string) (deviceRelays []DeviceRelay, err error) {
+	err = global.GVA_DB.Model(&DeviceRelay{}).Where("device_sn = ?", sn).Find(&deviceRelays).Error
+	return
+}
+
+func UpdateRelayState(deviceSn string, relayId int, state bool) error {
+	return global.GVA_DB.Model(&DeviceRelay{}).Where("device_sn = ? AND relay_id = ?", deviceSn, relayId).Update("state", state).Error
+}
+
+func GetCacheRelayState(sn string) (deviceRelays []DeviceRelay, err error) {
+	if global.GVA_REDIS == nil {
+		return
+	}
+	result, err := global.GVA_REDIS.Get(context.Background(), "device_relays_"+sn).Result()
+	if err != nil {
+		return
+	}
+	err = json.Unmarshal([]byte(result), &deviceRelays)
+	if err != nil {
+		return
+	}
+	return
+}
+
+// SaveCacheDeviceRelays 保存电感数据
+func SaveCacheDeviceRelays(sn string, deviceRelays []DeviceRelay) (err error) {
+	jsonData, err := json.Marshal(deviceRelays)
+	if err != nil {
+		fmt.Println("Error marshalling JSON:", err)
+		return
+	}
+	if global.GVA_REDIS == nil {
+		return
+	}
+	err = global.GVA_REDIS.Set(context.Background(), "device_relays_"+sn, jsonData, 0).Err()
+	return
 }

+ 62 - 0
server/dao/inductanceDetails.go

@@ -0,0 +1,62 @@
+package dao
+
+import "server/global"
+
+type InductanceDetails struct {
+	ID                 int     `json:"id" form:"id" gorm:"primarykey"`               // 主键ID
+	DeviceSn           string  `json:"deviceSn" form:"deviceSn" gorm:"comment:电感编码"` // 电感编码
+	VoltageA           int64   `json:"voltageA" form:"voltageA" gorm:"comment:电压A"`
+	VoltageB           int64   `json:"voltageB" form:"voltageB" gorm:"comment:电压B"`
+	VoltageC           int64   `json:"voltageC" form:"voltageC" gorm:"comment:电压C"`
+	CurrentA           float64 `json:"currentA" form:"currentA" gorm:"comment:电流A"`
+	CurrentB           float64 `json:"currentB" form:"currentB" gorm:"comment:电流B"`
+	CurrentC           float64 `json:"currentC" form:"currentC" gorm:"comment:电流C"`
+	ActivePowerA       int     `json:"activePowerA" form:"activePowerA" gorm:"comment:有功功率A"`
+	ActivePowerB       int     `json:"activePowerB" form:"activePowerB" gorm:"comment:有功功率B"`
+	ActivePowerC       int     `json:"activePowerC" form:"activePowerC" gorm:"comment:有功功率C"`
+	TotalActivePower   int     `json:"totalActivePower" form:"totalActivePower" gorm:"comment:总有功功率"`
+	ApparentPowerA     int     `json:"apparentPowerA" form:"apparentPowerA" gorm:"comment:视在功率A"`
+	ApparentPowerB     int     `json:"apparentPowerB" form:"apparentPowerB" gorm:"comment:视在功率B"`
+	ApparentPowerC     int     `json:"apparentPowerC" form:"apparentPowerC" gorm:"comment:视在功率C"`
+	TotalApparentPower int     `json:"totalApparentPower" form:"totalApparentPower" gorm:"comment:总视在功率"`
+	PowerFactorA       float64 `json:"powerFactorA" form:"powerFactorA" gorm:"comment:功率因数A"`
+	PowerFactorB       float64 `json:"powerFactorB" form:"powerFactorB" gorm:"comment:功率因数B"`
+	PowerFactorC       float64 `json:"powerFactorC" form:"powerFactorC" gorm:"comment:功率因数C"`
+	TotalPowerFactor   float64 `json:"totalPowerFactor" form:"totalPowerFactor" gorm:"comment:总功率因数"`
+	UploadTime         string  `json:"uploadTime" form:"uploadTime" gorm:"comment:上传时间"`
+}
+
+func (InductanceDetails) TableName() string {
+	return "inductance_details"
+}
+
+func (id InductanceDetails) CreateInductanceDetails() error {
+	return global.GVA_DB.Create(&id).Error
+}
+
+func QueryInductanceDetailsByCode(inductanceCode string) (inductanceDetails []InductanceDetails, err error) {
+	err = global.GVA_DB.Model(&InductanceDetails{}).Where("device_sn =?", inductanceCode).Scan(&inductanceDetails).Error
+	return
+}
+
+// QueryInductanceDetailsList 查询电感详情列表
+func QueryInductanceDetailsList(limit, offset int, code string) (list []InductanceDetails, total int64, err error) {
+	db := global.GVA_DB.Model(&InductanceDetails{}).Where("device_sn", code).Order("upload_time DESC")
+	err = db.Count(&total).Error
+	if err != nil {
+		return
+	}
+	err = db.Limit(limit).Offset(offset).Find(&list).Error
+
+	return list, total, err
+}
+
+func QueryInductanceDetailsOneDay(sn string) (list []InductanceDetails, err error) {
+	err = global.GVA_DB.Model(&InductanceDetails{}).Where("upload_time < NOW() AND upload_time > DATE_SUB(NOW(), INTERVAL 1 DAY) AND device_sn = ?", sn).Find(&list).Error
+	return
+}
+
+// TimingDeleteInductanceDetails 定时删除电感详情
+func TimingDeleteInductanceDetails() error {
+	return global.GVA_DB.Unscoped().Delete(&InductanceDetails{}, "upload_time < DATE_SUB(NOW(), INTERVAL 5 DAY)").Error
+}

+ 12 - 0
server/dao/power_statistics.go

@@ -0,0 +1,12 @@
+package dao
+
+import (
+	"server/global"
+	"time"
+)
+
+type PowerStatistics struct {
+	global.GVA_MODEL
+	TotalActivePower float64 `json:"totalActivePower" gorm:"comment:总有功功率"`
+	UploadTime       time.Time
+}

+ 8 - 0
server/dao/tunnel.go

@@ -95,6 +95,14 @@ func UpdateTunnelLamp(id, lamp1, lamp2 int) error {
 	return global.GVA_DB.Model(&Tunnel{}).Where("id =?", id).Update("lamp_value1", lamp1).Update("lamp_value2", lamp2).Error
 }
 
+func UpdateTunnelLamp1(sn string, lamp int) error {
+	return global.GVA_DB.Model(&Tunnel{}).Where("tunnel_sn =?", sn).Update("lamp_value1", lamp).Error
+}
+
+func UpdateTunnelLamp2(sn string, lamp int) error {
+	return global.GVA_DB.Model(&Tunnel{}).Where("tunnel_sn =?", sn).Update("lamp_value2", lamp).Error
+}
+
 func UpdateTactics(sn string, tactics int) error {
 	return global.GVA_DB.Model(&Tunnel{}).Where("tunnel_sn =?", sn).Update("tactics", tactics).Error
 }

+ 103 - 105
server/go.mod

@@ -1,154 +1,152 @@
 module server
 
-go 1.22
+go 1.22.2
+
+toolchain go1.23.0
 
 require (
-	github.com/aliyun/aliyun-oss-go-sdk v2.2.7+incompatible
-	github.com/aws/aws-sdk-go v1.44.307
-	github.com/casbin/casbin/v2 v2.87.1
-	github.com/casbin/gorm-adapter/v3 v3.18.0
+	github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
+	github.com/aws/aws-sdk-go v1.55.6
+	github.com/casbin/casbin/v2 v2.103.0
+	github.com/casbin/gorm-adapter/v3 v3.32.0
+	github.com/flipped-aurora/gin-vue-admin/server v0.0.0-20250408095327-8f7a8a9e6d34
 	github.com/flipped-aurora/ws v1.0.2
-	github.com/fsnotify/fsnotify v1.6.0
+	github.com/fsnotify/fsnotify v1.8.0
 	github.com/fvbock/endless v0.0.0-20170109170031-447134032cb6
-	github.com/gin-gonic/gin v1.9.1
-	github.com/glebarez/sqlite v1.8.0
-	github.com/go-sql-driver/mysql v1.7.1
+	github.com/gin-gonic/gin v1.10.0
+	github.com/glebarez/sqlite v1.11.0
+	github.com/go-sql-driver/mysql v1.8.1
 	github.com/gofrs/uuid/v5 v5.0.0
 	github.com/golang-jwt/jwt/v4 v4.5.0
-	github.com/gookit/color v1.5.4
-	github.com/huaweicloud/huaweicloud-sdk-go-obs v3.21.8+incompatible
-	github.com/jordan-wright/email v0.0.0-20200824153738-3f5bafa1cd84
-	github.com/mojocn/base64Captcha v1.3.6
-	github.com/otiai10/copy v1.7.0
+	github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible
+	github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
+	github.com/mojocn/base64Captcha v1.3.8
 	github.com/pkg/errors v0.9.1
 	github.com/qiniu/api.v7/v7 v7.4.1
-	github.com/qiniu/qmgo v1.1.8
-	github.com/redis/go-redis/v9 v9.0.5
+	github.com/qiniu/qmgo v1.1.9
+	github.com/redis/go-redis/v9 v9.7.0
 	github.com/robfig/cron/v3 v3.0.1
-	github.com/shirou/gopsutil/v3 v3.23.6
-	github.com/songzhibin97/gkit v1.2.11
-	github.com/spf13/viper v1.16.0
-	github.com/stretchr/testify v1.8.4
+	github.com/shirou/gopsutil/v3 v3.24.5
+	github.com/songzhibin97/gkit v1.2.13
+	github.com/spf13/viper v1.19.0
+	github.com/stretchr/testify v1.10.0
 	github.com/swaggo/files v1.0.1
 	github.com/swaggo/gin-swagger v1.6.0
 	github.com/swaggo/swag v1.16.4
-	github.com/tencentyun/cos-go-sdk-v5 v0.7.42
-	github.com/unrolled/secure v1.13.0
-	github.com/xuri/excelize/v2 v2.8.0
-	go.mongodb.org/mongo-driver v1.12.1
-	go.uber.org/automaxprocs v1.5.3
-	go.uber.org/zap v1.24.0
-	golang.org/x/crypto v0.25.0
-	golang.org/x/sync v0.7.0
-	golang.org/x/text v0.16.0
-	gorm.io/driver/mysql v1.5.6
-	gorm.io/driver/postgres v1.5.7
-	gorm.io/driver/sqlserver v1.5.1
-	gorm.io/gorm v1.25.9
+	github.com/tencentyun/cos-go-sdk-v5 v0.7.60
+	github.com/unrolled/secure v1.17.0
+	go.mongodb.org/mongo-driver v1.17.2
+	go.uber.org/automaxprocs v1.6.0
+	go.uber.org/zap v1.27.0
+	golang.org/x/crypto v0.32.0
+	golang.org/x/sync v0.10.0
+	golang.org/x/text v0.21.0
+	gorm.io/driver/mysql v1.5.7
+	gorm.io/driver/postgres v1.5.11
+	gorm.io/driver/sqlserver v1.5.4
+	gorm.io/gorm v1.25.12
 	nhooyr.io/websocket v1.8.7
 )
 
+require (
+	filippo.io/edwards25519 v1.1.0 // indirect
+	github.com/bmatcuk/doublestar/v4 v4.8.0 // indirect
+	github.com/bytedance/sonic/loader v0.2.3 // indirect
+	github.com/cloudwego/base64x v0.1.5 // indirect
+	github.com/jonboulle/clockwork v0.5.0 // indirect
+	github.com/ncruces/go-strftime v0.1.9 // indirect
+	github.com/sagikazarmark/locafero v0.7.0 // indirect
+	github.com/sagikazarmark/slog-shim v0.1.0 // indirect
+	github.com/sourcegraph/conc v0.3.0 // indirect
+	golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect
+)
+
 require (
 	github.com/KyleBanks/depth v1.2.1 // indirect
-	github.com/bytedance/sonic v1.9.1 // indirect
-	github.com/casbin/govaluate v1.1.1 // indirect
-	github.com/cespare/xxhash/v2 v2.2.0 // indirect
-	github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
+	github.com/bytedance/sonic v1.12.7 // indirect
+	github.com/casbin/govaluate v1.3.0 // indirect
+	github.com/cespare/xxhash/v2 v2.3.0 // indirect
 	github.com/clbanning/mxj v1.8.4 // indirect
-	github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
-	github.com/davecgh/go-spew v1.1.1 // indirect
+	github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
 	github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
 	github.com/dustin/go-humanize v1.0.1 // indirect
-	github.com/eclipse/paho.mqtt.golang v1.5.0 // indirect
-	github.com/gabriel-vasile/mimetype v1.4.2 // indirect
-	github.com/gin-contrib/sse v0.1.0 // indirect
-	github.com/glebarez/go-sqlite v1.21.1 // indirect
-	github.com/go-ole/go-ole v1.2.6 // indirect
-	github.com/go-openapi/jsonpointer v0.20.2 // indirect
-	github.com/go-openapi/jsonreference v0.20.3 // indirect
-	github.com/go-openapi/spec v0.20.12 // indirect
-	github.com/go-openapi/swag v0.22.5 // indirect
+	github.com/eclipse/paho.mqtt.golang v1.5.0
+	github.com/gabriel-vasile/mimetype v1.4.8 // indirect
+	github.com/gin-contrib/sse v1.0.0 // indirect
+	github.com/glebarez/go-sqlite v1.22.0 // indirect
+	github.com/go-ole/go-ole v1.3.0 // indirect
+	github.com/go-openapi/jsonpointer v0.21.0 // indirect
+	github.com/go-openapi/jsonreference v0.21.0 // indirect; indirectG
+	github.com/go-openapi/spec v0.21.0 // indirect
+	github.com/go-openapi/swag v0.23.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.14.0 // indirect
-	github.com/goccy/go-json v0.10.2 // indirect
+	github.com/go-playground/validator/v10 v10.24.0 // indirect
+	github.com/goccy/go-json v0.10.4 // indirect
 	github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
 	github.com/golang-sql/sqlexp v0.1.0 // indirect
 	github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
-	github.com/golang/snappy v0.0.1 // indirect
-	github.com/google/go-querystring v1.0.0 // indirect
-	github.com/google/uuid v1.3.0 // indirect
+	github.com/golang/snappy v0.0.4 // indirect
+	github.com/google/go-querystring v1.1.0 // indirect
+	github.com/google/uuid v1.6.0
 	github.com/gorilla/websocket v1.5.3 // indirect
 	github.com/hashicorp/hcl v1.0.0 // indirect
 	github.com/jackc/pgpassfile v1.0.0 // indirect
-	github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
-	github.com/jackc/pgx/v5 v5.5.5 // indirect
-	github.com/jackc/puddle/v2 v2.2.1 // indirect
+	github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
+	github.com/jackc/pgx/v5 v5.7.2 // indirect
+	github.com/jackc/puddle/v2 v2.2.2 // indirect
 	github.com/jinzhu/inflection v1.0.0 // indirect
 	github.com/jinzhu/now v1.1.5 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/klauspost/compress v1.13.6 // indirect
-	github.com/klauspost/cpuid/v2 v2.2.4 // indirect
-	github.com/leodido/go-urn v1.2.4 // indirect
-	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible // indirect
+	github.com/klauspost/compress v1.17.11 // indirect
+	github.com/klauspost/cpuid/v2 v2.2.9 // indirect
+	github.com/leodido/go-urn v1.4.0 // indirect
+	github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible
 	github.com/lestrrat-go/strftime v1.1.0 // indirect
-	github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
-	github.com/magiconair/properties v1.8.7 // indirect
-	github.com/mailru/easyjson v0.7.7 // indirect
-	github.com/mattn/go-isatty v0.0.19 // indirect
-	github.com/microsoft/go-mssqldb v1.1.0 // indirect
+	github.com/lufia/plan9stats v0.0.0-20240909124753-873cd0166683 // indirect
+	github.com/magiconair/properties v1.8.9 // indirect
+	github.com/mailru/easyjson v0.9.0 // indirect
+	github.com/mattn/go-isatty v0.0.20 // indirect
+	github.com/microsoft/go-mssqldb v1.8.0 // 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/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
-	github.com/montanaflynn/stats v0.7.0 // indirect
-	github.com/mozillazg/go-httpheader v0.2.1 // indirect
-	github.com/pelletier/go-toml/v2 v2.0.8 // indirect
-	github.com/pmezard/go-difflib v1.0.0 // indirect
-	github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
+	github.com/montanaflynn/stats v0.7.1 // indirect
+	github.com/mozillazg/go-httpheader v0.4.0 // indirect
+	github.com/pelletier/go-toml/v2 v2.2.3 // indirect
+	github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
+	github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
 	github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
-	github.com/richardlehane/mscfb v1.0.4 // indirect
-	github.com/richardlehane/msoleps v1.0.3 // indirect
-	github.com/russross/blackfriday/v2 v2.0.1 // indirect
 	github.com/shoenig/go-m1cpu v0.1.6 // indirect
-	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
-	github.com/sirupsen/logrus v1.9.3 // indirect
-	github.com/spf13/afero v1.9.5 // indirect
-	github.com/spf13/cast v1.5.1 // indirect
-	github.com/spf13/jwalterweatherman v1.1.0 // indirect
+	github.com/sirupsen/logrus v1.9.3
+	github.com/spf13/afero v1.12.0 // indirect
+	github.com/spf13/cast v1.7.1 // indirect
 	github.com/spf13/pflag v1.0.5 // indirect
-	github.com/subosito/gotenv v1.4.2 // indirect
-	github.com/tklauser/go-sysconf v0.3.11 // indirect
-	github.com/tklauser/numcpus v0.6.0 // indirect
+	github.com/subosito/gotenv v1.6.0 // indirect
+	github.com/tklauser/go-sysconf v0.3.14 // indirect
+	github.com/tklauser/numcpus v0.9.0 // indirect
 	github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
-	github.com/ugorji/go/codec v1.2.11 // indirect
-	github.com/urfave/cli/v2 v2.3.0 // indirect
+	github.com/ugorji/go/codec v1.2.12 // indirect
 	github.com/xdg-go/pbkdf2 v1.0.0 // indirect
 	github.com/xdg-go/scram v1.1.2 // indirect
 	github.com/xdg-go/stringprep v1.0.4 // indirect
-	github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect
-	github.com/xuri/efp v0.0.0-20230802181842-ad255f2331ca // indirect
-	github.com/xuri/nfp v0.0.0-20230819163627-dc951e3ffe1a // indirect
-	github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
-	github.com/yusufpapurcu/wmi v1.2.3 // indirect
-	go.uber.org/atomic v1.9.0 // indirect
-	go.uber.org/multierr v1.8.0 // indirect
-	golang.org/x/arch v0.3.0 // indirect
-	golang.org/x/image v0.15.0 // indirect
-	golang.org/x/net v0.27.0 // indirect
-	golang.org/x/sys v0.22.0 // indirect
-	golang.org/x/time v0.1.0 // indirect
-	golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
-	google.golang.org/protobuf v1.33.0 // indirect
+	github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
+	github.com/yusufpapurcu/wmi v1.2.4 // indirect
+	go.uber.org/multierr v1.11.0 // indirect
+	golang.org/x/arch v0.13.0 // indirect
+	golang.org/x/image v0.23.0 // indirect
+	golang.org/x/net v0.34.0 // indirect
+	golang.org/x/sys v0.29.0 // indirect
+	golang.org/x/time v0.9.0 // indirect
+	golang.org/x/tools v0.29.0 // indirect
+	google.golang.org/protobuf v1.36.3 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	gorm.io/plugin/dbresolver v1.4.1 // indirect
-	modernc.org/libc v1.24.1 // indirect
-	modernc.org/mathutil v1.5.0 // indirect
-	modernc.org/memory v1.6.0 // indirect
-	modernc.org/sqlite v1.23.0 // indirect
-	sigs.k8s.io/yaml v1.3.0 // indirect
+	gorm.io/plugin/dbresolver v1.5.3 // indirect
+	modernc.org/libc v1.61.9 // indirect
+	modernc.org/mathutil v1.7.1 // indirect
+	modernc.org/memory v1.8.2 // indirect
+	modernc.org/sqlite v1.34.5 // indirect
 )

A különbségek nem kerülnek megjelenítésre, a fájl túl nagy
+ 303 - 1179
server/go.sum


+ 1 - 0
server/initialize/gorm.go

@@ -54,6 +54,7 @@ func RegisterTables() {
 		dao.DeviceRelay{},
 		dao.EnvData{},
 		dao.OpticalData{},
+		dao.InductanceDetails{},
 	)
 	if err != nil {
 		global.GVA_LOG.Error("register table failed", zap.Error(err))

+ 11 - 0
server/initialize/timer.go

@@ -2,6 +2,7 @@ package initialize
 
 import (
 	"fmt"
+	"server/service/admin"
 	"server/task"
 
 	"github.com/robfig/cron/v3"
@@ -26,6 +27,16 @@ func Timer() {
 
 		// 其他定时任务定在这里 参考上方使用方法
 
+		_, err = global.GVA_Timer.AddTaskByFunc("Statistics", "0 0 0 * * ?", func() {
+			err := admin.InductanceStatistics()
+			if err != nil {
+				fmt.Println(err)
+			}
+		}, "定时统计", option...)
+		if err != nil {
+			fmt.Println("add timer error:", err)
+		}
+
 		//_, err := global.GVA_Timer.AddTaskByFunc("定时任务标识", "corn表达式", func() {
 		//	具体执行内容...
 		//  ......

+ 17 - 0
server/model/common/mqttData.go

@@ -0,0 +1,17 @@
+package common
+
+type SwitchData struct {
+	Sn     string `json:"sn"`
+	Way    int    `json:"way"`
+	TurnOf int    `json:"turnOf"`
+}
+
+type LampData struct {
+	Way        int `json:"way"`
+	BrightNess int `json:"brightNess"`
+}
+
+type InductanceData struct {
+	Sn         string `json:"sn"`
+	TotalPower int    `json:"totalPower"`
+}

+ 40 - 3
server/service/admin/device.go

@@ -5,8 +5,10 @@ import (
 	"server/dao"
 	"server/model/common/request"
 	"server/model/common/response"
+	"server/utils/data"
 	"server/utils/protocol"
 	"strconv"
+	"time"
 )
 
 type DeviceService struct{}
@@ -15,9 +17,10 @@ func (ds *DeviceService) QueryAllDevices() ([]dao.Device, error) {
 	return dao.QueryAllDevices()
 }
 
-func (ds *DeviceService) QueryDeviceList(info request.DeviceSearch) ([]dao.Device, int64, error) {
+func (ds *DeviceService) QueryDeviceList(info request.DeviceSearch) (devices []dao.Device, total int64, err error) {
 	limit := info.PageInfo.PageSize
 	offset := info.PageInfo.PageSize * (info.PageInfo.Page - 1)
+
 	return dao.QueryDeviceList(info.Sn, info.Name, info.Genre, limit, offset)
 }
 
@@ -60,7 +63,7 @@ func (ds *DeviceService) DeviceSwitch(info request.SwitchTunnel) error {
 	if err != nil {
 		return err
 	}
-	err = dao.UpdateRelayState(int(device.ID), info.RelayId, info.State)
+	err = dao.UpdateRelayState(device.Sn, info.RelayId, info.State)
 	if err != nil {
 		return err
 	}
@@ -89,16 +92,50 @@ func (ds *DeviceService) CreateDevice(device dao.Device) error {
 	}
 
 	if genre.Name == tunnel.SwitchType && genre.Type == "开关设备" {
-		return fmt.Errorf("开关设备需安隧道需求添加")
+		return fmt.Errorf("开关设备需安隧道需求添加")
 	}
 
 	return device.CreateDevice()
 }
 
 func (ds *DeviceService) UpdateDevice(device dao.Device) error {
+	tunnel, err := dao.QueryTunnelById(device.TunnelId)
+	if err != nil {
+		return err
+	}
+
+	if device.DeviceGenre.Name != tunnel.SwitchType && device.DeviceGenre.Type == "开关设备" {
+		return fmt.Errorf("开关设备需安照隧道需求添加")
+	}
+
+	device.DeviceGenre = dao.DeviceGenre{}
+	device.Tunnel = dao.Tunnel{}
+
 	return device.UpdateDevice()
 }
 
 func (ds *DeviceService) DeleteDevice(id int) error {
 	return dao.DeleteDevice(id)
 }
+
+func InductanceStatistics() error {
+	tunnels, _ := dao.QueryAllTunnels()
+
+	for _, tunnel := range tunnels {
+		device, _ := dao.QueryDGDeviceByTunnelSn(tunnel.TunnelSn)
+		list, err := dao.QueryInductanceDetailsOneDay(device.Sn)
+		if err != nil {
+			return err
+		}
+		preprocessData, err := data.PreprocessData(list)
+		if err != nil {
+			return err
+		}
+
+		consumption := data.CalculateDailyEnergyConsumption(preprocessData)
+		fmt.Println(time.Now())
+		fmt.Println(consumption)
+	}
+
+	return nil
+}

+ 35 - 0
server/service/admin/mqtt.go

@@ -7,6 +7,7 @@ import (
 	"regexp"
 	"runtime"
 	"server/dao"
+	"server/model/common"
 	"server/utils/logger"
 	"server/utils/mqtt"
 	"server/utils/protocol"
@@ -116,6 +117,40 @@ func (o *MqttHandler) Handler() interface{} {
 				logger.Get().Errorf("sn:%s device:%s 新增光感信息失败: %v", sn, data.Sn, err)
 				continue
 			}
+		case protocol.TopicGatherDataDG:
+			var data common.InductanceData
+			if err := json.Unmarshal(m.Payload(), &data); err != nil {
+				logger.Get().Errorf("Error unmarshalling JSON: %v", err)
+				continue
+			}
+			dao.InductanceDetails{
+				DeviceSn:         data.Sn,
+				TotalActivePower: data.TotalPower,
+				UploadTime:       time.Now().Format("2006-01-02 15:04:05"),
+			}.CreateInductanceDetails()
+		case protocol.TopicSwitchStates:
+			var data common.SwitchData
+			if err := json.Unmarshal(m.Payload(), &data); err != nil {
+				logger.Get().Errorf("Error unmarshalling JSON: %v", err)
+				continue
+			}
+			if data.TurnOf == 1 {
+				dao.UpdateRelayState(data.Sn, data.Way, true)
+			} else {
+				dao.UpdateRelayState(data.Sn, data.Way, false)
+			}
+
+		case protocol.TopicLampBrightNess:
+			var data common.LampData
+			if err := json.Unmarshal(m.Payload(), &data); err != nil {
+				logger.Get().Errorf("Error unmarshalling JSON: %v", err)
+				continue
+			}
+			if data.Way == 1 {
+				dao.UpdateTunnelLamp1(sn, data.BrightNess)
+			} else {
+				dao.UpdateTunnelLamp2(sn, data.BrightNess)
+			}
 		}
 
 	}

+ 1 - 1
server/service/system/sys_casbin.go

@@ -74,7 +74,7 @@ func (casbinService *CasbinService) UpdateCasbinApi(oldPath string, newPath stri
 func (casbinService *CasbinService) GetPolicyPathByAuthorityId(AuthorityID uint) (pathMaps []request.CasbinInfo) {
 	e := casbinService.Casbin()
 	authorityId := strconv.Itoa(int(AuthorityID))
-	list := e.GetFilteredPolicy(0, authorityId)
+	list, _ := e.GetFilteredPolicy(0, authorityId)
 	for _, v := range list {
 		pathMaps = append(pathMaps, request.CasbinInfo{
 			Path:   v[1],

+ 61 - 0
server/utils/data/statistics.go

@@ -0,0 +1,61 @@
+package data
+
+import (
+	"server/dao"
+	"time"
+)
+
+type ProcessedPowerData struct {
+	TotalActivePower float64
+	UploadTime       time.Time
+}
+
+func parseTime(uploadTimeString string) (time.Time, error) {
+	parsedTime, err := time.Parse("2006-01-02 15:04:05", uploadTimeString)
+	if err != nil {
+		return time.Time{}, err
+	}
+	return parsedTime, nil
+}
+
+func PreprocessData(data []dao.InductanceDetails) ([]ProcessedPowerData, error) {
+	processedData := make([]ProcessedPowerData, len(data))
+	for i, d := range data {
+		t, err := parseTime(d.UploadTime)
+		if err != nil {
+			return nil, err
+		}
+		processedData[i] = ProcessedPowerData{
+			TotalActivePower: float64(d.TotalActivePower),
+			UploadTime:       t,
+		}
+	}
+	return processedData, nil
+}
+
+func CalculateDailyEnergyConsumption(data []ProcessedPowerData) float64 {
+	if len(data) < 2 {
+		// 如果数据不足,根据实际情况返回值或进行估算
+		return 0 // 或者其它逻辑
+	}
+	var totalEnergy float64 = 0
+
+	for i := 0; i < len(data)-1; i++ {
+		current := data[i]
+		next := data[i+1]
+
+		duration := next.UploadTime.Sub(current.UploadTime).Minutes() // 时间差(分钟)
+
+		if duration > 10 { // 如果间隔超过10分钟,则用最后一次上报的功率估算缺失部分
+			missingIntervals := int(duration / 10)
+			for j := 0; j < missingIntervals; j++ {
+				totalEnergy += (current.TotalActivePower * 10 / 60 / 1000) // 计算每个10分钟的能量消耗
+			}
+		} else {
+			energy := ((current.TotalActivePower + next.TotalActivePower) / 2) * duration / 60 / 1000 // 平均功率乘以时间转换为kW·h
+			totalEnergy += energy
+		}
+	}
+
+	return totalEnergy
+}

+ 9 - 6
server/utils/protocol/protocol.go

@@ -1,10 +1,13 @@
 package protocol
 
 const (
-	TopicGatherDataEnv = "gatherDataEnv"
-	TopicGatherDataOpt = "gatherDataOpt"
-	TopicLampControl   = "lampControl"
-	TopicSwitchControl = "switchControl"
-	TopicTunnelTactics = "tunnelTactics"
-	TopicTunnelTiming  = "tunnelTiming"
+	TopicGatherDataEnv  = "gatherDataEnv"
+	TopicGatherDataOpt  = "gatherDataOpt"
+	TopicGatherDataDG   = "gatherDataDG"
+	TopicSwitchStates   = "switchStates"
+	TopicLampBrightNess = "lampBrightNess"
+	TopicLampControl    = "lampControl"
+	TopicSwitchControl  = "switchControl"
+	TopicTunnelTactics  = "tunnelTactics"
+	TopicTunnelTiming   = "tunnelTiming"
 )

+ 3 - 1
server/utils/upload/obs.go

@@ -30,7 +30,9 @@ func (o *Obs) UploadFile(file *multipart.FileHeader) (string, string, error) {
 				Bucket: global.GVA_CONFIG.HuaWeiObs.Bucket,
 				Key:    filename,
 			},
-			ContentType: file.Header.Get("content-type"),
+			HttpHeader: obs.HttpHeader{
+				ContentType: file.Header.Get("content-type"),
+			},
 		},
 		Body: open,
 	}

+ 4 - 4
web/src/view/admin/device/device.vue

@@ -336,7 +336,7 @@
           prop="taskTime"
         >
           <el-input
-            v-model="device.taskTime"
+            v-model.number="device.taskTime"
             style="width: 200px;"
           />
         </el-form-item>
@@ -346,7 +346,7 @@
           prop="waitTime"
         >
           <el-input
-            v-model="device.waitTime"
+            v-model.number="device.waitTime"
             style="width: 200px;"
           />
         </el-form-item>
@@ -463,7 +463,7 @@
           prop="taskTime"
         >
           <el-input
-            v-model="device.taskTime"
+            v-model.number="device.taskTime"
             style="width: 200px;"
           />
         </el-form-item>
@@ -473,7 +473,7 @@
           prop="waitTime"
         >
           <el-input
-            v-model="device.waitTime"
+            v-model.number="device.waitTime"
             style="width: 200px;"
           />
         </el-form-item>

+ 35 - 32
web/src/view/admin/tunnel/tunnel.vue

@@ -72,25 +72,25 @@
           align="center"
         />
         <el-table-column
-            prop="switchType"
-            label="开关类型"
-            align="center"
+          prop="switchType"
+          label="开关类型"
+          align="center"
         />
         <el-table-column
-            label="策略"
-            align="center"
+          label="策略"
+          align="center"
         >
           <template #default="scope">
             <el-select
-                v-model="scope.row.tactics"
-                style="width: 100px"
-                @change="changeTactics(scope.row)"
+              v-model="scope.row.tactics"
+              style="width: 100px"
+              @change="changeTactics(scope.row)"
             >
               <el-option
-                  v-for="item in tacticsOptions"
-                  :key="item.value"
-                  :label="item.label"
-                  :value="item.value"
+                v-for="item in tacticsOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
               />
             </el-select>
           </template>
@@ -102,9 +102,9 @@
         >
           <template #default="scope">
             <el-button
-                type="primary"
-                size="small"
-                @click="jumpScreen(scope.row)"
+              type="primary"
+              size="small"
+              @click="jumpScreen(scope.row)"
             >
               大屏
             </el-button>
@@ -131,6 +131,7 @@
             </el-button>
             <el-button
               type="success"
+              size="small"
               @click="tunnelDataPanel(scope.row)"
             >
               数据面板
@@ -339,16 +340,18 @@
               key="index"
               style="margin: 10px 0"
             >
-              <span style="margin: 0 20px 0 0;font-weight: 600;font-size: 16px">道路 {{ item.radarId }}</span>
-              <el-switch
-                v-for="(v, k) in item.deviceRelays"
-                key="k"
-                v-model="v.state"
-                class="ml-2"
-                :disabled="k === 0"
-                style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
-                @click="switchButton(item, v, k)"
-              />
+              <div v-if="item.genre === 6">
+                <span style="margin: 0 20px 0 0;font-weight: 600;font-size: 16px">道路 {{ item.radarId }}</span>
+                <el-switch
+                  v-for="(v, k) in item.deviceRelays"
+                  key="k"
+                  v-model="v.state"
+                  class="ml-2"
+                  :disabled="k === 0"
+                  style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
+                  @click="switchButton(item, v, k)"
+                />
+              </div>
             </div>
           </div>
           <div v-if="tunnelTimeData.switchType === '单灯控制器'">
@@ -424,7 +427,7 @@
     <!--    数据面板-->
     <el-drawer
       v-model="isDataPanel"
-      title="控制面板"
+      title="数据面板"
       direction="rtl"
       size="80%"
     >
@@ -480,7 +483,7 @@ const userInfo = userData.userInfo
 import { useRouter } from 'vue-router'
 const router = useRouter()
 
-const lampList = [33,66,100]
+const lampList = [33, 66, 100]
 const searchData = ref({
   pageInfo: {
     page: 1,
@@ -715,10 +718,10 @@ const tunnelTimeData = ref()
 const isControlPanel = ref(false)
 const tunnelControlPanel = (val) => {
   isControlPanel.value = true
-  let lampObj = {
-    0:0,
+  const lampObj = {
+    0: 0,
     33: 0,
-    50:50,
+    50: 50,
     66: 50,
     100: 100,
   }
@@ -748,7 +751,7 @@ const editTunnelTiming = async() => {
 }
 
 const lampSet = async(val) => {
-  let judge = {
+  const judge = {
     0: 33,
     50: 66,
     100: 100
@@ -933,7 +936,7 @@ const switchButton = async(device, relay, index) => {
 }
 
 // 大屏
-const useScreen =  useScreenStore()
+const useScreen = useScreenStore()
 const jumpScreen = (row) => {
   useScreen.setController(row)
   router.push('/dataDashboard')