feat: 重构各业务模块管理页面与服务
This commit is contained in:
166
apps/admin/src/pages/Expenses/ExpenseModals.tsx
Normal file
166
apps/admin/src/pages/Expenses/ExpenseModals.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
// 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>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user