diff --git a/.umirc.ts b/.umirc.ts index 723972c..b60deb3 100644 --- a/.umirc.ts +++ b/.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', diff --git a/src/pages/Subscription/List/index.tsx b/src/pages/Subscription/List/index.tsx new file mode 100644 index 0000000..41f801d --- /dev/null +++ b/src/pages/Subscription/List/index.tsx @@ -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 = { + active: { text: '激活' }, + cancelled: { text: '已取消' }, + expired: { text: '已过期' }, + pending: { text: '待处理' }, + 'on-hold': { text: '暂停' }, +}; + +/** + * 订阅列表页:展示、筛选、触发订阅同步 + */ +const ListPage: React.FC = () => { + // 表格操作引用:用于在同步后触发表格刷新 + const actionRef = useRef(); + + // 表格列定义(尽量与项目风格保持一致) + const columns: ProColumns[] = [ + { + 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 ? {SUBSCRIPTION_STATUS_ENUM[row.status]?.text || row.status} : '-', + 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 ( + + + 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={() => []} + /> + + ); +}; + +/** + * 同步订阅抽屉表单:选择站点后触发同步 + */ +const SyncForm: React.FC<{ + tableRef: React.MutableRefObject; +}> = ({ tableRef }) => { + const { message } = App.useApp(); + + return ( + + title="同步订阅" + trigger={ + + } + 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 || '同步失败'); + } + }} + > + { + const { data = [] } = await sitecontrollerAll(); + return data.map((item) => ({ + label: item.siteName, + value: item.id, + })); + }} + rules={[{ required: true, message: '请选择站点' }]} + /> + + ); +}; + +export default ListPage;