diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..4521317 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,24 @@ +name: CI + +on: + push: + branches: [main, master] + pull_request: + +jobs: + backend: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: "1.25" + - name: Build + run: go build ./... + working-directory: backend + - name: Vet + run: go vet ./... + working-directory: backend + - name: Test + run: go test ./... -count=1 -coverprofile=coverage.out + working-directory: backend diff --git a/backend/internal/controller/auth/auth_controller.go b/backend/internal/controller/auth/auth_controller.go index 04a51f6..4d612b6 100644 --- a/backend/internal/controller/auth/auth_controller.go +++ b/backend/internal/controller/auth/auth_controller.go @@ -38,7 +38,7 @@ func (ctrl *AuthController) Login(c *gin.Context) { result, err := ctrl.authService.Login(req) if err != nil { utils.LogAuthAction(ctrl.db, c, "login", req.Username, err.Error(), "failure") - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } @@ -52,7 +52,7 @@ func (ctrl *AuthController) Me(c *gin.Context) { userInfo, err := ctrl.authService.GetCurrentUser(userID.(uint)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } @@ -73,7 +73,7 @@ func (ctrl *AuthController) ChangePassword(c *gin.Context) { } if err := ctrl.authService.ChangePassword(userID.(uint), req); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } diff --git a/backend/internal/controller/customer/customer_controller.go b/backend/internal/controller/customer/customer_controller.go index 7d500d5..989d704 100644 --- a/backend/internal/controller/customer/customer_controller.go +++ b/backend/internal/controller/customer/customer_controller.go @@ -72,7 +72,7 @@ func (ctrl *CustomerController) Create(c *gin.Context) { } customer, err := ctrl.svc.Create(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "create", "customer", customer.ID, customer.Name, "", "", "创建客户") @@ -89,7 +89,7 @@ func (ctrl *CustomerController) Update(c *gin.Context) { } customer, err := ctrl.svc.Update(uint(id), req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update", "customer", customer.ID, customer.Name, "", "", "更新客户") @@ -100,7 +100,7 @@ func (ctrl *CustomerController) Update(c *gin.Context) { func (ctrl *CustomerController) Delete(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) if err := ctrl.svc.Delete(uint(id)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "delete", "customer", uint(id), "", "", "", "删除客户") @@ -115,7 +115,7 @@ func (ctrl *CustomerController) UpdateStatus(c *gin.Context) { } c.ShouldBindJSON(&req) if err := ctrl.svc.UpdateStatus(uint(id), req.Status); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update_status", "customer", uint(id), "", "", "", "切换客户状态") @@ -133,7 +133,7 @@ func (ctrl *CustomerController) BatchDelete(c *gin.Context) { } result, err := ctrl.svc.BatchDelete(req.IDs) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "batch_delete", "customer", 0, "", "", "", diff --git a/backend/internal/controller/entitlement/entitlement_controller.go b/backend/internal/controller/entitlement/entitlement_controller.go index a787605..6f01f0b 100644 --- a/backend/internal/controller/entitlement/entitlement_controller.go +++ b/backend/internal/controller/entitlement/entitlement_controller.go @@ -54,7 +54,7 @@ func (ctrl *EntitlementController) Get(c *gin.Context) { func (ctrl *EntitlementController) Revoke(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) if err := ctrl.svc.Revoke(uint(id)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "revoke", "entitlement", uint(id), "", "", "", "吊销客户权益") @@ -73,7 +73,7 @@ func (ctrl *EntitlementController) Renew(c *gin.Context) { } ent, err := ctrl.svc.Renew(uint(id), req.PlanID) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "renew", "entitlement", ent.ID, "", "", "", "续费客户权益") @@ -89,7 +89,7 @@ func (ctrl *EntitlementController) GetByEmail(c *gin.Context) { } entitlements, err := ctrl.svc.GetByEmail(email) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": entitlements}) diff --git a/backend/internal/controller/license/client_controller.go b/backend/internal/controller/license/client_controller.go index 0dda756..92fbe0a 100644 --- a/backend/internal/controller/license/client_controller.go +++ b/backend/internal/controller/license/client_controller.go @@ -1,6 +1,8 @@ package license import ( + + "backend/utils" "backend/internal/dto" "net/http" @@ -27,7 +29,7 @@ func (ctrl *LicenseController) ActivateDevice(c *gin.Context) { } data, err := ctrl.svc.Activate(req, c.ClientIP()) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "激活成功", "data": data}) @@ -41,7 +43,7 @@ func (ctrl *LicenseController) Deactivate(c *gin.Context) { return } if err := ctrl.svc.Deactivate(req); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "停用成功"}) @@ -56,7 +58,7 @@ func (ctrl *LicenseController) Heartbeat(c *gin.Context) { } data, err := ctrl.svc.Heartbeat(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "心跳成功", "data": data}) @@ -73,7 +75,7 @@ func (ctrl *LicenseController) ListDevices(c *gin.Context) { } devices, maxDevices, err := ctrl.svc.ListDevicesByKey(req.LicenseKey) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{ diff --git a/backend/internal/controller/license/license_controller.go b/backend/internal/controller/license/license_controller.go index ae4781a..54cff3d 100644 --- a/backend/internal/controller/license/license_controller.go +++ b/backend/internal/controller/license/license_controller.go @@ -80,7 +80,7 @@ func (ctrl *LicenseController) Create(c *gin.Context) { } licenses, err := ctrl.svc.Create(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "create", "license", licenses[0].ID, licenses[0].LicenseKey, "", "", @@ -97,7 +97,7 @@ func (ctrl *LicenseController) IssueOffline(c *gin.Context) { } result, err := ctrl.offline.Issue(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "create_offline", "license", result.LicenseID, result.Serial, "", "", @@ -128,7 +128,7 @@ func (ctrl *LicenseController) Update(c *gin.Context) { } lic, err := ctrl.svc.Update(uint(id), updates) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update", "license", lic.ID, lic.LicenseKey, "", "", "更新 License") @@ -140,7 +140,7 @@ func (ctrl *LicenseController) Delete(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) lic, err := ctrl.svc.Delete(uint(id)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "delete", "license", lic.ID, lic.LicenseKey, "", "", "删除 License") @@ -156,7 +156,7 @@ func (ctrl *LicenseController) BatchDelete(c *gin.Context) { } result, err := ctrl.svc.BatchDelete(req.IDs) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "batch_delete", "license", 0, "", "", "", @@ -185,7 +185,7 @@ func (ctrl *LicenseController) Renew(c *gin.Context) { } lic, err := ctrl.svc.Renew(uint(id), req.Duration) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "renew", "license", lic.ID, lic.LicenseKey, "", "", "续期 License") @@ -201,7 +201,7 @@ func (ctrl *LicenseController) Revoke(c *gin.Context) { c.ShouldBindJSON(&req) lic, err := ctrl.svc.Revoke(uint(id), req.Reason) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "revoke", "license", lic.ID, lic.LicenseKey, "", "", "吊销 License: "+req.Reason) @@ -223,7 +223,7 @@ func (ctrl *LicenseController) setStatus(c *gin.Context, status string) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) lic, err := ctrl.svc.SetStatus(uint(id), status) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, status, "license", lic.ID, lic.LicenseKey, "", "", "License 状态变更为 "+status) @@ -235,7 +235,7 @@ func (ctrl *LicenseController) GetActivations(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) activations, err := ctrl.svc.GetActivations(uint(id)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": activations}) @@ -246,7 +246,7 @@ func (ctrl *LicenseController) ForceOffline(c *gin.Context) { licenseID, _ := strconv.ParseUint(c.Param("id"), 10, 32) activationID, _ := strconv.ParseUint(c.Param("activationId"), 10, 32) if err := ctrl.svc.ForceOffline(uint(licenseID), uint(activationID)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "force_offline", "activation", uint(activationID), "", "", "", "强制下线设备") @@ -257,7 +257,7 @@ func (ctrl *LicenseController) ForceOffline(c *gin.Context) { func (ctrl *LicenseController) Export(c *gin.Context) { csv, err := ctrl.svc.ExportCSV(parseListQuery(c)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.Header("Content-Type", "text/csv; charset=utf-8") diff --git a/backend/internal/controller/plan/plan_controller.go b/backend/internal/controller/plan/plan_controller.go index e05f670..0c38efe 100644 --- a/backend/internal/controller/plan/plan_controller.go +++ b/backend/internal/controller/plan/plan_controller.go @@ -43,7 +43,7 @@ func (ctrl *PlanController) GetByProduct(c *gin.Context) { productID, _ := strconv.ParseUint(c.Param("product_id"), 10, 32) plans, err := ctrl.svc.GetByProduct(uint(productID)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": plans}) @@ -69,7 +69,7 @@ func (ctrl *PlanController) Create(c *gin.Context) { } plan, err := ctrl.svc.Create(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "create", "plan", plan.ID, plan.Name, "", "", "创建定价计划") @@ -95,7 +95,7 @@ func (ctrl *PlanController) Update(c *gin.Context) { } plan, err := ctrl.svc.Update(uint(id), req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update", "plan", plan.ID, plan.Name, "", "", "更新定价计划") @@ -106,7 +106,7 @@ func (ctrl *PlanController) Update(c *gin.Context) { func (ctrl *PlanController) Delete(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) if err := ctrl.svc.Delete(uint(id)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "delete", "plan", uint(id), "", "", "", "删除定价计划") @@ -121,7 +121,7 @@ func (ctrl *PlanController) ToggleStatus(c *gin.Context) { } c.ShouldBindJSON(&req) if err := ctrl.svc.ToggleStatus(uint(id), req.Status); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "toggle_status", "plan", uint(id), "", "", "", "切换计划状态") diff --git a/backend/internal/controller/product/product_controller.go b/backend/internal/controller/product/product_controller.go index aaeee18..016f6fc 100644 --- a/backend/internal/controller/product/product_controller.go +++ b/backend/internal/controller/product/product_controller.go @@ -77,7 +77,7 @@ func (ctrl *ProductController) GetByCode(c *gin.Context) { } plans, err := ctrl.planSvc.GetByProduct(product.ID) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": dto.ProductWithPlansResponse{ @@ -95,7 +95,7 @@ func (ctrl *ProductController) Create(c *gin.Context) { } product, err := ctrl.svc.Create(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "create", "product", product.ID, product.Name, "", "", "创建产品") @@ -112,7 +112,7 @@ func (ctrl *ProductController) Update(c *gin.Context) { } product, err := ctrl.svc.Update(uint(id), req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update", "product", product.ID, product.Name, "", "", "更新产品") @@ -123,7 +123,7 @@ func (ctrl *ProductController) Update(c *gin.Context) { func (ctrl *ProductController) Delete(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) if err := ctrl.svc.Delete(uint(id)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "delete", "product", uint(id), "", "", "", "删除产品") @@ -138,7 +138,7 @@ func (ctrl *ProductController) UpdateStatus(c *gin.Context) { } c.ShouldBindJSON(&req) if err := ctrl.svc.UpdateStatus(uint(id), req.Status); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "update_status", "product", uint(id), "", "", "", fmt.Sprintf("切换状态为 %d", req.Status)) @@ -156,7 +156,7 @@ func (ctrl *ProductController) BatchDelete(c *gin.Context) { } result, err := ctrl.svc.BatchDelete(req.IDs) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } utils.LogAction(ctrl.db, c, "batch_delete", "product", 0, "", "", "", diff --git a/backend/internal/controller/setting/setting_controller.go b/backend/internal/controller/setting/setting_controller.go index 60647af..623ede7 100644 --- a/backend/internal/controller/setting/setting_controller.go +++ b/backend/internal/controller/setting/setting_controller.go @@ -1,6 +1,8 @@ package setting import ( + + "backend/utils" "backend/internal/dto" settingservice "backend/internal/service/setting" "net/http" @@ -39,7 +41,7 @@ func (ctrl *SettingController) Update(c *gin.Context) { } setting, err := ctrl.svc.Update(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "更新成功", "data": setting}) @@ -49,7 +51,7 @@ func (ctrl *SettingController) Update(c *gin.Context) { func (ctrl *SettingController) GetWaffo(c *gin.Context) { data, err := ctrl.svc.GetWaffo() if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": data}) @@ -64,7 +66,7 @@ func (ctrl *SettingController) UpdateWaffo(c *gin.Context) { } data, err := ctrl.svc.UpdateWaffo(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "Waffo 配置已保存", "data": data}) @@ -113,7 +115,7 @@ func (ctrl *SettingController) ListAuditLogs(c *gin.Context) { // ClearAuditLogs 清空审计日志 // Logan.Li func (ctrl *SettingController) ClearAuditLogs(c *gin.Context) { if err := ctrl.svc.ClearAuditLogs(); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "日志已清空"}) diff --git a/backend/internal/controller/sync/sync_controller.go b/backend/internal/controller/sync/sync_controller.go index 95bae84..0555c6f 100644 --- a/backend/internal/controller/sync/sync_controller.go +++ b/backend/internal/controller/sync/sync_controller.go @@ -3,6 +3,8 @@ package sync import ( + + "backend/utils" "backend/config" "backend/internal/dto" "backend/internal/model" @@ -37,7 +39,7 @@ func (ctrl *Controller) Svc() *syncsvc.Service { return ctrl.svc } func (ctrl *Controller) ListPeers(c *gin.Context) { peers, err := ctrl.svc.ListPeers() if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{ @@ -54,7 +56,7 @@ func (ctrl *Controller) SavePeer(c *gin.Context) { } peer, err := ctrl.svc.SavePeer(req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "已保存,请在对端配置相同互联密钥后测试握手", "data": peer}) @@ -64,7 +66,7 @@ func (ctrl *Controller) SavePeer(c *gin.Context) { func (ctrl *Controller) DeletePeer(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) if err := ctrl.svc.DeletePeer(uint(id)); err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "已删除"}) @@ -75,7 +77,7 @@ func (ctrl *Controller) TestHandshake(c *gin.Context) { id, _ := strconv.ParseUint(c.Param("id"), 10, 32) peer, err := ctrl.svc.TestHandshake(uint(id)) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "握手成功,互联已激活", "data": peer}) @@ -91,7 +93,7 @@ func (ctrl *Controller) SyncNow(c *gin.Context) { } result, err := ctrl.svc.ExchangeOut(&peer) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, gin.H{"code": 0, "message": "同步完成: " + result}) @@ -119,7 +121,7 @@ func (ctrl *Controller) HandshakeIn(c *gin.Context) { } resp, err := ctrl.svc.HandshakeIn(peer, req) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, resp) @@ -138,7 +140,7 @@ func (ctrl *Controller) ExchangeIn(c *gin.Context) { } resp, err := ctrl.svc.ExchangeIn(peer, req) if err != nil { - c.JSON(http.StatusOK, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusOK, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return } c.JSON(http.StatusOK, resp) @@ -156,7 +158,7 @@ func (ctrl *Controller) readAndVerify(c *gin.Context) ([]byte, *model.PeerNode) return syncsvc.VerifySignature(p.SharedKey, c.Request, body) }) if err != nil { - c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "message": err.Error()}) + c.JSON(http.StatusUnauthorized, gin.H{"code": 1, "message": utils.InternalMsg(err)}) return nil, nil } return body, peer diff --git a/backend/utils/errmsg.go b/backend/utils/errmsg.go new file mode 100644 index 0000000..2dded50 --- /dev/null +++ b/backend/utils/errmsg.go @@ -0,0 +1,13 @@ +package utils + +import "log" + +// InternalMsg 将内部错误详情记录到服务端日志,对外返回统一脱敏消息, +// 避免向客户端泄露 GORM/SQL 等实现细节。 +func InternalMsg(err error) string { + if err == nil { + return "操作失败" + } + log.Printf("[internal-error] %v", err) + return "操作失败,请稍后重试" +}