|
|
@@ -0,0 +1,77 @@
|
|
|
+import React from 'react';
|
|
|
+import { Select, Spin, message } from 'antd';
|
|
|
+import type { Template } from '@/share/exceltypes';
|
|
|
+import { useQuery } from '@tanstack/react-query';
|
|
|
+
|
|
|
+interface TemplateSelectorProps {
|
|
|
+ onTemplateSelected: (templateId: string) => void;
|
|
|
+ value?: string;
|
|
|
+ disabled?: boolean;
|
|
|
+ required?: boolean;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * 模板选择器组件
|
|
|
+ * 用于通过模板ID选择Excel解析模板
|
|
|
+ * 注意: 使用时需确保同时提供input和templateId,两项均为必填
|
|
|
+ */
|
|
|
+const TemplateSelector: React.FC<TemplateSelectorProps> = ({
|
|
|
+ onTemplateSelected,
|
|
|
+ value,
|
|
|
+ disabled = false,
|
|
|
+ required = true
|
|
|
+}) => {
|
|
|
+ const { requestWithToken } = useApiRequest();
|
|
|
+
|
|
|
+ // 使用 React Query 获取模板数据
|
|
|
+ const { data, isLoading, isError } = useQuery({
|
|
|
+ queryKey: ['templates'],
|
|
|
+ queryFn: async () => {
|
|
|
+ try {
|
|
|
+ const result = await requestWithToken({
|
|
|
+ url: '/v1/member/templates',
|
|
|
+ method: 'GET'
|
|
|
+ });
|
|
|
+
|
|
|
+ if (result.success && Array.isArray(result.data)) {
|
|
|
+ return result.data as Template[];
|
|
|
+ } else {
|
|
|
+ message.error('获取模板列表失败');
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取模板列表错误:', error);
|
|
|
+ message.error('获取模板列表失败');
|
|
|
+ throw error;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ const handleChange = (value: string) => {
|
|
|
+ onTemplateSelected(value);
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <Spin spinning={isLoading}>
|
|
|
+ <Select
|
|
|
+ placeholder={required ? "请选择模板(必填)" : "请选择模板"}
|
|
|
+ style={{ width: '100%' }}
|
|
|
+ onChange={handleChange}
|
|
|
+ loading={isLoading}
|
|
|
+ allowClear={!required}
|
|
|
+ value={value}
|
|
|
+ disabled={disabled}
|
|
|
+ status={required && !value ? "error" : undefined}
|
|
|
+ >
|
|
|
+ {data?.map(template => (
|
|
|
+ <Select.Option key={template.id} value={String(template.id)}>
|
|
|
+ {template.template_name}
|
|
|
+ </Select.Option>
|
|
|
+ ))}
|
|
|
+ </Select>
|
|
|
+ {isError && <div style={{ color: 'red', marginTop: '4px' }}>获取模板列表失败</div>}
|
|
|
+ </Spin>
|
|
|
+ );
|
|
|
+};
|
|
|
+
|
|
|
+export default TemplateSelector;
|