fix(h5-partner): resolve merge conflicts for auth and sub-accounts
Merge partner session model (AuthGate, ensureSession, WeChat OAuth in Context) with sub-account routing, admin partner-account tree CRUD, upload lock, and partner staff flows. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import { AdminCellLine } from '../components/AdminCellLine';
|
||||
import { ACCOUNT_STATUS_LABELS, ADMIN_OPTIONS_PAGE_SIZE, ORDER_STATUS_LABELS, PARTNER_BILL_STATUS_LABELS, fmtTime } from '../lib/constants';
|
||||
|
||||
type PartnerOption = { id: string; companyName: string };
|
||||
type ParentAccount = { id: string; name: string; phone: string };
|
||||
|
||||
type AccountTreeRow = {
|
||||
id: string;
|
||||
@@ -16,10 +17,11 @@ type AccountTreeRow = {
|
||||
name: string;
|
||||
status: string;
|
||||
isPrimary: number;
|
||||
staffRole: string | null;
|
||||
parentAccountId: string | null;
|
||||
staffRole?: string | null;
|
||||
parentAccountId?: string | null;
|
||||
parent?: ParentAccount | null;
|
||||
createdAt: string;
|
||||
lastLoginAt: string | null;
|
||||
lastLoginAt?: string | null;
|
||||
partner?: { id: string; companyName: string };
|
||||
children?: AccountTreeRow[];
|
||||
};
|
||||
@@ -49,20 +51,29 @@ function filterTree(rows: AccountTreeRow[], phone?: string, status?: string): Ac
|
||||
return phoneOk && statusOk;
|
||||
};
|
||||
|
||||
const walk = (list: AccountTreeRow[]): AccountTreeRow[] =>
|
||||
list
|
||||
.map((row) => {
|
||||
const children = row.children?.length ? walk(row.children) : undefined;
|
||||
if (match(row) || (children && children.length > 0)) {
|
||||
return { ...row, children: children?.length ? children : undefined };
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter((row): row is AccountTreeRow => row !== null);
|
||||
const walk = (list: AccountTreeRow[]): AccountTreeRow[] => {
|
||||
const result: AccountTreeRow[] = [];
|
||||
for (const row of list) {
|
||||
const children = row.children?.length ? walk(row.children) : undefined;
|
||||
if (match(row) || (children && children.length > 0)) {
|
||||
result.push({ ...row, children: children?.length ? children : undefined });
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
return walk(rows);
|
||||
}
|
||||
|
||||
function accountTypeLabel(isPrimary: number) {
|
||||
return isPrimary === 1 ? '主账号' : '子账号';
|
||||
}
|
||||
|
||||
function staffRoleLabel(role?: string | null) {
|
||||
if (!role) return '-';
|
||||
return PARTNER_STAFF_ROLE_LABELS[role as keyof typeof PARTNER_STAFF_ROLE_LABELS] ?? role;
|
||||
}
|
||||
|
||||
export default function PartnerAccountsPage() {
|
||||
const [form] = Form.useForm();
|
||||
const [editForm] = Form.useForm();
|
||||
@@ -167,7 +178,7 @@ export default function PartnerAccountsPage() {
|
||||
primary={row.name}
|
||||
secondary={
|
||||
row.parentAccountId
|
||||
? `子账号 · ${PARTNER_STAFF_ROLE_LABELS[row.staffRole as keyof typeof PARTNER_STAFF_ROLE_LABELS] || row.staffRole || '—'}`
|
||||
? `子账号 · ${staffRoleLabel(row.staffRole)}`
|
||||
: row.isPrimary === 1
|
||||
? '主账号'
|
||||
: '合伙人账号'
|
||||
@@ -183,16 +194,29 @@ export default function PartnerAccountsPage() {
|
||||
render: (_, row) => row.partner?.companyName || '—',
|
||||
},
|
||||
{
|
||||
title: '标识',
|
||||
title: '账号类型',
|
||||
dataIndex: 'isPrimary',
|
||||
width: 90,
|
||||
render: (v, row) => (
|
||||
<Tag color={row.parentAccountId ? 'default' : v === 1 ? 'blue' : 'default'}>
|
||||
{row.parentAccountId ? '子账号' : accountTypeLabel(v)}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: '角色',
|
||||
dataIndex: 'staffRole',
|
||||
width: 100,
|
||||
render: (_, row) =>
|
||||
row.parentAccountId ? (
|
||||
<Tag>子账号</Tag>
|
||||
) : row.isPrimary === 1 ? (
|
||||
<Tag color="blue">主账号</Tag>
|
||||
) : (
|
||||
<Tag>账号</Tag>
|
||||
),
|
||||
render: (role) => staffRoleLabel(role),
|
||||
},
|
||||
{
|
||||
title: '所属主账号',
|
||||
width: 140,
|
||||
render: (_, row) => (
|
||||
row.isPrimary === 1 || !row.parentAccountId
|
||||
? '-'
|
||||
: (row.parent ? `${row.parent.name} / ${row.parent.phone}` : '-')
|
||||
),
|
||||
},
|
||||
{ title: '状态', dataIndex: 'status', width: 80, render: (s) => <Tag>{ACCOUNT_STATUS_LABELS[s] || s}</Tag> },
|
||||
{ title: '创建', dataIndex: 'createdAt', width: 160, render: fmtTime },
|
||||
@@ -282,7 +306,7 @@ export default function PartnerAccountsPage() {
|
||||
loading={loading}
|
||||
columns={columns}
|
||||
dataSource={treeData}
|
||||
scroll={{ x: 1100 }}
|
||||
scroll={{ x: 1200 }}
|
||||
pagination={false}
|
||||
expandable={{
|
||||
expandedRowKeys,
|
||||
@@ -320,12 +344,24 @@ export default function PartnerAccountsPage() {
|
||||
<Form.Item label="开城合伙人">
|
||||
<Input value={detail.partner?.companyName} disabled />
|
||||
</Form.Item>
|
||||
{detail.parentAccountId ? (
|
||||
<Form.Item label="账号类型">
|
||||
<Input
|
||||
value={`子账号 · ${PARTNER_STAFF_ROLE_LABELS[detail.staffRole as keyof typeof PARTNER_STAFF_ROLE_LABELS] || detail.staffRole || '—'}`}
|
||||
disabled
|
||||
/>
|
||||
<Form.Item label="账号类型">
|
||||
<Input
|
||||
value={
|
||||
detail.parentAccountId
|
||||
? `子账号 · ${staffRoleLabel(detail.staffRole)}`
|
||||
: accountTypeLabel(detail.isPrimary)
|
||||
}
|
||||
disabled
|
||||
/>
|
||||
</Form.Item>
|
||||
{detail.staffRole ? (
|
||||
<Form.Item label="角色">
|
||||
<Input value={staffRoleLabel(detail.staffRole)} disabled />
|
||||
</Form.Item>
|
||||
) : null}
|
||||
{detail.parentAccountId && detail.parent ? (
|
||||
<Form.Item label="所属主账号">
|
||||
<Input value={`${detail.parent.name} / ${detail.parent.phone}`} disabled />
|
||||
</Form.Item>
|
||||
) : null}
|
||||
<Form.Item name="name" label="姓名" rules={[{ required: true }]}><Input /></Form.Item>
|
||||
|
||||
Reference in New Issue
Block a user