= ({
- entry,
- decision,
- studentOptions,
- onChange,
-}) => {
- const action = decision?.action ?? 'skip';
-
- if (action === 'match') {
- const matchD = decision as { action: 'match'; matchStudentId: number };
- const matchedStudent = studentOptions.find((s) => s.id === matchD.matchStudentId);
- return (
-
- }>
- 已匹配
-
-
- {matchedStudent?.name ?? '未知'}
- {matchedStudent?.studentNo && (
-
- ({matchedStudent.studentNo})
-
- )}
-
-
-
- );
- }
-
- if (action === 'create') {
- const createD = decision as { action: 'create'; createName: string; createPhone: string };
- return (
-
- }>
- 将新建
-
-
- onChange({
- action: 'create',
- createName: e.target.value,
- createPhone: createD.createPhone,
- })
- }
- />
-
- onChange({
- action: 'create',
- createName: createD.createName,
- createPhone: e.target.value,
- })
- }
- />
-
-
- );
- }
-
- return (
-
-
- );
-};
-
-// ── Rule Editor sub-component ──
-
-interface RuleEditorProps {
- rule: MatchRule | null;
- formToken: string;
- fields: JinshujuFormField[];
- onSave: () => void;
- onDelete: (id: number) => void;
- onCancel: () => void;
-}
-
-const RuleEditor: React.FC = ({
- rule,
- formToken,
- fields,
- onSave,
- onDelete,
- onCancel,
-}) => {
- const [name, setName] = useState(rule?.name ?? '');
- const [mappings, setMappings] = useState>(
- rule?.mappings ?? { name: 'field_1', phone: 'field_2' },
- );
- const [saving, setSaving] = useState(false);
-
- const handleSave = async () => {
- if (!name.trim()) {
- message.warning('请输入规则名称');
- return;
- }
- setSaving(true);
- try {
- if (rule) {
- await api.put(`/sync/jinshuju/rules/${rule.id}`, { name, mappings });
- } else {
- await api.post('/sync/jinshuju/rules', { name, formToken, mappings });
- }
- message.success('规则已保存');
- onSave();
- } catch (e: unknown) {
- const err = e as { message?: string };
- if (err?.message) message.error(err.message);
- } finally {
- setSaving(false);
- }
- };
-
- return (
-
-
setName(e.target.value)}
- style={{ marginBottom: 12 }}
- />
-
- 选择金数据字段映射到学生资料
-
- {STUDENT_FIELDS.map((sf) => (
-
- {sf.label}
-
- ←
-
-
- ))}
-
-
} loading={saving} onClick={handleSave}>
- 保存
-
- {rule && (
-
onDelete(rule.id)}>
- }>
- 删除
-
-
- )}
-
-
-
- );
-};
-
-// ── Main MatchModal ──
-
interface MatchModalProps {
open: boolean;
onClose: () => void;
@@ -318,7 +36,6 @@ const JinshujuMatchModal: React.FC = ({ open, onClose, onApplie
const [step, setStep] = useState<'connection' | 'rule' | 'match' | 'applying'>('connection');
const [loading, setLoading] = useState(false);
const [selectedRuleId, setSelectedRuleId] = useState();
- const [rules, setRules] = useState([]);
const [editingRule, setEditingRule] = useState(null);
const [showRuleEditor, setShowRuleEditor] = useState(false);
const [credForm] = Form.useForm();
@@ -326,40 +43,35 @@ const JinshujuMatchModal: React.FC = ({ open, onClose, onApplie
const [entries, setEntries] = useState([]);
const [studentOptions, setStudentOptions] = useState([]);
- const [decisions, setDecisions] = useState