feat: optimize signature workflows and high-frequency queries
This commit is contained in:
@@ -214,6 +214,7 @@ export function ClientTemplatesPage() {
|
||||
const [templates, setTemplates] = useState<ClientSmsTemplate[]>([]);
|
||||
const [signatures, setSignatures] = useState<ClientSmsSignatureView[]>([]);
|
||||
const [keyword, setKeyword] = useState('');
|
||||
const [appliedKeyword, setAppliedKeyword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [modalTemplate, setModalTemplate] = useState<ClientSmsTemplate | 'new' | null>(null);
|
||||
@@ -224,13 +225,11 @@ export function ClientTemplatesPage() {
|
||||
function loadData(targetPage = page) {
|
||||
const sequence = ++requestSequence.current;
|
||||
setLoading(true);
|
||||
Promise.all([clientApi.listApplicationOptions(), clientApi.listTemplatesPage({ includeHistory: true, keyword: keyword.trim() || undefined, page: targetPage, pageSize }), clientApi.listSignatureOptions()])
|
||||
.then(([applicationItems, templateResult, signatureItems]) => {
|
||||
clientApi.listTemplatesPage({ includeHistory: true, keyword: appliedKeyword || undefined, page: targetPage, pageSize })
|
||||
.then((templateResult) => {
|
||||
if (sequence !== requestSequence.current) return;
|
||||
setApplications(applicationItems.filter((item) => item.status === 'active'));
|
||||
setTemplates(templateResult.items.filter((item) => item.auditStatus !== 'deleted' && item.auditStatus !== 'disabled'));
|
||||
setTotal(templateResult.total);
|
||||
setSignatures(signatureItems);
|
||||
setError('');
|
||||
})
|
||||
.catch((reason: Error) => { if (sequence === requestSequence.current) setError(reason.message || '短信模板加载失败'); })
|
||||
@@ -238,9 +237,22 @@ export function ClientTemplatesPage() {
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setTimeout(() => loadData(page), 300);
|
||||
return () => window.clearTimeout(timer);
|
||||
}, [page, keyword]);
|
||||
loadData(page);
|
||||
}, [appliedKeyword, page]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
void Promise.all([clientApi.listApplicationOptions(), clientApi.listSignatureOptions()])
|
||||
.then(([applicationItems, signatureItems]) => {
|
||||
if (cancelled) return;
|
||||
setApplications(applicationItems.filter((item) => item.status === 'active'));
|
||||
setSignatures(signatureItems);
|
||||
})
|
||||
.catch((reason: Error) => {
|
||||
if (!cancelled) setError(reason.message || '模板选项加载失败');
|
||||
});
|
||||
return () => { cancelled = true; };
|
||||
}, []);
|
||||
|
||||
const filteredTemplates = templates;
|
||||
const totalPages = Math.max(1, Math.ceil(total / pageSize));
|
||||
@@ -282,11 +294,15 @@ export function ClientTemplatesPage() {
|
||||
|
||||
<div className="template-toolbar">
|
||||
<Input
|
||||
onChange={(event) => { setKeyword(event.target.value); setPage(1); }}
|
||||
onChange={(event) => setKeyword(event.target.value)}
|
||||
placeholder="搜索模板名称、应用、签名或内容"
|
||||
prefix={<Search size={17} />}
|
||||
value={keyword}
|
||||
/>
|
||||
<div className="ui-query-actions">
|
||||
<Button icon={<Search size={17} />} onClick={() => { setPage(1); setAppliedKeyword(keyword.trim()); }}>查询</Button>
|
||||
<Button onClick={() => { setKeyword(''); setPage(1); setAppliedKeyword(''); }} variant="ghost">重置</Button>
|
||||
</div>
|
||||
<Button icon={<Plus size={17} />} onClick={() => setModalTemplate('new')}>添加短信模板</Button>
|
||||
</div>
|
||||
{loading ? <p className="muted">正在加载短信模板...</p> : null}
|
||||
|
||||
Reference in New Issue
Block a user