+ {!hideSubmitButton && (
+ <>
+
客户录入
+
录入客户基本信息
+ >
+ )}
+
+
+
+
+
+ {/* Row 4: Physical Info */}
+ {isMobile ? (
+ // Mobile Layout
+
+ {/* 1. Scores (Full width) */}
+ {scoresNode}
+
+ {/* 2. Height & Weight */}
+
+ {heightNode}
+ {weightNode}
+
+
+ {/* 3. Degree & Academy */}
+
+ {degreeNode}
+ {academyNode}
+
+
+ ) : (
+ // PC Layout
+
+ {scoresNode}
+ {heightNode}
+ {weightNode}
+
+ )}
+
+ {/* Row 5a: 学历、院校 */}
+
+ {degreeNode}
+ {academyNode}
+
+
+ {/* Row 5b: 职业、收入 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Row 5c: 资产、流动资产 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Row 5d: 房产情况、汽车情况 */}
+
+
+
+
+
+
+
+
+
+
+
+ {/* Row 6: 户口城市、常住城市、籍贯 */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Row 7: 是否独生子 */}
+
+
+ 是
+ 否
+
+
+
+ {/* Row 8: 原生家庭 */}
+
+
+
+
+ {/* Row 9: 择偶要求 */}
+
+
+
+
+ {/* Row 10: 其他信息 (KeyValueList) */}
+
+
+
+
+ {/* Row 11: 客户等级、是否公开 */}
+
+
+
+
+
+
+
+
+ 是
+ 否
+
+
+
+
+
+ {/* Row 13: 备注评论 (KeyValueList) */}
+
+
+
+
+ {!hideSubmitButton && (
+
+
+
+ )}
+
+
+ );
+};
+
+export default CustomForm;
diff --git a/src/components/CustomList.tsx b/src/components/CustomList.tsx
new file mode 100644
index 0000000..bc1e2de
--- /dev/null
+++ b/src/components/CustomList.tsx
@@ -0,0 +1,613 @@
+import React, { useEffect, useState, useRef } from 'react';
+import { Layout, Typography, Table, Grid, Button, Space, message, Descriptions, Tag, Modal, Popconfirm, Dropdown } from 'antd';
+import type { ColumnsType } from 'antd/es/table';
+import type { FormInstance } from 'antd';
+import {
+ ManOutlined,
+ WomanOutlined,
+ PictureOutlined,
+ DeleteOutlined,
+ EditOutlined,
+ UserOutlined,
+ EllipsisOutlined,
+ ShareAltOutlined,
+ DownloadOutlined,
+ CopyOutlined
+} from '@ant-design/icons';
+import { getCustoms, deleteCustom } from '../apis/custom';
+import type { Custom } from '../apis/types';
+import './MainContent.css';
+import ImageModal from './ImageModal.tsx';
+import NumberRangeFilterDropdown from './NumberRangeFilterDropdown';
+import CustomForm from './CustomForm.tsx';
+import ImageSelectorModal from './ImageSelectorModal';
+import ImageCropperModal from './ImageCropperModal';
+import { generateShareImage, type ShareData } from '../utils/shareImageGenerator';
+import { useAuth } from '../contexts/useAuth';
+
+const { Content } = Layout;
+const { useBreakpoint } = Grid;
+
+// 扩展 Custom 类型以确保 id 存在
+type CustomResource = Custom & { id: string };
+
+const CustomList: React.FC = () => {
+ const { user } = useAuth();
+ const screens = useBreakpoint();
+ const [data, setData] = useState