V4.0.9版本更新合伙人H5端调整

This commit is contained in:
2026-09-02 09:46:41 +08:00
parent af3c4b6f08
commit c905b3f930
33 changed files with 893 additions and 176 deletions
@@ -0,0 +1,141 @@
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import PageHeader from '@dukang/shared-ui/PageHeader';
import type { PartnerMe, UpdatePartnerBankRequest } from '@dukang/shared-types';
import { request } from '../lib/api';
import { usePartnerSession } from '../contexts/PartnerSessionContext';
import { toastError, toastSuccess } from '../lib/toast';
type FieldErrors = {
bankAccountName?: string;
bankAccountNo?: string;
bankBranch?: string;
};
export default function BankAccountPage() {
const navigate = useNavigate();
const { account, refresh } = usePartnerSession();
const [bankAccountName, setBankAccountName] = useState(account?.bankAccount?.bankAccountName ?? '');
const [bankAccountNo, setBankAccountNo] = useState(account?.bankAccount?.bankAccountNo ?? '');
const [bankBranch, setBankBranch] = useState(account?.bankAccount?.bankBranch ?? '');
const [submitting, setSubmitting] = useState(false);
const [fieldErrors, setFieldErrors] = useState<FieldErrors>({});
useEffect(() => {
document.title = '收款账户';
}, []);
useEffect(() => {
setBankAccountName(account?.bankAccount?.bankAccountName ?? '');
setBankAccountNo(account?.bankAccount?.bankAccountNo ?? '');
setBankBranch(account?.bankAccount?.bankBranch ?? '');
}, [account?.bankAccount]);
async function submit() {
const name = bankAccountName.trim();
const no = bankAccountNo.replace(/\s+/g, '');
const branch = bankBranch.trim();
const next: FieldErrors = {};
if (!name) next.bankAccountName = '请填写收款人';
if (!/^\d{8,32}$/.test(no)) next.bankAccountNo = '请填写 8~32 位数字账号';
if (!branch) next.bankBranch = '请填写开户行名称';
setFieldErrors(next);
if (Object.keys(next).length) return;
setSubmitting(true);
try {
const body: UpdatePartnerBankRequest = {
bankAccountName: name,
bankAccountNo: no,
bankBranch: branch,
};
await request<PartnerMe>('PARTNER_H5', '/partner/me/bank', {
method: 'PUT',
body: JSON.stringify(body),
});
await refresh();
toastSuccess('收款账户已保存');
navigate('/center');
} catch (e) {
toastError(e instanceof Error ? e.message : '保存失败');
} finally {
setSubmitting(false);
}
}
return (
<div className="partner-page-sticky">
<PageHeader title="收款账户" onBack={() => navigate('/center')} />
<section className="partner-form-card">
<div className="partner-section-title">
<div className="partner-section-bar" />
<h2 className="headline-md">银行账号</h2>
</div>
<p className="label-md text-muted" style={{ marginBottom: 16, lineHeight: 1.5 }}>
用于总部打款。请填写与合同一致的对公或对私账户。
</p>
<div className="partner-field">
<label>收款人 <span className="text-primary">*</span></label>
<div className="partner-field-input">
<span className="material-symbols-outlined">person</span>
<input
placeholder="户名 / 收款人姓名"
value={bankAccountName}
maxLength={64}
onChange={(e) => setBankAccountName(e.target.value)}
/>
</div>
{fieldErrors.bankAccountName && (
<p className="partner-field-error" role="alert">{fieldErrors.bankAccountName}</p>
)}
</div>
<div className="partner-field">
<label>银行账号 <span className="text-primary">*</span></label>
<div className="partner-field-input">
<span className="material-symbols-outlined">credit_card</span>
<input
inputMode="numeric"
placeholder="请输入银行账号"
value={bankAccountNo}
maxLength={32}
onChange={(e) => setBankAccountNo(e.target.value.replace(/[^\d]/g, ''))}
/>
</div>
{fieldErrors.bankAccountNo && (
<p className="partner-field-error" role="alert">{fieldErrors.bankAccountNo}</p>
)}
</div>
<div className="partner-field">
<label>开户行名称 <span className="text-primary">*</span></label>
<div className="partner-field-input">
<span className="material-symbols-outlined">account_balance</span>
<input
placeholder="如 中国工商银行洛阳分行"
value={bankBranch}
maxLength={128}
onChange={(e) => setBankBranch(e.target.value)}
/>
</div>
{fieldErrors.bankBranch && (
<p className="partner-field-error" role="alert">{fieldErrors.bankBranch}</p>
)}
</div>
</section>
<footer className="partner-sticky-footer">
<button
type="button"
className="partner-btn-primary"
disabled={submitting}
onClick={() => void submit()}
>
{submitting ? '保存中…' : '保存'}
</button>
</footer>
</div>
);
}