fix(douyu): 批量改状态强制回退确认并清理勾选

This commit is contained in:
yml2213
2026-10-24 09:59:31 +08:00
parent 9c31de1e73
commit 935be7a613
+68 -3
View File
@@ -6,6 +6,7 @@ import {
Badge,
Button,
Card,
Checkbox,
Col,
Descriptions,
Drawer,
@@ -253,6 +254,7 @@ export default function DouyuCollabPage() {
const [batchStatusOpen, setBatchStatusOpen] = useState(false);
const [statusValue, setStatusValue] = useState<DouyuCollabStatus>('to_recharge');
const [statusReason, setStatusReason] = useState('');
const [batchStatusRollback, setBatchStatusRollback] = useState(false);
const [statusBusy, setStatusBusy] = useState(false);
// 勾选导出 CK:明文只在弹窗 state 里,关闭即清空
@@ -291,6 +293,8 @@ export default function DouyuCollabPage() {
});
setOrders(data.items);
setTotal(data.total);
// 与虎牙一致:勾选只对「当前页当前筛选结果」有效,刷新后剔除已不在列表里的单。
setSelectedRowKeys((keys) => keys.filter((key) => data.items.some((row) => row.id === Number(key))));
} catch (error) {
message.error(getErrorMessage(error));
} finally {
@@ -441,6 +445,17 @@ export default function DouyuCollabPage() {
selectedOrders.length === selectedIds.length &&
selectedOrders.every((row) => row.status === 'done' && !row.is_archived);
/** 批量改状态时,所选订单里是否有必须显式勾「回退」的单(与后端 set_status 规则一致)。 */
const batchRollbackRequired = useMemo(() => {
const targetIndex = FLOW_ORDER.indexOf(statusValue);
if (targetIndex < 0) return false;
return selectedOrders.some((row) => {
if (row.status === 'failed' || row.status === 'void') return true;
const currentIndex = FLOW_ORDER.indexOf(row.status);
return currentIndex >= 0 && targetIndex < currentIndex;
});
}, [selectedOrders, statusValue]);
/** 与「CK 管理」保持一致:账号----密码----CK,每行一条。 */
const ckExportText = useMemo(() => {
if (!ckExport) return '';
@@ -697,6 +712,7 @@ export default function DouyuCollabPage() {
setBatchStatusOpen(false);
setStatusValue(order.next_status || order.status);
setStatusReason('');
setBatchStatusRollback(false);
};
const openBatchStatus = () => {
@@ -708,9 +724,14 @@ export default function DouyuCollabPage() {
setBatchStatusOpen(true);
setStatusValue('recharged');
setStatusReason('');
setBatchStatusRollback(false);
};
const submitStatus = async () => {
if (batchStatusOpen && batchRollbackRequired && !batchStatusRollback) {
message.warning('所选订单需要回退状态,请先勾选「回退」再提交');
return;
}
setStatusBusy(true);
try {
if (batchStatusOpen) {
@@ -718,8 +739,29 @@ export default function DouyuCollabPage() {
ids: selectedIds,
status: statusValue,
reason: statusReason,
rollback: batchStatusRollback,
});
message.success(`批量改状态完成:${result.results.filter((item) => item.success).length}/${result.results.length}`);
const failures = result.results.filter((item) => !item.success);
const orderNoById = new Map(selectedOrders.map((row) => [row.id, row.order_no]));
if (failures.length === 0) {
message.success(
`批量改状态完成:${result.results.length} 单 →「${STATUS_META[statusValue].label}」`,
);
} else {
modal.info({
title: `改状态完成:成功 ${result.results.length - failures.length} / 未通过 ${failures.length}`,
width: 640,
content: (
<Space direction="vertical" style={{ width: '100%' }}>
{failures.map((item) => (
<Text key={item.id} type="danger">
{orderNoById.get(item.id) || `#${item.id}`}:{item.message || '未通过'}
</Text>
))}
</Space>
),
});
}
setBatchStatusOpen(false);
setSelectedRowKeys([]);
} else if (statusTarget) {
@@ -732,6 +774,7 @@ export default function DouyuCollabPage() {
expected_version: statusTarget.version,
});
message.success('状态已更新');
setSelectedRowKeys((keys) => keys.filter((key) => Number(key) !== statusTarget.id));
setStatusTarget(null);
}
refreshAll();
@@ -1619,7 +1662,6 @@ export default function DouyuCollabPage() {
rowSelection={{
selectedRowKeys,
onChange: (keys) => setSelectedRowKeys(keys),
preserveSelectedRowKeys: true,
}}
pagination={{
current: page,
@@ -1835,7 +1877,10 @@ export default function DouyuCollabPage() {
}}
onOk={() => void submitStatus()}
confirmLoading={statusBusy}
okText="确定"
okText={batchStatusOpen ? `改成「${STATUS_META[statusValue].label}」` : '确定'}
okButtonProps={{
disabled: batchStatusOpen && batchRollbackRequired && !batchStatusRollback,
}}
>
<Space direction="vertical" style={{ width: '100%' }}>
<Select
@@ -1850,6 +1895,26 @@ export default function DouyuCollabPage() {
{statusValue === 'void' && (
<Alert type="warning" showIcon message="作废后不可恢复;请在备注里写作废原因。" />
)}
{batchStatusOpen && (
<>
<Checkbox
checked={batchStatusRollback}
onChange={(event) => setBatchStatusRollback(event.target.checked)}
>
回退(目标比当前状态靠前,或从「抢购失败 / 已作废」回到流程时必须勾选)
</Checkbox>
{batchRollbackRequired && !batchStatusRollback && (
<Alert
type="warning"
showIcon
message="所选订单里有需要回退的单,勾选「回退」后才能提交。"
/>
)}
<Text type="secondary" style={{ fontSize: 12 }}>
逐行独立提交:某一行校验没过(例如资料不全进不了「待充值」)只跳过那一行,结果会逐条列出。
</Text>
</>
)}
<Input.TextArea
rows={2}
value={statusReason}