Files
gongxue-base/apps/admin/src/pages/Expenses/ExpenseModals.tsx

167 lines
5.5 KiB
TypeScript

// aislop-ignore-file: duplicate-block -- 表格/表单声明结构相似且参数不同,渲染逻辑已共享组件化
import React from 'react';
import {
DatePicker,
Form,
Input,
InputNumber,
Modal,
Select,
} from 'antd';
const { RangePicker } = DatePicker;
export const RoomExpenseModal: React.FC<{
open: boolean;
editing: boolean;
saving: boolean;
form: ReturnType<typeof Form.useForm>[0];
rooms: any[];
typeOptions: Array<{ value: string; label: string }>;
onOk: () => void;
onCancel: () => void;
}> = ({ open, editing, saving, form, rooms, typeOptions, onOk, onCancel }) => {
return (
<Modal
title={editing ? '编辑宿舍费用' : '录入宿舍费用'}
open={open}
onOk={onOk}
onCancel={onCancel}
okText={editing ? '保存' : '确认录入'}
confirmLoading={saving}
>
<Form form={form} layout="vertical">
<Form.Item name="roomId" label="宿舍" rules={[{ required: true }]}>
<Select
showSearch
optionFilterProp="label"
options={rooms.map((r: any) => ({
value: r.id,
label: `${r.roomNumber} (${r.building || ''})`,
}))}
/>
</Form.Item>
<Form.Item name="expenseType" label="费用类型" rules={[{ required: true }]}>
<Select options={typeOptions} />
</Form.Item>
<Form.Item name="amount" label="金额(元)" rules={[{ required: true }]}>
<InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="period" label="账单周期" rules={[{ required: true }]}>
<RangePicker
style={{ width: '100%' }}
placeholder={['开始日期', '结束日期']}
format="YYYY-MM-DD"
/>
</Form.Item>
<Form.Item name="description" label="说明">
<Input.TextArea rows={2} />
</Form.Item>
</Form>
</Modal>
);
};
export const UtilityModal: React.FC<{
open: boolean;
saving: boolean;
form: ReturnType<typeof Form.useForm>[0];
students: any[];
onOk: () => void;
onCancel: () => void;
}> = ({ open, saving, form, students, onOk, onCancel }) => {
return (
<Modal
title="添加学生水电费并立即出账"
open={open}
onOk={onOk}
onCancel={onCancel}
okText="生成账单并扣余额"
confirmLoading={saving}
>
<Form form={form} layout="vertical">
<Form.Item name="studentId" label="学生" rules={[{ required: true }]}>
<Select
showSearch
optionFilterProp="label"
options={students.map((student: any) => ({
value: student.id,
label: `${student.name} (${student.studentNo || `#${student.id}`})`,
}))}
/>
</Form.Item>
<Form.Item name="expenseType" label="费用类型" rules={[{ required: true }]}>
<Select
options={[
{ value: 'water', label: '水费' },
{ value: 'electricity', label: '电费' },
]}
/>
</Form.Item>
<Form.Item name="amount" label="金额(元)" rules={[{ required: true }]}>
<InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="period" label="账单周期" rules={[{ required: true }]}>
<RangePicker style={{ width: '100%' }} format="YYYY-MM-DD" />
</Form.Item>
<Form.Item name="description" label="说明">
<Input.TextArea rows={2} maxLength={300} />
</Form.Item>
</Form>
</Modal>
);
};
export const PersonalExpenseModal: React.FC<{
open: boolean;
editing: boolean;
saving: boolean;
form: ReturnType<typeof Form.useForm>[0];
students: any[];
rooms: any[];
personalTypeOptions: Array<{ value: string; label: string }>;
onOk: () => void;
onCancel: () => void;
}> = ({ open, editing, saving, form, students, rooms, personalTypeOptions, onOk, onCancel }) => {
return (
<Modal
title={editing ? '编辑个人费用' : '录入个人附加费'}
open={open}
onOk={onOk}
onCancel={onCancel}
okText={editing ? '保存' : '确认录入'}
confirmLoading={saving}
>
<Form form={form} layout="vertical">
<Form.Item name="studentId" label="学生" rules={[{ required: true }]}>
<Select
showSearch
optionFilterProp="label"
options={students.map((s: any) => ({ value: s.id, label: s.name }))}
/>
</Form.Item>
<Form.Item name="roomId" label="关联宿舍">
<Select
allowClear
showSearch
optionFilterProp="label"
options={rooms.map((r: any) => ({ value: r.id, label: r.roomNumber }))}
/>
</Form.Item>
<Form.Item name="expenseType" label="费用类型" rules={[{ required: true }]}>
<Select options={personalTypeOptions} />
</Form.Item>
<Form.Item name="amount" label="金额(元)" rules={[{ required: true }]}>
<InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
</Form.Item>
<Form.Item name="expenseDate" label="费用日期" rules={[{ required: true }]}>
<DatePicker style={{ width: '100%' }} placeholder="选择日期" format="YYYY-MM-DD" />
</Form.Item>
<Form.Item name="description" label="说明">
<Input.TextArea rows={2} />
</Form.Item>
</Form>
</Modal>
);
};