From 60102aead6293a90231e3bd920ce35f56321e372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E7=90=A6?= Date: Wed, 15 Jul 2026 08:47:41 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E5=A4=84=E6=96=B9=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/COMMANDS.md | 3 +- internal/logweb/upload_handlers.go | 10 +++++ internal/logweb/web/supervise_step.html | 9 +++- internal/sync/sync.go | 56 ++++++++++++++++--------- internal/sync/upload_test_result.go | 22 +++++++--- internal/xkapi/client.go | 8 ++-- 6 files changed, 77 insertions(+), 31 deletions(-) diff --git a/docs/COMMANDS.md b/docs/COMMANDS.md index 23a762e..e335029 100644 --- a/docs/COMMANDS.md +++ b/docs/COMMANDS.md @@ -219,7 +219,8 @@ xk-hy-transit-go\log\transit\ | 路径 | 说明 | |------|------| | `/config` | 查看云端 / 本地 / 生效互医配置;对比云端预生成 token 与 Runner 本地 FileAuth token | -| `/upload` | 测试 PDF 上传(失败时展示完整 upstream 错误,Toast 提示) | +| `/upload` | 测试 PDF 上传(含 `httpStatus`/`rawBody` 政务云文件服务响应) | +| `/supervise-step` | 处方/核销单步联调(含 `push.response_body` 业务上报响应) | | `/runs` | 同步流水;失败记录可「整条重试」 | 改 xk-api `.env` 后:`php artisan config:clear` + 重启 PHP/Laravel-S,再在 transit `/config` 点重新拉取。 diff --git a/internal/logweb/upload_handlers.go b/internal/logweb/upload_handlers.go index 2447b04..64070fc 100644 --- a/internal/logweb/upload_handlers.go +++ b/internal/logweb/upload_handlers.go @@ -42,6 +42,16 @@ func uploadTestPayload(res *syncer.UploadTestResult, uploadURL string, ok bool, if res != nil { out["filename"] = res.Filename out["scope"] = res.Scope + if res.HTTPStatus != 0 { + out["httpStatus"] = res.HTTPStatus + } + if res.RawBody != "" { + out["rawBody"] = res.RawBody + } + if res.Message != "" { + out["message"] = res.Message + } + out["success"] = res.Success } if fileID != "" { out["fileId"] = fileID diff --git a/internal/logweb/web/supervise_step.html b/internal/logweb/web/supervise_step.html index 1d1b7ff..e42979e 100644 --- a/internal/logweb/web/supervise_step.html +++ b/internal/logweb/web/supervise_step.html @@ -87,7 +87,14 @@ function renderStepResult(data) { lines.push('\n[推送头 push_headers]\n' + JSON.stringify(it.push_headers, null, 2)); } if (it.push) { - lines.push('\n[政务云上报]\n' + JSON.stringify(it.push, null, 2)); + const hasResp = it.push.response_body || it.push.http_code || it.push.msg; + if (hasResp) { + lines.push('\n[政务云上报]\n' + JSON.stringify(it.push, null, 2)); + } else if (it.validation_errors && it.validation_errors.length) { + lines.push('\n[政务云上报] 未执行(组包校验失败,记录已 skipped)'); + } else { + lines.push('\n[政务云上报] 未执行(未到达 PostForward,请检查拉取条数或前置步骤)'); + } } if (it.callback) { lines.push('\n[云端回调 CallbackItem]\n' + JSON.stringify(it.callback, null, 2)); diff --git a/internal/sync/sync.go b/internal/sync/sync.go index 0db1e2a..7d36f4d 100644 --- a/internal/sync/sync.go +++ b/internal/sync/sync.go @@ -174,7 +174,11 @@ func (r *Runner) executeStep(step, anchorDate string, opts StepRunOptions) (*Ste validationCount++ } } - applog.Pullf("pull done step=%s batch_id=%d items=%d validation_failed=%d", step, batchID, len(pull.Items), validationCount) + followUpCount := 0 + if step == "verification" { + followUpCount = len(pull.FollowUpRecipeItems) + } + applog.Pullf("pull done step=%s batch_id=%d items=%d validation_failed=%d follow_up_recipe=%d", step, batchID, len(pull.Items), validationCount, followUpCount) if result != nil { result.PullSummary = PullSummary{ Total: len(pull.Items), @@ -192,28 +196,40 @@ func (r *Runner) executeStep(step, anchorDate string, opts StepRunOptions) (*Ste var callbacks []xkapi.CallbackItem success, failed, skipped := 0, 0, 0 - for _, item := range items { - var tr *itemTraceCtx - if opts.CollectTrace { - tr = newItemTraceCtx(item) - if item.BizKey == "" && item.Payload != nil { - tr.out.BizKey = hy.BizKey(step, anchorDate, item.Payload) + appendProcessed := func(processStep, processMethod string, batchItems []xkapi.PullItem) { + for _, item := range batchItems { + var tr *itemTraceCtx + if opts.CollectTrace { + tr = newItemTraceCtx(item) + if item.BizKey == "" && item.Payload != nil { + tr.out.BizKey = hy.BizKey(processStep, anchorDate, item.Payload) + } + } + cb := r.processItem(processStep, anchorDate, processMethod, batchID, item, tr) + callbacks = append(callbacks, cb) + if tr != nil { + tr.finish(cb) + result.Items = append(result.Items, *tr.out) + } + switch cb.PushStatus { + case "success": + success++ + case "skipped": + skipped++ + default: + failed++ } } - cb := r.processItem(step, anchorDate, method, batchID, item, tr) - callbacks = append(callbacks, cb) - if tr != nil { - tr.finish(cb) - result.Items = append(result.Items, *tr.out) - } - switch cb.PushStatus { - case "success": - success++ - case "skipped": - skipped++ - default: - failed++ + } + appendProcessed(step, method, items) + + if step == "verification" && len(pull.FollowUpRecipeItems) > 0 { + followUpMethod, ok := hy.StepMethods["recipe"] + if !ok { + return result, fmt.Errorf("unknown follow-up step: recipe") } + applog.Pullf("verification follow-up recipe items=%d", len(pull.FollowUpRecipeItems)) + appendProcessed("recipe", followUpMethod, pull.FollowUpRecipeItems) } if err := r.xk.BatchCallback(batchID, callbacks); err != nil { diff --git a/internal/sync/upload_test_result.go b/internal/sync/upload_test_result.go index 9c357a9..f78086d 100644 --- a/internal/sync/upload_test_result.go +++ b/internal/sync/upload_test_result.go @@ -11,10 +11,14 @@ import ( // UploadTestResult Web 测试上传结果(含本次 FileAuth.java token 分步信息)。 type UploadTestResult struct { - FileID string - Filename string - Scope string - Parts fileauth.UploadTokenParts + FileID string + Filename string + Scope string + Parts fileauth.UploadTokenParts + HTTPStatus int + RawBody string + Success bool + Message string } // uploadTokenPartsForUpload 生成 FileAuth.java upload profile token(scope=仅 bucket)。 @@ -53,11 +57,17 @@ func (r *Runner) UploadTestPDF(pdf []byte, filename string) (*UploadTestResult, Scope: bucket, Parts: parts, } - fileID, err := hyfile.UploadPDF(pdf, filename, url, parts.UploadToken, r.cfg.ForwardSharedSecret) + upRes, err := hyfile.UploadPDFDetail(pdf, filename, url, parts.UploadToken, r.cfg.ForwardSharedSecret) + if upRes != nil { + res.HTTPStatus = upRes.HTTPStatus + res.RawBody = upRes.RawBody + res.Success = upRes.Success + res.Message = upRes.Message + res.FileID = upRes.FileID + } if err != nil { return res, err } - res.FileID = fileID return res, nil } diff --git a/internal/xkapi/client.go b/internal/xkapi/client.go index 54dc494..96ae11a 100644 --- a/internal/xkapi/client.go +++ b/internal/xkapi/client.go @@ -47,9 +47,11 @@ func New(baseURL, token, callbackPath string) *Client { // PullResponse 单次拉取响应。 type PullResponse struct { - AnchorDate string `json:"anchor_date"` - BatchID int `json:"batch_id"` - Items []PullItem `json:"items"` + AnchorDate string `json:"anchor_date"` + BatchID int `json:"batch_id"` + Items []PullItem `json:"items"` + FollowUpRecipeItems []PullItem `json:"follow_up_recipe_items"` + PrescriptionIDs []int `json:"prescription_ids"` } // PullItem 单条组包记录(含云端 record_id)。