feat: optimize signature workflows and high-frequency queries

This commit is contained in:
hectorzhao
2026-09-02 15:45:48 +08:00
parent 9b8196ecab
commit ad89e8fed7
48 changed files with 1334 additions and 352 deletions
@@ -1,4 +1,4 @@
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { FileSpreadsheet, Plus, Search } from 'lucide-react';
import { useNavigate } from 'react-router-dom';
import { adminApi, type ClientSmsApplication, type ClientSmsSignature, type TenantOption } from '@/api/adminApi';
@@ -51,6 +51,7 @@ export function AdminEnterpriseSignaturesPage() {
const [importOpen, setImportOpen] = useState(false);
const [message, setMessage] = useState('');
const [materialChangedSignature, setMaterialChangedSignature] = useState<ClientSmsSignature | null>(null);
const listRequestSequence = useRef(0);
const pageSize = 10;
@@ -64,22 +65,33 @@ export function AdminEnterpriseSignaturesPage() {
targetPage = page,
targetSort = signatureSort,
) {
const sequence = ++listRequestSequence.current;
try {
const [signatureResult, tenantItems, applicationItems] = await Promise.all([
adminApi.listEnterpriseSignaturesPage({ ...filters, signatureSort: targetSort, page: targetPage, pageSize }),
adminApi.listTenants(),
adminApi.listEnterpriseApplicationOptions(),
]);
const signatureResult = await adminApi.listEnterpriseSignaturesPage({ ...filters, signatureSort: targetSort, page: targetPage, pageSize });
if (sequence !== listRequestSequence.current) return;
setSignatures(signatureResult.items);
setTotal(signatureResult.total);
setTenants(tenantItems.filter((tenant) => tenant.status !== 'deleted'));
setApplications(applicationItems);
setError('');
} catch (failure) {
if (sequence !== listRequestSequence.current) return;
setError(failure instanceof Error ? failure.message : '企业签名加载失败');
}
}
useEffect(() => {
let cancelled = false;
void Promise.all([adminApi.listTenantOptions(), adminApi.listEnterpriseApplicationOptions()])
.then(([tenantItems, applicationItems]) => {
if (cancelled) return;
setTenants(tenantItems.filter((tenant) => tenant.status !== 'deleted'));
setApplications(applicationItems);
})
.catch((failure: Error) => {
if (!cancelled) setError(failure.message || '企业及应用选项加载失败');
});
return () => { cancelled = true; };
}, []);
useEffect(() => {
queueMicrotask(() => void loadData(undefined, page));
}, [page]);
@@ -142,6 +154,46 @@ export function AdminEnterpriseSignaturesPage() {
await loadData();
}
async function editSignature(signature: ClientSmsSignature) {
try {
setSignatureModal(await adminApi.getEnterpriseSignature(signature.id));
} catch (failure) {
setError(failure instanceof Error ? failure.message : '签名详情加载失败');
}
}
async function openSignatureReport(signature: ClientSmsSignature) {
try {
const reportTargets = await adminApi.getEnterpriseSignatureReportTargets(signature.id);
setReportStatusTarget({ ...signature, reportTargets });
} catch (failure) {
setError(failure instanceof Error ? failure.message : '签名报备状态加载失败');
}
}
async function editDrainage(signature: ClientSmsSignature, item: DrainageInfo) {
try {
const detail = await adminApi.getEnterpriseSignature(signature.id);
const detailItem = readDrainagePayload(detail).links.find((candidate) => candidate.id === item.id);
if (!detailItem) throw new Error('引流信息不存在或已删除');
setDrainageModal({ signatureId: signature.id, item: detailItem });
} catch (failure) {
setError(failure instanceof Error ? failure.message : '引流信息详情加载失败');
}
}
async function openDrainageReport(signature: ClientSmsSignature, item: DrainageInfo) {
try {
const targets = await adminApi.getDrainageInfoReportTargets(item.id);
setDrainageStatusTarget({
signature: { ...signature, drainageReportTargets: { [item.id]: targets } },
item,
});
} catch (failure) {
setError(failure instanceof Error ? failure.message : '引流报备状态加载失败');
}
}
async function confirmDelete() {
if (!deleteTarget) {
return;
@@ -158,9 +210,10 @@ export function AdminEnterpriseSignaturesPage() {
expandedSignatureId={expandedSignatureId}
filteredSignatures={filteredSignatures}
loadData={loadData}
onAddDrainage={(signature) => setDrainageModal({ signatureId: signature.id })}
setDeleteTarget={setDeleteTarget}
setDrainageModal={setDrainageModal}
setDrainageStatusTarget={setDrainageStatusTarget}
onEditDrainage={(signature, item) => void editDrainage(signature, item)}
onOpenDrainageReport={(signature, item) => void openDrainageReport(signature, item)}
setExpandedSignatureId={setExpandedSignatureId}
setPage={setPage}
setSignatureSort={(nextSort) => {
@@ -168,8 +221,8 @@ export function AdminEnterpriseSignaturesPage() {
if (page === 1) void loadData(undefined, 1, nextSort);
else setPage(1);
}}
setReportStatusTarget={setReportStatusTarget}
setSignatureModal={setSignatureModal}
onEditSignature={(signature) => void editSignature(signature)}
onOpenSignatureReport={(signature) => void openSignatureReport(signature)}
signatureSort={signatureSort}
total={total}
totalPages={totalPages}
@@ -237,8 +290,8 @@ export function AdminEnterpriseSignaturesPage() {
setAppliedApplicationKeyword(filters.applicationKeyword);
setAppliedSignatureKeyword(filters.signatureKeyword);
setAppliedDrainageKeyword(filters.drainageKeyword);
setPage(1);
void loadData(filters, 1);
if (page !== 1) setPage(1);
else void loadData(filters, 1);
}}
>
@@ -259,8 +312,8 @@ export function AdminEnterpriseSignaturesPage() {
setAppliedApplicationKeyword('');
setAppliedSignatureKeyword('');
setAppliedDrainageKeyword('');
setPage(1);
void loadData(filters, 1);
if (page !== 1) setPage(1);
else void loadData(filters, 1);
}}
variant="ghost"
>