137 lines
6.1 KiB
SQL
137 lines
6.1 KiB
SQL
CREATE TABLE IF NOT EXISTS qipai_cleaning_settlement_reversals (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
tenant_id BIGINT UNSIGNED NOT NULL,
|
|
reversal_no VARCHAR(64) NOT NULL,
|
|
settlement_id BIGINT UNSIGNED NOT NULL,
|
|
amount_delta_cents BIGINT NOT NULL,
|
|
reason VARCHAR(512) NOT NULL,
|
|
reversed_by BIGINT UNSIGNED NOT NULL,
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_reversal_tenant FOREIGN KEY (tenant_id)
|
|
REFERENCES qipai_tenants(id),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_reversal_settlement FOREIGN KEY (settlement_id)
|
|
REFERENCES qipai_cleaning_settlements(id),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_reversal_actor FOREIGN KEY (reversed_by)
|
|
REFERENCES qipai_users(id),
|
|
CONSTRAINT chk_qipai_cleaning_settlement_reversal_amount CHECK (amount_delta_cents <= 0),
|
|
UNIQUE KEY uq_qipai_cleaning_settlement_reversal_no (tenant_id, reversal_no),
|
|
UNIQUE KEY uq_qipai_cleaning_settlement_reversal_parent (tenant_id, settlement_id),
|
|
KEY idx_qipai_cleaning_settlement_reversal_created (tenant_id, created_at)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
CREATE TABLE IF NOT EXISTS qipai_cleaning_settlement_events (
|
|
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
|
|
tenant_id BIGINT UNSIGNED NOT NULL,
|
|
settlement_id BIGINT UNSIGNED NOT NULL,
|
|
from_status VARCHAR(32) NULL,
|
|
to_status VARCHAR(32) NOT NULL,
|
|
action VARCHAR(32) NOT NULL,
|
|
actor_id BIGINT UNSIGNED NOT NULL,
|
|
actor_type VARCHAR(16) NOT NULL DEFAULT 'USER',
|
|
trace_id VARCHAR(64) NOT NULL,
|
|
note VARCHAR(512) NOT NULL DEFAULT '',
|
|
metadata JSON NOT NULL,
|
|
created_at DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_event_tenant FOREIGN KEY (tenant_id)
|
|
REFERENCES qipai_tenants(id),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_event_parent FOREIGN KEY (settlement_id)
|
|
REFERENCES qipai_cleaning_settlements(id),
|
|
CONSTRAINT fk_qipai_cleaning_settlement_event_actor FOREIGN KEY (actor_id)
|
|
REFERENCES qipai_users(id),
|
|
CONSTRAINT chk_qipai_cleaning_settlement_event_actor_type CHECK (
|
|
actor_type IN ('USER', 'SYSTEM')
|
|
),
|
|
UNIQUE KEY uq_qipai_cleaning_settlement_event_trace
|
|
(tenant_id, settlement_id, action, trace_id),
|
|
KEY idx_qipai_cleaning_settlement_event_history
|
|
(tenant_id, settlement_id, created_at, id)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
|
|
|
ALTER TABLE qipai_cleaning_settlements
|
|
ADD COLUMN cancelled_by BIGINT UNSIGNED NULL AFTER paid_by,
|
|
ADD COLUMN cancelled_at DATETIME(3) NULL AFTER paid_at,
|
|
ADD COLUMN payout_request_no VARCHAR(64) NOT NULL DEFAULT '' AFTER payout_channel,
|
|
ADD COLUMN payout_request_key VARCHAR(128)
|
|
GENERATED ALWAYS AS (
|
|
CASE WHEN payout_request_no <> ''
|
|
THEN CONCAT(payout_channel, ':', payout_request_no)
|
|
ELSE NULL
|
|
END
|
|
) STORED AFTER payout_request_no,
|
|
ADD CONSTRAINT fk_qipai_cleaning_settlements_cancelled_by FOREIGN KEY (cancelled_by)
|
|
REFERENCES qipai_users(id),
|
|
ADD KEY idx_qipai_cleaning_settlement_cancelled (tenant_id, status, cancelled_at),
|
|
ADD UNIQUE KEY uq_qipai_cleaning_settlement_payout_request
|
|
(tenant_id, payout_request_key);
|
|
|
|
ALTER TABLE qipai_cleaning_settlement_items
|
|
DROP INDEX uq_qipai_cleaning_settlement_item_task_user,
|
|
ADD COLUMN reversal_id BIGINT UNSIGNED NULL AFTER reward_cents,
|
|
ADD COLUMN reversed_at DATETIME(3) NULL AFTER reversal_id,
|
|
ADD COLUMN active_share_key VARCHAR(128)
|
|
GENERATED ALWAYS AS (
|
|
CASE WHEN reversed_at IS NULL
|
|
THEN CONCAT(CAST(task_id AS CHAR), ':', CAST(cleaner_user_id AS CHAR))
|
|
ELSE NULL
|
|
END
|
|
) STORED AFTER reversed_at,
|
|
ADD CONSTRAINT fk_qipai_cleaning_settlement_items_reversal FOREIGN KEY (reversal_id)
|
|
REFERENCES qipai_cleaning_settlement_reversals(id),
|
|
ADD UNIQUE KEY uq_qipai_cleaning_settlement_active_share (tenant_id, active_share_key),
|
|
ADD KEY idx_qipai_cleaning_settlement_item_reversal (tenant_id, reversal_id);
|
|
|
|
UPDATE qipai_cleaning_settlements
|
|
SET cancelled_by = generated_by,
|
|
cancelled_at = COALESCE(cancelled_at, updated_at)
|
|
WHERE status = 'CANCELLED' AND cancelled_by IS NULL;
|
|
|
|
INSERT IGNORE INTO qipai_cleaning_settlement_reversals
|
|
(tenant_id, reversal_no, settlement_id, amount_delta_cents, reason, reversed_by, created_at)
|
|
SELECT s.tenant_id, CONCAT('CLR-M09C-', s.id), s.id, -CAST(s.total_reward_cents AS SIGNED),
|
|
'M09-C historical cancellation baseline', s.cancelled_by,
|
|
COALESCE(s.cancelled_at, s.updated_at)
|
|
FROM qipai_cleaning_settlements s
|
|
WHERE s.status = 'CANCELLED' AND s.deleted_at IS NULL;
|
|
|
|
UPDATE qipai_cleaning_settlement_items i
|
|
INNER JOIN qipai_cleaning_settlement_reversals r
|
|
ON r.tenant_id = i.tenant_id AND r.settlement_id = i.settlement_id
|
|
SET i.reversal_id = r.id,
|
|
i.reversed_at = r.created_at
|
|
WHERE i.reversed_at IS NULL;
|
|
|
|
UPDATE qipai_cleaning_task_members m
|
|
INNER JOIN qipai_cleaning_settlement_items i
|
|
ON i.tenant_id = m.tenant_id AND i.task_id = m.task_id AND i.cleaner_user_id = m.user_id
|
|
INNER JOIN qipai_cleaning_settlements s
|
|
ON s.tenant_id = i.tenant_id AND s.id = i.settlement_id AND s.deleted_at IS NULL
|
|
SET m.settled_at = CASE
|
|
WHEN s.status = 'PAID' AND i.reversed_at IS NULL
|
|
THEN COALESCE(s.paid_at, m.settled_at, UTC_TIMESTAMP(3))
|
|
ELSE NULL
|
|
END
|
|
WHERE i.id IS NOT NULL;
|
|
|
|
UPDATE qipai_cleaning_tasks t
|
|
SET t.status = 'COMPLETED', t.settled_at = NULL
|
|
WHERE t.status = 'SETTLED'
|
|
AND EXISTS (
|
|
SELECT 1
|
|
FROM qipai_cleaning_task_members pending
|
|
WHERE pending.tenant_id = t.tenant_id AND pending.task_id = t.id
|
|
AND pending.removed_at IS NULL AND pending.reward_cents > 0
|
|
AND pending.settled_at IS NULL
|
|
);
|
|
|
|
INSERT IGNORE INTO qipai_cleaning_settlement_events
|
|
(tenant_id, settlement_id, from_status, to_status, action, actor_id,
|
|
actor_type, trace_id, note, metadata, created_at)
|
|
SELECT s.tenant_id, s.id, NULL, s.status, 'MIGRATE', s.generated_by, 'SYSTEM',
|
|
CONCAT('m09c-', s.id), 'M09-C settlement history baseline',
|
|
JSON_OBJECT('source', '2026081006'), s.created_at
|
|
FROM qipai_cleaning_settlements s
|
|
WHERE s.deleted_at IS NULL;
|
|
|
|
INSERT IGNORE INTO qipai_schema_migrations (version, name)
|
|
VALUES ('2026081006', 'm09c_cleaning_settlement_integrity');
|