Files
lislgosms/src/apps/admin/AdminCustomerDetailPage.tsx
T

103 lines
6.8 KiB
TypeScript

import { useEffect, useMemo, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { ArrowLeft, FileText, MessageSquare, Server } from 'lucide-react';
import { adminApi, type ClientSmsSignature, type ClientSmsTemplate, type EnterpriseApplication, type TenantAccount, type TenantOption } from '@/api/adminApi';
import { Breadcrumb, Button, Table, Tag, type TableColumn } from '@/components/ui';
export function AdminCustomerDetailPage() {
const navigate = useNavigate();
const { enterpriseId } = useParams();
const [tenant, setTenant] = useState<TenantOption | null>(null);
const [account, setAccount] = useState<TenantAccount | null>(null);
const [applications, setApplications] = useState<EnterpriseApplication[]>([]);
const [signatures, setSignatures] = useState<ClientSmsSignature[]>([]);
const [templates, setTemplates] = useState<ClientSmsTemplate[]>([]);
const [error, setError] = useState('');
useEffect(() => {
if (!enterpriseId) return;
Promise.all([
adminApi.getTenant(enterpriseId),
adminApi.listAccounts(),
adminApi.listEnterpriseApplications({ tenantId: enterpriseId }),
adminApi.listEnterpriseSignatures({ tenantId: enterpriseId }),
adminApi.listEnterpriseTemplates({ tenantId: enterpriseId }),
])
.then(([tenantItem, accounts, applicationItems, signatureItems, templateItems]) => {
setTenant(tenantItem);
setAccount(accounts.find((item) => item.tenantId === enterpriseId) ?? null);
setApplications(applicationItems);
setSignatures(Array.isArray(signatureItems) ? signatureItems : []);
setTemplates(Array.isArray(templateItems) ? templateItems : []);
setError('');
})
.catch((failure: Error) => setError(failure.message || '企业详情加载失败'));
}, [enterpriseId]);
const appColumns = useMemo<Array<TableColumn<EnterpriseApplication>>>(() => [
{ key: 'name', title: '应用名称', render: (record) => <strong>{record.name}</strong> },
{ key: 'scene', title: '场景', render: (record) => record.scene ?? '-' },
{ key: 'status', title: '状态', render: (record) => <Tag tone={record.status === 'active' ? 'success' : 'warning'}>{record.status}</Tag> },
{ key: 'cmpp', title: 'CMPP 状态', render: (record) => record.cmppStatus ?? '-' },
], []);
const signatureColumns = useMemo<Array<TableColumn<ClientSmsSignature>>>(() => [
{ key: 'name', title: '签名', render: (record) => <strong>{record.name}</strong> },
{ key: 'purpose', title: '用途', render: (record) => record.purpose ?? '-' },
{ key: 'status', title: '审核状态', render: (record) => <Tag tone={record.auditStatus === 'approved' ? 'success' : record.auditStatus === 'rejected' ? 'danger' : 'info'}>{record.auditStatus}</Tag> },
], []);
const templateColumns = useMemo<Array<TableColumn<ClientSmsTemplate>>>(() => [
{ key: 'name', title: '模板', render: (record) => <strong>{record.name}</strong> },
{ key: 'content', title: '内容', render: (record) => <span className="table-long-text">{record.content}</span> },
{ key: 'status', title: '审核状态', render: (record) => <Tag tone={record.auditStatus === 'approved' ? 'success' : record.auditStatus === 'rejected' ? 'danger' : 'info'}>{record.auditStatus}</Tag> },
], []);
return (
<section className="page-stack enterprise-detail-page">
<div className="page-heading">
<div>
<Breadcrumb items={['企业管理', tenant?.name ?? '企业详情']} />
<h1>{tenant?.name ?? '企业详情'}</h1>
</div>
<Button icon={<ArrowLeft size={16} />} onClick={() => navigate('/admin/customers')} variant="ghost">返回</Button>
</div>
{error ? <p className="form-error">{error}</p> : null}
<div className="dashboard-grid enterprise-summary-grid">
<div className="surface mini-status-card"><Server size={22} /><div><span>企业编码</span><strong>{tenant?.code ?? '-'}</strong><small>{tenant?.status ?? '-'}</small></div></div>
<div className="surface mini-status-card"><MessageSquare size={22} /><div><span>短信余量</span><strong>{(account?.smsUnits ?? 0).toLocaleString('zh-CN')}</strong><small>真实账户余量</small></div></div>
<div className="surface mini-status-card"><FileText size={22} /><div><span>现金余额</span><strong>¥{((account?.balanceCents ?? 0) / 100).toLocaleString('zh-CN')}</strong><small>真实账户余额</small></div></div>
</div>
<div className="surface section-stack">
<div className="section-heading"><div><h2>企业档案</h2><p className="muted">来自真实企业档案接口。</p></div></div>
<div className="ui-detail-info-grid">
<div className="ui-detail-info-grid__item"><span>统一社会信用代码</span><strong>{tenant?.enterpriseProfile?.creditCode || '-'}</strong></div>
<div className="ui-detail-info-grid__item"><span>/</span><strong>{[tenant?.enterpriseProfile?.province, tenant?.enterpriseProfile?.city].filter(Boolean).join(' / ') || '-'}</strong></div>
<div className="ui-detail-info-grid__item ui-detail-info-grid__item--full"><span>通讯地址</span><strong>{tenant?.enterpriseProfile?.address || '-'}</strong></div>
<div className="ui-detail-info-grid__item"><span>联系人</span><strong>{tenant?.enterpriseProfile?.contactName || '-'}</strong></div>
<div className="ui-detail-info-grid__item"><span>手机号</span><strong>{tenant?.enterpriseProfile?.contactPhone || '-'}</strong></div>
<div className="ui-detail-info-grid__item"><span>身份证号</span><strong>{tenant?.enterpriseProfile?.contactIdCard || '-'}</strong></div>
<div className="ui-detail-info-grid__item"><span>电子邮箱</span><strong>{tenant?.enterpriseProfile?.contactEmail || '-'}</strong></div>
</div>
</div>
<div className="surface section-stack">
<div className="section-heading"><div><h2>短信应用</h2><p className="muted">来自企业应用真实接口。</p></div><Tag tone="info">{applications.length} </Tag></div>
<Table columns={appColumns} data={applications} emptyText="暂无短信应用" rowKey="id" />
</div>
<div className="surface section-stack">
<div className="section-heading"><div><h2>短信签名</h2><p className="muted">来自企业签名真实接口。</p></div><Tag tone="info">{signatures.length} </Tag></div>
<Table columns={signatureColumns} data={signatures} emptyText="暂无签名" rowKey="id" />
</div>
<div className="surface section-stack">
<div className="section-heading"><div><h2>短信模板</h2><p className="muted">来自企业模板真实接口。</p></div><Tag tone="info">{templates.length} </Tag></div>
<Table columns={templateColumns} data={templates} emptyText="暂无模板" rowKey="id" />
</div>
</section>
);
}