forked from wangziqi/gongxue-base
feat: add rental_category/rate to Room, rental_type/tenant_id to Occupancy, tenant_id to Student
This commit is contained in:
@@ -34,6 +34,7 @@ const OccupanciesPage: React.FC = () => {
|
||||
const [data, setData] = useState<any[]>([]);
|
||||
const [students, setStudents] = useState<any[]>([]);
|
||||
const [rooms, setRooms] = useState<any[]>([]);
|
||||
const [tenants, setTenants] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [checkInModal, setCheckInModal] = useState(false);
|
||||
const [checkOutModal, setCheckOutModal] = useState<any>(null);
|
||||
@@ -52,14 +53,16 @@ const OccupanciesPage: React.FC = () => {
|
||||
const fetchData = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
const [occ, stu, rm]: any[] = await Promise.all([
|
||||
const [occ, stu, rm, tn]: any[] = await Promise.all([
|
||||
api.get('/occupancies', { params: { active: showActive ? 'true' : undefined } }),
|
||||
api.get('/students'),
|
||||
api.get('/rooms/overview'),
|
||||
api.get('/tenants'),
|
||||
]);
|
||||
setData(occ);
|
||||
setStudents(stu);
|
||||
setRooms(rm);
|
||||
setTenants(tn);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
@@ -89,6 +92,8 @@ const OccupanciesPage: React.FC = () => {
|
||||
roomId: values.roomId,
|
||||
checkInDate: values.checkInDate.format('YYYY-MM-DD'),
|
||||
billingStartDate: values.billingStartDate?.format('YYYY-MM-DD'),
|
||||
rentalType: values.rentalType,
|
||||
tenantId: values.tenantId,
|
||||
notes: values.notes,
|
||||
});
|
||||
message.success('入住登记成功');
|
||||
@@ -508,6 +513,28 @@ const OccupanciesPage: React.FC = () => {
|
||||
format="YYYY-MM-DD"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="rentalType" label="租赁类型">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: 'short', label: '短租' },
|
||||
{ value: 'long', label: '长租' },
|
||||
]}
|
||||
placeholder="默认为短租"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="tenantId" label="关联单位">
|
||||
<Select
|
||||
showSearch
|
||||
allowClear
|
||||
optionFilterProp="label"
|
||||
placeholder="选择关联单位"
|
||||
options={tenants.map((t: { id: number; name: string }) => ({
|
||||
value: t.id,
|
||||
label: t.name,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="notes" label="备注">
|
||||
<Input.TextArea rows={2} />
|
||||
</Form.Item>
|
||||
|
||||
@@ -422,6 +422,19 @@ const RoomsPage: React.FC = () => {
|
||||
placeholder="留空自动解析"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="rentalCategory" label="租赁类别">
|
||||
<Select
|
||||
allowClear
|
||||
options={[
|
||||
{ value: 'short', label: '短租' },
|
||||
{ value: 'long', label: '长租' },
|
||||
]}
|
||||
placeholder="默认为短租"
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name="monthlyRate" label="月租金">
|
||||
<InputNumber min={0} precision={2} style={{ width: '100%' }} placeholder="长租月租金" />
|
||||
</Form.Item>
|
||||
{editing && (
|
||||
<Form.Item name="status" label="状态">
|
||||
<Select
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from 'typeorm';
|
||||
import { Student } from './student.entity';
|
||||
import { Room } from './room.entity';
|
||||
import { Tenant } from './tenant.entity';
|
||||
|
||||
@Entity('occupancies')
|
||||
export class Occupancy {
|
||||
@@ -38,6 +39,16 @@ export class Occupancy {
|
||||
@Column({ type: 'text', nullable: true })
|
||||
notes: string;
|
||||
|
||||
@Column({ name: 'rental_type', length: 10, default: 'short' })
|
||||
rentalType: string;
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'integer', nullable: true })
|
||||
tenantId: number;
|
||||
|
||||
@ManyToOne(() => Tenant, { nullable: true })
|
||||
@JoinColumn({ name: 'tenant_id' })
|
||||
tenant: Tenant;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
@@ -28,6 +28,12 @@ export class Room {
|
||||
@Column({ length: 10, nullable: true })
|
||||
gender: string;
|
||||
|
||||
@Column({ name: 'rental_category', length: 10, default: 'short' })
|
||||
rentalCategory: string;
|
||||
|
||||
@Column({ name: 'monthly_rate', type: 'decimal', precision: 10, scale: 2, default: 0 })
|
||||
monthlyRate: number;
|
||||
|
||||
@CreateDateColumn({ name: 'created_at' })
|
||||
createdAt: Date;
|
||||
|
||||
|
||||
@@ -4,11 +4,14 @@ import {
|
||||
Column,
|
||||
CreateDateColumn,
|
||||
UpdateDateColumn,
|
||||
ManyToOne,
|
||||
JoinColumn,
|
||||
OneToMany,
|
||||
} from 'typeorm';
|
||||
import { Occupancy } from './occupancy.entity';
|
||||
import { PersonalExpense } from './personal-expense.entity';
|
||||
import { Bill } from './bill.entity';
|
||||
import { Tenant } from './tenant.entity';
|
||||
|
||||
@Entity('students')
|
||||
export class Student {
|
||||
@@ -54,6 +57,13 @@ export class Student {
|
||||
@OneToMany(() => Occupancy, (o) => o.student)
|
||||
occupancies: Occupancy[];
|
||||
|
||||
@Column({ name: 'tenant_id', type: 'integer', nullable: true })
|
||||
tenantId: number;
|
||||
|
||||
@ManyToOne(() => Tenant, { nullable: true })
|
||||
@JoinColumn({ name: 'tenant_id' })
|
||||
tenant: Tenant;
|
||||
|
||||
@OneToMany(() => PersonalExpense, (e) => e.student)
|
||||
personalExpenses: PersonalExpense[];
|
||||
|
||||
|
||||
@@ -17,6 +17,14 @@ export class CheckInDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
notes?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
rentalType?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsInt()
|
||||
tenantId?: number;
|
||||
}
|
||||
|
||||
export class CheckOutDto {
|
||||
|
||||
@@ -65,6 +65,8 @@ export class OccupanciesService {
|
||||
roomId: dto.roomId,
|
||||
checkInDate: dto.checkInDate,
|
||||
billingStartDate: dto.billingStartDate || dto.checkInDate,
|
||||
rentalType: dto.rentalType,
|
||||
tenantId: dto.tenantId,
|
||||
notes: dto.notes,
|
||||
});
|
||||
const saved = await this.repo.save(occ);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { IsString, IsOptional, IsInt, IsEnum, Min } from 'class-validator';
|
||||
import { IsString, IsOptional, IsInt, IsEnum, Min, IsNumber } from 'class-validator';
|
||||
|
||||
export class CreateRoomDto {
|
||||
@IsString()
|
||||
@@ -19,6 +19,14 @@ export class CreateRoomDto {
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
roomType?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
rentalCategory?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
monthlyRate?: number;
|
||||
}
|
||||
|
||||
export class UpdateRoomDto {
|
||||
@@ -50,4 +58,12 @@ export class UpdateRoomDto {
|
||||
@IsOptional()
|
||||
@IsEnum(['available', 'full', 'maintenance'])
|
||||
status?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsString()
|
||||
rentalCategory?: string;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
monthlyRate?: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user