feat: 添加对站点的配置页面 #29
13
.umirc.ts
13
.umirc.ts
|
|
@ -124,6 +124,19 @@ export default defineConfig({
|
|||
},
|
||||
],
|
||||
},
|
||||
// 新增:订阅管理路由分组(权限复用 canSeeOrder)
|
||||
{
|
||||
name: '订阅管理',
|
||||
path: '/subscription',
|
||||
access: 'canSeeOrder',
|
||||
routes: [
|
||||
{
|
||||
name: '订阅列表',
|
||||
path: '/subscription/list',
|
||||
component: './Subscription/List',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: '客户管理',
|
||||
path: '/customer',
|
||||
|
|
|
|||
|
|
@ -0,0 +1,202 @@
|
|||
import React, { useRef } from 'react';
|
||||
import {
|
||||
ActionType,
|
||||
DrawerForm,
|
||||
PageContainer,
|
||||
ProColumns,
|
||||
ProFormSelect,
|
||||
ProTable,
|
||||
} from '@ant-design/pro-components';
|
||||
import { App, Button, Tag } from 'antd';
|
||||
import {
|
||||
subscriptioncontrollerList,
|
||||
subscriptioncontrollerSync,
|
||||
} from '@/servers/api/subscription';
|
||||
import { sitecontrollerAll } from '@/servers/api/site';
|
||||
|
||||
/**
|
||||
* 订阅状态枚举(用于筛选与展示)
|
||||
* 保持与后端同步的原始状态值
|
||||
*/
|
||||
const SUBSCRIPTION_STATUS_ENUM: Record<string, { text: string }> = {
|
||||
active: { text: '激活' },
|
||||
cancelled: { text: '已取消' },
|
||||
expired: { text: '已过期' },
|
||||
pending: { text: '待处理' },
|
||||
'on-hold': { text: '暂停' },
|
||||
};
|
||||
|
||||
/**
|
||||
* 订阅列表页:展示、筛选、触发订阅同步
|
||||
*/
|
||||
const ListPage: React.FC = () => {
|
||||
// 表格操作引用:用于在同步后触发表格刷新
|
||||
const actionRef = useRef<ActionType>();
|
||||
|
||||
// 表格列定义(尽量与项目风格保持一致)
|
||||
const columns: ProColumns<API.Subscription>[] = [
|
||||
{
|
||||
title: '站点',
|
||||
dataIndex: 'siteId',
|
||||
valueType: 'select',
|
||||
// 动态加载站点选项
|
||||
request: async () => {
|
||||
const { data = [] } = await sitecontrollerAll();
|
||||
return data.map((item) => ({
|
||||
label: item.siteName,
|
||||
value: item.id,
|
||||
}));
|
||||
},
|
||||
render: (_, row) => row?.siteId ?? '-',
|
||||
},
|
||||
{
|
||||
title: '订阅ID',
|
||||
dataIndex: 'externalSubscriptionId',
|
||||
hideInSearch: true,
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '状态',
|
||||
dataIndex: 'status',
|
||||
valueType: 'select',
|
||||
valueEnum: SUBSCRIPTION_STATUS_ENUM,
|
||||
// 以 Tag 形式展示,更易辨识
|
||||
render: (_, row) =>
|
||||
row?.status ? <Tag>{SUBSCRIPTION_STATUS_ENUM[row.status]?.text || row.status}</Tag> : '-',
|
||||
width: 120,
|
||||
},
|
||||
{
|
||||
title: '客户邮箱',
|
||||
dataIndex: 'customer_email',
|
||||
width: 180,
|
||||
},
|
||||
{
|
||||
title: '金额',
|
||||
dataIndex: 'total',
|
||||
hideInSearch: true,
|
||||
width: 100,
|
||||
},
|
||||
{
|
||||
title: '币种',
|
||||
dataIndex: 'currency',
|
||||
hideInSearch: true,
|
||||
width: 80,
|
||||
},
|
||||
{
|
||||
title: '开始时间',
|
||||
dataIndex: 'start_date',
|
||||
hideInSearch: true,
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '下次支付',
|
||||
dataIndex: 'next_payment_date',
|
||||
hideInSearch: true,
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '结束时间',
|
||||
dataIndex: 'end_date',
|
||||
hideInSearch: true,
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createdAt',
|
||||
valueType: 'dateTime',
|
||||
hideInSearch: true,
|
||||
width: 160,
|
||||
},
|
||||
{
|
||||
title: '更新时间',
|
||||
dataIndex: 'updatedAt',
|
||||
valueType: 'dateTime',
|
||||
hideInSearch: true,
|
||||
width: 160,
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<PageContainer header={{ title: '订阅列表' }}>
|
||||
<ProTable<API.Subscription>
|
||||
headerTitle="查询表格"
|
||||
rowKey="id"
|
||||
actionRef={actionRef}
|
||||
/**
|
||||
* 列表数据请求;保持与后端分页参数一致
|
||||
* 兼容后端 data.items 或 data.list 返回字段
|
||||
*/
|
||||
request={async (params) => {
|
||||
const { data, success } = await subscriptioncontrollerList(params);
|
||||
return {
|
||||
total: data?.total || 0,
|
||||
data: data?.items || data?.list || [],
|
||||
success,
|
||||
};
|
||||
}}
|
||||
columns={columns}
|
||||
// 工具栏:订阅同步入口
|
||||
toolBarRender={() => [<SyncForm key="sync" tableRef={actionRef} />]}
|
||||
/>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 同步订阅抽屉表单:选择站点后触发同步
|
||||
*/
|
||||
const SyncForm: React.FC<{
|
||||
tableRef: React.MutableRefObject<ActionType | undefined>;
|
||||
}> = ({ tableRef }) => {
|
||||
const { message } = App.useApp();
|
||||
|
||||
return (
|
||||
<DrawerForm<API.subscriptioncontrollerSyncParams>
|
||||
title="同步订阅"
|
||||
trigger={
|
||||
<Button key="syncSite" type="primary">
|
||||
同步订阅
|
||||
</Button>
|
||||
}
|
||||
autoFocusFirstInput
|
||||
drawerProps={{ destroyOnHidden: true }}
|
||||
/**
|
||||
* 提交逻辑:
|
||||
* 1. 必填校验由 ProForm + rules 保证
|
||||
* 2. 调用同步接口,失败时友好提示
|
||||
* 3. 成功后刷新列表
|
||||
*/
|
||||
onFinish={async (values) => {
|
||||
try {
|
||||
const { success, message: errMsg } = await subscriptioncontrollerSync(values);
|
||||
if (!success) {
|
||||
throw new Error(errMsg);
|
||||
}
|
||||
message.success('同步成功');
|
||||
tableRef.current?.reload();
|
||||
return true;
|
||||
} catch (error: any) {
|
||||
message.error(error.message || '同步失败');
|
||||
}
|
||||
}}
|
||||
>
|
||||
<ProFormSelect
|
||||
name="siteId"
|
||||
width="lg"
|
||||
label="站点"
|
||||
placeholder="请选择站点"
|
||||
// 动态加载站点选项
|
||||
request={async () => {
|
||||
const { data = [] } = await sitecontrollerAll();
|
||||
return data.map((item) => ({
|
||||
label: item.siteName,
|
||||
value: item.id,
|
||||
}));
|
||||
}}
|
||||
rules={[{ required: true, message: '请选择站点' }]}
|
||||
/>
|
||||
</DrawerForm>
|
||||
);
|
||||
};
|
||||
|
||||
export default ListPage;
|
||||
Loading…
Reference in New Issue