forked from yoone/WEB
1
0
Fork 0
WEB/src/pages/Site/Shop/Subscriptions/index.tsx

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;