index.tsx 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import { fetchInitialCredentials, fetchProductList, fetchUpdateProduct } from '@/services/product';
  2. import { ActionType, PageContainer, ProColumns, ProTable } from '@ant-design/pro-components';
  3. import { useIntl, useLocation, useNavigate } from '@umijs/max';
  4. import { Button, Popconfirm, Tag, message } from 'antd';
  5. import { useRef, useState } from 'react';
  6. import { ProductForm } from './components/Form';
  7. import { CredentialModal } from './Detail/components/CredentialModal';
  8. interface LocationState {
  9. page?: number;
  10. pageSize?: number;
  11. }
  12. export default function ProductPage() {
  13. const intl = useIntl();
  14. const navigate = useNavigate();
  15. const location = useLocation();
  16. const state = (location.state ?? {}) as LocationState;
  17. const actionRef = useRef<ActionType>();
  18. const [credData, setCredData] = useState<API.FetchInitialCredentialsResp | null>(null);
  19. const [credOpen, setCredOpen] = useState(false);
  20. const [pagination, setPagination] = useState({
  21. current: state.page ?? 1,
  22. pageSize: state.pageSize ?? 20,
  23. });
  24. const handleCreateSuccess = async (ticket?: string) => {
  25. actionRef.current?.reload();
  26. if (!ticket) return;
  27. const res = await fetchInitialCredentials({ ticket });
  28. setCredData(res.data ?? null);
  29. setCredOpen(true);
  30. };
  31. const handleToggleStatus = async (record: API.ProductItem) => {
  32. const res = await fetchUpdateProduct({
  33. id: record.id,
  34. name: record.name,
  35. status: record.status === 1 ? 0 : 1,
  36. });
  37. if (!res.success) return;
  38. message.success('操作成功');
  39. actionRef.current?.reload();
  40. };
  41. const columns: ProColumns<API.ProductItem>[] = [
  42. {
  43. title: '名称',
  44. dataIndex: 'name',
  45. width: 160,
  46. render: (_, r) => (
  47. <a
  48. onClick={() =>
  49. navigate(`/admin/products/${r.id}`, {
  50. state: { page: pagination.current, pageSize: pagination.pageSize },
  51. })
  52. }
  53. >
  54. {r.name}
  55. </a>
  56. ),
  57. },
  58. { title: 'Code', dataIndex: 'code', width: 160, copyable: true },
  59. { title: 'App Key', dataIndex: 'appKey', width: 300, copyable: true },
  60. { title: '备注', dataIndex: 'remark' },
  61. {
  62. title: '状态',
  63. dataIndex: 'status',
  64. width: 80,
  65. render: (_, r) => (
  66. <Tag color={r.status === 1 ? 'success' : 'default'}>{r.status === 1 ? '启用' : '禁用'}</Tag>
  67. ),
  68. },
  69. { title: '创建时间', dataIndex: 'createTime', valueType: 'dateTime', width: 180 },
  70. {
  71. title: '操作',
  72. valueType: 'option',
  73. width: 120,
  74. render: (_, r) => [
  75. <ProductForm
  76. key="edit"
  77. mode="edit"
  78. initialValues={r}
  79. onSuccess={() => actionRef.current?.reload()}
  80. trigger={<a>编辑</a>}
  81. />,
  82. <Popconfirm
  83. key="status"
  84. title={r.status === 1 ? `确认禁用「${r.name}」?` : `确认启用「${r.name}」?`}
  85. onConfirm={() => handleToggleStatus(r)}
  86. >
  87. <a>{r.status === 1 ? '禁用' : '启用'}</a>
  88. </Popconfirm>,
  89. ],
  90. },
  91. ];
  92. return (
  93. <PageContainer title={intl.formatMessage({ id: 'admin.product.title' })}>
  94. <ProTable<API.ProductItem>
  95. actionRef={actionRef}
  96. columns={columns}
  97. rowKey="id"
  98. search={false}
  99. request={fetchProductList}
  100. scroll={{ x: 900 }}
  101. tableLayout="fixed"
  102. pagination={{
  103. current: pagination.current,
  104. pageSize: pagination.pageSize,
  105. defaultPageSize: 20,
  106. pageSizeOptions: [10, 20, 50, 100],
  107. showSizeChanger: true,
  108. onChange: (page, pageSize) => setPagination({ current: page, pageSize }),
  109. }}
  110. toolBarRender={() => [
  111. <ProductForm
  112. key="create"
  113. mode="add"
  114. onSuccess={handleCreateSuccess}
  115. trigger={
  116. <Button type="primary">{intl.formatMessage({ id: 'admin.product.create' })}</Button>
  117. }
  118. />,
  119. ]}
  120. />
  121. <CredentialModal open={credOpen} data={credData} onClose={() => setCredOpen(false)} />
  122. </PageContainer>
  123. );
  124. }