18. 房地产房源展示系统(technical-architecture)
1. 架构设计
2. 技术描述
- 前端框架:React@18 + TypeScript + Vite
- UI组件库:Ant Design@5 + 自定义组件
- 状态管理:Zustand + React Query
- 地图集成:高德地图API / 百度地图API
- 3D/VR渲染:Three.js + React Three Fiber
- 图片处理:React Image Gallery + Sharp
- 样式方案:Tailwind CSS + Styled Components
- 初始化工具:vite-init
- 后端服务:Supabase (BaaS)
- 数据库:PostgreSQL (Supabase)
- 文件存储:Supabase Storage
- 认证授权:Supabase Auth
3. 路由定义
| 路由路径 | 页面名称 | 功能描述 |
|---|---|---|
| / | 房源地图展示页 | 地图模式浏览房源,支持区域筛选 |
| /listings | 房源列表页 | 列表模式展示房源,多条件筛选 |
| /listing/:id | 房源详情页 | 展示房源详细信息,3D/VR看房 |
| /agent/dashboard | 经纪人管理页 | 房源管理、客户管理、数据统计 |
| /appointment | 看房预约页 | 预约看房时间,选择经纪人 |
| /calculator | 贷款计算器页 | 计算房贷月供,对比还款方案 |
| /favorites | 房源收藏页 | 管理收藏房源,对比分析 |
| /login | 登录页 | 用户身份验证 |
| /register | 注册页 | 新用户注册 |
| /profile | 个人中心 | 用户信息管理 |
4. API定义
4.1 房源相关API
获取房源列表
GET /api/listings
请求参数:
| 参数名 | 类型 | 必需 | 描述 |
|---|---|---|---|
| page | number | false | 页码,默认1 |
| limit | number | false | 每页数量,默认20 |
| price_min | number | false | 最低价格 |
| price_max | number | false | 最高价格 |
| area_min | number | false | 最小面积 |
| area_max | number | false | 最大面积 |
| property_type | string | false | 房源类型 |
| district | string | false | 区域 |
| subway | string | false | 地铁线路 |
响应示例:
{
"data": [
{
"id": "uuid",
"title": "豪华三居室",
"price": 5800000,
"area": 128,
"property_type": "住宅",
"district": "朝阳区",
"images": ["url1", "url2"],
"location": {
"lat": 39.9042,
"lng": 116.4074
}
}
],
"total": 156,
"page": 1,
"limit": 20
}
获取房源详情
GET /api/listings/:id
创建预约
POST /api/appointments
请求参数:
| 参数名 | 类型 | 必需 | 描述 |
|---|---|---|---|
| listing_id | string | true | 房源ID |
| agent_id | string | true | 经纪人ID |
| appointment_date | string | true | 预约日期 |
| appointment_time | string | true | 预约时间 |
| notes | string | false | 备注信息 |
4.2 用户认证API
用户注册
POST /api/auth/register
用户登录
POST /api/auth/login
获取用户信息
GET /api/auth/me
5. 服务器架构图
6. 数据模型
6.1 数据模型定义
erDiagram
USER ||--o{ LISTING : favorites
USER ||--o{ APPOINTMENT : makes
USER ||--o{ AGENT : works_as
LISTING ||--o{ APPOINTMENT : has
LISTING ||--o{ PROPERTY_IMAGE : contains
AGENT ||--o{ APPOINTMENT : handles
USER {
uuid id PK
string email UK
string phone UK
string password_hash
string name
string avatar_url
string role
timestamp created_at
timestamp updated_at
}
LISTING {
uuid id PK
uuid agent_id FK
string title
text description
decimal price
integer area
string property_type
string property_status
string district
string address
decimal latitude
decimal longitude
integer bedrooms
integer bathrooms
integer floor
integer total_floors
string orientation
string decoration
integer year_built
json features
timestamp created_at
timestamp updated_at
}
PROPERTY_IMAGE {
uuid id PK
uuid listing_id FK
string image_url
string image_type
integer sort_order
boolean is_primary
timestamp created_at
}
APPOINTMENT {
uuid id PK
uuid user_id FK
uuid listing_id FK
uuid agent_id FK
date appointment_date
time appointment_time
string status
text notes
timestamp created_at
timestamp updated_at
}
AGENT {
uuid id PK
uuid user_id FK
string license_number
string company
string district
decimal rating
integer total_deals
json specialties
boolean is_verified
timestamp created_at
timestamp updated_at
}
6.2 数据定义语言
用户表 (users)
-- 创建用户表
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
phone VARCHAR(20) UNIQUE,
password_hash VARCHAR(255) NOT NULL,
name VARCHAR(100) NOT NULL,
avatar_url TEXT,
role VARCHAR(20) DEFAULT 'user' CHECK (role IN ('user', 'agent', 'admin')),
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 创建索引
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_phone ON users(phone);
房源表 (listings)
-- 创建房源表
CREATE TABLE listings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id UUID REFERENCES users(id) ON DELETE CASCADE,
title VARCHAR(200) NOT NULL,
description TEXT,
price DECIMAL(12,2) NOT NULL,
area INTEGER NOT NULL,
property_type VARCHAR(50) NOT NULL,
property_status VARCHAR(20) DEFAULT 'active' CHECK (property_status IN ('active', 'sold', 'rented', 'inactive')),
district VARCHAR(50) NOT NULL,
address TEXT NOT NULL,
latitude DECIMAL(10,8) NOT NULL,
longitude DECIMAL(11,8) NOT NULL,
bedrooms INTEGER DEFAULT 0,
bathrooms INTEGER DEFAULT 0,
floor INTEGER,
total_floors INTEGER,
orientation VARCHAR(20),
decoration VARCHAR(50),
year_built INTEGER,
features JSONB DEFAULT '[]',
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 创建索引
CREATE INDEX idx_listings_agent_id ON listings(agent_id);
CREATE INDEX idx_listings_price ON listings(price);
CREATE INDEX idx_listings_area ON listings(area);
CREATE INDEX idx_listings_district ON listings(district);
CREATE INDEX idx_listings_location ON listings(latitude, longitude);
CREATE INDEX idx_listings_status ON listings(property_status);
房源图片表 (property_images)
-- 创建房源图片表
CREATE TABLE property_images (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
listing_id UUID REFERENCES listings(id) ON DELETE CASCADE,
image_url TEXT NOT NULL,
image_type VARCHAR(20) DEFAULT 'interior' CHECK (image_type IN ('interior', 'exterior', 'floorplan', 'vr')),
sort_order INTEGER DEFAULT 0,
is_primary BOOLEAN DEFAULT FALSE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 创建索引
CREATE INDEX idx_property_images_listing_id ON property_images(listing_id);
CREATE INDEX idx_property_images_primary ON property_images(is_primary);
预约表 (appointments)
-- 创建预约表
CREATE TABLE appointments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
listing_id UUID REFERENCES listings(id) ON DELETE CASCADE,
agent_id UUID REFERENCES users(id) ON DELETE CASCADE,
appointment_date DATE NOT NULL,
appointment_time TIME NOT NULL,
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'completed', 'cancelled')),
notes TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- 创建索引
CREATE INDEX idx_appointments_user_id ON appointments(user_id);
CREATE INDEX idx_appointments_listing_id ON appointments(listing_id);
CREATE INDEX idx_appointments_agent_id ON appointments(agent_id);
CREATE INDEX idx_appointments_date ON appointments(appointment_date);
权限配置
-- 匿名用户权限
GRANT SELECT ON listings TO anon;
GRANT SELECT ON property_images TO anon;
-- 认证用户权限
GRANT ALL PRIVILEGES ON listings TO authenticated;
GRANT ALL PRIVILEGES ON property_images TO authenticated;
GRANT ALL PRIVILEGES ON appointments TO authenticated;
GRANT ALL PRIVILEGES ON users TO authenticated;
-- RLS策略示例
ALTER TABLE listings ENABLE ROW LEVEL SECURITY;
CREATE POLICY "用户只能查看活跃的房源" ON listings
FOR SELECT USING (property_status = 'active');
ALTER TABLE appointments ENABLE ROW LEVEL SECURITY;
CREATE POLICY "用户只能查看自己的预约" ON appointments
FOR SELECT USING (auth.uid() = user_id);
20大项目拆解:从PRD到架构 文章被收录于专栏
想独立做出一个完整的项目却不知从何下手?本专栏是你的终极路线图。我们由浅入深,通过20个经典项目案例,手把手带你走过产品构思、需求撰写、功能设计、技术选型、架构搭建的全过程。从“音乐播放器”到“企业后台”,你将逐步建立对软件系统的完整认知,完成从理论到实践、从单一技能到复合能力的飞跃。