forked from wangziqi/gongxue-base
125 lines
3.7 KiB
TypeScript
125 lines
3.7 KiB
TypeScript
import React from 'react';
|
|
import { Button, Input, Select, Tag, Typography } from 'antd';
|
|
import { LinkOutlined, PlusOutlined } from '@ant-design/icons';
|
|
import type { JinshujuEntryRow, MatchDecision, StudentOption } from './JinshujuMatchModal.types';
|
|
|
|
const { Text } = Typography;
|
|
|
|
interface MatchSelectorProps {
|
|
entry: JinshujuEntryRow;
|
|
decision: MatchDecision | undefined;
|
|
studentOptions: StudentOption[];
|
|
onChange: (d: MatchDecision) => void;
|
|
}
|
|
|
|
const MatchSelector: React.FC<MatchSelectorProps> = ({
|
|
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 (
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%' }}>
|
|
<Tag color="blue" icon={<LinkOutlined />}>
|
|
已匹配
|
|
</Tag>
|
|
<Text style={{ flex: 1 }}>
|
|
{matchedStudent?.name ?? '未知'}
|
|
{matchedStudent?.studentNo && (
|
|
<Text type="secondary" style={{ fontSize: 12, marginLeft: 4 }}>
|
|
({matchedStudent.studentNo})
|
|
</Text>
|
|
)}
|
|
</Text>
|
|
<Button size="small" type="link" danger onClick={() => onChange({ action: 'skip' })}>
|
|
取消
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
if (action === 'create') {
|
|
const createD = decision as { action: 'create'; createName: string; createPhone: string };
|
|
return (
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%' }}>
|
|
<Tag color="green" icon={<PlusOutlined />}>
|
|
将新建
|
|
</Tag>
|
|
<Input
|
|
size="small"
|
|
value={createD.createName}
|
|
placeholder="姓名"
|
|
style={{ width: 100 }}
|
|
onChange={(e) =>
|
|
onChange({
|
|
action: 'create',
|
|
createName: e.target.value,
|
|
createPhone: createD.createPhone,
|
|
})
|
|
}
|
|
/>
|
|
<Input
|
|
size="small"
|
|
value={createD.createPhone}
|
|
placeholder="手机号"
|
|
style={{ width: 120 }}
|
|
onChange={(e) =>
|
|
onChange({
|
|
action: 'create',
|
|
createName: createD.createName,
|
|
createPhone: e.target.value,
|
|
})
|
|
}
|
|
/>
|
|
<Button size="small" type="link" danger onClick={() => onChange({ action: 'skip' })}>
|
|
取消
|
|
</Button>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8, width: '100%' }}>
|
|
<Select
|
|
showSearch
|
|
size="small"
|
|
placeholder="搜索学生…"
|
|
style={{ flex: 1 }}
|
|
value={undefined}
|
|
filterOption={(input, option) =>
|
|
((option?.label as string) || '').toLowerCase().includes(input.toLowerCase())
|
|
}
|
|
options={studentOptions.map((s) => ({
|
|
value: s.id,
|
|
label: `${s.name}${s.phone ? ` (${s.phone})` : ''}${s.studentNo ? ` [${s.studentNo}]` : ''}`,
|
|
}))}
|
|
onChange={(studentId: number) => onChange({ action: 'match', matchStudentId: studentId })}
|
|
/>
|
|
<Button
|
|
size="small"
|
|
type="dashed"
|
|
icon={<PlusOutlined />}
|
|
onClick={() =>
|
|
onChange({
|
|
action: 'create',
|
|
createName: entry.name || '',
|
|
createPhone: entry.phone || '',
|
|
})
|
|
}
|
|
>
|
|
新建
|
|
</Button>
|
|
<Button size="small" type="link" onClick={() => onChange({ action: 'skip' })}>
|
|
跳过
|
|
</Button>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default MatchSelector;
|