整改三期:退款、后台增改删、悬赏

退款原来只有会员那条路,而且只能全额、只改本地状态。现在代喂任务的退款
能分几次退到退完:每一笔单独记一行(谁退的、多少、走哪条通道、为什么),
订单上的 refunded_cent 跟着累加,退完且未结算的任务才关闭。渠道接通时按
金额原路退回并带独立幂等键,没接通或沙箱支付的登记为"线下已退"——假装
调用了渠道比说实话更糟。已结算的任务不能顺手退:钱在喂养者账上,要退只能
由平台承担,必须显式勾选。

后台从"只能通过或驳回"变成能改能删:宠物档案可代建、可编辑、可软删除
(有进行中任务的删不掉),送养与配种能改文案和城市、能下架能删,代喂任务
能改备注、能取消(托管中的钱必须先退)。每一个写操作都进审计日志。

悬赏按方案里的 A 做:主人自愿加的钱跟着任务一起托管,结算时全额给喂养者,
平台服务费只算在基础报酬上。抽悬赏是喂养者一眼能算出来的事。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Your Name
2026-09-07 11:25:02 +08:00
co-authored by Claude Opus 5
parent ebf7189533
commit a889cb42e4
8 changed files with 1011 additions and 22 deletions
@@ -0,0 +1,34 @@
SET NAMES utf8mb4;
-- 悬赏:主人愿意在标准报酬之外多给一点来吸引人接单。它跟着任务一起托管,
-- 结算时全额给喂养者——平台服务费只算在基础报酬上,抽悬赏是喂养者一眼就
-- 能算出来的事,不值得。
ALTER TABLE pet_feed_tasks
ADD COLUMN tip_cent INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '主人自愿加的悬赏(分),不参与平台抽成' AFTER price_cent,
ADD COLUMN refunded_cent INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已退给主人的金额(分)' AFTER payout_cent;
ALTER TABLE orders
ADD COLUMN refunded_cent INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '已退金额(分),支持多次部分退款' AFTER paid_amount_cent;
-- 每一次退款都单独记一行:谁退的、退了多少、走的哪条通道、为什么。
-- 部分退款要能退好几次,所以这里不是一条订单一行。
CREATE TABLE IF NOT EXISTS pet_feed_refunds (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
task_id BIGINT UNSIGNED NOT NULL,
order_id BIGINT UNSIGNED NULL,
refund_no VARCHAR(60) NOT NULL COMMENT '幂等键,重复通知不会退第二次',
user_id BIGINT UNSIGNED NOT NULL COMMENT '收到退款的人,通常是主人',
amount_cent INT UNSIGNED NOT NULL,
channel VARCHAR(20) NOT NULL DEFAULT 'gateway' COMMENT 'gateway 原路退回 / offline 线下已退',
platform_bears TINYINT(1) NOT NULL DEFAULT 0 COMMENT '已结算的任务由平台承担时为 1',
reason VARCHAR(500) NOT NULL DEFAULT '',
handled_by BIGINT UNSIGNED NULL,
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
PRIMARY KEY (id),
UNIQUE KEY uk_refund_no (refund_no),
KEY idx_refunds_task (task_id, id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO system_configs(config_key,config_value,value_type,description) VALUES
('pet.feed_tip_max_cent','20000','integer','单个任务的悬赏上限(分)')
ON DUPLICATE KEY UPDATE description=VALUES(description);