Java开发全终端实战租房项目——项目介绍以及开发后台系统
时间:2022-11-19 07:00:01
好客租房
项目背景
近年来,中国经济的跨越式发展速度有目共睹。农村正在向城市化发展,农民积极走出家乡,致力于城市建设
因此,也促进了城市房地产和租赁业的新发展机遇。房屋租赁业的发展离不开房屋租赁政策的支持。
财政部、国家发展和改革委员会发布通知称,自2015年11月1日起,包括房屋租赁费在内的全国统一取消和暂停征收
自2016年1月1日起,取消人力资源和社会保障部门所属公共就业和人才服务机构的37项行政事业性收费
人才集体户籍管理服务费。上述费用取消或暂停征收后,有关部门及其所属事业单位依法投入管理职能资金
数量,安排中央政府合理的房屋租赁财务预算,确保工作顺利完成,各级政府相关价格管理部门应加强房地产市场
现场价格监控,消除不合理乱收费现象,坚决取缔超过政府公共机构,升级改革行政人员制度,使其精英化,
严格杜绝各种乱收费现象。
北京、上海外来人口众多,租房问题亟待解决,租房供不应求。根据数据分析,国内一线城市每年都在住房
需求高达650套。在第六次人口普及调查中,在北京、上海、广州和珠江三角洲发达地区,外来人口占成熟人口的比例
比例接近一半。2015年,北京和上海的平均家庭规模约为2.42人。根据房地产网站搜索的出租房屋数据,北京出租房屋
平均合租户数为2.04.按照一线城市标准,我国房屋租赁市场发展前景广阔
项目介绍
好客租房是一个直接促进房东与租户对接的生活服务平台。它包括房东发布房屋、租户多维度寻找房屋、智能匹配房屋
来源、近期市场查询等功能。降低中间环节产生的成本,提高房东与租户匹配的成功率。
采用好客租房项目SOA设计架构思想,采用架构思想SpringBoot、SpringMVC、Mybaits、Dubbo等实际的技术框架
现在,好客租房是一个直接促进房东与租户对接的生活服务平台。它包括房东发布房屋、租户多维度寻找房屋和智能匹配
房源、近期市场查询等功能。降低中间环节产生的成本,提高房东与租户匹配的成功率。
好客租房项目融合RPC、大数据等相技术,如SpringBoot、SpringMVC、Mybaits、Dubbo、React.js、
GraphQL、RocketMQ、Flume、ELK实现移动等技术web应用、微信小程序应用、后台管理应用等功能
技术架构
后端架构:SpringBoot StringMVC Dubbo Mybatis ELK 区块链
前端架构:React.js html5 百度地图 微信小程序
系统架构
构建后台系统
前端搭建
创建工程
第一步是在数据文件中itcast-haoke-manage-web.zip解压到指定目录(我的F:\code\itcast-haoke);
第二步,导入Idea中
第三步是将执行命令引入相关依赖
tyarn install #安装安装 #如果tyarn install安装失败(提示Integrity check failed for "antd" (computed integrity doesn't match our records),然后运行此命令 yarn --update-checksums tyarn start #启动服务
修改logo版权信息
全局布局文件在这里,打开代码,发现左边的菜单是自定义的组件
打开/components/SiderMenu文件:
在Footer.js修改文件中的版权信息:
左侧菜单
修改左侧菜单:
{
///住房管理 path: '/house', name: 'house', icon: 'home', routes: [ {
path: '/house/resource', name: 'resource', component: './haoke/House/Resource' }, {
path: '/house/addResource', name: 'addResource', component: './haoke/House/AddResource' }, {
path
:
'/house/kanfang'
,
name
:
'kanfang'
,
component
:
'./haoke/House/KanFang'
}
,
{
path
:
'/house/zufang'
,
name
:
'zufang'
,
component
:
'./haoke/House/ZuFang'
}
]
}
,
{
//房东管理
path
:
'/fangdong'
,
name
:
'fangdong'
,
icon
:
'key'
,
routes
:
[
{
path
:
'/fangdong/list'
,
name
:
'list'
,
component
:
'./haoke/FangDong/List'
}
]
}
,
{
//用户管理
path
:
'/users'
,
name
:
'users'
,
icon
:
'user'
,
routes
:
[
{
path
:
'/users/list'
,
name
:
'list'
,
component
:
'./haoke/Users/List'
}
]
}
,
{
//合约管理
path
:
'/heyue'
,
name
:
'heyue'
,
icon
:
'file-text'
,
routes
:
[
{
path
:
'/heyue/list'
,
name
:
'list'
,
component
:
'./haoke/HeYue/List'
}
]
}
,
{
//资讯管理
path
:
'/news'
,
name
:
'news'
,
icon
:
'message'
,
routes
:
[
{
path
:
'/news/list'
,
name
:
'list'
,
component
:
'./haoke/News/List'
}
]
}
,
{
//问答管理
path
:
'/qa'
,
name
:
'qa'
,
icon
:
'question-circle'
,
routes
:
[
{
path
:
'/news/list'
,
name
:
'list'
,
component
:
'./haoke/News/List'
}
]
}
,
{
//财务管理
path
:
'/finance'
,
name
:
'finance'
,
icon
:
'money-collect'
,
routes
:
[
{
path
:
'/finance/bill'
,
name
:
'bill'
,
component
:
'./haoke/Finance/Bill'
}
,
{
path
:
'/finance/tixian'
,
name
:
'tixian'
,
component
:
'./haoke/Finance/TiXian'
}
]
}
,
{
//系统管理
path
:
'/system'
,
name
:
'system'
,
icon
:
'laptop'
,
routes
:
[
{
path
:
'/system/interface'
,
name
:
'interface'
,
component
:
'./haoke/System/Interface'
}
,
{
path
:
'/system/dict'
,
name
:
'dict'
,
component
:
'./haoke/System/Dict'
}
,
{
path
:
'/system/contract'
,
name
:
'contract'
,
component
:
'./haoke/System/Contract'
}
]
}
,
在src/pages目录下创建haoke文件夹,项目中的页面代码均放在此目录中:
修改,进入系统后,默认打开房源管理页面:
新增房源
数据结构
楼盘数据(estate)
字段 | 类型 | 备注 |
---|---|---|
id | Long | 楼盘id |
name | String | 楼盘名称 |
province | String | 所在省 |
city | String | 所在市 |
area | String | 所在区 |
address | String | 具体地址 |
year | String | 建筑年代 |
type | String | 建筑类型 |
propertyCost | String | 物业费 |
propertyCompany | String | 物业公司 |
developers | String | 开发商 |
created | datetime | 创建时间 |
updated | datetime | 更新时间 |
房源数据(houseResources)
字段 | 类型 | 备注 |
---|---|---|
id | Long | 房源id |
title | String | 房源标题,如:南北通透,两室朝南,主卧带阳台 |
estateId | Long | 楼盘id |
buildingNum | String | 楼号(栋) |
buildingUnit | String | 单元号 |
buildingFloorNum | String | 门牌号 |
rent | int | 租金 |
rentMethod | int | 租赁方式,1-整租,2-合租 |
paymentMethod | int | 支付方式,1-付一押一,2-付三押一,3-付六押一,4-年付押一,5-其它 |
houseType | String | 户型,如:2室1厅1卫 |
coveredArea | String | 建筑面积 |
useArea | String | 使用面积 |
floor | String | 楼层,如:8/26 |
orientation | int | 朝向:东、南、西、北 |
decoration | String | 装修,1-精装,2-简装,3-毛坯 |
facilities | String | 配套设施, 如:1,2,3 |
pic | String | 图片,最多5张 |
desc | String | 房源描述,如:出小区门,门口有时代联华超市,餐饮有川菜馆,淮南牛肉汤,黄焖鸡沙县小吃等;可到达亲水湾城市生活广场,里面有儿童乐园,台球室和康桥健身等休闲娱乐;生活广场往北沿御水路往北步行一公里就是御桥路,旁边就是御桥地铁站,地铁站商场… |
contact | String | 联系人 |
mobile | String | 手机号 |
time | int | 看房时间,1-上午,2-中午,3-下午,4-晚上,5-全天 |
propertyCost | String | 物业费 |
created | datetime | 创建时间 |
updated | datetime | 更新时间 |
编写页面“新增房源”
form组件
在页面中,通过@Form.create()对页面进行了包装,包装之后,会在this.props中增加form对象,该对象将包含有丰富的功能。
在from表单中,需要通过getFieldDecorator(表单数据双向绑定)方法进行包装注册,才能获取到其值
<FormItem {
...formItemLayout} label="支付方式">
{
getFieldDecorator('paymentMethod',{
initialValue:'1',rules:[{
required: true, message:"此项为必填项" }]})
(
<Select style={
{
width: '50%' }}>
<Option value="1">付一押一</Option>
<Option value="2">付三押一</Option>
<Option value="3">付六押一</Option>
<Option value="4">年付押一</Option>
<Option value="5">其它</Option>
</Select>
)}
</FormItem>
在getFieldDecorator的参数中可以增加校验规则
{
initialValue:'1',rules:[{
required: true, message:"此项为必填项" }]}
表单提交
表单的提交通过submit按钮完成,通过onSubmit方法进行拦截处理。
handleSubmit = e => {
const {
dispatch, form } = this.props;
e.preventDefault();
console.log(this.state.fileList);
form.validateFieldsAndScroll((err, values) => {
if (!err) {
if(values.facilities){
values.facilities = values.facilities.join(",");
}
if(values.floor_1 && values.floor_2){
values.floor = values.floor_1 + "/" + values.floor_2;
}
values.houseType = values.houseType_1 + "室" + values.houseType_2 + "厅"
+ values.houseType_3 + "卫" + values.houseType_4 + "厨"
+ values.houseType_2 + "阳台";
delete values.floor_1;
delete values.floor_2;
delete values.houseType_1;
delete values.houseType_2;
delete values.houseType_3;
delete values.houseType_4;
delete values.houseType_5;
dispatch({
type: 'form/submitRegularForm',
payload: values,
});
}
});
};
通过form.validateFieldsAndScroll()对表单进行校验,通过values获取表单中输入的值。通过dispatch()调用model中定义的方法。
自动完成
const estateMap = new Map([
['中远两湾城','1001|上海市,上海市,普陀区,远景路97弄'],
['上海康城','1002|上海市,上海市,闵行区,莘松路958弄'],
['保利西子湾','1003|上海市,上海市,松江区,广富林路1188弄'],
['万科城市花园','1004|上海市,上海市,闵行区,七莘路3333弄2区-15区'],
['上海阳城','1005|上海市,上海市,闵行区,罗锦路888弄']
]);
<FormItem {
...formItemLayout} label="楼盘名称">
<AutoComplete
style={
{
width: '100%' }}
dataSource={
this.state.estateDataSource}
placeholder="搜索楼盘"
onSelect={
(value, option)=>{
let v = estateMap.get(value);
this.setState({
estateAddress: v.substring(v.indexOf('|')+1),
estateId : v.substring(0,v.indexOf('|'))
});
}}
onSearch={
this.handleSearch}
filterOption={
(inputValue, option) => option.props.children.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}
/>
</FormItem>
handleSearch = (value)=>{
let arr = new Array();
if(value.length > 0 ){
estateMap.forEach((v, k) => {
if(k.startsWith(value)){
arr.push(k);
}
});
}
this.setState({
estateDataSource: arr
});
} ;
图片上传
图片上传通过自定义组件PicturesWall完成,在PicturesWall中,通过Upload组件实现
在代码实现中,需要解决的问题是:父组件如何获取子组件中的数据。
解决思路:父组件通过属性的方式进行引用子组件,在bind方法中改变this的引用为父组件,在子组件中,通过this.props获取传入的函数,进行调用,即可把数据传递到父组件中
<FormItem {
...formItemLayout} label="上传室内图">
<PicturesWall handleFileList={
this.handleFileList.bind(this)}/>
</FormItem>
handleChange = ({
fileList }) => {
this.setState({
fileList });
this.props.handleFileList(this.state.fileList);
}
handleFileList = (obj)=>{
console.log(obj, "图片列表");
}
源代码
链接:https://pan.baidu.com/s/1VJZwJdnMGNzeuWH4nbBDRw?pwd=3i3x
提取码:3i3x
–来自百度网盘超级会员V3的分享