forked from yoone/WEB
260 lines
7.4 KiB
TypeScript
260 lines
7.4 KiB
TypeScript
import {} from '@/servers/api/subscription';
|
|
import { DeleteFilled, EditOutlined, PlusOutlined } from '@ant-design/icons';
|
|
import {
|
|
ActionType,
|
|
PageContainer,
|
|
ProColumns,
|
|
ProTable,
|
|
} from '@ant-design/pro-components';
|
|
import { useParams } from '@umijs/max';
|
|
import { App, Button, Drawer, List, Popconfirm, Space, Tag } from 'antd';
|
|
import dayjs from 'dayjs';
|
|
import React, { useRef, useState } from 'react';
|
|
import { request } from 'umi';
|
|
|
|
/**
|
|
* 订阅状态枚举(用于筛选与展示)
|
|
* 保持与后端同步的原始状态值
|
|
*/
|
|
const SUBSCRIPTION_STATUS_ENUM: Record<string, { text: string }> = {
|
|
active: { text: '激活' },
|
|
cancelled: { text: '已取消' },
|
|
expired: { text: '已过期' },
|
|
pending: { text: '待处理' },
|
|
'on-hold': { text: '暂停' },
|
|
};
|
|
|
|
/**
|
|
* 订阅列表页:展示,筛选,触发订阅同步
|
|
*/
|
|
const SubscriptionsPage: React.FC = () => {
|
|
// 表格操作引用:用于在同步后触发表格刷新
|
|
const actionRef = useRef<ActionType>();
|
|
const { message } = App.useApp();
|
|
const { siteId } = useParams<{ siteId: string }>();
|
|
|
|
// 监听 siteId 变化并重新加载表格
|
|
React.useEffect(() => {
|
|
actionRef.current?.reload();
|
|
}, [siteId]);
|
|
|
|
// 关联订单抽屉状态
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
const [drawerTitle, setDrawerTitle] = useState('详情');
|
|
const [relatedOrders, setRelatedOrders] = useState<any[]>([]);
|
|
|
|
// 表格列定义(尽量与项目风格保持一致)
|
|
const [editing, setEditing] = useState<any>(null);
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState<React.Key[]>([]);
|
|
|
|
const columns: ProColumns<any>[] = [
|
|
// Site column removed
|
|
{
|
|
title: '订阅ID',
|
|
dataIndex: 'id',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '状态',
|
|
dataIndex: 'status',
|
|
valueType: 'select',
|
|
valueEnum: SUBSCRIPTION_STATUS_ENUM,
|
|
// 以 Tag 形式展示,更易辨识
|
|
render: (_, row) =>
|
|
row?.status ? (
|
|
<Tag>{SUBSCRIPTION_STATUS_ENUM[row.status]?.text || row.status}</Tag>
|
|
) : (
|
|
'-'
|
|
),
|
|
},
|
|
{
|
|
title: '客户ID',
|
|
dataIndex: 'customer_id',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '计费周期',
|
|
dataIndex: 'billing_period',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '计费间隔',
|
|
dataIndex: 'billing_interval',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '开始时间',
|
|
dataIndex: 'start_date',
|
|
hideInSearch: true,
|
|
width: 160,
|
|
},
|
|
{
|
|
title: '下次支付',
|
|
dataIndex: 'next_payment_date',
|
|
hideInSearch: true,
|
|
width: 160,
|
|
},
|
|
{
|
|
// 创建时间
|
|
title: '创建时间',
|
|
dataIndex: 'date_created',
|
|
valueType: 'dateTime',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
// 修改时间
|
|
title: '修改时间',
|
|
dataIndex: 'date_modified',
|
|
valueType: 'dateTime',
|
|
hideInSearch: true,
|
|
},
|
|
{
|
|
title: '操作',
|
|
valueType: 'option',
|
|
render: (_, row) => (
|
|
<Space>
|
|
<Button
|
|
type="link"
|
|
title="编辑"
|
|
icon={<EditOutlined />}
|
|
onClick={() => setEditing(row)}
|
|
/>
|
|
<Popconfirm
|
|
title="确定删除?"
|
|
onConfirm={() => message.info('订阅删除未实现')}
|
|
>
|
|
<Button type="link" danger title="删除" icon={<DeleteFilled />} />
|
|
</Popconfirm>
|
|
</Space>
|
|
),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<PageContainer ghost header={{ title: null, breadcrumb: undefined }}>
|
|
<ProTable<API.Subscription>
|
|
headerTitle="查询表格"
|
|
rowKey="id"
|
|
actionRef={actionRef}
|
|
/**
|
|
* 列表数据请求;保持与后端分页参数一致
|
|
* 兼容后端 data.items 或 data.list 返回字段
|
|
*/
|
|
request={async (params) => {
|
|
if (!siteId) return { data: [], success: true };
|
|
const response = await request(`/site-api/${siteId}/subscriptions`, {
|
|
params: {
|
|
...params,
|
|
page: params.current,
|
|
per_page: params.pageSize,
|
|
},
|
|
});
|
|
|
|
if (!response.success) {
|
|
message.error(response.message || '获取订阅列表失败');
|
|
return {
|
|
data: [],
|
|
total: 0,
|
|
success: false,
|
|
};
|
|
}
|
|
|
|
const { data } = response;
|
|
return {
|
|
total: data?.total || 0,
|
|
data: data?.items || [],
|
|
success: true,
|
|
};
|
|
}}
|
|
columns={columns}
|
|
// 工具栏:订阅同步入口
|
|
rowSelection={{ selectedRowKeys, onChange: setSelectedRowKeys }}
|
|
toolBarRender={() => [
|
|
<Button
|
|
type="primary"
|
|
title="新增"
|
|
icon={<PlusOutlined />}
|
|
onClick={() => message.info('订阅新增未实现')}
|
|
/>,
|
|
<Button
|
|
title="批量编辑"
|
|
icon={<EditOutlined />}
|
|
onClick={() => message.info('批量编辑未实现')}
|
|
/>,
|
|
<Button
|
|
title="批量导出"
|
|
onClick={async () => {
|
|
if (!siteId) return;
|
|
const res = await request(
|
|
`/site-api/${siteId}/subscriptions/export`,
|
|
{ params: {} },
|
|
);
|
|
if (res?.success && res?.data?.csv) {
|
|
const blob = new Blob([res.data.csv], {
|
|
type: 'text/csv;charset=utf-8;',
|
|
});
|
|
const url = URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = 'subscriptions.csv';
|
|
a.click();
|
|
URL.revokeObjectURL(url);
|
|
} else {
|
|
message.error(res.message || '导出失败');
|
|
}
|
|
}}
|
|
/>,
|
|
<Button
|
|
title="批量删除"
|
|
danger
|
|
icon={<DeleteFilled />}
|
|
onClick={() => message.info('订阅删除未实现')}
|
|
/>,
|
|
]}
|
|
/>
|
|
<Drawer
|
|
open={drawerOpen}
|
|
title={drawerTitle}
|
|
width={720}
|
|
onClose={() => setDrawerOpen(false)}
|
|
>
|
|
<List
|
|
header={<div>关联订单</div>}
|
|
dataSource={relatedOrders}
|
|
renderItem={(item: any) => (
|
|
<List.Item>
|
|
<List.Item.Meta
|
|
title={`#${item?.externalOrderId || '-'}`}
|
|
description={`关系:${item?.relationship || '-'},站点:${
|
|
item?.name || '-'
|
|
}`}
|
|
/>
|
|
<div style={{ display: 'flex', gap: 12, alignItems: 'center' }}>
|
|
<span>
|
|
{item?.date_created
|
|
? dayjs(item.date_created).format('YYYY-MM-DD HH:mm')
|
|
: '-'}
|
|
</span>
|
|
<Tag>{item?.status || '-'}</Tag>
|
|
<span>
|
|
{item?.currency_symbol || ''}
|
|
{typeof item?.total === 'number'
|
|
? item.total.toFixed(2)
|
|
: item?.total ?? '-'}
|
|
</span>
|
|
</div>
|
|
</List.Item>
|
|
)}
|
|
/>
|
|
</Drawer>
|
|
</PageContainer>
|
|
);
|
|
};
|
|
|
|
/**
|
|
* 同步订阅抽屉表单:选择站点后触发同步
|
|
*/
|
|
// 已移除订阅同步入口,改为直接从站点实时获取
|
|
|
|
export default SubscriptionsPage;
|