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, &params)
+	err = service.NewConfigService().SetNetConfig(params.ID, &params)
 	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(&params.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