feat: refine client status and review views
This commit is contained in:
@@ -19,9 +19,8 @@ import {
|
||||
type TableColumn,
|
||||
} from '@/components/ui';
|
||||
import { clientApi, type SmsBatchTask } from '@/api/adminApi';
|
||||
import { formatDateTime } from '@/utils/dateTime';
|
||||
|
||||
type BatchTaskStatus = 'completed' | 'sending' | 'terminated';
|
||||
import { formatDateTime, recentBeijingDateRange } from '@/utils/dateTime';
|
||||
import { batchTaskStatusMeta, canClientCancelBatchTask, normalizeBatchTaskStatus, type BatchTaskDisplayStatus } from '@/utils/batchTaskStatus';
|
||||
|
||||
type BatchTask = {
|
||||
id: string;
|
||||
@@ -37,19 +36,11 @@ type BatchTask = {
|
||||
failedCount: number;
|
||||
totalCount: number;
|
||||
templateContent: string;
|
||||
status: BatchTaskStatus;
|
||||
};
|
||||
|
||||
const statusToneMap: Record<BatchTaskStatus, 'success' | 'info' | 'danger'> = {
|
||||
completed: 'success',
|
||||
sending: 'info',
|
||||
terminated: 'danger',
|
||||
};
|
||||
|
||||
const statusLabelMap: Record<BatchTaskStatus, string> = {
|
||||
completed: '已完成',
|
||||
sending: '发送中',
|
||||
terminated: '已终止',
|
||||
status: BatchTaskDisplayStatus;
|
||||
rawStatus: string;
|
||||
reviewReason?: string | null;
|
||||
rejectReason?: string | null;
|
||||
riskTaskId?: string | null;
|
||||
};
|
||||
|
||||
function splitSignature(content: string) {
|
||||
@@ -72,13 +63,8 @@ function getDeliveredCount(task: BatchTask) {
|
||||
return task.deliveredCount;
|
||||
}
|
||||
|
||||
function normalizeTaskStatus(status: string): BatchTaskStatus {
|
||||
if (['completed', 'done'].includes(status)) return 'completed';
|
||||
if (['cancelled', 'terminated', 'rejected', 'failed'].includes(status)) return 'terminated';
|
||||
return 'sending';
|
||||
}
|
||||
|
||||
function mapTask(task: SmsBatchTask): BatchTask {
|
||||
const displayStatus = normalizeBatchTaskStatus(task.status);
|
||||
return {
|
||||
id: task.taskNo || task.id,
|
||||
backendId: task.id,
|
||||
@@ -88,12 +74,16 @@ function mapTask(task: SmsBatchTask): BatchTask {
|
||||
wordCount: [...task.content].length,
|
||||
sendType: task.scheduledAt ? 'scheduled' : 'immediate',
|
||||
scheduledAt: task.scheduledAt,
|
||||
sentCount: task.progressSent ?? task.submittedTotal ?? 0,
|
||||
sentCount: displayStatus === 'pending_review' ? 0 : task.progressSent ?? task.submittedTotal ?? 0,
|
||||
deliveredCount: task.progressDelivered ?? task.successTotal ?? 0,
|
||||
failedCount: task.progressFailed ?? task.failedTotal ?? 0,
|
||||
totalCount: task.progressTotal || task.phoneTotal,
|
||||
templateContent: task.content,
|
||||
status: normalizeTaskStatus(task.status),
|
||||
status: displayStatus,
|
||||
rawStatus: task.status,
|
||||
reviewReason: task.reviewReason,
|
||||
rejectReason: task.rejectReason,
|
||||
riskTaskId: task.riskTaskId,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -106,7 +96,7 @@ export function ClientBatchTasksPage() {
|
||||
const [applications, setApplications] = useState<Array<{ id: string; name: string }>>([]);
|
||||
const [keyword, setKeyword] = useState(() => searchParams.get('taskNo') ?? '');
|
||||
const [application, setApplication] = useState('all');
|
||||
const [submittedDateRange, setSubmittedDateRange] = useState<DateRangeValue>({});
|
||||
const [submittedDateRange, setSubmittedDateRange] = useState<DateRangeValue>(() => recentBeijingDateRange(7));
|
||||
const [hoveredTaskId, setHoveredTaskId] = useState<string | null>(null);
|
||||
const [page, setPage] = useState(1);
|
||||
const [selectedTask, setSelectedTask] = useState<BatchTask | null>(null);
|
||||
@@ -166,7 +156,7 @@ export function ClientBatchTasksPage() {
|
||||
render: (record) => (
|
||||
<div className="batch-task-id">
|
||||
<strong>{record.id}</strong>
|
||||
<Tag tone={statusToneMap[record.status]}>{statusLabelMap[record.status]}</Tag>
|
||||
<Tag tone={batchTaskStatusMeta[record.status].tone}>{batchTaskStatusMeta[record.status].label}{record.status === 'unknown' ? `(${record.rawStatus})` : ''}</Tag>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -215,15 +205,14 @@ export function ClientBatchTasksPage() {
|
||||
render: (record) => (
|
||||
<div className="batch-actions">
|
||||
<Button icon={<Eye size={14} />} onClick={() => setSelectedTask(record)} size="sm" variant="ghost">详情</Button>
|
||||
<Button
|
||||
disabled={record.status !== 'sending'}
|
||||
{canClientCancelBatchTask(record.rawStatus) ? <Button
|
||||
icon={<StopCircle size={14} />}
|
||||
onClick={() => terminateTask(record.id)}
|
||||
size="sm"
|
||||
variant="ghost"
|
||||
>
|
||||
终止
|
||||
</Button>
|
||||
</Button> : null}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
@@ -325,7 +314,7 @@ export function ClientBatchTasksPage() {
|
||||
>
|
||||
{selectedTask ? (
|
||||
<div className="task-detail">
|
||||
<DetailSection title="基本信息" extra={<Tag tone={statusToneMap[selectedTask.status]}>{statusLabelMap[selectedTask.status]}</Tag>}>
|
||||
<DetailSection title="基本信息" extra={<Tag tone={batchTaskStatusMeta[selectedTask.status].tone}>{batchTaskStatusMeta[selectedTask.status].label}{selectedTask.status === 'unknown' ? `(${selectedTask.rawStatus})` : ''}</Tag>}>
|
||||
<DetailInfoGrid
|
||||
items={[
|
||||
{ label: '发送批次号', value: selectedTask.id },
|
||||
@@ -345,6 +334,8 @@ export function ClientBatchTasksPage() {
|
||||
{ label: '批次总号码数', value: `${selectedTask.totalCount.toLocaleString('zh-CN')} 个`, tone: 'primary' },
|
||||
{ label: '总计费条数', value: `${getBillingCount(selectedTask).toLocaleString('zh-CN')} 条`, tone: 'primary' },
|
||||
{ label: '模板内容', value: selectedTask.templateContent, full: true },
|
||||
...(selectedTask.reviewReason ? [{ label: '审核原因', value: selectedTask.reviewReason, full: true }] : []),
|
||||
...(selectedTask.rejectReason ? [{ label: '驳回原因', value: selectedTask.rejectReason, full: true }] : []),
|
||||
]}
|
||||
/>
|
||||
</DetailSection>
|
||||
@@ -354,7 +345,7 @@ export function ClientBatchTasksPage() {
|
||||
label="发送进度"
|
||||
meta={`${selectedTask.sentCount.toLocaleString('zh-CN')} / ${selectedTask.totalCount.toLocaleString('zh-CN')} 已处理`}
|
||||
percent={getProgress(selectedTask)}
|
||||
status={selectedTask.status}
|
||||
status={selectedTask.status === 'completed' ? 'completed' : ['failed', 'rejected', 'canceled'].includes(selectedTask.status) ? 'terminated' : 'sending'}
|
||||
stats={[
|
||||
{ label: '提交总数量', value: selectedTask.totalCount.toLocaleString('zh-CN') },
|
||||
{ label: '提交成功数量', value: selectedTask.totalCount.toLocaleString('zh-CN') },
|
||||
|
||||
Reference in New Issue
Block a user