From ec64a2b58bad6ebed9a06e8eb9c739a542156098 Mon Sep 17 00:00:00 2001 From: wangqiyang Date: Thu, 23 Jul 2026 15:28:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E6=89=AB=E6=8F=8F=E6=95=B0?= =?UTF-8?q?=E9=87=8F=E9=85=8D=E7=BD=AE=E6=8C=81=E4=B9=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/module/m9zTtyApi/init.go | 9 ++ internal/module/m9zTtyApi/scan.go | 7 +- internal/module/m9zTtyApi/scan_config.go | 117 +++++++++++++++++++++++ internal/module/m9zTtyApi/scan_test.go | 24 +++++ 4 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 internal/module/m9zTtyApi/scan_config.go create mode 100644 internal/module/m9zTtyApi/scan_test.go diff --git a/internal/module/m9zTtyApi/init.go b/internal/module/m9zTtyApi/init.go index 1cb12f9..5c6a7c4 100644 --- a/internal/module/m9zTtyApi/init.go +++ b/internal/module/m9zTtyApi/init.go @@ -9,6 +9,12 @@ import ( ) func Init() { + if err := scanConfigManager.loadFromFile(); err != nil { + g.GVA_LOG.Sugar().Warnf("load scan config failed: %v, using default", err) + if err := scanConfigManager.SetLoopCount(normalizeLoopCount(g.Config().DeviceInfo.LoopCount)); err != nil { + panic(err) + } + } towgo.SetFunc("/m9z/fault/list", faultList) towgo.SetFunc("/m9z/fault/batchExec", execFailByIds) @@ -74,12 +80,15 @@ func Init() { towgo.SetFunc("/m9z/getSubLoopParameters", getSubLoopParameters) towgo.SetFunc("/m9z/getAllSubLoopParameter", getAllSubLoopParameter) towgo.SetFunc("/m9z/touchdisplay/getDeviceID", getTouchDeviceId) + towgo.SetFunc("/m9z/scan/getConfig", getScanConfig) + towgo.SetFunc("/m9z/scan/setConfig", setScanConfig) } func getTouchDeviceId(rpc towgo.JsonRpcConnection) { deviceInfo := g.Config().DeviceInfo deviceInfo.MeterFirm = meterFirm.Manager().Get() + deviceInfo.LoopCount = configuredLoopCount() rpc.WriteResult(deviceInfo) } func faultDelete(rpc towgo.JsonRpcConnection) { diff --git a/internal/module/m9zTtyApi/scan.go b/internal/module/m9zTtyApi/scan.go index fd7b8ba..26077a6 100644 --- a/internal/module/m9zTtyApi/scan.go +++ b/internal/module/m9zTtyApi/scan.go @@ -1,14 +1,15 @@ package m9zApi -import g "tgk-touch/internal/global" - const ( defaultLoopCount = 10 maxLoopCount = 10 ) func configuredLoopCount() int { - loopCount := g.Config().DeviceInfo.LoopCount + return scanConfigManager.GetLoopCount() +} + +func normalizeLoopCount(loopCount int) int { if loopCount <= 0 { return defaultLoopCount } diff --git a/internal/module/m9zTtyApi/scan_config.go b/internal/module/m9zTtyApi/scan_config.go new file mode 100644 index 0000000..60961ff --- /dev/null +++ b/internal/module/m9zTtyApi/scan_config.go @@ -0,0 +1,117 @@ +package m9zApi + +import ( + "encoding/json" + "os" + "path/filepath" + "sync" + + g "tgk-touch/internal/global" + + "github.com/towgo/towgo/lib/system" + "github.com/towgo/towgo/towgo" +) + +type ScanConfigManager struct { + mu sync.RWMutex + loopCount int +} + +type ScanConfigData struct { + LoopCount int `json:"loop_count"` +} + +var scanConfigManager = &ScanConfigManager{} + +func getScanConfigFilePath() string { + return filepath.Join(system.GetPathOfProgram(), "data", "scanConfig.json") +} + +func (m *ScanConfigManager) GetLoopCount() int { + m.mu.RLock() + defer m.mu.RUnlock() + return normalizeLoopCount(m.loopCount) +} + +func (m *ScanConfigManager) SetLoopCount(loopCount int) error { + m.mu.Lock() + defer m.mu.Unlock() + + m.loopCount = loopCount + if err := m.saveToFile(); err != nil { + return err + } + g.GVA_Config.DeviceInfo.LoopCount = loopCount + return nil +} + +func (m *ScanConfigManager) loadFromFile() error { + m.mu.Lock() + defer m.mu.Unlock() + + filePath := getScanConfigFilePath() + jsonData, err := os.ReadFile(filePath) + if err != nil { + if os.IsNotExist(err) { + m.loopCount = normalizeLoopCount(g.Config().DeviceInfo.LoopCount) + return m.saveToFile() + } + return err + } + + var data ScanConfigData + if err := json.Unmarshal(jsonData, &data); err != nil { + return err + } + m.loopCount = normalizeLoopCount(data.LoopCount) + g.GVA_Config.DeviceInfo.LoopCount = m.loopCount + return nil +} + +func (m *ScanConfigManager) saveToFile() error { + filePath := getScanConfigFilePath() + dir := filepath.Dir(filePath) + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + + jsonData, err := json.Marshal(ScanConfigData{ + LoopCount: normalizeLoopCount(m.loopCount), + }) + if err != nil { + return err + } + return os.WriteFile(filePath, jsonData, 0600) +} + +func getScanConfig(rpcConn towgo.JsonRpcConnection) { + rpcConn.WriteResult(map[string]interface{}{ + "loop_count": scanConfigManager.GetLoopCount(), + "max_loop_count": maxLoopCount, + "min_loop_count": 1, + }) +} + +type SetScanConfigReq struct { + LoopCount int `json:"loop_count"` +} + +func setScanConfig(rpcConn towgo.JsonRpcConnection) { + var req SetScanConfigReq + rpcConn.ReadParams(&req) + + if req.LoopCount < 1 || req.LoopCount > maxLoopCount { + rpcConn.WriteError(400, "loop_count must be between 1 and 10") + return + } + if err := scanConfigManager.SetLoopCount(req.LoopCount); err != nil { + rpcConn.WriteError(500, "save scan config failed: "+err.Error()) + return + } + rpcConn.WriteResult(map[string]interface{}{ + "success": true, + "loop_count": scanConfigManager.GetLoopCount(), + "max_loop_count": maxLoopCount, + "min_loop_count": 1, + }) +} diff --git a/internal/module/m9zTtyApi/scan_test.go b/internal/module/m9zTtyApi/scan_test.go new file mode 100644 index 0000000..58992d3 --- /dev/null +++ b/internal/module/m9zTtyApi/scan_test.go @@ -0,0 +1,24 @@ +package m9zApi + +import "testing" + +func TestNormalizeLoopCount(t *testing.T) { + tests := []struct { + name string + in int + want int + }{ + {name: "default when empty", in: 0, want: defaultLoopCount}, + {name: "default when negative", in: -1, want: defaultLoopCount}, + {name: "keeps valid value", in: 6, want: 6}, + {name: "clamps max value", in: 12, want: maxLoopCount}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := normalizeLoopCount(tt.in); got != tt.want { + t.Fatalf("normalizeLoopCount(%d) = %d, want %d", tt.in, got, tt.want) + } + }) + } +}