import RegionCascader from '@/components/RegionCascader';
|
import { PlusOutlined } from '@ant-design/icons';
|
import { history, useAccess } from '@umijs/max';
|
import { Button, Descriptions, Form, Input, Modal, Pagination, Space, Table, message } from 'antd';
|
import React, { useEffect, useState } from 'react';
|
import { createAgent, deleteAgent, getAgentDetail, getAgentPage, updateAgent } from './service';
|
|
type RegionValue = { regionCode?: string[]; regionName?: string };
|
type AgentItem = { id: number; agentName: string; contactInfo?: string; address?: string; regionNames?: string[]; createdAt?: string };
|
|
const AgentPage: React.FC = () => {
|
const access = useAccess();
|
const [searchForm] = Form.useForm<{ regionPath?: string[]; agentName?: string }>();
|
const [form] = Form.useForm();
|
const [list, setList] = useState<AgentItem[]>([]);
|
const [pagination, setPagination] = useState({ page: 1, pageSize: 10, total: 0 });
|
const [loading, setLoading] = useState(false);
|
const [open, setOpen] = useState(false);
|
const [detail, setDetail] = useState<any>();
|
const [editingId, setEditingId] = useState<number>();
|
const canView = access['member:agent:view'];
|
|
const load = async (page = 1, pageSize = pagination.pageSize) => {
|
const search = searchForm.getFieldsValue();
|
setLoading(true);
|
try {
|
const response = await getAgentPage({
|
page,
|
pageSize,
|
agentName: search.agentName?.trim() || undefined,
|
regionCode: search.regionPath?.[search.regionPath.length - 1],
|
});
|
setList(response.data?.list || []);
|
setPagination({
|
page: Number(response.data?.page || page),
|
pageSize: Number(response.data?.pageSize || pageSize),
|
total: Number(response.data?.total || 0),
|
});
|
} finally {
|
setLoading(false);
|
}
|
};
|
|
useEffect(() => {
|
if (!canView) history.replace('/Welcome');
|
else void load();
|
}, [canView]);
|
|
const openForm = async (id?: number) => {
|
setEditingId(id);
|
setDetail(undefined);
|
setOpen(true);
|
form.resetFields();
|
if (!id) {
|
form.setFieldsValue({ regions: [{}] });
|
return;
|
}
|
const response = await getAgentDetail(id);
|
form.setFieldsValue({
|
...response.data,
|
regions: (response.data?.regions || []).map((region: any) => ({
|
...region,
|
regionCode: region.regionPath,
|
})),
|
});
|
};
|
|
const openDetail = async (id: number) => {
|
const response = await getAgentDetail(id);
|
setEditingId(undefined);
|
setDetail(response.data);
|
setOpen(true);
|
};
|
|
const submit = async () => {
|
const values = await form.validateFields();
|
const regions = (values.regions || []).map((region: RegionValue) => ({
|
regionCode: region.regionCode?.[region.regionCode.length - 1],
|
}));
|
try {
|
if (editingId) await updateAgent(editingId, { ...values, regions });
|
else await createAgent({ ...values, regions });
|
message.success(editingId ? '保存成功' : '新增成功');
|
setOpen(false);
|
await load(editingId ? pagination.page : 1);
|
} catch (error) {
|
message.error((error as Error)?.message || '保存失败');
|
}
|
};
|
|
const columns = [
|
{ title: '序号', width: 70, render: (_: any, __: any, index: number) => (pagination.page - 1) * pagination.pageSize + index + 1 },
|
{ title: '代理负责人', dataIndex: 'agentName' },
|
{ title: '负责省份', render: (_: any, record: AgentItem) => (record.regionNames || []).join('、') || '-' },
|
{ title: '联系信息', dataIndex: 'contactInfo', render: (value: string) => value || '-' },
|
{ title: '详细地址', dataIndex: 'address', render: (value: string) => value || '-' },
|
{ title: '创建时间', dataIndex: 'createdAt', width: 180 },
|
{
|
title: '操作',
|
width: 180,
|
render: (_: any, record: AgentItem, index: number) => <Space size={0}>
|
{access['member:agent:detail'] && <Button type="link" onClick={() => openDetail(record.id)}>详情</Button>}
|
{access['member:agent:edit'] && <Button type="link" onClick={() => openForm(record.id)}>编辑</Button>}
|
{access['member:agent:delete'] && !(pagination.page === 1 && index === 0) && <Button type="link" danger onClick={() => Modal.confirm({
|
title: '确定删除该省代理吗?',
|
onOk: async () => { await deleteAgent(record.id); message.success('删除成功'); await load(); },
|
})}>删除</Button>}
|
</Space>,
|
},
|
];
|
|
return <div style={{ padding: 24 }}>
|
<h2>省代理管理</h2>
|
<Form form={searchForm} layout="inline" onFinish={() => load(1)}>
|
<Form.Item name="regionPath" label="负责省份"><RegionCascader allowClear changeOnSelect placeholder="全部" /></Form.Item>
|
<Form.Item name="agentName" label="代理负责人"><Input allowClear placeholder="请输入" /></Form.Item>
|
<Button onClick={() => { searchForm.resetFields(); void load(1); }}>重置</Button>
|
<Button type="primary" htmlType="submit" style={{ marginLeft: 8 }}>查询</Button>
|
</Form>
|
<div style={{ margin: '16px 0' }}>{access['member:agent:add'] && <Button type="primary" icon={<PlusOutlined />} onClick={() => openForm()}>新增</Button>}</div>
|
<Table rowKey="id" columns={columns as any} dataSource={list} loading={loading} pagination={false} />
|
<Pagination style={{ marginTop: 16, textAlign: 'right' }} current={pagination.page} pageSize={pagination.pageSize} total={pagination.total} showSizeChanger onChange={load} />
|
<Modal open={open} title={detail ? '省代理详情' : editingId ? '编辑省代理' : '新增省代理'} width={760} onCancel={() => setOpen(false)} footer={detail ? null : <><Button onClick={() => setOpen(false)}>取消</Button><Button type="primary" onClick={submit}>确定</Button></>}>
|
{detail ? <Descriptions bordered column={2} items={[
|
['代理负责人', detail.agentName], ['负责省份', (detail.regionNames || []).join('、')],
|
['开户银行', detail.bankName], ['银行账号', detail.accountNumber], ['账户名称', detail.accountHolder],
|
['开户支行', detail.branchName], ['联系信息', detail.contactInfo], ['详细地址', detail.address],
|
].map(([label, children]) => ({ label, children: children || '-' }))} /> :
|
<Form form={form} labelCol={{ span: 5 }}>
|
<Form.Item name="agentName" label="代理负责人" rules={[{ required: true, message: '请输入代理负责人' }]}><Input maxLength={50} /></Form.Item>
|
<Form.List name="regions" rules={[{ validator: async (_, value) => { if (!value?.length) throw new Error('请选择负责省份'); } }]}>
|
{(fields, { add, remove }, { errors }) => <Form.Item label="负责省份" required>
|
{fields.map(({ key, name, ...rest }) => <Space key={key} align="baseline">
|
<Form.Item {...rest} name={[name, 'regionCode']} rules={[{ required: true, message: '请选择负责省份' }]}><RegionCascader changeOnSelect /></Form.Item>
|
{fields.length > 1 && <Button onClick={() => remove(name)}>删除</Button>}
|
</Space>)}
|
<Button type="dashed" onClick={() => add({})}>添加负责省份</Button>
|
<Form.ErrorList errors={errors} />
|
</Form.Item>}
|
</Form.List>
|
<Form.Item name="bankName" label="开户银行"><Input maxLength={100} /></Form.Item>
|
<Form.Item name="accountNumber" label="银行账号"><Input maxLength={30} /></Form.Item>
|
<Form.Item name="accountHolder" label="账户名称"><Input maxLength={50} /></Form.Item>
|
<Form.Item name="branchName" label="开户支行"><Input maxLength={100} /></Form.Item>
|
<Form.Item name="contactInfo" label="联系信息"><Input maxLength={200} /></Form.Item>
|
<Form.Item name="address" label="详细地址"><Input.TextArea rows={3} maxLength={255} /></Form.Item>
|
</Form>}
|
</Modal>
|
</div>;
|
};
|
|
export default AgentPage;
|