From eba4eb850f0ecfb5839395aa125955ceaa2a454f Mon Sep 17 00:00:00 2001 From: zhangqian <zhangqian@123.com> Date: 星期四, 19 十月 2023 16:39:07 +0800 Subject: [PATCH] Merge branch 'feat-serf' --- model/net_config.go | 32 .gitignore | 6 service/config.go | 4 model/plc_brand.go | 27 model/procedures.go | 33 service/plc_brand.go | 6 model/device.go | 12 go.mod | 13 serf/sqlite.go | 137 ++++ model/request/task.go | 4 api/v1/plc_brand.go | 8 service/cache_store.go | 2 service/progress.go | 11 model/util.go | 2 model/production_progress.go | 39 model/process_model.go | 28 model/task_status_sync.go | 223 +++++++ serf/config.go | 38 + nsq/nsq.go | 115 ++- service/task.go | 49 - nsq/msg_handler.go | 71 ++ model/common/common.go | 32 pkg/nsqclient/consumer.go | 8 model/request/plcBrand.go | 2 serf/sync.go | 378 ++++++++++++ service/device_plc.go | 5 api/v1/config.go | 4 crontask/cron_task.go | 85 ++ nsq/consumer.go | 19 api/v1/task.go | 125 +-- constvar/const.go | 2 go.sum | 62 + model/device_plc.go | 31 model/request/plc.go | 2 model/index.go | 12 conf/apsClient.json | 4 main.go | 73 + model/work_order.go | 28 pkg/sqlitex/sqlitex.go | 31 39 files changed, 1,350 insertions(+), 413 deletions(-) diff --git a/.gitignore b/.gitignore index 6872e17..b44b3d7 100644 --- a/.gitignore +++ b/.gitignore @@ -21,9 +21,11 @@ *.exe *.test -apsClient +apsClient* aps.db aps.db-journal .idea logs -datafile \ No newline at end of file +datafile +datafile.zip +nohup.out diff --git a/api/v1/config.go b/api/v1/config.go index 2e94285..267a041 100644 --- a/api/v1/config.go +++ b/api/v1/config.go @@ -53,14 +53,14 @@ return } - _, err := service.NewConfigService().GetNetConfig(params.Id) + _, err := service.NewConfigService().GetNetConfig(params.ID) if err != nil { logx.Errorf("get net config error: %v", err.Error()) ctx.FailWithMsg(ecode.DBErr, "鑾峰彇缃戠粶閰嶇疆澶辫触") return } - err = service.NewConfigService().SetNetConfig(params.Id, ¶ms) + err = service.NewConfigService().SetNetConfig(params.ID, ¶ms) if err != nil { logx.Errorf("SetNetConfig error: %v", err.Error()) ctx.FailWithMsg(ecode.DBErr, "璁剧疆澶辫触") diff --git a/api/v1/plc_brand.go b/api/v1/plc_brand.go index 94ada0d..2475b9f 100644 --- a/api/v1/plc_brand.go +++ b/api/v1/plc_brand.go @@ -7,7 +7,7 @@ "apsClient/pkg/ecode" "apsClient/service" "github.com/gin-gonic/gin" - "strconv" + "github.com/spf13/cast" ) type PlcBrandApi struct{} @@ -48,7 +48,7 @@ return } - id, _ := strconv.Atoi(c.Param("id")) + id := cast.ToUint(c.Param("id")) errCode := service.NewPlcBrandService().DeletePlcBrand(id) if errCode != ecode.OK { ctx.Fail(errCode) @@ -71,10 +71,10 @@ if !ok { return } - if params.Id == 0 { + if params.ID == 0 { ctx.Fail(ecode.ParamsErr) } - params.PlcBrand.Id = params.Id + params.PlcBrand.ID = params.ID errCode := service.NewPlcBrandService().UpdatePlcBrand(¶ms.PlcBrand) if errCode != ecode.OK { diff --git a/api/v1/task.go b/api/v1/task.go index 5604993..c2b864c 100644 --- a/api/v1/task.go +++ b/api/v1/task.go @@ -4,21 +4,17 @@ "apsClient/conf" "apsClient/constvar" "apsClient/model" - "apsClient/model/common" "apsClient/model/request" "apsClient/model/response" - "apsClient/nsq" "apsClient/pkg/contextx" - "apsClient/pkg/convertx" "apsClient/pkg/ecode" "apsClient/pkg/logx" - "apsClient/pkg/safe" "apsClient/service" "apsClient/service/plc_address" "errors" - "fmt" "github.com/gin-gonic/gin" - "gorm.io/gorm" + "github.com/jinzhu/gorm" + "github.com/spf13/cast" "sort" "sync" "time" @@ -144,7 +140,7 @@ ctx.Fail(ecode.ParamsErr) return } - id := convertx.Atoi(idx) + id := cast.ToUint(idx) procedure, code := service.NewTaskService().GetProcedureById(id) if code != ecode.OK { ctx.Fail(code) @@ -179,15 +175,6 @@ }) } - safe.Go(func() { - caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicGetPlcAddress, conf.Conf.NsqConf.NodeId), fmt.Sprintf(constvar.NsqTopicSendPlcAddress, conf.Conf.NsqConf.NodeId)) - var addressResult common.ResponsePlcAddress - err := caller.Call(common.RequestPlcAddress{DeviceId: conf.Conf.System.DeviceId}, &addressResult, time.Second*3) - if err != nil { - logx.Infof("get plc address err: %v", err.Error()) - } - }) - resp := response.ProcessParamsResponse{ Number: processModel.Number, Params: processParamsArr, @@ -212,7 +199,7 @@ ctx.Fail(ecode.ParamsErr) return } - id := convertx.Atoi(idx) + id := cast.ToUint(idx) procedure, code := service.NewTaskService().GetProcedureById(id) if code != ecode.OK { ctx.Fail(code) @@ -226,25 +213,26 @@ ctx.Fail(ecode.ParamsErr) return } - err := service.NewTaskService().UpdateProcedureStatus(nil, id, model.ProcedureStatusFinished, procedure.Channel) + + err := model.WithTransaction(func(db *gorm.DB) error { + err := service.NewTaskService().UpdateProcedureStatus(db, id, model.ProcedureStatusFinished, procedure.Channel) + if err != nil { + return err + } + record := model.TaskStatusSync{ + WorkOrderId: procedure.WorkOrderID, + ProcedureID: procedure.ProcedureID, + DeviceId: procedure.DeviceID, + IsProcessing: false, + IsFinish: true, + } + return service.NewTaskService().SaveTaskStatusSync(db, &record) + }) + if err != nil { - logx.Errorf("UpdateProcedureStatus err: %v", err.Error()) + logx.Errorf("TaskFinish UpdateProcedureStatus err: %v", err.Error()) ctx.Fail(ecode.UnknownErr) return - } - - msg := &common.MsgTaskStatusUpdate{ - WorkOrderId: procedure.WorkOrderID, - ProcedureID: procedure.ProceduresInfo.ProcedureID, - DeviceId: procedure.ProceduresInfo.DeviceID, - IsProcessing: false, - IsFinish: true, - } - - caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicTaskProcedureStatusUpdate, conf.Conf.NsqConf.NodeId), "") - err = caller.Send(msg) - if err != nil { - logx.Errorf("send task status update msg error:%v", err.Error()) } service.TaskFlagUnset(procedure.Channel) @@ -290,7 +278,23 @@ ctx.FailWithMsg(ecode.ParamsErr, "鏈幏鍙栧埌宸ヨ壓鍙傛暟锛岃鍦ㄥ伐鑹烘ā鍨嬪簱涓笂浼狅紒") return } - + plcConfig, code := service.NewDevicePlcService().GetDevicePlc() + if code != ecode.OK || plcConfig.ID == 0 { + ctx.FailWithMsg(ecode.NeedConfirmedErr, "璇峰厛閰嶇疆PLC") + return + } + plcConfig.MaxTryTimes = 2 + err = SendParams(processModel.ParamsMap, plcConfig) + if err != nil { + ctx.FailWithMsg(ecode.NeedConfirmedErr, "PLC璇锋眰澶辫触锛岃妫�鏌LC閰嶇疆锛�") + return + } + plcConfig.CurrentTryTimes = 0 + err = service.PlcWrite(plcConfig, constvar.PlcStartAddressTypeTotalNumber, procedure.Channel, order.Amount.IntPart()) + if err != nil { + ctx.FailWithMsg(ecode.NeedConfirmedErr, "PLC璇锋眰澶辫触锛岃妫�鏌LC閰嶇疆锛�") + return + } err = model.WithTransaction(func(db *gorm.DB) error { err = taskService.UpdateProcedureStatusAndChannel(db, params.ProcedureId, model.ProcedureStatusProcessing, procedure.Channel, processModel.Number) if err != nil { @@ -300,52 +304,25 @@ if err != nil { return err } - return service.NewProgressService().Add(db, procedure, order) + err = service.NewProgressService().Add(db, procedure, order) + if err != nil { + return err + } + record := model.TaskStatusSync{ + WorkOrderId: procedure.WorkOrderID, + ProcedureID: procedure.ProcedureID, + DeviceId: procedure.DeviceID, + IsProcessing: true, + IsFinish: false, + } + return service.NewTaskService().SaveTaskStatusSync(db, &record) }) if err != nil { logx.Errorf("SendProcessParams update order and procedure status error:%v", err.Error()) ctx.FailWithMsg(ecode.DBErr, "鏇存敼宸ュ崟鐘舵�佸け璐�") return } - plcConfig, code := service.NewDevicePlcService().GetDevicePlc() - if code != ecode.OK || plcConfig.Id == 0 { - ctx.FailWithMsg(ecode.NeedConfirmedErr, "璇峰厛閰嶇疆PLC") - return - } - plcConfig.MaxTryTimes = 2 - err = SendParams(processModel.ParamsMap, plcConfig) - if err != nil { - logx.Errorf("SendProcessParams: %v", err.Error()) - err = model.WithTransaction(func(db *gorm.DB) error { - err = taskService.UpdateProcedureStatusAndChannel(db, params.ProcedureId, model.ProcedureStatusWaitProcess, procedure.Channel, "") - if err != nil { - return err - } - return nil - }) - ctx.FailWithMsg(ecode.NeedConfirmedErr, "PLC璇锋眰澶辫触锛岃妫�鏌LC閰嶇疆锛�") - return - } - plcConfig.CurrentTryTimes = 0 - err = service.PlcWrite(plcConfig, constvar.PlcStartAddressTypeTotalNumber, procedure.Channel, order.Amount.IntPart()) - if err != nil { - ctx.FailWithMsg(ecode.NeedConfirmedErr, "PLC璇锋眰澶辫触锛岃妫�鏌LC閰嶇疆") - return - } - msg := &common.MsgTaskStatusUpdate{ - WorkOrderId: procedure.WorkOrderID, - ProcedureID: procedure.ProceduresInfo.ProcedureID, - DeviceId: procedure.ProceduresInfo.DeviceID, - IsProcessing: true, - IsFinish: false, - } - - caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicTaskProcedureStatusUpdate, conf.Conf.NsqConf.NodeId), "") - err = caller.Send(msg) - if err != nil { - logx.Errorf("send task status update msg error:%v", err.Error()) - } service.TaskFlagSet(procedure.Channel) ctx.Ok() } @@ -388,7 +365,7 @@ } plcConfig, code := service.NewDevicePlcService().GetDevicePlc() - if code != ecode.OK || plcConfig.Id == 0 { + if code != ecode.OK || plcConfig.ID == 0 { ctx.FailWithMsg(ecode.NeedConfirmedErr, "璇峰厛閰嶇疆PLC") return } diff --git a/conf/apsClient.json b/conf/apsClient.json index 18ccd69..975c370 100644 --- a/conf/apsClient.json +++ b/conf/apsClient.json @@ -29,8 +29,8 @@ "nsqlookupdAddr":"" }, "plc": { - "finishNumberTimeInterval": 10, - "totalNumberTimeInterval": 100, + "finishNumberTimeInterval": 100, + "totalNumberTimeInterval": 1000, "modbusIntType": "DINT", "slaveId": 0, "package": "goborrow", diff --git a/constvar/const.go b/constvar/const.go index 6bea5e5..5a294e8 100644 --- a/constvar/const.go +++ b/constvar/const.go @@ -10,6 +10,8 @@ NsqTopicTaskProcedureStatusUpdate = "aps.%v.task.procedure.status" //宸ュ簭鐘舵�佹洿鏂� NsqTopicSyncTaskProgress = "aps.%v.task.procedure.progress" //宸ュ簭鐢熶骇杩涘害 NsqTopicDeviceUpdate = "aps.%v.device.update" //璁惧淇℃伅鏇存敼 + NsqTopicPullDataRequest = "aps.%v.pull.data.request" //鎷夊彇鏁版嵁璇锋眰 + NsqTopicPullDataResponse = "aps.%v.pull.data.response" //鎷夊彇鏁版嵁鍝嶅簲 ) type PlcStartAddressType int diff --git a/crontask/cron_task.go b/crontask/cron_task.go index 9454dbe..cd4e9e6 100644 --- a/crontask/cron_task.go +++ b/crontask/cron_task.go @@ -3,6 +3,7 @@ import ( "apsClient/conf" "apsClient/constvar" + "apsClient/model/common" "apsClient/nsq" "apsClient/pkg/ecode" "apsClient/pkg/logx" @@ -13,8 +14,9 @@ "time" ) -func InitTask() error { +var s *gocron.Scheduler +func StartTask(isMaster bool) error { finishNumberTimeInterval := conf.Conf.PLC.FinishNumberTimeInterval totalNumberTimeInterval := conf.Conf.PLC.TotalNumberTimeInterval if finishNumberTimeInterval == 0 { @@ -23,7 +25,7 @@ if totalNumberTimeInterval == 0 { totalNumberTimeInterval = 60 } - s := gocron.NewScheduler(time.UTC) + s = gocron.NewScheduler(time.UTC) _, err := s.Every(finishNumberTimeInterval).Seconds().Do(func() { plcConfig, code := service.NewDevicePlcService().GetDevicePlc() if code != ecode.OK { @@ -73,36 +75,79 @@ }) - s.Every(180).Seconds().Do(SyncProductionProgress) //鍚屾鐢熶骇鏁版嵁 + if isMaster { + s.Every(60).Seconds().Do(SyncProductionProgress) //鍚屾鐢熶骇鏁版嵁 + s.Every(30).Seconds().Do(SyncTaskStatus) //鍚屾浠诲姟鐘舵�� + } s.StartAsync() return nil } func SyncProductionProgress() { - plcConfig, code := service.NewDevicePlcService().GetDevicePlc() - if code != ecode.OK { + progressList, err := service.NewProgressService().GetProgressList() + if err != nil { + logx.Errorf("SyncProductionProgress get records err:%v", err) return } - var channels []int32 - for _, item := range plcConfig.Details { - if item.FieldName == constvar.PlcStartAddressTypeFinishNumber { - channels = append(channels, item.Channel) - } - } - for _, channel := range channels { - progress, err := service.NewProgressService().GetCurrentProgress(channel) - if err != nil { - return - } - if progress == nil { - return - } - + for _, progress := range progressList { caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicSyncTaskProgress, conf.Conf.NsqConf.NodeId), "") err = caller.Send(progress) if err != nil { logx.Errorf("SyncProductionProgress error:%v", err.Error()) } } +} +func SyncTaskStatus() { + records, err := service.NewTaskService().GetTaskStatusSync(100) + if err != nil { + logx.Errorf("SyncTaskStatus get records err:%v", err) + } + syncOkIds := make([]uint, 0, len(records)) + for _, record := range records { + msg := &common.MsgTaskStatusUpdate{ + WorkOrderId: record.WorkOrderId, + ProcedureID: record.ProcedureID, + DeviceId: record.DeviceId, + IsProcessing: record.IsProcessing, + IsFinish: record.IsFinish, + } + caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicTaskProcedureStatusUpdate, conf.Conf.NsqConf.NodeId), "") + err = caller.Send(msg) + if err != nil { + logx.Errorf("sync task status send msg error:%v", err.Error()) + } + syncOkIds = append(syncOkIds, record.ID) + } + if len(syncOkIds) > 0 { + err = service.NewTaskService().RemoveTaskStatusSync(syncOkIds) + if err != nil { + logx.Errorf("sync task status delete sync ok records error:%v", err) + } + } +} + +func RestartTask(isMaster bool) error { + if s != nil { + s.Stop() + } + return StartTask(isMaster) +} + +// Once 涓�娆℃�т换鍔� +func Once(isMaster bool) { + if !isMaster { + return + } + msg := &common.MsgPullDataRequest{DataType: common.PullDataTypeProcessModel} + caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicPullDataRequest, conf.Conf.NsqConf.NodeId), constvar.NsqTopicPullDataResponse) + err := caller.Send(msg) + if err != nil { + logx.Errorf("send pull data msg error:%v", err.Error()) + } + caller = nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicGetPlcAddress, conf.Conf.NsqConf.NodeId), "") + err = caller.Send(common.RequestPlcAddress{DeviceId: conf.Conf.System.DeviceId}) + if err != nil { + logx.Infof("get plc address err: %v", err.Error()) + } } diff --git a/go.mod b/go.mod index dd6904d..f87ef64 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,9 @@ require ( basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25 + basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3 + basic.com/valib/bhomeclient.git v1.2.1 + basic.com/valib/bhomedbapi.git v0.0.0-20220825084023-fe74ddd6ae6e github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558 github.com/gin-contrib/cors v1.4.0 github.com/gin-gonic/gin v1.9.1 @@ -11,8 +14,10 @@ github.com/go-redis/redis/v8 v8.11.4 github.com/goburrow/modbus v0.1.0 github.com/gofrs/uuid v4.4.0+incompatible + github.com/gogo/protobuf v1.3.2 github.com/gorilla/websocket v1.5.0 github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 + github.com/jinzhu/gorm v1.9.16 github.com/mitchellh/mapstructure v1.5.0 github.com/mojocn/base64Captcha v1.3.1 github.com/nsqio/go-nsq v1.1.0 @@ -29,14 +34,13 @@ golang.org/x/crypto v0.12.0 golang.org/x/sync v0.3.0 gopkg.in/natefinch/lumberjack.v2 v2.2.1 - gorm.io/driver/sqlite v1.5.2 - gorm.io/gorm v1.25.3 - moul.io/zapgorm2 v1.3.0 ) require ( + basic.com/valib/c_bhomebus.git v0.0.0-20230203061815-9f24b2f398b7 // indirect github.com/IBM/netaddr v1.5.0 // indirect github.com/KyleBanks/depth v1.2.1 // indirect + github.com/ajg/form v1.5.1 // indirect github.com/bytedance/sonic v1.9.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect @@ -56,6 +60,7 @@ github.com/goburrow/serial v0.1.0 // indirect github.com/goccy/go-json v0.10.2 // indirect github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/google/uuid v1.3.0 // indirect github.com/gopacket/gopacket v1.1.1 // indirect @@ -96,6 +101,8 @@ golang.org/x/sys v0.11.0 // indirect golang.org/x/text v0.12.0 // indirect golang.org/x/tools v0.12.0 // indirect + google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect + google.golang.org/grpc v1.55.0 // indirect google.golang.org/protobuf v1.30.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 0921b1b..3832c1e 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,13 @@ basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25 h1:sZyNfIISgP1eoY94LG48Kav6HYVLem6EzaEbCeXlcXQ= basic.com/aps/nsqclient.git v0.0.0-20230517072415-37491f4a5d25/go.mod h1:1RnwEtePLR7ATQorQTxdgvs1o7uuUy1Vw8W7GYtVnoY= +basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3 h1:h6dF39g4oqEMY0wDcFG3W4wYpeTNFjwWMp8TmFKnrAg= +basic.com/pubsub/protomsg.git v0.0.0-20230210092337-5f1e6cdae7c3/go.mod h1:un5NV5VWQoblVLZfx1Rt5vyLgwR0jI92d3VJhfrJhWU= +basic.com/valib/bhomeclient.git v1.2.1 h1:2q5hcf8V0lSTJSX+WcJh9rI/LDnD+We65+yXK04rjfY= +basic.com/valib/bhomeclient.git v1.2.1/go.mod h1:QEPxNQPQjTTVrsMI+AyVRzq/bI99lxmct1BgCmu/Pvs= +basic.com/valib/bhomedbapi.git v0.0.0-20220825084023-fe74ddd6ae6e h1:LYulJQfA5y0/y51KOTQfAGIA/l6r6cQ36Fvrwfce5Pk= +basic.com/valib/bhomedbapi.git v0.0.0-20220825084023-fe74ddd6ae6e/go.mod h1:no2OZ7ght2oZ6thE+e0w3UdJjgjt/TgKlWSwdPs9GAc= +basic.com/valib/c_bhomebus.git v0.0.0-20230203061815-9f24b2f398b7 h1:ck7olnaIkX0bJ3LfY3n1yaaRBjYlYJYrdieDqigfIKQ= +basic.com/valib/c_bhomebus.git v0.0.0-20230203061815-9f24b2f398b7/go.mod h1:QFq9kACofwTIwjtY3xyfrSnhr3NLWJt8WSvwnnEta1U= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -44,14 +52,17 @@ github.com/IBM/netaddr v1.5.0/go.mod h1:DDBPeYgbFzoXHjSz9Jwk7K8wmWV4+a/Kv0LqRnb8we4= github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc= github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE= +github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= github.com/ajankovic/xdiff v0.0.1 h1:V1cj8t5xwYzm6ZGPqPOlAc9AIajXuTEn41D/1MJBWMM= +github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y= github.com/antchfx/xpath v0.0.0-20170515025933-1f3266e77307 h1:C735MoY/X+UOx6SECmHk5pVOj51h839Ph13pEoY8UmU= github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558 h1:d3INvMf4ei9qlX10We5+z/+dQnmmCx0J0wflcZVihGo= github.com/apache/plc4x/plc4go v0.0.0-20230817065839-dd203446b558/go.mod h1:KC3Kj7xv0dlGb5yT1+Mz9cI9YZj1RD19cr8TyqfnBDU= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= @@ -76,6 +87,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dchest/uniuri v1.2.0 h1:koIcOUdrTIivZgSLhHQvKgqdWZq5d7KdMEWF1Ud6+5g= github.com/dchest/uniuri v1.2.0/go.mod h1:fSzm4SLHzNZvWLvWJew423PhAzkpNQYq+uNLq4kxhkY= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd h1:83Wprp6ROGeiHFAP8WJdI2RoxALQYgdllERc3N5N2DM= +github.com/denisenkom/go-mssqldb v0.0.0-20191124224453-732737034ffd/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -84,6 +97,8 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= +github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -130,6 +145,8 @@ github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= github.com/go-redis/redis/v8 v8.11.4 h1:kHoYkfZP6+pe04aFTnhDH6GDROa5yJdHJVNxV3F46Tg= github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/goburrow/modbus v0.1.0 h1:DejRZY73nEM6+bt5JSP6IsFolJ9dVcqxsYbpLbeW/ro= github.com/goburrow/modbus v0.1.0/go.mod h1:Kx552D5rLIS8E7TyUwQ/UdHEqvX5T8tyiGBTlzMcZBg= @@ -141,6 +158,10 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -170,6 +191,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -224,9 +247,11 @@ github.com/icza/mighty v0.0.0-20180919140131-cfd07d671de6/go.mod h1:xQig96I1VNBDIWGCdTt54nHt6EeI639SmHycLYL7FkA= github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4 h1:G2ztCwXov8mRvP0ZfjE6nAlaCX2XbykaeHdbT6KwDz0= github.com/jacobsa/go-serial v0.0.0-20180131005756-15cf729a72d4/go.mod h1:2RvX5ZjVtsznNZPEt4xwJXNJrM3VTZoQf7V6gk0ysvs= +github.com/jinzhu/gorm v1.9.16 h1:+IyIjPEABKRpsu/F8OvDPy9fyQlgsg2luMV2ZIH5i5o= +github.com/jinzhu/gorm v1.9.16/go.mod h1:G3LB3wezTOWM2ITLzPxEXgSkOXAntiLHS7UdBefADcs= 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.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jinzhu/now v1.0.1/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/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -235,6 +260,7 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -251,6 +277,8 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= +github.com/lib/pq v1.1.1 h1:sJZmqHoEaY7f+NPP8pgLB/WxulyR3fewgCM2qaSlBb4= +github.com/lib/pq v1.1.1/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/libp2p/go-reuseport v0.4.0 h1:nR5KU7hD0WxXCJbmw7r2rhRYruNRl2koHw8fQscQm2s= github.com/libp2p/go-reuseport v0.4.0/go.mod h1:ZtI03j/wO5hZVDFo2jKywN6bYKWLOy8Se6DrI2E1cLU= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -267,6 +295,7 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus= github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -297,7 +326,6 @@ github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= @@ -366,7 +394,6 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -378,21 +405,19 @@ 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/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= -go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191205180655-e7c4368fe9dd/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= @@ -438,9 +463,9 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -474,7 +499,6 @@ golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -501,7 +525,6 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= @@ -542,11 +565,9 @@ golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -614,6 +635,7 @@ golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -623,9 +645,9 @@ golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss= golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= @@ -695,6 +717,8 @@ google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 h1:KpwkzHKEF7B9Zxg18WzOa7djJ+Ha5DzthMyZYQfEn2A= +google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -711,6 +735,8 @@ google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag= +google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -741,7 +767,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= @@ -750,11 +775,6 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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/driver/sqlite v1.5.2 h1:TpQ+/dqCY4uCigCFyrfnrJnrW9zjpelWVoEVNy5qJkc= -gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= -gorm.io/gorm v1.23.6/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8= -gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -762,8 +782,6 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -moul.io/zapgorm2 v1.3.0 h1:+CzUTMIcnafd0d/BvBce8T4uPn6DQnpIrz64cyixlkk= -moul.io/zapgorm2 v1.3.0/go.mod h1:nPVy6U9goFKHR4s+zfSo1xVFaoU7Qgd5DoCdOfzoCqs= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/main.go b/main.go index f9585bf..74d4c67 100644 --- a/main.go +++ b/main.go @@ -6,13 +6,12 @@ "apsClient/model" "apsClient/nsq" "apsClient/pkg/logx" + "apsClient/pkg/sqlitex" "apsClient/router" + "apsClient/serf" "apsClient/service/plc_address" "fmt" "net/http" - "os" - "os/signal" - "syscall" "time" ) @@ -26,22 +25,39 @@ return } - if err := nsq.Init(); err != nil { - logx.Errorf("nsq Init err:%v", err) - return - } - - if err := crontask.InitTask(); err != nil { - logx.Errorf("crontab task Init err:%v", err) - return - } //鍔犺浇plc鍐欏叆鍦板潃 plc_address.LoadAddressFromFile() - ////鎻愬墠鍔犺浇浠诲姟 - //service.NewTaskService().GetTask() + // 鍚姩鏁版嵁鍚屾 + var serfStartChan = make(chan bool) + // 闇�瑕佸悓姝ョ殑琛� + var syncTables = []string{ + "procedures", + "process_model", + "production_progress", + "work_order", + "task_status_sync", + } - go shutdown() + agent := serf.InitAgent("apsClient", syncTables, sqlitex.GetDB()) + agent.RegisterClusterEvent(serfClusterEvent) + go agent.Serve(serfStartChan) + <-serfStartChan + + // 鍒ゆ柇褰撳墠闆嗙兢鐘舵�� + if agent.ClusterStatus != "slave" { + if err := nsq.Init(); err != nil { + logx.Errorf("nsq Init err:%v", err) + return + } + + } + crontask.Once(agent.ClusterStatus != "slave") + if err := crontask.StartTask(agent.ClusterStatus != "slave"); err != nil { + logx.Errorf("crontab task Init err:%v", err) + return + } + logx.Infof("apsClient start serve...") server := &http.Server{ Addr: fmt.Sprintf(":%d", conf.Conf.System.Port), @@ -52,11 +68,26 @@ logx.Error(server.ListenAndServe().Error()) } -func shutdown() { - quit := make(chan os.Signal, 1) - signal.Notify(quit, syscall.SIGKILL, syscall.SIGQUIT, syscall.SIGINT, syscall.SIGTERM) - <-quit +func serfClusterEvent(stat int) { + switch stat { + case serf.EventCreateCluster, serf.EventSlave2Master, serf.EventLeaveCluster: + if err := nsq.Init(); err != nil { //寮�鍚痭sq + logx.Errorf("nsq Init err:%v", err) + return + } + crontask.Once(true) + if err := crontask.RestartTask(true); err != nil { //浠aster鏂瑰紡閲嶅惎task + logx.Errorf("crontab task Init err:%v", err) + return + } + case serf.EventJoinCluster, serf.EventMaster2Slave: + nsq.Stop() //鍏抽棴nsq + crontask.Once(false) + if err := crontask.RestartTask(false); err != nil { //浠ラ潪master鏂瑰紡閲嶅惎task + logx.Errorf("crontab task Init err:%v", err) + return + } + } - logx.Infof("apsClient exited...") - os.Exit(0) + logx.Infof("serf cluster event: %v", stat) } diff --git a/model/common/common.go b/model/common/common.go index 2b3e2c9..9df61af 100644 --- a/model/common/common.go +++ b/model/common/common.go @@ -74,14 +74,14 @@ } PlcConfig struct { - Brand string `gorm:"type:varchar(191);comment:PLC鍝佺墝" json:"brand"` - Method constvar.PlcMethod `gorm:"type:varchar(191);comment:鎺ュ彛鏂瑰紡" json:"method"` - Address string `gorm:"type:varchar(191);comment:PLC鍦板潃" json:"address"` //plc ip鍦板潃锛� method = modbusTCP鐢� - Port int `gorm:"type:int(11);comment:绔彛" json:"port"` //plc 绔彛鍙凤紝 method = modbusTCP鐢� - BaudRate int `gorm:"type:int(11);comment:娉㈢壒鐜�" json:"baudRate"` //涓插彛娉㈢壒鐜囷紝 method = serial鏃� 鐢� - SerialName string `gorm:"type:int(11);comment:涓插彛鍚嶇О" json:"serialName"` //涓插彛鍚嶇О锛宮ethod = serial鏃� 鐢� - IsOpen bool `gorm:"type:tinyint(1);comment:鏄惁寮�鍚�" json:"isOpen"` - Detail string `gorm:"type:varchar(2048);comment:鏁版嵁璇︽儏" json:"-"` + Brand string `gorm:"type:varchar(191)" json:"brand"` //comment:PLC鍝佺墝 + Method constvar.PlcMethod `gorm:"type:varchar(191)" json:"method"` //comment:鎺ュ彛鏂瑰紡 + Address string `gorm:"type:varchar(191)" json:"address"` //plc ip鍦板潃锛� method = modbusTCP鐢� + Port int `gorm:"type:int(11)" json:"port"` //plc 绔彛鍙凤紝 method = modbusTCP鐢� + BaudRate int `gorm:"type:int(11)" json:"baudRate"` //涓插彛娉㈢壒鐜囷紝 method = serial鏃� 鐢� + SerialName string `gorm:"type:int(11)" json:"serialName"` //涓插彛鍚嶇О锛宮ethod = serial鏃� 鐢� + IsOpen bool `gorm:"type:tinyint(1)" json:"isOpen"` + Detail string `gorm:"type:varchar(2048)" json:"-"` Details []*PlcAddress `gorm:"-" json:"details"` } @@ -137,3 +137,19 @@ ProcedureName string `gorm:"type:varchar(191);comment:宸ュ簭鍚嶇О" json:"procedureName"` DeviceID string `gorm:"index;type:varchar(191);not null;comment:璁惧ID" json:"deviceId"` } + +type PullDataType string + +const ( + PullDataTypeProcessModel = "process_model" +) + +// MsgPullDataRequest 鎷夊彇浜戠鏁版嵁 +type MsgPullDataRequest struct { + DataType PullDataType `json:"dataType"` //瑕佹媺鍙栫殑鏁版嵁绫诲瀷 +} + +type MsgPullDataResponse struct { + DataType PullDataType `json:"dataType"` //瑕佹媺鍙栫殑鏁版嵁绫诲瀷 + Data interface{} //杩斿洖鐨勬暟鎹� +} diff --git a/model/device.go b/model/device.go index 0a1f686..46e2665 100644 --- a/model/device.go +++ b/model/device.go @@ -3,18 +3,18 @@ import ( "apsClient/pkg/sqlitex" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" "strings" ) type ( // Device 璁惧 Device struct { - gorm.Model `json:"-"` - DeviceID string `gorm:"unique;column:device_id;type:varchar(255);not null;default '';comment:璁惧缂栧彿" json:"deviceID"` //璁惧缂栧彿 - ExtChannelAmount int `gorm:"type:tinyint;comment:棰濆鐨勯�氶亾鏁伴噺;default:0;" json:"extChannelAmount"` - Procedures string `gorm:"column:procedure;type:varchar(255);not null;default '';comment:宸ュ簭" json:"procedures"` //璁惧鏀寔鐨勫伐搴忥紝鐢ㄩ�楀彿鍒嗛殧 - ProceduresArr []string `gorm:"-" json:"procedureAdd"` //璁惧鏀寔鐨勫伐搴忓垏鐗� + gorm.Model + DeviceID string `gorm:"unique;column:device_id;type:varchar(255);not null;default ''" json:"deviceID"` //璁惧缂栧彿 + ExtChannelAmount int `gorm:"type:tinyint;default:0" json:"extChannelAmount"` + Procedures string `gorm:"column:procedure;type:varchar(255);not null;default ''" json:"procedures"` //璁惧鏀寔鐨勫伐搴忥紝鐢ㄩ�楀彿鍒嗛殧 + ProceduresArr []string `gorm:"-" json:"procedureAdd"` //璁惧鏀寔鐨勫伐搴忓垏鐗� } DeviceSearch struct { diff --git a/model/device_plc.go b/model/device_plc.go index fc8330e..9ce9bbc 100644 --- a/model/device_plc.go +++ b/model/device_plc.go @@ -5,25 +5,22 @@ "apsClient/pkg/sqlitex" "encoding/json" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) type ( // DevicePlc 璁惧鐨凱LC閰嶇疆 DevicePlc struct { - gorm.Model `json:"-"` - Id int `gorm:"primarykey;type:int;" json:"id"` - Brand string `gorm:"type:varchar(191);comment:PLC鍝佺墝" json:"brand"` - Method constvar.PlcMethod `gorm:"type:varchar(191);comment:鎺ュ彛鏂瑰紡" json:"method"` - //PortName string `gorm:"type:varchar(191);comment:绔彛鍚嶇О" json:"portName"` - //Frequency int `gorm:"comment:鏁版嵁鏇存柊棰戠巼 0-瀹炴椂鏇存柊 1-1娆�/绉�" json:"frequency"` - Address string `gorm:"type:varchar(191);comment:PLC鍦板潃" json:"address"` //plc ip鍦板潃锛� method = modbusTCP鐢� - Port int `gorm:"comment:绔彛" json:"port"` //plc 绔彛鍙凤紝 method = modbusTCP鐢� - BaudRate int `gorm:"comment:娉㈢壒鐜�" json:"baudRate"` //涓插彛娉㈢壒鐜囷紝 method = serial鏃� 鐢� - SerialName string `gorm:"comment:涓插彛鍚嶇О" json:"serialName"` //涓插彛鍚嶇О锛宮ethod = serial鏃� 鐢� - IsOpen bool `gorm:"comment:鏄惁寮�鍚�" json:"isOpen"` - Detail string `gorm:"type:varchar(2048);comment:鏁版嵁璇︽儏" json:"-"` + gorm.Model + Brand string `gorm:"type:varchar(191)" json:"brand"` + Method constvar.PlcMethod `gorm:"type:varchar(191)" json:"method"` + Address string `gorm:"type:varchar(191)" json:"address"` //plc ip鍦板潃锛� method = modbusTCP鐢� + Port int `json:"port"` //plc 绔彛鍙凤紝 method = modbusTCP鐢� + BaudRate int `json:"baudRate"` //涓插彛娉㈢壒鐜囷紝 method = serial鏃� 鐢� + SerialName string `json:"serialName"` //涓插彛鍚嶇О锛宮ethod = serial鏃� 鐢� + IsOpen bool `json:"isOpen"` + Detail string `gorm:"type:varchar(2048)" json:"-"` Details []*DevicePlcAddress `gorm:"-" json:"details"` @@ -82,16 +79,16 @@ return slf } -func (slf *DevicePlcSearch) SetId(id int) *DevicePlcSearch { - slf.Id = id +func (slf *DevicePlcSearch) SetId(id uint) *DevicePlcSearch { + slf.ID = id return slf } func (slf *DevicePlcSearch) build() *gorm.DB { var db = slf.Orm.Table(slf.TableName()) - if slf.Id > 0 { - db = db.Where("id = ?", slf.Id) + if slf.ID > 0 { + db = db.Where("id = ?", slf.ID) } if slf.Order != "" { diff --git a/model/index.go b/model/index.go index 8b3f8c1..1b12699 100644 --- a/model/index.go +++ b/model/index.go @@ -8,20 +8,18 @@ ) func Init() error { - if err := sqlitex.Init(&conf.Conf.Sqlite, logx.GetLogger()); err != nil { + if err := sqlitex.Init(&conf.Conf.Sqlite); err != nil { return err } - if err := RegisterTables(); err != nil { - return err - } + RegisterTables() InsertDefaultData() return nil } -func RegisterTables() error { +func RegisterTables() { db := sqlitex.GetDB() - err := db.AutoMigrate( + db.AutoMigrate( Order{}, Procedures{}, NetConfig{}, @@ -30,8 +28,8 @@ ProcessModel{}, ProductionProgress{}, Device{}, + TaskStatusSync{}, ) - return err } type InitDefaultData interface { diff --git a/model/net_config.go b/model/net_config.go index 70fd169..0223a47 100644 --- a/model/net_config.go +++ b/model/net_config.go @@ -3,20 +3,19 @@ import ( "apsClient/pkg/sqlitex" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" "sync" ) type ( NetConfig struct { - gorm.Model `json:"-"` - Id int `gorm:"primarykey;type:int;" json:"id"` - NetworkCard string `gorm:"type:varchar(100);not null;default '';comment:缃戝崱" json:"networkCard" binding:"required"` //缃戝崱 - IP string `gorm:"type:varchar(100);not null;default '';comment:鏈満ip" json:"ip" binding:"required"` //鏈満ip - MASK string `gorm:"type:varchar(100);not null;default '';comment:瀛愮綉鎺╃爜" json:"mask" binding:"required"` //瀛愮綉鎺╃爜 - Gateway string `gorm:"type:varchar(100);not null;default '';comment:缃戝叧" json:"gateway" binding:"required"` //缃戝叧 - DNS string `gorm:"type:varchar(100);not null;default '';comment:DNS" json:"dns"` //dns - Status NetConfigStatus `gorm:"type:tinyint;not null;default 0;comment:鐘舵�侊紙1鍚姩2绂佺敤锛�" json:"status"` //鐘舵�侊紙1鍚敤2绂佺敤锛� + gorm.Model + NetworkCard string `gorm:"type:varchar(100);not null;default ''" json:"networkCard" binding:"required"` //缃戝崱 + IP string `gorm:"type:varchar(100);not null;default ''" json:"ip" binding:"required"` //鏈満ip + MASK string `gorm:"type:varchar(100);not null;default ''" json:"mask" binding:"required"` //瀛愮綉鎺╃爜 + Gateway string `gorm:"type:varchar(100);not null;default ''" json:"gateway" binding:"required"` //缃戝叧 + DNS string `gorm:"type:varchar(100);not null;default ''" json:"dns"` //dns + Status NetConfigStatus `gorm:"type:tinyint;not null;default 0" json:"status"` //鐘舵�侊紙1鍚敤2绂佺敤锛� } NetConfigSearch struct { @@ -53,15 +52,15 @@ return slf } -func (slf *NetConfigSearch) SetId(id int) *NetConfigSearch { - slf.Id = id +func (slf *NetConfigSearch) SetId(id uint) *NetConfigSearch { + slf.ID = id return slf } func (slf *NetConfigSearch) build() *gorm.DB { var db = slf.Orm.Model(&NetConfig{}) - if slf.Id > 0 { - db = db.Where("id = ?", slf.Id) + if slf.ID > 0 { + db = db.Where("id = ?", slf.ID) } return db } @@ -173,7 +172,10 @@ func (slf *NetConfigSearch) CreateBatch(records []*NetConfig) error { var db = slf.build() - return db.Create(records).Error + for _, record := range records{ + db.Create(record) + } + return nil } // InitDefaultData 鍒濆鍖栨暟鎹� @@ -193,7 +195,6 @@ } records := []*NetConfig{ { - Id: 1, NetworkCard: "enp3s0", IP: "", MASK: "", @@ -202,7 +203,6 @@ Status: 0, }, { - Id: 2, NetworkCard: "enp2s0", IP: "", MASK: "", diff --git a/model/plc_brand.go b/model/plc_brand.go index 4bf7bff..21a8505 100644 --- a/model/plc_brand.go +++ b/model/plc_brand.go @@ -5,15 +5,15 @@ "apsClient/pkg/sqlitex" "errors" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" "sync" ) type ( // PlcBrand plc鍝佺墝 PlcBrand struct { - Id int `json:"id" gorm:"column:id;type:int;primary_key;AUTO_INCREMENT"` - Name string `json:"name" gorm:"column:name;type:varchar(255);not null;default:'';comment:鍚嶇О"` + gorm.Model + Name string `json:"name" gorm:"column:name;type:varchar(255);not null;default:''"` } // PlcBrandSearch plc鍝佺墝鎼滅储鏉′欢 @@ -40,8 +40,8 @@ func (slf *PlcBrandSearch) build() *gorm.DB { var db = slf.Orm.Model(&PlcBrand{}) - if slf.Id != 0 { - db = db.Where("id = ?", slf.Id) + if slf.ID != 0 { + db = db.Where("id = ?", slf.ID) } return db @@ -54,7 +54,10 @@ func (slf *PlcBrandSearch) CreateBatch(records []*PlcBrand) error { var db = slf.build() - return db.Create(records).Error + for _, record := range records{ + db.Create(record) + } + return nil } func (slf *PlcBrandSearch) Delete() error { @@ -74,8 +77,8 @@ return record, err } -func (slf *PlcBrandSearch) SetId(id int) *PlcBrandSearch { - slf.Id = id +func (slf *PlcBrandSearch) SetId(id uint) *PlcBrandSearch { + slf.ID = id return slf } @@ -102,7 +105,7 @@ } func (slf *PlcBrandSearch) Save(record *PlcBrand) error { - if record.Id == 0 { + if record.ID == 0 { return errors.New("id涓虹┖") } var db = slf.build() @@ -145,9 +148,9 @@ return } records := []*PlcBrand{ - {1, "娆у榫�"}, - {2, "瑗块棬瀛�"}, - {3, "鏉句笅"}, + {Name: "娆у榫�"}, + {Name: "瑗块棬瀛�"}, + {Name: "鏉句笅"}, } err := slf.CreateBatch(records) if err != nil { diff --git a/model/procedures.go b/model/procedures.go index 8a7f145..64d3cbb 100644 --- a/model/procedures.go +++ b/model/procedures.go @@ -6,22 +6,20 @@ "apsClient/pkg/sqlitex" "encoding/json" "fmt" - "gorm.io/gorm" - "gorm.io/gorm/clause" + "github.com/jinzhu/gorm" ) type ( Procedures struct { gorm.Model `json:"-"` - ID int `gorm:"primarykey"` - WorkOrderID string `gorm:"index;type:varchar(191);not null;comment:宸ュ崟ID" json:"-"` - OrderID string `gorm:"index;type:varchar(191);not null;comment:璁㈠崟ID" json:"-"` - DeviceID string `gorm:"index;type:varchar(191);comment:璁惧ID" json:"deviceId"` - ProcedureID string `gorm:"index;type:varchar(191);comment:宸ュ簭ID" json:"procedureId"` - Channel int32 `gorm:"index;comment:閫氶亾" json:"channel"` //閫氶亾 - ProcessModelNumber string `gorm:"index;comment:宸ヨ壓妯″瀷缂栧彿" json:"processModelNumber"` //宸ヨ壓妯″瀷缂栧彿 - StartTime int64 `gorm:"comment:璁″垝寮�濮嬫椂闂�" json:"startTime"` - EndTime int64 `gorm:"comment:璁″垝缁撴潫鏃堕棿" json:"endTime"` + WorkOrderID string `gorm:"index;type:varchar(191);not null" json:"-"` + OrderID string `gorm:"index;type:varchar(191);not null" json:"-"` + DeviceID string `gorm:"index;type:varchar(191)" json:"deviceId"` + ProcedureID string `gorm:"index;type:varchar(191)" json:"procedureId"` + Channel int32 `gorm:"index;" json:"channel"` //閫氶亾 + ProcessModelNumber string `gorm:"index;" json:"processModelNumber"` //宸ヨ壓妯″瀷缂栧彿 + StartTime int64 `json:"startTime"` + EndTime int64 `json:"endTime"` Status ProcedureStatus ProcedureData string `json:"-"` //common.ProductProcedure json涓� ProceduresInfo common.ProductProcedure `json:"procedure" gorm:"-"` //common.ProductProcedure 瀵硅薄 @@ -106,7 +104,7 @@ return slf } -func (slf *ProceduresSearch) SetId(id int) *ProceduresSearch { +func (slf *ProceduresSearch) SetId(id uint) *ProceduresSearch { slf.ID = id return slf } @@ -181,7 +179,7 @@ } if len(slf.ProcedureIds) > 0 { - db = db.Where("procedure_id in ?", slf.ProcedureIds) + db = db.Where("procedure_id IN (?)", slf.ProcedureIds) } if slf.ProcedureID != "" { @@ -189,7 +187,7 @@ } if len(slf.Channels) > 0 { - db = db.Where("channel in ?", slf.Channels) + db = db.Where("channel IN (?)", slf.Channels) } return db @@ -222,10 +220,11 @@ old, err := slf.First() if err != gorm.ErrRecordNotFound && old.ID != 0 { record.ID = old.ID + err = db.Save(&record).Error + } else { + err = db.Create(&record).Error } - if err := db.Clauses(clause.OnConflict{ - UpdateAll: true, - }).Create(&record).Error; err != nil { + if err != nil { return fmt.Errorf("save err: %v, record: %+v", err, record) } diff --git a/model/process_model.go b/model/process_model.go index a08e694..eeffa77 100644 --- a/model/process_model.go +++ b/model/process_model.go @@ -5,21 +5,21 @@ "apsClient/pkg/sqlitex" "encoding/json" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) type ( // ProcessModel 宸ヨ壓鍙傛暟 ProcessModel struct { gorm.Model `json:"-"` - Number string `gorm:"index;column:number;type:varchar(255);not null;default '';comment:宸ヨ壓妯″瀷缂栧彿" json:"number"` //宸ヨ壓妯″瀷缂栧彿 - Product string `gorm:"column:product;type:varchar(255);not null;default '';comment:浜у搧鍚嶇О" json:"product"` //浜у搧鍚嶇О - Procedure string `gorm:"column:procedure;type:varchar(255);not null;default '';comment:宸ュ簭" json:"procedure"` //宸ュ簭 - Params string `gorm:"type:text;comment:宸ヨ壓鍙傛暟閿�煎json涓�"` + Number string `gorm:"index;column:number;type:varchar(255);not null;default ''" json:"number"` //宸ヨ壓妯″瀷缂栧彿 + Product string `gorm:"column:product;type:varchar(255);not null;default ''" json:"product"` //浜у搧鍚嶇О + Procedure string `gorm:"column:procedure;type:varchar(255);not null;default ''" json:"procedure"` //宸ュ簭 + Params string ParamsMap map[string]interface{} `json:"paramsMap" gorm:"-"` - DeviceId string `json:"deviceId" gorm:"-"` //鐢ㄤ簬杩囨护鑾峰彇nsq娑堟伅 - IsNew bool `json:"-" gorm:"column:is_new;comment:鏄惁鏈�鏂扮殑"` //鏄惁鏈�鏂扮殑 - IsUpdate bool `json:"isUpdate" gorm:"-"` //鍓嶇鐢� + DeviceId string `json:"deviceId" gorm:"-"` //鐢ㄤ簬杩囨护鑾峰彇nsq娑堟伅 + IsNew bool `json:"-" gorm:"column:is_new"` //鏄惁鏈�鏂扮殑 + IsUpdate bool `json:"isUpdate" gorm:"-"` //鍓嶇鐢� NewParamsMap map[string]interface{} `json:"newParamsMap" gorm:"-"` NewNumber string `json:"newNumber" gorm:"-"` } @@ -32,6 +32,7 @@ Orm *gorm.DB Procedures []string CurrentNumber string + Numbers []string } ) @@ -77,6 +78,11 @@ return slf } +func (slf *ProcessModelSearch) SetNumbers(numbers []string) *ProcessModelSearch { + slf.Numbers = numbers + return slf +} + func (slf *ProcessModelSearch) SetCurrentNumber(number string) *ProcessModelSearch { slf.CurrentNumber = number return slf @@ -118,7 +124,7 @@ } if len(slf.Procedures) != 0 { - db = db.Where("`procedure` in ?", slf.Procedures) + db = db.Where("`procedure` IN (?)", slf.Procedures) } if len(slf.Number) != 0 { @@ -137,6 +143,10 @@ db = db.Where("number != ?", slf.CurrentNumber) } + if len(slf.Numbers) != 0 { + db = db.Where("number in ?", slf.Numbers) + } + return db } diff --git a/model/production_progress.go b/model/production_progress.go index 4a159af..d928936 100644 --- a/model/production_progress.go +++ b/model/production_progress.go @@ -3,28 +3,28 @@ import ( "apsClient/pkg/sqlitex" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) type ( ProductionProgress struct { - gorm.Model `json:"-"` - ID int `gorm:"primarykey"` - WorkOrderID string `gorm:"index;type:varchar(191);not null;comment:宸ュ崟ID" json:"workOrderID"` - OrderID string `gorm:"index;type:varchar(191);not null;comment:璁㈠崟ID" json:"orderID"` - ProcedureID string `gorm:"type:varchar(191);comment:宸ュ簭ID" json:"procedureId"` - DeviceID string `gorm:"type:varchar(191);not null;comment:璁惧ID" json:"deviceId"` - FinishedQuantity int64 `gorm:"type:int;not null;comment:瀹屾垚鏁伴噺" json:"finishedQuantity"` - Channel int32 `gorm:"type:int;comment:宸ヤ綔閫氶亾" json:"channel"` //閫氶亾 - TotalQuantity int64 `gorm:"type:int;not null;comment:鎬婚噺" json:"totalQuantity"` + gorm.Model + WorkOrderID string `gorm:"index;type:varchar(191);not null" json:"workOrderID"` + OrderID string `gorm:"index;type:varchar(191);not null" json:"orderID"` + ProcedureID string `gorm:"type:varchar(191)" json:"procedureId"` + DeviceID string `gorm:"type:varchar(191);not null" json:"deviceId"` + FinishedQuantity int64 `gorm:"type:int;not null" json:"finishedQuantity"` + Channel int32 `gorm:"type:int" json:"channel"` //閫氶亾 + TotalQuantity int64 `gorm:"type:int;not null" json:"totalQuantity"` } ProductionProgressSearch struct { ProductionProgress - Order string - PageNum int - PageSize int - Orm *gorm.DB + Order string + PageNum int + PageSize int + Orm *gorm.DB + UnFinished bool } ) @@ -69,13 +69,18 @@ return slf } -func (slf *ProductionProgressSearch) SetId(id int) *ProductionProgressSearch { +func (slf *ProductionProgressSearch) SetId(id uint) *ProductionProgressSearch { slf.ID = id return slf } func (slf *ProductionProgressSearch) SetChannel(channel int32) *ProductionProgressSearch { slf.Channel = channel + return slf +} + +func (slf *ProductionProgressSearch) SetUnFinished() *ProductionProgressSearch { + slf.UnFinished = true return slf } @@ -110,6 +115,10 @@ db = db.Where("channel = ?", slf.Channel) } + if slf.UnFinished { + db = db.Where("finished_quantity < total_quantity") + } + return db } diff --git a/model/request/plc.go b/model/request/plc.go index d0d930f..feeb368 100644 --- a/model/request/plc.go +++ b/model/request/plc.go @@ -9,6 +9,6 @@ } type UpdatePlc struct { - Id int `json:"id"` + Id uint `json:"id"` model.DevicePlc } diff --git a/model/request/plcBrand.go b/model/request/plcBrand.go index dde82ba..e4c3a31 100644 --- a/model/request/plcBrand.go +++ b/model/request/plcBrand.go @@ -10,7 +10,7 @@ } type UpdatePlcBrand struct { - Id int `json:"id"` + Id uint `json:"id"` model.PlcBrand } diff --git a/model/request/task.go b/model/request/task.go index 99b71c2..6198d95 100644 --- a/model/request/task.go +++ b/model/request/task.go @@ -18,7 +18,7 @@ } type SendProcessParams struct { - ProcedureId int `json:"procedureId" binding:"required"` + ProcedureId uint `json:"procedureId" binding:"required"` } type GetProductProgress struct { @@ -29,6 +29,6 @@ // ProcessModelList 宸ヨ壓鍙傛暟鍒楄〃璇锋眰鍙傛暟 type ProcessModelList struct { PageInfo - ProcedureId int `json:"procedureId" form:"procedureId" binding:"required"` //褰撳墠鐨勫伐搴廼d + ProcedureId uint `json:"procedureId" form:"procedureId" binding:"required"` //褰撳墠鐨勫伐搴廼d Number string `json:"number" form:"number" binding:"required"` //褰撳墠姝e湪浣跨敤鐨勫伐鑹哄弬鏁扮紪鍙� } diff --git a/model/task_status_sync.go b/model/task_status_sync.go new file mode 100644 index 0000000..503af79 --- /dev/null +++ b/model/task_status_sync.go @@ -0,0 +1,223 @@ +package model + +import ( + "apsClient/pkg/sqlitex" + "fmt" + "github.com/jinzhu/gorm" +) + +type ( + // TaskStatusSync 浠诲姟鐘舵�佸悓姝� + TaskStatusSync struct { + gorm.Model + WorkOrderId string `json:"workOrderId"` //宸ュ崟缂栧彿 + ProcedureID string `json:"procedureId"` // 宸ュ簭缂栧彿 + DeviceId string `json:"deviceId"` //璁惧缂栧彿 + IsProcessing bool //鏄惁澶勭悊涓� + IsFinish bool //鏄惁瀹屾垚 + } + + TaskStatusSyncSearch struct { + TaskStatusSync + Order string + PageNum int + PageSize int + Orm *gorm.DB + IDs []uint + } +) + +func (slf *TaskStatusSync) TableName() string { + return "task_status_sync" +} + +func NewTaskStatusSyncSearch(db *gorm.DB) *TaskStatusSyncSearch { + if db == nil { + db = sqlitex.GetDB() + } + return &TaskStatusSyncSearch{Orm: db} +} + +func (slf *TaskStatusSyncSearch) SetOrm(tx *gorm.DB) *TaskStatusSyncSearch { + slf.Orm = tx + return slf +} + +func (slf *TaskStatusSyncSearch) SetPage(page, size int) *TaskStatusSyncSearch { + slf.PageNum, slf.PageSize = page, size + return slf +} + +func (slf *TaskStatusSyncSearch) SetOrder(order string) *TaskStatusSyncSearch { + slf.Order = order + return slf +} + +func (slf *TaskStatusSyncSearch) SetID(id uint) *TaskStatusSyncSearch { + slf.ID = id + return slf +} + +func (slf *TaskStatusSyncSearch) SetIDs(ids []uint) *TaskStatusSyncSearch { + slf.IDs = ids + return slf +} + +func (slf *TaskStatusSyncSearch) build() *gorm.DB { + var db = slf.Orm.Table(slf.TableName()) + + if slf.ID != 0 { + db = db.Where("id = ?", slf.ID) + } + + if len(slf.IDs) != 0 { + db = db.Where("id in ?", slf.IDs) + } + + if slf.Order != "" { + db = db.Order(slf.Order) + } + + return db +} + +// Create 鍗曟潯鎻掑叆 +func (slf *TaskStatusSyncSearch) Create(record *TaskStatusSync) error { + var db = slf.build() + + if err := db.Create(record).Error; err != nil { + return fmt.Errorf("create err: %v, record: %+v", err, record) + } + + return nil +} + +func (slf *TaskStatusSyncSearch) Save(record *TaskStatusSync) error { + var db = slf.build() + + if err := db.Updates(record).Error; err != nil { + return fmt.Errorf("create err: %v, record: %+v", err, record) + } + return nil +} + +func (slf *TaskStatusSyncSearch) UpdateByMap(upMap map[string]interface{}) error { + var ( + db = slf.build() + ) + + if err := db.Updates(upMap).Error; err != nil { + return fmt.Errorf("update by map err: %v, upMap: %+v", err, upMap) + } + + return nil +} + +func (slf *TaskStatusSyncSearch) UpdateByQuery(query string, args []interface{}, upMap map[string]interface{}) error { + var ( + db = slf.Orm.Table(slf.TableName()).Where(query, args...) + ) + + if err := db.Updates(upMap).Error; err != nil { + return fmt.Errorf("update by query err: %v, query: %s, args: %+v, upMap: %+v", err, query, args, upMap) + } + + return nil +} + +func (slf *TaskStatusSyncSearch) Delete() error { + var db = slf.build() + + if err := db.Unscoped().Delete(&TaskStatusSync{}).Error; err != nil { + return err + } + + return nil +} + +func (slf *TaskStatusSyncSearch) First() (*TaskStatusSync, error) { + var ( + record = new(TaskStatusSync) + db = slf.build() + ) + + if err := db.First(record).Error; err != nil { + return record, err + } + + return record, nil +} + +func (slf *TaskStatusSyncSearch) Find() ([]*TaskStatusSync, int64, error) { + var ( + records = make([]*TaskStatusSync, 0) + total int64 + db = slf.build() + ) + + if err := db.Count(&total).Error; err != nil { + return records, total, fmt.Errorf("find count err: %v", err) + } + if slf.PageNum*slf.PageSize > 0 { + db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) + } + if err := db.Find(&records).Error; err != nil { + return records, total, fmt.Errorf("find records err: %v", err) + } + + return records, total, nil +} + +func (slf *TaskStatusSyncSearch) FindNotTotal() ([]*TaskStatusSync, error) { + var ( + records = make([]*TaskStatusSync, 0) + db = slf.build() + ) + + if slf.PageNum*slf.PageSize > 0 { + db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) + } + if err := db.Find(&records).Error; err != nil { + return records, fmt.Errorf("find records err: %v", err) + } + + return records, nil +} + +// FindByQuery 鎸囧畾鏉′欢鏌ヨ. +func (slf *TaskStatusSyncSearch) FindByQuery(query string, args []interface{}) ([]*TaskStatusSync, int64, error) { + var ( + records = make([]*TaskStatusSync, 0) + total int64 + db = slf.Orm.Table(slf.TableName()).Where(query, args...) + ) + + if err := db.Count(&total).Error; err != nil { + return records, total, fmt.Errorf("find by query count err: %v", err) + } + if slf.PageNum*slf.PageSize > 0 { + db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) + } + if err := db.Find(&records).Error; err != nil { + return records, total, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args) + } + + return records, total, nil +} + +// FindByQueryNotTotal 鎸囧畾鏉′欢鏌ヨ&涓嶆煡璇㈡�绘潯鏁�. +func (slf *TaskStatusSyncSearch) FindByQueryNotTotal(query string, args []interface{}) ([]*TaskStatusSync, error) { + var ( + records = make([]*TaskStatusSync, 0) + db = slf.Orm.Table(slf.TableName()).Where(query, args...) + ) + + if slf.PageNum*slf.PageSize > 0 { + db = db.Offset((slf.PageNum - 1) * slf.PageSize).Limit(slf.PageSize) + } + if err := db.Find(&records).Error; err != nil { + return records, fmt.Errorf("find by query records err: %v, query: %s, args: %+v", err, query, args) + } + + return records, nil +} diff --git a/model/util.go b/model/util.go index 55746a4..a7f8519 100644 --- a/model/util.go +++ b/model/util.go @@ -3,7 +3,7 @@ import ( "apsClient/pkg/sqlitex" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) // WithTransaction 锛� var funcs []func(db *gorm.DB) error锛屾妸鐩稿叧鍑芥暟娣诲姞杩涘幓 diff --git a/model/work_order.go b/model/work_order.go index 076edef..b854461 100644 --- a/model/work_order.go +++ b/model/work_order.go @@ -3,25 +3,25 @@ import ( "apsClient/pkg/sqlitex" "fmt" + "github.com/jinzhu/gorm" "github.com/shopspring/decimal" - "gorm.io/gorm" ) type ( Order struct { - gorm.Model `json:"-"` - WorkOrderID string `gorm:"index;type:varchar(191);not null;comment:宸ュ崟ID" json:"workOrderId"` - OrderID string `gorm:"index;type:varchar(191);not null;comment:璁㈠崟ID" json:"orderId"` - ProductID string `gorm:"type:varchar(191);comment:浜у搧ID" json:"productId"` - ProductName string `gorm:"type:varchar(191);comment:浜у搧鍚嶇О" json:"productName"` - Parameter string `gorm:"type:varchar(1024);comment:鍙傛暟闇�姹�" json:"parameter"` - Customer string `gorm:"type:varchar(191);comment:瀹㈡埛缂栫爜" json:"customer"` - DeliverDate string `gorm:"type:varchar(100);comment:浜よ揣鏃ユ湡" json:"deliverDate"` + gorm.Model + WorkOrderID string `gorm:"index;type:varchar(191);not null" json:"workOrderId"` + OrderID string `gorm:"index;type:varchar(191);not null" json:"orderId"` + ProductID string `gorm:"type:varchar(191)" json:"productId"` + ProductName string `gorm:"type:varchar(191)" json:"productName"` + Parameter string `gorm:"type:varchar(1024)" json:"parameter"` + Customer string `gorm:"type:varchar(191)" json:"customer"` + DeliverDate string `gorm:"type:varchar(100)" json:"deliverDate"` OrderAttr string `json:"orderAttr"` // 璁㈠崟灞炴�ф嫾鎺ョ殑瀛楃涓诧紝鍗宠揣鐗╂弿杩� - Amount decimal.Decimal `gorm:"type:decimal(35,18);comment:鏁伴噺" json:"amount"` - Unit string `gorm:"type:varchar(100);comment:鍗曚綅" json:"unit"` - StartTime int64 `gorm:"comment:璁″垝寮�濮嬫椂闂�" json:"startTime"` - EndTime int64 `gorm:"comment:璁″垝缁撴潫鏃堕棿" json:"endTime"` + Amount decimal.Decimal `gorm:"type:decimal(35,18)" json:"amount"` + Unit string `gorm:"type:varchar(100)" json:"unit"` + StartTime int64 `json:"startTime"` + EndTime int64 `json:"endTime"` Status OrderStatus } @@ -132,7 +132,7 @@ } if len(slf.StatusList) != 0 { - db = db.Where("status in ?", slf.StatusList) + db = db.Where("status IN (?)", slf.StatusList) } if slf.StartTimeMax != 0 { diff --git a/nsq/consumer.go b/nsq/consumer.go index d6e668a..d75a999 100644 --- a/nsq/consumer.go +++ b/nsq/consumer.go @@ -5,12 +5,11 @@ "apsClient/constvar" "apsClient/pkg/logx" "apsClient/pkg/nsqclient" - "context" "fmt" ) -func Consume(topic, channel string) (err error) { - c, err := nsqclient.NewNsqConsumer(context.Background(), topic, channel) +func NewConsumer(topic, channel string) (c *nsqclient.NsqConsumer, err error) { + c, err = nsqclient.NewNsqConsumer(topic, channel) if err != nil { logx.Errorf("NewNsqConsumer err:%v", err) return @@ -28,19 +27,9 @@ handler = &ProcessParamsSync{Topic: topic} case fmt.Sprintf(constvar.NsqTopicDeviceUpdate, conf.Conf.NsqConf.NodeId): handler = &DeviceUpdate{Topic: topic} + case fmt.Sprintf(constvar.NsqTopicPullDataResponse, conf.Conf.NsqConf.NodeId): + handler = &PullDataResponse{Topic: topic} } c.AddHandler(handler.HandleMessage) - - if len(conf.Conf.NsqConf.NsqlookupdAddr) > 0 { - if err = c.RunLookupd(conf.Conf.NsqConf.NsqlookupdAddr, 1); err != nil { - logx.Errorf("RunLookupd err:%v", err) - return - } - } else { - if err = c.Run(conf.Conf.NsqConf.NsqdAddr, 1); err != nil { - logx.Errorf("Run err:%v", err) - return - } - } return } diff --git a/nsq/msg_handler.go b/nsq/msg_handler.go index 175f3e7..1db651e 100644 --- a/nsq/msg_handler.go +++ b/nsq/msg_handler.go @@ -11,9 +11,9 @@ "apsClient/utils/file" "encoding/json" "fmt" + "github.com/jinzhu/gorm" "github.com/mitchellh/mapstructure" "github.com/spf13/cast" - "gorm.io/gorm" "strings" ) @@ -98,7 +98,7 @@ return nil }) if err != nil { - logx.Errorf(" save task message error err: %v", err.Error()) + logx.Errorf(" save task message error err: %v", err) return err } } @@ -170,8 +170,8 @@ } detail, err := json.Marshal(record.Details) record.Detail = string(detail) - record.Id = 1 - err = model.NewDevicePlcSearch().SetId(record.Id).Save(&record) + record.ID = 1 + err = model.NewDevicePlcSearch().SetId(record.ID).Save(&record) if err != nil { return err } @@ -275,3 +275,66 @@ return nil } + +type PullDataResponse struct { + Topic string +} + +func (slf *PullDataResponse) HandleMessage(data []byte) (err error) { + logx.Infof("get a pull data response message :%s", data) + var pullDataResponse common.MsgPullDataResponse + err = json.Unmarshal(data, &pullDataResponse) + if err != nil { + logx.Infof("unmarshal msg err :%s", err) + return err + } + switch pullDataResponse.DataType { + case common.PullDataTypeProcessModel: + err = slf.DealProcessModelData(pullDataResponse.Data) + + } + if err != nil { + logx.Infof("process pull data err :%s", err) + return err + } + return nil +} + +func (slf *PullDataResponse) DealProcessModelData(data interface{}) error { + var processModels []*model.ProcessModel + err := mapstructure.Decode(data, &processModels) + if err != nil { + return err + } + numbers := make([]string, 0, len(processModels)) + for _, processModel := range processModels { + numbers = append(numbers, processModel.Number) + } + existsProcessModels, err := model.NewProcessModelSearch().SetIsNew(true).SetNumbers(numbers).FindNotTotal() + if err != nil { + return err + } + + existsProcessModelsMap := make(map[string]struct{}, len(existsProcessModels)) + for _, processModel := range existsProcessModels { + existsProcessModelsMap[processModel.Number] = struct{}{} + } + + for _, processModel := range processModels { + if _, exists := existsProcessModelsMap[processModel.Number]; exists { + continue + } + err = model.WithTransaction(func(db *gorm.DB) error { + err = model.NewProcessModelSearch().SetOrm(db).SetProcedure(processModel.Procedure).SetProduct(processModel.Product).SetIsNew(true).UpdateByMap(map[string]interface{}{"is_new": 0}) + if err != nil { + return err + } + processModel.IsNew = true + return model.NewProcessModelSearch().SetOrm(db).Create(processModel) + }) + if err != nil { + return err + } + } + return nil +} diff --git a/nsq/nsq.go b/nsq/nsq.go index 0c293db..888cf08 100644 --- a/nsq/nsq.go +++ b/nsq/nsq.go @@ -3,66 +3,85 @@ import ( "apsClient/conf" "apsClient/constvar" - "apsClient/model/common" "apsClient/pkg/logx" + "apsClient/pkg/nsqclient" "apsClient/pkg/safe" + "context" "errors" "fmt" - "time" + "sync" ) -func Init() error { +type consumerManager struct { + ctx context.Context + clients sync.Map +} + +var defaultConsumerManager *consumerManager + +func init() { + defaultConsumerManager = new(consumerManager) +} + +func (c *consumerManager) init() error { if len(conf.Conf.NsqConf.NodeId) <= 0 { return errors.New("no NodeId") } - if err := initProducer(); err != nil { return err } - safe.Go(func() { - caller := NewCaller(fmt.Sprintf(constvar.NsqTopicGetPlcAddress, conf.Conf.NsqConf.NodeId), fmt.Sprintf(constvar.NsqTopicSendPlcAddress, conf.Conf.NsqConf.NodeId)) - var addressResult common.ResponsePlcAddress - err := caller.Call(common.RequestPlcAddress{DeviceId: conf.Conf.System.DeviceId}, &addressResult, time.Second*3) - if err != nil { - logx.Infof("get plc address err: %v", err.Error()) - } - }) - - safe.Go(func() { - err := Consume(fmt.Sprintf(constvar.NsqTopicScheduleTask, conf.Conf.NsqConf.NodeId), conf.Conf.System.DeviceId) - if err != nil { - logx.Errorf("start nsq consume err: %v", err) - } - }) - - safe.Go(func() { - err := Consume(fmt.Sprintf(constvar.NsqTopicSendPlcAddress, conf.Conf.NsqConf.NodeId), conf.Conf.System.DeviceId) - if err != nil { - logx.Errorf("start nsq consume err: %v", err) - } - }) - - safe.Go(func() { - err := Consume(fmt.Sprintf(constvar.NsqTopicProcessParamsResponse, conf.Conf.NsqConf.NodeId), conf.Conf.System.DeviceId) - if err != nil { - logx.Errorf("start nsq consume err: %v", err) - } - }) - - safe.Go(func() { - err := Consume(fmt.Sprintf(constvar.NsqTopicApsProcessParams, conf.Conf.NsqConf.NodeId), conf.Conf.System.DeviceId) - if err != nil { - logx.Errorf("start nsq consume err: %v", err) - } - }) - - safe.Go(func() { - err := Consume(fmt.Sprintf(constvar.NsqTopicDeviceUpdate, conf.Conf.NsqConf.NodeId), conf.Conf.System.DeviceId) - if err != nil { - logx.Errorf("start nsq consume err: %v", err) - } - }) - + var topics = []string{ + constvar.NsqTopicScheduleTask, + constvar.NsqTopicSendPlcAddress, + constvar.NsqTopicProcessParamsResponse, + constvar.NsqTopicApsProcessParams, + constvar.NsqTopicDeviceUpdate, + constvar.NsqTopicPullDataResponse, + } + for _, t := range topics { + topic := fmt.Sprintf(t, conf.Conf.NsqConf.NodeId) + c.AddConsumer(topic) + } return nil } + +func (c *consumerManager) AddConsumer(topic string) { + safe.Go(func() { + client, err := NewConsumer(topic, conf.Conf.System.DeviceId) + if err != nil { + logx.Errorf("start nsq consume err: %v", err) + } + c.clients.Store(topic, client) + if len(conf.Conf.NsqConf.NsqlookupdAddr) > 0 { + if err = client.RunLookupd(conf.Conf.NsqConf.NsqlookupdAddr, 1); err != nil { + logx.Errorf("RunLookupd err:%v", err) + return + } + } else { + if err = client.Run(conf.Conf.NsqConf.NsqdAddr, 1); err != nil { + logx.Errorf("Run err:%v", err) + return + } + } + logx.Infof("add consumer success, topic:%v", topic) + }) +} + +func (c *consumerManager) stop() { + c.clients.Range(func(key, value any) bool { + if consumer, ok := value.(*nsqclient.NsqConsumer); ok { + nsqclient.DestroyNsqConsumer(consumer) + logx.Infof("try stop consumer, topic : %v", key) + } + return true + }) +} + +func Init() error { + return defaultConsumerManager.init() +} + +func Stop() { + defaultConsumerManager.stop() +} diff --git a/pkg/nsqclient/consumer.go b/pkg/nsqclient/consumer.go index a0df0b0..6e377b2 100644 --- a/pkg/nsqclient/consumer.go +++ b/pkg/nsqclient/consumer.go @@ -1,6 +1,7 @@ package nsqclient import ( + "apsClient/pkg/logx" "context" "fmt" "time" @@ -18,7 +19,7 @@ channel string } -func NewNsqConsumer(ctx context.Context, topic, channel string, options ...func(*nsq.Config)) (*NsqConsumer, error) { +func NewNsqConsumer(topic, channel string, options ...func(*nsq.Config)) (*NsqConsumer, error) { conf := nsq.NewConfig() conf.MaxAttempts = 0 conf.MsgTimeout = 10 * time.Minute // 榛樿涓�涓秷鎭渶澶氳兘澶勭悊鍗佸垎閽燂紝鍚﹀垯灏变細閲嶆柊涓㈠叆闃熷垪 @@ -33,7 +34,6 @@ } return &NsqConsumer{ consumer: consumer, - ctx: ctx, topic: topic, channel: channel, }, nil @@ -90,9 +90,9 @@ for { select { case <-n.ctx.Done(): - fmt.Println("[%s] %s,%s", "stop consumer", n.topic, n.channel) + logx.Infof("[%s]%s stop consumer...", n.topic, n.channel) n.consumer.Stop() - fmt.Println("[%s] %s,%s", "stop consumer success", n.topic, n.channel) + logx.Infof("[%s]%s stop consumer success", n.topic, n.channel) return nil } } diff --git a/pkg/sqlitex/sqlitex.go b/pkg/sqlitex/sqlitex.go index 2c221a5..92fde9e 100644 --- a/pkg/sqlitex/sqlitex.go +++ b/pkg/sqlitex/sqlitex.go @@ -1,12 +1,8 @@ package sqlitex import ( - "go.uber.org/zap" - "gorm.io/driver/sqlite" - "gorm.io/gorm" - "gorm.io/gorm/logger" - "gorm.io/gorm/schema" - "moul.io/zapgorm2" + "github.com/jinzhu/gorm" + _ "github.com/jinzhu/gorm/dialects/sqlite" "time" ) @@ -22,33 +18,18 @@ var openDb *gorm.DB -func Init(conf *Conf, log *zap.Logger) error { - gConfig := &gorm.Config{ - PrepareStmt: true, - NamingStrategy: schema.NamingStrategy{ - TablePrefix: "", - SingularTable: true, - }, - DisableForeignKeyConstraintWhenMigrating: true, - } - dbLogger := zapgorm2.New(log).LogMode(logger.Info) - if !conf.LogMode { - dbLogger = dbLogger.LogMode(logger.Silent) - } - gConfig.Logger = dbLogger - db, err := gorm.Open(sqlite.Open(conf.Dsn), gConfig) +func Init(conf *Conf) error { + db, err := gorm.Open("sqlite3", conf.Dsn) if err != nil { return err } - sqlDb, err := db.DB() - if err != nil { - return err - } + sqlDb := db.DB() sqlDb.SetMaxIdleConns(int(conf.MaxIdleCon)) sqlDb.SetMaxOpenConns(int(conf.MaxOpenCon)) sqlDb.SetConnMaxLifetime(time.Duration(conf.ConnMaxLifeTimeSecond) * time.Second) sqlDb.SetConnMaxIdleTime(time.Duration(conf.ConnMaxIdleTimeSecond) * time.Second) openDb = db + db.LogMode(true) return nil } diff --git a/serf/config.go b/serf/config.go new file mode 100644 index 0000000..70dfa1b --- /dev/null +++ b/serf/config.go @@ -0,0 +1,38 @@ +package serf + +import ( + "fmt" + "github.com/spf13/viper" +) + +type vasystem struct { + ServerName string `mapstructure:"serverName"` + ServerID string `mapstructure:"analyServerId"` +} + +var Vasystem = &vasystem{} + +// Init is an exported method that takes the environment starts the viper +// (external lib) and returns the configuration struct. +func init() { + var err error + v := viper.New() + v.SetConfigType("yaml") + v.SetConfigName("pro") + v.AddConfigPath("") + v.AddConfigPath("../config/") + v.AddConfigPath("./config/") + v.AddConfigPath("/opt/vasystem/config/") + + err = v.ReadInConfig() + if err != nil { + fmt.Println("error on parsing configuration file", err) + } + + read2Conf(v) +} + +func read2Conf(v *viper.Viper) { + v.UnmarshalKey("server", Vasystem) + fmt.Println("ServerID:", Vasystem.ServerID) +} diff --git a/serf/sqlite.go b/serf/sqlite.go new file mode 100644 index 0000000..79021d9 --- /dev/null +++ b/serf/sqlite.go @@ -0,0 +1,137 @@ +package serf + +import ( + "errors" + "fmt" + "regexp" + "strings" + + "github.com/jinzhu/gorm" +) + +type DumpSql struct { + Sql string `json:"sql"` +} + +type TableDesc struct { + Cid int `json:"cid"` + Name string `json:"name"` + Type string `json:"type"` + Notnull bool `json:"notnull"` + DFltValue interface{} `json:"dflt_value"` + Pk int `json:"pk"` +} + +var syncSqlChan = make(chan string, 10) + +func DumpTables(db *gorm.DB, tableNames []string) ([]string, error) { + db.LogMode(false) + defer db.LogMode(true) + + if tableNames != nil { + var arr []string + var dumpSql []DumpSql + + for _, table := range tableNames { + fmt.Println("dump current tableName:", table) + + dumpSql = make([]DumpSql, 0) + var tDescArr []TableDesc + + tSql := fmt.Sprintf(`PRAGMA table_info("%s")`, table) + err := db.Raw(tSql).Scan(&tDescArr).Error + + fmt.Println("tDescArr err:", err, "len(tDescArr)=", len(tDescArr)) + if err != nil { + return nil, errors.New("tableDesc err") + } + + fmt.Println(table, "'Columns is:", tDescArr) + if tDescArr == nil || len(tDescArr) == 0 { + return nil, errors.New(table + " has no column") + } + + var columnNames []string + for _, col := range tDescArr { + columnNames = append(columnNames, fmt.Sprintf(`'||quote("%s")||'`, col.Name)) + } + + tSql = fmt.Sprintf(`SELECT 'INSERT INTO "%s" VALUES(%s)' as sql FROM "%s";`, + table, + strings.Join(columnNames, ","), + table) + //fmt.Println("tSql:", tSql) + + err = db.Raw(tSql).Scan(&dumpSql).Error + if err != nil { + return nil, errors.New("dump err") + } + + if len(dumpSql) > 0 { + for _, d := range dumpSql { + arr = append(arr, d.Sql) + } + } + } + + return arr, nil + } + + return nil, errors.New("tableNames is nil") +} + +type DbLogger struct { +} + +func (dbLogger *DbLogger) Print(values ...interface{}) { + var ( + level = values[0] + ) + + fmt.Println("dblogger", values) + + if level == "sql" { + msgArr := gorm.LogFormatter(values...) + sql := msgArr[3].(string) + sql = strings.TrimPrefix(sql, " ") + if !strings.HasPrefix(sql, "SELECT") && !strings.HasPrefix(sql, "select") && !strings.Contains(sql, "PRAGMA") && !strings.Contains(sql, "pragma") { + affected := values[5].(int64) + if affected > 0 { //鎵ц鎴愬姛 + //鍒ゆ柇鎿嶄綔鐨勬槸鍝紶琛� + whereIdx := strings.Index(sql, "WHERE") + sqlWithTable := sql + if whereIdx > -1 { + sqlWithTable = sql[:whereIdx] + } + + fmt.Println("鍒ゆ柇鏄摢寮犺〃 sqlWithTable:", sqlWithTable) + + insertReg := regexp.MustCompile(`^\s*(?i:insert)\s`) //insert + updateReg := regexp.MustCompile(`^\s*(?i:update)\s`) //update + delReg := regexp.MustCompile(`^\s*(?i:delete)\s`) //delete + + if insertReg.MatchString(sqlWithTable) { + fmt.Println("鎻掑叆鎿嶄綔") + for _, t := range agent.syncTables { + reg := regexp.MustCompile(`\s+\"?(?i:` + t + `)\"?\s+`) + if reg.MatchString(sqlWithTable) { + fmt.Println("灞炰簬鍚屾琛�:", t) + syncSqlChan <- sql + } + } + } else if updateReg.MatchString(sqlWithTable) || delReg.MatchString(sqlWithTable) { + fmt.Println("鍒犻櫎鎴栬�呮洿鏂�") + for _, t := range agent.syncTables { + reg := regexp.MustCompile(`\s+\"?(?i:` + t + `)\"?\s+`) + if reg.MatchString(sqlWithTable) { + fmt.Println("灞炰簬鍚屾琛�:", t) + syncSqlChan <- sql + } + } + } + } + } + } else { + fmt.Println("dbLogger level!=sql") + } +} diff --git a/serf/sync.go b/serf/sync.go new file mode 100644 index 0000000..7675e84 --- /dev/null +++ b/serf/sync.go @@ -0,0 +1,378 @@ +package serf + +import ( + "context" + "encoding/json" + "fmt" + "os" + "os/signal" + "strings" + "syscall" + "time" + + "basic.com/pubsub/protomsg.git" + "basic.com/valib/bhomeclient.git" + "basic.com/valib/bhomedbapi.git" + + "github.com/gogo/protobuf/proto" + "github.com/jinzhu/gorm" +) + +var ( + agent = SyncServer{} +) + +const ( + serfSyncTopic = "sync-proc-message-to-serf" + + EventCreateCluster = 0 + EventJoinCluster = 1 + EventLeaveCluster = 2 + EventMaster2Slave = 3 + EventSlave2Master = 4 +) + +type ProcMessageEvent struct { + Owner string `json:"owner"` // 鍙戦�佽�� + Target string `json:"target"` // 鎸囧畾鎺ユ敹鑰� + Proc string `json:"procName"` // 杩涚▼鍚� + Topic string `json:"topic"` // 涓婚 + Payload []byte `json:"payload"` // 娑堟伅浣�,鑷瑙f瀽 +} + +type SyncServer struct { + ProcName string // 杩涚▼鍚嶇О + ServerId string // 鏈満id + ClusterStatus string // 闆嗙兢鐘舵�� master/slave 涓虹┖琛ㄧず鏈姞鍏ラ泦缇� + syncSqlTopic string // 鍚屾sql娑堟伅鐨勪富棰� + queryTableTopic string // 鍔犲叆闆嗙兢鍚庤姹傞泦缇ゆ暟鎹殑涓婚 + syncTables []string // 闇�瑕佸悓姝ョ殑琛� + sqlDB *gorm.DB // 鏁版嵁搴� + bhClient *bhomeclient.MicroNode + clusterEventFn func(int) +} + +func InitAgent(procName string, syncTables []string, db *gorm.DB) *SyncServer { + agent.ProcName = procName + agent.ServerId = Vasystem.ServerID + agent.sqlDB = db + agent.syncTables = syncTables + agent.syncSqlTopic = procName + "/serf/sync/sql" + agent.queryTableTopic = procName + "/serf/query/sqls" + + // 璁剧疆鏃ュ織鍥炶皟 + db.SetLogger(&DbLogger{}) + // 鍏堝叧闂棩蹇� + db.LogMode(false) + + return &agent +} + +func (ss *SyncServer) RegisterClusterEvent(fn func(int)) { + ss.clusterEventFn = fn +} + +func (ss *SyncServer) Serve(initChan chan bool) { + proc := &bhomeclient.ProcInfo{ + Name: ss.ProcName, //杩涚▼鍚嶇О + ID: ss.ProcName, //杩涚▼id + Info: "", //杩涚▼鐨勬弿杩颁俊鎭紝鐢ㄤ簬鍖哄垎鍚屼竴杩涚▼鍚嶇О涓嬪涓繘绋� + } + + ctx, cancel := context.WithCancel(context.Background()) + var reg = &bhomeclient.RegisterInfo{ + Proc: *proc, + Channel: nil, + PubTopic: []string{}, + SubTopic: []string{bhomeclient.Proc_System_Service, ss.syncSqlTopic, ss.queryTableTopic}, + SubNetTopic: []string{}, + } + + q := make(chan os.Signal, 1) + signal.Notify(q, os.Interrupt, os.Kill, syscall.SIGTERM) + + client, err := bhomeclient.NewMicroNode(ctx, q, ss.ServerId, reg, nil) + if err != nil { + initChan <- false + return + } + + bhomedbapi.InitGetNetNode(client.GetLocalNetNodeByTopic) + bhomedbapi.InitDoReq(client.RequestOnly) + //bhomedbapi.InitLog(logger.Debug) + + go client.StartServer(nil) + + ss.bhClient = client + + go ss.subBusMessage(ctx) + + go ss.handleDbLoggerPrint() + + // 鍚姩鍚庢煡璇竴娆¢泦缇ょ姸鎬� + ss.QueryClusterStat() + + if ss.ClusterStatus != "" { + ss.sqlDB.LogMode(true) + } + + initChan <- true + <-q + + client.DeRegister() + cancel() + client.Free() + + os.Exit(0) +} + +func (ss *SyncServer) pubSyncSqlMessage(payload []byte, targetId string) error { + var msg = ProcMessageEvent{ + Owner: ss.ServerId, + Target: targetId, + Proc: ss.ProcName, + Topic: ss.syncSqlTopic, + Payload: payload, + } + + b, err := json.Marshal(msg) + if err != nil { + return err + } + + return ss.bhClient.Publish(serfSyncTopic, b) +} + +// 璇锋眰鍚屾琛ㄧ殑鍏ㄩ噺鏁版嵁, 鍙戦�佽嚜宸辩殑id +func (ss *SyncServer) pubSyncTableMessage() error { + var msg = ProcMessageEvent{ + Owner: ss.ServerId, + Proc: ss.ProcName, + Topic: ss.queryTableTopic, + Payload: []byte(ss.ServerId), + } + + b, err := json.Marshal(msg) + if err != nil { + return err + } + + fmt.Println("鍔犲叆闆嗙兢, 璇锋眰鍚屾鍏ㄩ噺鏁版嵁,id:", ss.ServerId) + return ss.bhClient.Publish(serfSyncTopic, b) +} + +func (ss *SyncServer) subBusMessage(ctx context.Context) { + //fmt.Println("sub bus msg") + + for { + select { + case <-ctx.Done(): + fmt.Println("sub bus msg exit") + return + case busMsg := <-ss.bhClient.SubCh: + if string(busMsg.Topic) == ss.syncSqlTopic { + ss.handleClusterMessage(busMsg.Data) + } + + // 澶勭悊鍚屾鍏ㄩ噺鏁版嵁鐨勮姹� + if string(busMsg.Topic) == ss.queryTableTopic { + if ss.ClusterStatus == "master" { + fmt.Println("鎺ユ敹鍒板悓姝ュ叏閲忔暟鎹姹�") + ss.handleSyncTableMessage(busMsg.Data) + } + } + + // system-service鍙戦�佺殑娑堟伅 + if string(busMsg.Topic) == bhomeclient.Proc_System_Service { + var clusterMsg = &protomsg.DbChangeMessage{} + + if err := proto.Unmarshal(busMsg.Data, clusterMsg); err != nil { + if err = json.Unmarshal(busMsg.Data, clusterMsg); err != nil { + fmt.Println("proto.Unmarshal ", err.Error()) + continue + } + } + + if clusterMsg.Table == protomsg.TableChanged_T_Cluster { + switch clusterMsg.Info { + case "create": + // 鍒涘缓闆嗙兢, 寮�鍚棩蹇楄窡韪�, 璁剧疆瑙掕壊master + ss.clusterEventFn(EventCreateCluster) + ss.ClusterStatus = "master" + ss.sqlDB.LogMode(true) + + case "join": + // 鍔犲叆闆嗙兢, 寮�鍚棩蹇楄窡韪�, 璁剧疆瑙掕壊slave + ss.clusterEventFn(EventJoinCluster) + ss.onJoinCluster() + ss.ClusterStatus = "slave" + ss.sqlDB.LogMode(true) + + case "leave": + // 閫�鍑洪泦缇�, 寮�鍚棩蹇楄窡韪�, 璁剧疆瑙掕壊slave + ss.clusterEventFn(EventLeaveCluster) + ss.ClusterStatus = "" + ss.sqlDB.LogMode(false) + case "slave2master": + ss.clusterEventFn(EventSlave2Master) + ss.ClusterStatus = "master" + ss.sqlDB.LogMode(true) + case "master2slave": + ss.clusterEventFn(EventMaster2Slave) + ss.ClusterStatus = "slave" + ss.sqlDB.LogMode(true) + } + } + } + } + } +} + +// 鍔犲叆闆嗙兢, 娓呯┖鏈湴琛�, 鍚屾闆嗙兢鍐呮暟鎹� +func (ss *SyncServer) onJoinCluster() { + var err error + + db := ss.sqlDB + + tx := db.Begin() + defer func() { + if err != nil && tx != nil { + tx.Rollback() + } + }() + + tx.Exec("PRAGMA foreign_keys=OFF") + //1.鍒犻櫎鏈湴鐨勫悓姝ュ簱鏁版嵁 + for _, t := range ss.syncTables { + delSql := "delete from " + t + "" + + err = tx.Exec(delSql).Error + if err != nil { + fmt.Println("鍒犻櫎鏈湴鐨勫悓姝ュ簱鏁版嵁澶辫触,", err.Error()) + } + } + + //4.寮�鍚痳eference + tx.Exec("PRAGMA foreign_keys=ON") + tx.Commit() + + // 鎷夊彇闆嗙兢鍐呯殑鍚屾搴撴暟鎹埌鏈湴鏁版嵁搴撹〃涓� + ss.pubSyncTableMessage() +} + +func (ss *SyncServer) onLeaveCluster() { + +} + +func (ss *SyncServer) onCreateCluster() { + +} + +// 鏌ヨ闆嗙兢鐘舵��, 杩斿洖 master, slave, leave +func (ss *SyncServer) QueryClusterStat() string { + clusterStatTopic := "/data/api-v/cluster/status" + req := bhomeclient.Request{ + Path: clusterStatTopic, + Method: "POST", + } + + reply, err := ss.bhClient.RequestTopic(ss.ServerId, req, 3000) + if err != nil { + fmt.Println("RequestTopic error", err.Error()) + + return "" + } + + ss.ClusterStatus = reply.Msg + + fmt.Println("褰撳墠闆嗙兢鐘舵��:", ss.ClusterStatus) + + return reply.Msg +} + +func (ss *SyncServer) handleDbLoggerPrint() { + sqlBuf := make([]string, 0) + ticker := time.NewTicker(3 * time.Second) + sendSize := 0 //serf MaxUserEventSize is 9*1024 + for { + select { + case <-ticker.C: + if len(sqlBuf) > 0 { + syncSql := strings.Join(sqlBuf, "") + + //fmt.Println("鍚屾sql璇彞:", syncSql) + ss.pubSyncSqlMessage([]byte(syncSql), "") + + sqlBuf = append([]string{}) + sendSize = 0 + } + case sql := <-syncSqlChan: + if sendSize+len(sql) > (9*1024 - 1024) { + if len(sqlBuf) > 0 { + syncSql := strings.Join(sqlBuf, "") + //fmt.Println("鍚屾sql璇彞:", syncSql) + + ss.pubSyncSqlMessage([]byte(syncSql), "") + + sqlBuf = append([]string{}) + } + + s := strings.TrimRight(sql, ";") + sqlBuf = append(sqlBuf, s+";") + sendSize = len(sql) + } else { + s := strings.TrimRight(sql, ";") + sqlBuf = append(sqlBuf, s+";") + + sendSize = sendSize + len(sql) + } + } + } +} + +func (ss *SyncServer) handleClusterMessage(msg []byte) { + //fmt.Println("clusterMessage:", string(msg)) + sql := string(msg) + + if len(sql) <= 0 { + return + } + + db := ss.sqlDB + if db != nil { + db.LogMode(false) + defer db.LogMode(true) + + var err error + tx := db.Begin() + defer func() { + if err != nil && tx != nil { + tx.Rollback() + } + }() + result := tx.Exec(sql) + err = result.Error + if err != nil { + fmt.Println("ExecuteSqlByGorm err:", err, ",sql:", sql) + } + if result.RowsAffected == 0 { + fmt.Println("ExecuteSqlByGorm RowsAffected == 0", ",sql:", sql) + } + tx.Commit() + } +} + +func (ss *SyncServer) handleSyncTableMessage(msg []byte) error { + targetId := string(msg) + fmt.Println("鍚屾鍏ㄩ噺鏁版嵁缁欒妭鐐�:", targetId) + sqls, err := DumpTables(ss.sqlDB, ss.syncTables) + if err != nil { + fmt.Println("DumpTables error, ", err.Error()) + return err + } + + syncSql := strings.Join(sqls, ";") + err = ss.pubSyncSqlMessage([]byte(syncSql), targetId) + + return err +} diff --git a/service/cache_store.go b/service/cache_store.go index cfb9557..743e4a7 100644 --- a/service/cache_store.go +++ b/service/cache_store.go @@ -5,8 +5,8 @@ "apsClient/constvar" "apsClient/model" "fmt" + "github.com/jinzhu/gorm" "github.com/spf13/cast" - "gorm.io/gorm" "sync" "time" ) diff --git a/service/config.go b/service/config.go index 3378b2a..e1fdc57 100644 --- a/service/config.go +++ b/service/config.go @@ -17,11 +17,11 @@ } // GetNetConfig 鑾峰彇缃戠粶閰嶇疆 -func (slf ConfigService) GetNetConfig(id int) (ConfigData *model.NetConfig, err error) { +func (slf ConfigService) GetNetConfig(id uint) (ConfigData *model.NetConfig, err error) { return model.NewNetConfigSearch(nil).SetId(id).First() } // SetNetConfig 璁剧疆缃戠粶閰嶇疆 -func (slf ConfigService) SetNetConfig(id int, config *model.NetConfig) error { +func (slf ConfigService) SetNetConfig(id uint, config *model.NetConfig) error { return model.NewNetConfigSearch(nil).SetId(id).Save(config) } diff --git a/service/device_plc.go b/service/device_plc.go index b0281dd..90c3e51 100644 --- a/service/device_plc.go +++ b/service/device_plc.go @@ -8,7 +8,7 @@ "apsClient/pkg/structx" "encoding/json" "errors" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) type DevicePlcService struct{} @@ -21,7 +21,6 @@ DevicePlc, err := model.NewDevicePlcSearch().SetOrder("id desc").First() if err == gorm.ErrRecordNotFound { return &model.DevicePlc{ - Id: 0, Brand: "", Method: "", Address: "", @@ -42,7 +41,7 @@ func (slf DevicePlcService) GetDeviceChannelAmount() (int, error) { plcConfig, code := slf.GetDevicePlc() - if code != ecode.OK || plcConfig.Id == 0 { + if code != ecode.OK || plcConfig.ID == 0 { return 0, errors.New("鏈幏鍙栧埌PLC鍦板潃锛岃鍦ㄥ伐鑹烘ā鍨嬪簱涓笂浼狅紒") } if len(plcConfig.Details) == 0 { diff --git a/service/plc_brand.go b/service/plc_brand.go index 36628cd..1d04062 100644 --- a/service/plc_brand.go +++ b/service/plc_brand.go @@ -21,7 +21,7 @@ return ecode.OK } -func (PlcBrandService) GetPlcBrand(id int) (*model.PlcBrand, int) { +func (PlcBrandService) GetPlcBrand(id uint) (*model.PlcBrand, int) { plcBrand, err := model.NewPlcBrandSearch().SetId(id).First() if err != nil { return nil, ecode.DBErr @@ -30,7 +30,7 @@ return plcBrand, ecode.OK } -func (PlcBrandService) DeletePlcBrand(id int) int { +func (PlcBrandService) DeletePlcBrand(id uint) int { err := model.NewPlcBrandSearch().SetId(id).Delete() if err != nil { return ecode.DBErr @@ -65,7 +65,7 @@ } func (PlcBrandService) UpdatePlcBrand(plcBrand *model.PlcBrand) int { - err := model.NewPlcBrandSearch().SetId(plcBrand.Id).Save(plcBrand) + err := model.NewPlcBrandSearch().SetId(plcBrand.ID).Save(plcBrand) if err != nil { return ecode.DBErr } diff --git a/service/progress.go b/service/progress.go index 6eab830..ed904f1 100644 --- a/service/progress.go +++ b/service/progress.go @@ -1,9 +1,10 @@ package service import ( + "apsClient/conf" "apsClient/model" "errors" - "gorm.io/gorm" + "github.com/jinzhu/gorm" ) type ProgressService struct { @@ -54,7 +55,7 @@ var ok bool progressCache, ok = ProgressCacheGet(channel) if !ok { - progressCache, err = model.NewProductionProgressSearch(nil).SetChannel(channel).SetOrder("id desc").First() + progressCache, err = model.NewProductionProgressSearch(nil).SetDeviceId(conf.Conf.System.DeviceId).SetChannel(channel).SetOrder("id desc").First() if err == gorm.ErrRecordNotFound { return nil, errors.New("progress not found") } @@ -71,3 +72,9 @@ } return } + +// GetProgressList 鑾峰彇寰呭悓姝ヨ繘搴﹀伐搴� +func (slf ProgressService) GetProgressList() (progressList []*model.ProductionProgress, err error) { + progressList, err = model.NewProductionProgressSearch(nil).SetUnFinished().SetOrder("id desc").SetPage(1, 100).FindNotTotal() + return +} diff --git a/service/task.go b/service/task.go index a9b75ca..fbc355f 100644 --- a/service/task.go +++ b/service/task.go @@ -6,12 +6,10 @@ "apsClient/model" "apsClient/model/common" "apsClient/model/response" - "apsClient/nsq" "apsClient/pkg/ecode" "apsClient/pkg/logx" - "apsClient/pkg/structx" "fmt" - "gorm.io/gorm" + "github.com/jinzhu/gorm" "time" ) @@ -123,7 +121,7 @@ return NoRepeatedWorkers } -func (slf TaskService) GetProcedureById(id int) (*model.Procedures, int) { +func (slf TaskService) GetProcedureById(id uint) (*model.Procedures, int) { procedure, err := model.NewProceduresSearch(nil).SetId(id).First() if err != nil { return nil, ecode.DBErr @@ -131,7 +129,7 @@ return procedure, ecode.OK } -func (slf TaskService) UpdateProcedureStatusAndChannel(db *gorm.DB, id int, status model.ProcedureStatus, channel int32, processModelNumber string) error { +func (slf TaskService) UpdateProcedureStatusAndChannel(db *gorm.DB, id uint, status model.ProcedureStatus, channel int32, processModelNumber string) error { if status == model.ProcedureStatusFinished || status == model.ProcedureStatusWaitProcess { ProgressCacheUnset(channel) } @@ -146,7 +144,7 @@ return model.NewProceduresSearch(db).SetId(id).UpdateByMap(upMap) } -func (slf TaskService) UpdateProcedureStatus(db *gorm.DB, id int, status model.ProcedureStatus, channel int32) error { +func (slf TaskService) UpdateProcedureStatus(db *gorm.DB, id uint, status model.ProcedureStatus, channel int32) error { if status == model.ProcedureStatusFinished { ProgressCacheUnset(channel) } @@ -177,30 +175,6 @@ if err == nil { return data, nil } - - if err == gorm.ErrRecordNotFound { //濡傛灉鏁版嵁搴撴病鏈変粠浜戠鑾峰彇 - caller := nsq.NewCaller(fmt.Sprintf(constvar.NsqTopicProcessParamsRequest, conf.Conf.NsqConf.NodeId), fmt.Sprintf(constvar.NsqTopicProcessParamsResponse, conf.Conf.NsqConf.NodeId)) - var result common.ResponseProcessParams - err = caller.Call(common.RequestProcessParams{ - WorkOrder: procedure.WorkOrderID, - OrderId: procedure.OrderID, - Product: order.ProductName, - Procedure: procedure.ProceduresInfo.ProcedureName, - Device: procedure.ProceduresInfo.DeviceName, - DeviceId: conf.Conf.System.DeviceId, - }, &result, time.Second*3) - if err != nil { - logx.Errorf("TaskStart GetProcessModel error:%v", err.Error()) - return - } - if result.ParamsMap == nil { - logx.Errorf("TaskStart GetProcessModel response miss process params:%v", result) - return - } - processModel = new(model.ProcessModel) - err = structx.AssignTo(result, &processModel) - return processModel, err - } return } @@ -212,3 +186,18 @@ SetStartTimeMin(nowTs). SetStatus(model.OrderStatusWaitProcess).First() } + +// SaveTaskStatusSync 淇濆瓨浠诲姟鍚屾淇℃伅 +func (slf TaskService) SaveTaskStatusSync(db *gorm.DB, record *model.TaskStatusSync) (err error) { + return model.NewTaskStatusSyncSearch(db).Create(record) +} + +// GetTaskStatusSync 鑾峰彇寰呭悓姝ヤ换鍔′俊鎭� +func (slf TaskService) GetTaskStatusSync(limit int) ([]*model.TaskStatusSync, error) { + return model.NewTaskStatusSyncSearch(nil).SetOrder("id desc").SetPage(1, limit).FindNotTotal() +} + +// RemoveTaskStatusSync 鍒犻櫎鍚屾瀹岀殑璁板綍 +func (slf TaskService) RemoveTaskStatusSync(ids []uint) (err error) { + return model.NewTaskStatusSyncSearch(nil).SetIDs(ids).Delete() +} -- Gitblit v1.8.0