feat: replace tenants with organization management

This commit is contained in:
2026-07-10 21:27:26 +08:00
parent 8ed1682b90
commit 8f0991a51f
49 changed files with 1292 additions and 698 deletions

View File

@@ -31,7 +31,7 @@ export const unavailableDatesCacheKey = (classroomId: number, date: Dayjs) =>
const ClassroomRentalsPage: React.FC = () => {
const [data, setData] = useState<any[]>([]);
const [classrooms, setClassrooms] = useState<any[]>([]);
const [tenants, setTenants] = useState<any[]>([]);
const [organizations, setOrganizations] = useState<any[]>([]);
const [loading, setLoading] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [editing, setEditing] = useState<any>(null);
@@ -50,8 +50,8 @@ const ClassroomRentalsPage: React.FC = () => {
const s = searchText.toLowerCase();
return data.filter((r: any) => {
const matchClassroom = r.classroom?.name?.toLowerCase().includes(s);
const matchTenant = r.tenant?.name?.toLowerCase().includes(s);
return matchClassroom || matchTenant;
const matchOrganization = r.lesseeOrganization?.name?.toLowerCase().includes(s);
return matchClassroom || matchOrganization;
});
}, [data, searchText]);
@@ -70,9 +70,12 @@ const ClassroomRentalsPage: React.FC = () => {
const fetchMeta = async () => {
try {
const [cr, tn]: any = await Promise.all([api.get('/classrooms'), api.get('/tenants')]);
const [cr, tn]: any = await Promise.all([
api.get('/classrooms'),
api.get('/organizations', { params: { scope: 'all' } }),
]);
setClassrooms(cr);
setTenants(tn);
setOrganizations(tn);
} catch (e: any) {
message.error(e?.message || '加载教室列表失败');
}
@@ -166,7 +169,8 @@ const ClassroomRentalsPage: React.FC = () => {
setSaving(true);
const payload = {
classroomId: values.classroomId,
tenantId: values.tenantId,
lessorOrganizationId: values.lessorOrganizationId,
lesseeOrganizationId: values.lesseeOrganizationId,
startDate: values.dateRange[0].format('YYYY-MM-DD'),
endDate: values.dateRange[1].format('YYYY-MM-DD'),
dailyRate: values.dailyRate,
@@ -188,7 +192,7 @@ const ClassroomRentalsPage: React.FC = () => {
} catch (e: any) {
if (e?.conflicts?.length) {
const list = e.conflicts
.map((c: any) => `${c.tenantName}(${c.startDate}~${c.endDate})`)
.map((c: any) => `${c.organizationName}(${c.startDate}~${c.endDate})`)
.join('、');
message.error(`时间段冲突:${list}`);
} else {
@@ -232,7 +236,8 @@ const ClassroomRentalsPage: React.FC = () => {
resetUnavailableDates();
form.setFieldsValue({
classroomId: record.classroomId,
tenantId: record.tenantId,
lessorOrganizationId: record.lessorOrganizationId,
lesseeOrganizationId: record.lesseeOrganizationId,
dateRange: [dayjs(record.startDate), dayjs(record.endDate)],
dailyRate: record.dailyRate ? Number(record.dailyRate) : undefined,
totalAmount: record.totalAmount ? Number(record.totalAmount) : undefined,
@@ -264,9 +269,9 @@ const ClassroomRentalsPage: React.FC = () => {
),
},
{
title: '租赁方',
title: '承租机构',
width: 100,
dataIndex: 'tenant',
dataIndex: 'lesseeOrganization',
render: (t: any) =>
t ? (
<Tag
@@ -392,7 +397,7 @@ const ClassroomRentalsPage: React.FC = () => {
>
<Space wrap>
<Input.Search
placeholder="搜索教室/租赁方"
placeholder="搜索教室/承租机构"
allowClear
style={{ width: 180 }}
onSearch={(v) => setSearchText(v)}
@@ -458,12 +463,35 @@ const ClassroomRentalsPage: React.FC = () => {
}))}
/>
</Form.Item>
<Form.Item name="tenantId" label="租赁方" rules={[{ required: true }]}>
<Form.Item name="lessorOrganizationId" label="出租机构" tooltip="默认由本机构出租">
<Select
showSearch
optionFilterProp="label"
placeholder="选择租赁方"
options={tenants.map((t) => ({ value: t.id, label: t.name }))}
placeholder="默认本机构"
allowClear
options={organizations
.filter((organization) => organization.isHost)
.map((organization) => ({
value: organization.id,
label: `${organization.name}(本机构)`,
}))}
/>
</Form.Item>
<Form.Item
name="lesseeOrganizationId"
label="承租机构"
rules={[{ required: true, message: '请选择承租机构' }]}
>
<Select
showSearch
optionFilterProp="label"
placeholder="选择外部承租机构"
options={organizations
.filter((organization) => !organization.isHost && organization.status === 'active')
.map((organization) => ({
value: organization.id,
label: organization.name,
}))}
/>
</Form.Item>
<Form.Item name="dateRange" label="租赁起止日期" rules={[{ required: true }]}>