fix: harden real backend workflows and channel connections

This commit is contained in:
hectorzhao
2026-07-06 17:54:53 +08:00
parent 8cca361441
commit b5132d7f4e
47 changed files with 2530 additions and 314 deletions
+31 -2
View File
@@ -1,5 +1,5 @@
import { useEffect, useMemo, useState } from 'react';
import { Check, FileText, Plus, Search, Send, Trash2 } from 'lucide-react';
import { Check, Download, FileText, Plus, Search, Send, Trash2 } from 'lucide-react';
import { Button, DateTimeInput, Input, Modal, Select, Tag, Textarea } from '@/components/ui';
import { clientApi, type ClientSmsApplication, type ClientSmsSignature, type ClientSmsTemplate, type ImportPreviewResponse, type SmsBatchTask } from '@/api/adminApi';
@@ -29,6 +29,7 @@ export function ClientSendPage() {
const [recipients, setRecipients] = useState<Recipient[]>([{ id: '1', phone: '' }]);
const [importContent, setImportContent] = useState('');
const [importFileName, setImportFileName] = useState('');
const [importFileUrl, setImportFileUrl] = useState('');
const [importPreview, setImportPreview] = useState<ImportPreviewResponse | null>(null);
const [importLoading, setImportLoading] = useState(false);
const [submittedRecord, setSubmittedRecord] = useState<SmsBatchTask | null>(null);
@@ -44,6 +45,12 @@ export function ClientSendPage() {
.catch((reason: Error) => setError(reason.message || '短信发送基础数据加载失败'));
}, []);
useEffect(() => () => {
if (importFileUrl) {
URL.revokeObjectURL(importFileUrl);
}
}, [importFileUrl]);
const selectedSignature = useMemo(
() => signatures.find((item) => item.id === signatureId),
[signatures, signatureId],
@@ -133,10 +140,22 @@ export function ClientSendPage() {
});
setImportContent(content);
setImportFileName(file.name);
setImportFileUrl((current) => {
if (current) {
URL.revokeObjectURL(current);
}
return URL.createObjectURL(file);
});
setImportPreview(preview);
} catch (reason) {
setImportContent('');
setImportFileName('');
setImportFileUrl((current) => {
if (current) {
URL.revokeObjectURL(current);
}
return '';
});
setImportPreview(null);
setError(reason instanceof Error ? reason.message : '导入预览失败');
} finally {
@@ -294,7 +313,17 @@ export function ClientSendPage() {
<Button disabled={importLoading || !templateId} onClick={() => document.getElementById('sms-import-file')?.click()} variant="ghost">
{importLoading ? '解析中...' : '选择文件'}
</Button>
{importFileName ? <span>{importFileName}</span> : null}
{importFileName ? (
<span>
{importFileName}
{importFileUrl ? (
<a className="file-action-link" download={importFileName} href={importFileUrl}>
<Download size={14} />
</a>
) : null}
</span>
) : null}
{importPreview ? (
<div className="detail-grid">
<div><span></span><strong>{importPreview.totalRows}</strong></div>