From e883d2cff0f64c6e2f3e9f7eda636919ce2b6a9f Mon Sep 17 00:00:00 2001 From: actiontech-zihan Date: Tue, 28 Jul 2026 17:50:14 +0800 Subject: [PATCH] feat: optional approval comment for data export approve Support empty body Approve via Param path inject; persist optional payload.reason on steps. Co-authored-by: Cursor --- api/dms/service/v1/data_export_workflow.go | 7 +++++++ internal/apiserver/service/dms_controller.go | 20 +++++++++++++++++--- internal/dms/biz/data_export_workflow_ce.go | 2 +- internal/dms/service/data_export_workflow.go | 2 +- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/api/dms/service/v1/data_export_workflow.go b/api/dms/service/v1/data_export_workflow.go index 2ecfaf1a..21dc4323 100644 --- a/api/dms/service/v1/data_export_workflow.go +++ b/api/dms/service/v1/data_export_workflow.go @@ -316,6 +316,11 @@ type WorkflowStep struct { Reason string `json:"reason,omitempty"` } +type ApproveDataExportWorkflowPayload struct { + // optional approval comment; empty / omitted means no comment + Reason string `json:"reason"` +} + // swagger:parameters ApproveDataExportWorkflow type ApproveDataExportWorkflowReq struct { // project id @@ -325,6 +330,8 @@ type ApproveDataExportWorkflowReq struct { // Required: true // in:path DataExportWorkflowUid string `param:"data_export_workflow_uid" json:"data_export_workflow_uid" validate:"required"` + // optional body; omit / empty payload / empty reason → "" + Payload ApproveDataExportWorkflowPayload `json:"payload"` } // swagger:parameters ExportDataExportWorkflow diff --git a/internal/apiserver/service/dms_controller.go b/internal/apiserver/service/dms_controller.go index f91f4856..4fd4b159 100644 --- a/internal/apiserver/service/dms_controller.go +++ b/internal/apiserver/service/dms_controller.go @@ -14,6 +14,7 @@ import ( "path/filepath" "strings" "time" + "unicode/utf8" "github.com/actiontech/dms/api" aV1 "github.com/actiontech/dms/api/dms/service/v1" @@ -3763,10 +3764,23 @@ func (ctl *DMSController) AddDataExportWorkflow(c echo.Context) error { // default: body:GenericResp func (ctl *DMSController) ApproveDataExportWorkflow(c echo.Context) error { req := &aV1.ApproveDataExportWorkflowReq{} - err := bindAndValidateReq(c, req) - if nil != err { - return NewErrResp(c, err, apiError.BadRequestErr) + // 兼容旧客户端:无 body / ContentLength=0 时按空意见处理。 + // path 参数与 body 同属 req,跳过 bind 时须从 Param 注入,避免空 uid 查库失败。 + if c.Request().ContentLength != 0 { + err := bindAndValidateReq(c, req) + if nil != err { + return NewErrResp(c, err, apiError.BadRequestErr) + } + } else { + req.ProjectUid = c.Param("project_uid") + req.DataExportWorkflowUid = c.Param("data_export_workflow_uid") + } + + reason := strings.TrimSpace(req.Payload.Reason) + if utf8.RuneCountInString(reason) > 255 { + return NewErrResp(c, fmt.Errorf("审批意见不能超过255个字符"), apiError.BadRequestErr) } + req.Payload.Reason = reason currentUserUid, err := jwt.GetUserUidStrFromContext(c) if err != nil { diff --git a/internal/dms/biz/data_export_workflow_ce.go b/internal/dms/biz/data_export_workflow_ce.go index 880b08b5..1489cfe3 100644 --- a/internal/dms/biz/data_export_workflow_ce.go +++ b/internal/dms/biz/data_export_workflow_ce.go @@ -23,7 +23,7 @@ func (d *DataExportWorkflowUsecase) GetDataExportWorkflow(ctx context.Context, w return nil, errNotDataExportWorkflow } -func (d *DataExportWorkflowUsecase) ApproveDataExportWorkflow(ctx context.Context, projectId, workflowId, userId string) error { +func (d *DataExportWorkflowUsecase) ApproveDataExportWorkflow(ctx context.Context, projectId, workflowId, userId, reason string) error { return errNotDataExportWorkflow } diff --git a/internal/dms/service/data_export_workflow.go b/internal/dms/service/data_export_workflow.go index 679afcc4..9294bfc9 100644 --- a/internal/dms/service/data_export_workflow.go +++ b/internal/dms/service/data_export_workflow.go @@ -379,7 +379,7 @@ func (d *DMSService) ListDataExportTaskSQLs(ctx context.Context, req *dmsV1.List } func (d *DMSService) ApproveDataExportWorkflow(ctx context.Context, req *dmsV1.ApproveDataExportWorkflowReq, userId string) (err error) { - return d.DataExportWorkflowUsecase.ApproveDataExportWorkflow(ctx, req.ProjectUid, req.DataExportWorkflowUid, userId) + return d.DataExportWorkflowUsecase.ApproveDataExportWorkflow(ctx, req.ProjectUid, req.DataExportWorkflowUid, userId, req.Payload.Reason) } func (d *DMSService) RejectDataExportWorkflow(ctx context.Context, req *dmsV1.RejectDataExportWorkflowReq, userId string) (err error) {