-- 退款资产后处理:逐次尝试记录 + 退款单上的当前状态、次数、最后错误与下次重试时间。 -- 每单自动重试最多 10 次,尝试记录量很小,不分区。 BEGIN; ALTER TABLE tb_refund_request ADD COLUMN IF NOT EXISTS asset_post_status smallint NOT NULL DEFAULT 0, ADD COLUMN IF NOT EXISTS asset_post_attempts int NOT NULL DEFAULT 0, ADD COLUMN IF NOT EXISTS asset_post_last_error varchar(500) NOT NULL DEFAULT '', ADD COLUMN IF NOT EXISTS asset_post_next_at timestamptz; COMMENT ON COLUMN tb_refund_request.asset_post_status IS '资产后处理状态 0-未开始 1-待重试 2-已完成 3-需人工处理'; COMMENT ON COLUMN tb_refund_request.asset_post_attempts IS '资产后处理已尝试次数'; COMMENT ON COLUMN tb_refund_request.asset_post_last_error IS '资产后处理最后一次错误摘要'; COMMENT ON COLUMN tb_refund_request.asset_post_next_at IS '资产后处理下次自动重试时间,为空表示可立即执行'; -- 已完成的存量退款单同步为已完成。 UPDATE tb_refund_request SET asset_post_status = 2 WHERE asset_reset = true AND asset_post_status = 0; CREATE INDEX IF NOT EXISTS idx_refund_request_asset_post_status ON tb_refund_request (asset_post_status, asset_post_next_at); CREATE TABLE IF NOT EXISTS tb_refund_post_process_attempt ( id BIGSERIAL PRIMARY KEY, refund_id BIGINT NOT NULL, refund_no VARCHAR(64) NOT NULL DEFAULT '', step VARCHAR(32) NOT NULL, asset_type VARCHAR(16) NOT NULL DEFAULT '', asset_id BIGINT NOT NULL DEFAULT 0, iccid VARCHAR(30) NOT NULL DEFAULT '', attempt INT NOT NULL, trigger VARCHAR(16) NOT NULL, result VARCHAR(16) NOT NULL, error_code VARCHAR(32) NOT NULL DEFAULT '', error_message VARCHAR(500) NOT NULL DEFAULT '', duration_ms INT NOT NULL DEFAULT 0, created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP ); COMMENT ON TABLE tb_refund_post_process_attempt IS '退款资产后处理逐次尝试记录,只新增不修改'; COMMENT ON COLUMN tb_refund_post_process_attempt.step IS '处理步骤 load-读取订单与资产 invalidate-套餐失效 activate-接续激活 check_main-查询生效主套餐 stop-停机评估或停机 mark-标记完成 done-全部完成'; COMMENT ON COLUMN tb_refund_post_process_attempt.trigger IS '触发方式 outbox-Outbox投递 manual-人工重试'; COMMENT ON COLUMN tb_refund_post_process_attempt.result IS '结果 success-成功 failed-失败'; CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_refund ON tb_refund_post_process_attempt (refund_id, created_at DESC); CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_time ON tb_refund_post_process_attempt (created_at DESC); CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_result ON tb_refund_post_process_attempt (result, created_at DESC); CREATE INDEX IF NOT EXISTS idx_refund_post_attempt_error ON tb_refund_post_process_attempt (error_code, created_at DESC); COMMIT;