src/views/Home/index.jsx
import React from 'react';
import { TabBar } from 'antd-mobile';
import { useNavigate, Outlet } from 'react-router-dom';
import { AppOutline, MessageOutline, UnorderedListOutline, UserOutline } from 'antd-mobile-icons';
const tabs = [
{
key: '/',
label: '首页',
icon: <AppOutline />,
},
{
key: '/home/list',
label: '找房',
icon: <UnorderedListOutline />,
},
{
key: '/home/news',
label: '资讯',
icon: <MessageOutline />,
},
{
key: '/home/my',
label: '我的',
icon: <UserOutline />,
},
];
function Home() {
const navigate = useNavigate()
const setRouteActive = (value) => {
navigate(value);
};
return (
<>
<Outlet />
<div className='bottom'>
<TabBar /* activeKey={pathname} */ onChange={value => setRouteActive(value)}>
{tabs.map(item => (<TabBar.Item key={item.key} icon={item.icon} title={item.label} />))}
</TabBar>
</div>
</>
);
}
export default Home;
src/views/Home/index.css
.header>.adm-search-bar-input-box {
height: 50px;
background-color: white;
margin-top: 50px;
margin-left: 70px;
}
.adm-swiper {
height: 212px;
width: 100%;
}
/*
.bottom {
position: fixed;
bottom: 0;
width: 100%;
background-color: white;
}*/
src/views/Home/HomeView/index.jsx
import React, { Component } from 'react'
import Swiper from '../Swiper'
import Icon from '../Icon'
import Msg from '../Msg'
import Team from '../Team'
export default class HomeView extends Component {
render() {
return (
<div>
<Swiper/>
<Icon/>
<Team/>
<Msg/>
</div>
)
}
}
src/views/Home/Icon/index.jsx
import React, { PureComponent } from 'react'
import './index.css'
export default class Icon extends PureComponent {
state = {
image:[
{id:1,name:'整租',img:'整租.png'},
{id:2,name:'合租',img:'合租.png'},
{id:3,name:'地图找房',img:'地图找房.png'},
{id:4,name:'去出租',img:'去出租.png'}
]
}
render() {
return (
<div className='icon'>
{this.state.image.map(i=>{
return <li key={i.id} onClick={()=>{
if(i.img.split('.')[0] == '去出租'){
if(sessionStorage.getItem('token')){
window.location.href = '/rent/add'
}
else{
window.location.href = '/login'
}
}
}}>
<img src={'/images/'+i.img} />
{i.name}
</li>
})}
</div>
)
}
}
src/views/Home/Icon/index.css
.header1 {
margin: 10px 0;
}
.icon {
display: flex;
text-align: center;
background-color: white;
}
.icon>li {
list-style: none;
width: 25%;
margin: 0 15px;
}
.icon>li img {
width: 60px;
height: 60px;
}
src/views/Msg/index.jsx
import React, { PureComponent } from 'react'
import './index.css'
import request from '../../../service/request'
export default class Msg extends PureComponent {
state = {
news: []
}
componentDidMount = () => {
request.get('/home/news').then(value => {
this.setState({
news: value.body
})
})
}
render() {
return (
<div className='msg'>
<h5 style={{ fontSize: '15px', marginLeft: '10px' }}>最新资讯</h5>
<div className='msg1'>
{this.state.news.map(i => {
return (
<li key={i.id}>
<img src={i.imgSrc} alt="" />
<div className='msg2'>
<h4>{i.title}</h4>
<label>{i.from}</label><a>{i.date}</a>
</div>
</li>
)
})}
</div>
</div>
)
}
}
src/views/Msg/index.css
.msg{
background-color: white;
}
.msg > .msg1 li{
list-style: none;
display: flex;
padding: 10px;
}
.msg img{
width: 30%;
height: 80px;
/* padding: 10px; */
}
.msg > .msg1{
width: 100%;
}
.msg2{
width: 65%;
margin-left: 10px;
}
.msg h5{
padding: 10px 10px 5px 10px;
margin-bottom: 0;
}
.msg2 h4{
font-size: 14px;
font-weight: bolder;
margin-top: 0px;
margin-bottom: 28px;
}
.msg2 a{
margin-left: 60%;
color: #100b0b56;
}
.msg2 label{
color: #100b0b56;
}
.msg1 > li:last-child > img{
padding-bottom: 50px;
}
src/views/Home/Swiper/index.jsx
import React, { useState } from 'react'
import { Swiper, SearchBar, Dropdown } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
//import Icon from '../Home/Icon'
import request from '../../../service/request'
import './index.css'
import { useEffect } from 'react'
export default function Home() {
const navigate = useNavigate()
const [todolist, setTodolist] = useState([])
useEffect(() => {
request.get('/home/swiper').then(values => {
setTodolist(values.body)
})
}, [])
let city = sessionStorage.getItem('city')
return (
<div className='header'>
<>
<Swiper autoplay>
{todolist.map((i, index) => {
return (
<Swiper.Item key={i.id}>
<img src={i.imgSrc} alt="" height='212px' width='100%'/>
</Swiper.Item>
)
})}
</Swiper>
</>
<div className='header11'>
<Dropdown onChange={() => {
navigate('/cities')
}}>
<Dropdown.Item key='sorter' title={city?city:'上海'} >
</Dropdown.Item>
</Dropdown>
<span></span>
</div>
<SearchBar placeholder='请输入小区或地址' />
<i className='iconfont icon-map' onClick={() => {
navigate('/map')
}}></i>
</div>
)
}
src/views/Home/Swiper/index.css
.header{
position: relative;
width: 100%;
}
.header11{
background-color: white;
}
.adm-search-bar{
width: 70%;
position: absolute;
top: 10px;
left: 16%;
/* background-color: white; */
}
.header11 > .adm-dropdown{
position: absolute;
top: -15px;
width: 100%;
}
.adm-dropdown-item .adm-dropdown-item-title{
padding-top: 8px;
margin-left: 5px;
}
.adm-swiper-item> span{
position: absolute;
top: 15px;
display: block;
background-color: #7d7c7c;
height: 20px;
width: 1px;
left: 15.5%;
}
.header11 > .adm-dropdown > .adm-dropdown-nav{
background-color: white;
height: 31px;
width: 55px;
position: absolute;
top: -20px;
left: 10px;
border-radius: 5px;
}
.header > .icon-map{
position: absolute;
top: 12px;
right: 20px;
font-size: 25px;
color: white;
}
src/views/Home/Team/index.jsx
import React, { PureComponent } from 'react'
import './index.css'
import request from '../../../service/request'
export default class Team extends PureComponent {
state = {
teams: []
}
componentDidMount = () => {
request.get('/home/groups').then(value => {
this.setState({
teams:value.body
})
})
}
render() {
return (
<div className='team'>
<h5 style={{ fontSize: '15px', marginLeft: '20px' }}>租房小组</h5>
<div className='team1'>
{this.state.teams.map(i => {
return <li key={i.id}>
<div className='team2'>
<h4>{i.title}</h4>
<span>{i.desc}</span>
</div>
<img src={i.imgSrc} alt="" />
</li>
})}
</div>
</div>
)
}
}
src/views/Home/Team/index.css
.team1{
display: flex;
align-items: center; /*对齐*/
flex-wrap: wrap;
}
.team1 > li{
justify-content: space-around;
list-style: none;
margin: 0 10px 10px 10px;
background-color: white;
width: 43%;
height: 80px;
}
.team1 > li > img{
width: 50px;
height: 50px;
float: right;
margin-top: -45px;
margin-right: 10px;
}
.team2{
padding: 0 0 0 10px;
}
.team2 > h4{
margin-bottom: 5px;
font-size: 14px;
}
.team2 > span{
font-size: 10px;
}
.team{
width: 100%;
}
src/views/Login/index.jsx
import React,{ useState } from 'react'
import './index.css'
import { NavBar, Input, Button } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
import request from '../../service/request'
// import PropTypes from 'prop-types'
function Login() {
const [name,setName] = useState()
const [pwd,setPwd] = useState()
const navigate = useNavigate()
async function islogin(){
const body = {
username:name,
password:pwd
}
console.log(body);
let data = await request.post('/user/login',body)
console.log(data);
if(data.status == 200){
sessionStorage.setItem('token',JSON.stringify(data.body.token))
sessionStorage.setItem('name',name)
navigate('/home/my')
}
}
return (
<div className='islogin'>
<div className='islogin-header'>
<NavBar onBack={() => {
navigate(-1)
}}>
账号登录
</NavBar>
</div>
<div className='islogin-search'>
<Input placeholder='请输入账号' value={name} onChange={(e)=>{
setName(e)
}}/>
<span></span>
<Input placeholder='请输入密码' value={pwd} onChange={(e)=>{
setPwd(e)
}}/>
<span></span>
</div>
<Button color='success' onClick={islogin}>登录</Button>
<p onClick={()=>{
console.log(1111)
}}>还没有账号,去注册~</p>
</div>
)
}
export default Login
src/views/Login/index.css
#root{
height: 100vh;
background-color: white;
}
.islogin > .islogin-header{
background-color: #f6f5f6;
}
/* .islogin > .login-header{
height: 10%;
}
.islogin > .login-search{
height: 40%;
} */
.islogin > .islogin-search{
width: 85%;
margin-top: 50px;
/* justify-content: center; */
margin-left: 25px;
}
.islogin-search > .adm-input > .adm-input-element::placeholder{
padding-left: 5px;
}
.islogin > .islogin-search > span{
display: block;
border: 2px solid #f4f4f4;
width: 95%;
margin: 0 auto;
margin-top: 10px ;
margin-bottom: 15px;
}
.islogin > .adm-button{
width: 95%;
margin-left: 10px;
margin-top: 20px;
padding: 10px 0;
}
.islogin{
width: 100%;
}
.islogin p{
text-align: center;
margin-top: 35px;
}
src/views/Cities/index.jsx
import React from 'react';
import { IndexBar, List, NavBar } from 'antd-mobile';
import { useEffect } from 'react';
import request from '../../service/request'
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
export default () => {
const [cities, setCities] = useState([])
const charCodeOfA = 'A'.charCodeAt(0);
const navigate = useNavigate()
const groups = Array(26)
.fill('')
.map((_, i) => ({
title: String.fromCharCode(charCodeOfA + i),
items: cities.reduce((arr, item) => {
if (item.pinyin[0].toUpperCase() == String.fromCharCode(charCodeOfA + i)) {
arr.push(item)
}
return arr
}, [])
}));
useEffect(() => {
request.get('/area/city?level=1').then(value => {
setCities(value.body)
})
}, [])
return (<div style={{ height: window.innerHeight }}>
<NavBar onBack={() => {
window.location.href = '/home'
}}>城市选择</NavBar>
<IndexBar>
{groups.map(group => {
const { title, items } = group;
return (
<IndexBar.Panel index={title} key={`标题${title}`}>
<List>
{items.map((item, index) => (
<List.Item key={index} onClick={() => {
console.log(item,'0000000000');
sessionStorage.setItem('city', item.label)
sessionStorage.setItem('cityid', item.value)
navigate(-1)
}}>
{item.label}
</List.Item>
))}
</List>
</IndexBar.Panel>);
})}
</IndexBar>
</div>);
};
src/views/Detail/index.jsx
import React, { useState } from 'react'
import { Swiper, Tag, NavBar, Toast } from 'antd-mobile'
//import Icon from '../Home/Icon'
import request from '../../service/request'
import './index.css'
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { Map } from 'react-bmapgl'
import { CustomOverlay } from 'react-bmapgl'
export default function Detail() {
const [todolist, setTodolist] = useState({})
const [todoimg, setTodoImg] = useState([])
const [tags, setTags] = useState([])
const [point, setPoint] = useState([])
const navigate = useNavigate()
const [bgr, setBgr] = useState()
const [bottom,setBottom] = useState('detail-bottom')
useEffect(() => {
request.get('/houses/' + window.location.pathname.split('/')[2]).then(values => {
console.log(values);
// console.log(values);
setTodolist(values.body)
setTodoImg(values.body.houseImg)
setTags(values.body.tags)
setPoint(values.body.oriented)
})
getmsg()
}, [])
async function getmsg() {
let { body } = await request.get('/user/favorites/' + window.location.pathname.split('/')[2])
setBgr(body.isFavorite)
}
async function show() {
if (sessionStorage.getItem('token')) {
if (bgr) {
let { description, status } = await request.delete('/user/favorites/' + todolist.houseCode)
console.log(description);
if (status == 200) {
setBgr(false)
}
}
else if (!bgr) {
let { description, status } = await request.post('/user/favorites/' + todolist.houseCode)
console.log(description);
if (status == 200) {
setBgr(true)
}
}
}
else {
navigate('/login')
}
if (!bgr) {
Toast.show({
content: '已收藏'
})
}
else if (bgr) {
Toast.show({
content: '取消收藏'
})
}
}
return (
<div className='detail' >
<NavBar onBack={() => {
navigate('/home/index')
}} style={{ color: 'white' }}>
{todolist.community}
</NavBar>
<Swiper autoplay>
{todoimg.map((i, index) => {
return (
<Swiper.Item key={index}>
<img src={i} alt="" height='212px' width='100%' />
</Swiper.Item>
)
})}
</Swiper>
<p>{todolist.title}</p>
{tags.map(i => {
return <Tag>{i}</Tag>
})}
<hr />
<div className='detail1'>
<span>
<p>{todolist.price}<a>/月</a></p>
<label>租金</label>
</span>
<span>
<p>{todolist.roomType}</p>
<label>房型</label>
</span>
<span>
<p>{todolist.size}平米</p>
<label>面积</label>
</span>
</div>
<hr />
<div className='detail2'>
<label>
装修:
</label>
{point.map(i => {
if (point.length >= 1) {
return (
<label>
朝向:<a>{i}</a>
</label>
)
} else if (point.length < 1) {
return (
<label>
朝向:<a>{i}、</a>
</label>
)
}
})}
<label>
楼层:<a>{todolist.floor}</a>
</label>
<label>
类型:<a>{todolist.floor}</a>
</label>
</div>
<hr />
<div className='detail3'>
<p>小区:<a>{todolist.community}</a></p>
<Map
center={new window.BMapGL.Point(116.35, 39.88)}
zoom={12}
>
<CustomOverlay position={new window.BMapGL.Point(116.35, 39.88)}>
{todolist.community}
</CustomOverlay>
</Map>
<label>房屋配套</label>
<hr />
<label>暂无数据</label>
<hr />
<label>房源概况</label>
</div>
<div className={bottom}>
<li onClick={() => show()}>
<img src={!bgr ? '/images/unstar.png' : '/images/star.png'} alt="" width='20px' height='20px' />
收藏
</li>
<li>
在线咨询
</li>
<li style={{ background: 'green', color: 'white' }}>
电话预约
</li>
</div>
</div>
)
}
.detail>p {
padding-left: 15px;
}
.detail > .adm-nav-bar > .adm-nav-bar-title{
color: black;
}
.detail{
position: relative;
}
.detail>.adm-tag {
margin-bottom: 2px;
background-color: #e1f5f8;
color: #39becd;
border: 0;
font-size: 10px;
margin-left: 15px;
}
.detail > .adm-nav-bar{
position: absolute;
top: 0;
background-color: white;
width: 100%;
z-index: 1000;
}
.detail1 {
display: flex;
flex-wrap: wrap;
justify-content: center;
margin-bottom: 15px;
}
.detail1 span {
text-align: center;
width: 30%;
font-size: 20px;
}
.detail1 p {
color: red;
margin-bottom: 0;
margin-top: 5px;
}
.detail1 p>a {
color: red;
font-size: 5px;
}
.detail1 span label {
color: rgb(134, 136, 138);
font-size: 10px;
}
.detail2 {
display: flex;
width: 100%;
flex-wrap: wrap;
justify-content: center;
}
.detail2 label{
width: 45%;
margin-left: 10px;
margin-top: 5px;
color: rgb(134, 136, 138);
}
.detail2 label a{
color: black;
}
.detail3 p{
color: rgb(113, 114, 116);
font-size: 15px;
margin-left: 15px;
}
.detail3 p a{
color: black;
}
.detail3 label{
margin-left: 15px;
}
.detail3 label:last-child{
font-weight: bolder;
}
.detail3 label:first-child{
font-weight: bolder;
}
.detail-bottom{
text-align: center;
position: relative;
display: flex;
height: 55px;
line-height: 55px;
width: 100%;
justify-content: center;
bottom: -18px;
}
.detail-bottom li{
list-style: none;
width: 33%;
background-color: rgb(245, 241, 241);
}
.detail3 > .bmap-container{
height: 80px;
}
src/views/Favorate/index.jsx
import React from 'react'
import { NavBar, Tag } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
import { useEffect, useState } from 'react'
import request from '../../service/request'
import './index.css'
export default function Favorate() {
const [showtodo, setShowTodo] = useState([])
const navigate = useNavigate()
function back() {
navigate('/home/my')
}
useEffect(() => {
getshow()
}, [])
async function getshow() {
let { body } = await request.get('/user/favorites')
setShowTodo(body)
}
return (
<div className='favorate'>
<NavBar onBack={back}>我的收藏</NavBar>
{showtodo.map(i => {
return <li key={i.houseCode} onClick={() => this.check(i.houseCode)}>
<div className='f-content1'>
<img src={i.houseImg} alt="" />
<div className='f-content11'>
<h3>{i.title}</h3>
<p>{i.desc}</p>
<Tag>{i.tags}</Tag>
<br />
<label>{i.price}</label><a>元/月</a>
</div>
</div>
<span></span>
</li>
})}
</div>
)
}
.favorate > li {
list-style: none;
width: 100%;
}
.favorate > li > .f-content1{
width: 100%;
display: flex;
}
.favorate > li > .f-content1 > img{
width: 100px;
height: 80px;
margin: 10px;
}
.favorate > li:last-child > .f-content1 > img{
padding-bottom: 50px;
}
.favorate > li > .f-content1 > .content11{
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.favorate > li > .f-content1 > .f-content11 h3{
margin-top: 10px;
margin-bottom: -5px;
}
.favorate > li > .f-content1 > .f-content11 p{
font-size: 10px;
color: #080e1037;
margin: 5px 0 8px 0;
}
.favorate > li > .f-content1 > .f-content11 label{
font-size: 18px;
color: rgb(233, 60, 60);
font-weight: bolder;
}
.favorate > li > .f-content1 > .f-content11 > a{
color: rgb(233, 60, 60);
padding-left: 5px;
}
src/views/Map/index.jsx
import { Map } from 'react-bmapgl'
import React, { PureComponent } from 'react'
import { CustomOverlay } from 'react-bmapgl'
import { Tag, NavBar, SearchBar } from 'antd-mobile'
import './index.css'
import { Popup } from 'react-vant'
import request from '../../service/request'
export default class Maps extends PureComponent {
state = {
city: sessionStorage.getItem('city'),
childCity: [],
zoom: 10,
poup: '',
poupstate: false,
pouplist: []
}
componentDidMount = () => {
this.getCity()
console.log(this.state.childCity);
}
getCity = async () => {
let { body } = await request.get('/area/map?id=' + sessionStorage.getItem('cityid'))
console.log(body,'map00000000');
this.setState({
childCity: body
})
}
firstLevel = async (i) => {
console.log(i,'firstLevel');
sessionStorage.setItem('cityid', i.value)
let { body } = await request.get('/area/map?id=' + i.value)
this.setState({
childCity: body,
city: new window.BMapGL.Point(i.coord.longitude, i.coord.latitude),
zoom: this.state.zoom + 2
})
}
endLevel = async (i) => {
let { body } = await request.get('/houses?cityId=' + i.value)
console.log(body.list);
this.setState({
poup: 'bottom',
poupstate: true,
pouplist: body.list
})
}
back = () => {
window.location.href = '/home/index'
}
DOM = () => {
if (this.state.zoom < 13) {
return this.state.childCity.map(i => {
return <CustomOverlay position={new window.BMapGL.Point(i.coord.longitude, i.coord.latitude)}>
<div className="custom" style={{ width: 80, height: 80, background: 'rgba(12,181,106,.9)', borderRadius: '50%', textAlign: 'center' }} onClick={() => this.firstLevel(i)}>
<span style={{ color: '#fff' }}>{i.label}</span>
<p>{i.count}</p>
</div>
</CustomOverlay>
})
}
else {
return this.state.childCity.map(i => {
return <CustomOverlay position={new window.BMapGL.Point(i.coord.longitude, i.coord.latitude)}>
<div className="customs" style={{ width: 60, height: 20, background: 'rgba(12,181,106,.9)', borderRadius: '5px', textAlign: 'center' }} onClick={() => this.endLevel(i)}>
<span style={{ color: '#fff' }}>{i.label}</span>
<p>{i.count}</p>
</div>
</CustomOverlay>
})
}
}
onClose = () => {
this.setState({
poup: ''
})
}
check = (id) => {
window.location.href = '/detail/' + id
}
render() {
let { city, zoom } = this.state
return (
<div className='map'>
<NavBar onBack={this.back}>
找图找房
</NavBar>
<Map
center={city}
zoom={zoom}
tilt={40}
style={{ height: '855px' }}
>
{this.DOM()}
</Map>
<Popup
visible={this.state.poupstate}
style={{ height: '30%' }}
position='bottom'
onClose={this.onClose}
>
{this.state.pouplist.map(i => {
return <li key={i.houseCode} onClick={() => this.check(i.houseCode)}>
<div className='map1'>
<img src={i.houseImg} alt="" />
<div className='map11'>
<h3>{i.title}</h3>
<p>{i.desc}</p>
<Tag>{i.tags}</Tag>
<br />
<label>{i.price}</label><a>元/月</a>
</div>
</div>
<span></span>
</li>
})}
</Popup>
</div>
)
}
}
.rv-popup{
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.rv-popup > li{
width: 80%;
list-style: none;
}
.rv-popup > li img{
width: 40%;
}
.rv-popup li{
list-style: none;
width: 100%;
margin-top: 20px;
}
li > .map1{
width: 100%;
display: flex;
}
li > .map1 > img{
width: 100px;
height: 80px;
margin: 10px;
}
li:last-child > .map1 > img{
padding-bottom: 50px;
}
li > .map1 > .map11{
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
li > .map1 > .map11 h3{
margin-top: 10px;
margin-bottom: -5px;
}
li > .map1 > .map11 p{
font-size: 10px;
color: #10080837;
margin: 5px 0 8px 0;
}
li > .map1 > .map11 label{
font-size: 18px;
color: rgb(233, 60, 60);
font-weight: bolder;
}
li > .map1 > .map11 > a{
color: rgb(233, 60, 60);
padding-left: 5px;
}
li > .map1 > span{
display: block;
border: 1px solid rgb(226, 218, 218);
width: 100%;
}
.map11 > .adm-tag{
margin-bottom: 2px;
background-color: #e1f5f8;
color: #39becd;
border: 0;
font-size: 13px;
}
/* .adm-dropdown-nav{
position: fixed;
background-color: white;
width: 100%;
margin-top: 0;
} */
src/views/My/index.jsx
import React, { PureComponent } from 'react'
import './index.css'
import { Button } from 'antd-mobile'
export default class My extends PureComponent {
state = {
icons:[
{id:1,title:'我的收藏',icon:'iconfont icon-coll'},
{id:2,title:'我的出租',icon:'iconfont icon-ind'},
{id:3,title:'看房记录',icon:'iconfont icon-record'},
{id:4,title:'成为房主',icon:'iconfont icon-identity'},
{id:5,title:'个人资料',icon:'iconfont icon-myinfo'},
{id:6,title:'联系我们',icon:'iconfont icon-cust'}
]
}
isLogin = ()=>{
window.location.href = '/login'
}
show = (i) => {
if(i.title == '我的收藏'){
window.location.href = '/favorate'
}
}
render() {
let user = sessionStorage.getItem('token')
let name = sessionStorage.getItem('name')
return (
<div className='my'>
<div className='my-bgr'>
<img src='/myImg/bg.png' alt="" style={{height:'212px',width:'100%'}} />
<div className='my-login'>
{user?<img src={user} alt="" />:<img src="/myImg/avatar.png" alt="" />}
<p>{user?name:'游客'}</p>
{user?<Button color='success' onClick={()=>{
sessionStorage.clear('token')
window.location.href = '/home/my'
}}>退出</Button>
:<Button color='success' onClick={this.isLogin}>去登录</Button>}
<br />
{user?<span className='edit'>编辑个人资料</span>:''}
</div>
</div>
<div className='my-icon'>
{this.state.icons.map(i=>{
return <li key={i.id} onClick={()=>this.show(i)}>
<i className={i.icon} style={{width:'50px',height:'50px'}}></i>
{i.title}
</li>
})}
</div>
<div className='my-footer'>
<img src="/myImg/join.png" alt="" style={{height:'150',width:'100%'}} />
</div>
</div>
)
}
}
.my{
height: 100vh;
position: relative;
}
.my > .my-bgr{
height: 58%;
}
.my > .my-bgr > .my-login {
background-color: white;
width: 85%;
height: 25%;
position: absolute;
top: 22%;
left: 8%;
box-shadow: 0 2px 2px #bdbdbd;
}
.my > .my-bgr > .my-login > p{
margin-top: 50px;
margin-left: 45%;
}
.my > .my-bgr > .my-login >.adm-button{
display: block;
margin: 0 auto;
text-align: center;
font-size: small;
}
.my > .my-bgr > .my-login img{
border-radius: 50%;
border: 5px solid #f5f5f5;
box-shadow: 0 2px 2px #bdbdbd;
width: 60px;
height: 60px;
position: absolute;
right: 40%;
top: -20%;
}
.my > .my-footer{
position: absolute;
bottom: 80px;
width: 90%;
margin: 0 20px;
}
.my > .my-icon{
text-align: center;
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.my > .my-icon > li{
list-style: none;
width: 30%;
margin-bottom: 50px;
}
.my-login > .edit{
display: block;
margin: 10px 120px;
}
src/views/Nd/index.jsx
import React, { PureComponent } from 'react'
import { NavBar, Dropdown, Tag, SearchBar, CascadePickerView, Popup, Button, Picker, Toast } from 'antd-mobile'
// import { useNavigate } from 'react-router-dom'
import request from '../../service/request'
import { ArrowDownCircleOutline, DownOutline } from 'antd-mobile-icons'
import { Drawer } from 'antd'
// import { ArrowDownCircleOutline, DownOutline } from 'antd-mobile-icons'
import './index.css'
import { DropdownMenu } from 'react-vant'
const option1 = [
{ text: '全部商品', value: 0 },
{ text: '新款商品', value: 1 },
{ text: '活动商品', value: 2 },
]
const option2 = [
{ text: '不限', value: 'null' },
{ text: '整租', value: 'true' },
{ text: '合租', value: 'false' }
]
const option3 = [
{ text: '不限', value: 'null' },
{ text: '1000及以下', value: 'PRICE|1000' },
{ text: '1000 - 2000', value: 'PRICE|2000' },
{ text: '2000 - 3000', value: 'PRICE|3000' },
{ text: '3000 - 4000', value: 'PRICE|4000' },
{ text: '4000 - 5000', value: 'PRICE|5000' },
{ text: '5000 - 7000', value: 'PRICE|7000' },
{ text: '7000以上', value: 'PRICE|100001' }
]
const columns = [
{ text: '南京', value: 0 },
{ text: '苏州', value: 1 },
{ text: '常州', value: 2 },
{ text: '淮安', value: 3 },
{ text: '扬州', value: 4 },
{ text: '南通', value: 5 },
{ text: '宿迁', value: 6 },
{ text: '泰州', value: 7 },
{ text: '无锡', value: 8 },
{ text: '长沙', value: 9 },
]
export default class Nd extends PureComponent {
state = {
houses: [],
dropdowns: '',
value: ['周二', '晚上'],
poup: false,
value: [],
city: sessionStorage.getItem('city'),
cityarea: [],
cityprice: [],
citytype: [],
cityroom: [],
open: false,
methods: '',
value: '',
cities: [],
states: 'right'
}
componentDidMount = async () => {
let { body: { list } } = await request.get('/houses')
console.log(list, '77777777777777');
this.setState({
houses: list
})
this.getAll();
this.getAreas();
window.addEventListener('scroll', this.handleScroll, true)
}
componentWillUnmount() {
window.removeEventListener('scroll', this.handleScroll, true)
}
getAreas = () => {
request.get('/area/city?level=1').then(value => {
// setCities(value.body)
console.log(value, '000000');
this.setState({
cities: value
})
})
}
getAll = async () => {
let { body: { area: { children }, characteristic, floor, oriented, price, rentType, roomType, subway, code } } = await request.get('/houses/condition?id=' + sessionStorage.getItem('cityid'))
console.log(children, characteristic, floor, oriented, price, rentType, roomType, subway);
this.setState({
cityarea: children,
cityprice: price,
citytype: rentType,
cityroom: roomType
})
}
handleScroll = () => {
//距离顶部的高度
// console.log(document.documentElement.scrollTop);
if (document.documentElement.scrollTop >= 82.6) {
this.setState({
dropdowns: 'dropdowns'
})
}
else if (document.documentElement.scrollTop < 82.6) {
this.setState({
dropdowns: ''
})
}
}
back = () => {
window.location.href = '/home/index'
}
check = (id) => {
window.location.href = '/detail/' + id
}
poups = () => {
this.setState({
poup: 'right'
})
}
onClose = () => {
this.setState({
open: true
})
};
search = () => {
console.log('找到20套房源');
}
changeFields = async (e) => {
if (e['rentType'] && e['price']) {
let { body: { list } } = await request.get('/houses?rentType=' + e['rentType'] + '&price=' + e['price'])
console.log(list, '99999999999999999');
this.setState({
houses: list
})
}
if (e['rentType']) {
let { body: { list } } = await request.get('/houses?rentType=' + e['rentType'])
console.log(list, '77777777777777');
this.setState({
houses: list
})
}
if (e['price']) {
let { body: { list } } = await request.get('/houses?price=' + e['price'].split('|')[1])
console.log(list, '888888888888');
this.setState({
houses: list
})
}
}
render() {
return (
<div className='nd'>
<div className='nd-header11'>
<Dropdown onChange={() => {
window.location.href = '/cities'
}}>
<Dropdown.Item key='sorter' title={this.state.city ? this.state.city : '上海'} >
</Dropdown.Item>
</Dropdown>
<span></span>
</div>
<NavBar onBack={this.back}>
<SearchBar placeholder='请输入小区或地址' />
</NavBar>
<i className='iconfont icon-map' onClick={() => {
window.location.href = '/map'
}}></i>
{/* <Dropdown arrow={<DownOutline />} onChange={e => console.log(e)}>
<Dropdown.Item key='value1' title='区域'>
</Dropdown.Item>
<Dropdown.Item
key='rentType'
title='方式'
arrow={<ArrowDownCircleOutline />}
>
<div style={{ padding: 12 }}>
{option2.map(i => {
return <p
onClick={() => console.log(i, '00')}>{i.text}</p>
})}
</div>
</Dropdown.Item>
<Dropdown.Item key='price' title='租金'>
<div style={{ padding: 12 }}>
{option3.map(i => {
return <p>{i.text}</p>
})}
</div>
</Dropdown.Item>
<Dropdown.Item key='sx' title='筛选'>
<div style={{ padding: 12 }}>
{option3.map(i => {
return <p>{i.text}</p>
})}
</div>
</Dropdown.Item>
</Dropdown> */}
<DropdownMenu
activeColor='#f44336'
onChange={(e) => this.changeFields(e)}
// value={this.state.value}
// onChange={v => this.setState({ value: v })}
>
<DropdownMenu.Item name='value1' title='区域' options={option1}>
{/* <Picker value={value} onChange={setValue} columns={cascaderData} columnsFieldNames={{
}}/> */}
</DropdownMenu.Item>
<DropdownMenu.Item name='rentType' title='方式' options={option2} />
<DropdownMenu.Item name='price' title='租金' options={option3} />
<DropdownMenu.Item name='筛选' title='筛选'>
<Popup
visible={this.state.states === 'right'}
style={{ width: '30%', height: '100%' }}
position='right'
description='11111'
// onClose={onClose}
/>
</DropdownMenu.Item>
</DropdownMenu>
<Drawer
placement='right'
// closable={false}
// onClose={this.onClose}
open={this.state.open}
// key='right'
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
<Popup
visible={this.state.poup}
onMaskClick={() => {
this.setState({
poup: true
})
}}
position='right'
bodyStyle={{ width: '200%' }}
>
右侧
</Popup>
<div className='content'>
{this.state.houses.map((i, index) => {
return (
<li key={index} onClick={() => this.check(i.houseCode)}>
<div className='content1'>
<img src={i.houseImg} alt="" />
<div className='content11'>
<h3>{i.title}</h3>
<p>{i.desc}</p>
<Tag>{i.tags}</Tag>
<br />
<label>{i.price}</label><a>元/月</a>
</div>
</div>
<span></span>
</li>
)
})}
</div>
</div>
)
}
}
.nd{
position: relative;
width: 100%;
text-align: center;
background-color: white;
}
.nd> .content{
margin-top: 50px;
}
.nd> .content > li {
list-style: none;
width: 100%;
}
.nd > .content > li > .content1{
width: 100%;
display: flex;
}
.nd > .content > li > .content1 > img{
width: 100px;
height: 80px;
margin: 10px;
}
.nd > .content > li:last-child > .content1 > img{
padding-bottom: 50px;
}
.nd > .content > li > .content1 > .content11{
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.nd > .content > li > .content1 > .content11 h3{
margin-top: 10px;
margin-bottom: -5px;
}
.nd > .content > li > .content1 > .content11 p{
font-size: 10px;
color: #10080837;
margin: 5px 0 8px 0;
}
.nd > .content > li > .content1 > .content11 label{
font-size: 18px;
color: rgb(233, 60, 60);
font-weight: bolder;
}
.nd > .content > li > .content1 > .content11 > a{
color: rgb(233, 60, 60);
padding-left: 5px;
}
.nd > .content > li > span{
display: block;
border: 1px solid rgb(226, 218, 218);
width: 100%;
}
.content11 > .adm-tag{
margin-bottom: 2px;
background-color: #e1f5f8;
color: #39becd;
border: 0;
font-size: 13px;
}
.nd > .dropdowns{
position: fixed !important;
width: 100% !important;
padding: 5px;
margin-top: -50px !important;
}
.adm-dropdown{
width: 100%;
margin-top: 45px;
}
/* .adm-dropdown-nav{
position: fixed;
background-color: white;
width: 100%;
margin-top: 0;
} */
.nd > .adm-dropdown{
margin-top: 0 !important;
}
.nd > .content{
margin-top: 0 !important;
}
.dropdowns{
position: absolute;
top: 0;
}
.nd-header11{
background-color: white;
}
.nd-header11 > .adm-dropdown{
position: absolute;
top: -15px;
width: 100%;
}
.nd-header11 > .adm-dropdown > .adm-dropdown-nav{
background-color: white;
height: 31px;
width: 55px;
position: absolute;
top: -20px;
left: 25px;
border-radius: 5px;
}
.nd > .adm-search-bar{
margin-left: 20px;
}
.nd > .icon-map{
position: absolute;
top: 12px;
right: 10px;
font-size: 25px;
color: rgb(28, 198, 54);
}
.area > .adm-button,.method > .adm-button,.price > .adm-button{
width: 50%;
}
src/views/Poup/index.jsx
import React, { useState } from 'react'
import { Cell, Popup, } from 'react-vant'
export default () => {
const [state, setState] = useState('')
const onClose = () => setState('')
return (
<>
<Cell title='顶部弹出' isLink onClick={() => setState('top')} />
<Cell title='底部弹出' isLink onClick={() => setState('bottom')} />
<Cell title='左侧弹出' isLink onClick={() => setState('left')} />
<Cell title='右侧弹出' isLink onClick={() => setState('right')} />
<Popup
visible={state === 'top'}
style={{ height: '30%' }}
position='top'
onClose={onClose}
/>
<Popup
visible={state === 'bottom'}
style={{ height: '30%' }}
position='bottom'
onClose={onClose}
/>
<Popup
visible={state === 'left'}
style={{ width: '30%', height: '100%' }}
position='left'
onClose={onClose}
/>
<Popup
visible={state === 'right'}
style={{ width: '30%', height: '100%' }}
position='right'
onClose={onClose}
/>
</>
)
}
src/views/Product/index.jsx
import React, { PureComponent } from 'react'
export default class Product extends PureComponent {
render() {
return (
<div>
Product
</div>
)
}
}
src/views/Rent/Add/index.jsx
import React,{useRef} from 'react'
import { NavBar } from 'antd-mobile'
import { useNavigate } from 'react-router-dom'
import './index.css'
import {
Button,
Input,
Uploader,
Form,
Picker
} from 'react-vant'
export default function Add() {
const navigate = useNavigate()
const [form] = Form.useForm()
const prices = useRef()
const sizes = useRef()
const onFinish = values => {
console.log(form.getFieldsValue());
}
// const onFinish = (values: any) => {
// Dialog.alert({
// content: <pre>{JSON.stringify(values, null, 2)}</pre>,
// })
// }
return (
<div className='rent-add'>
<NavBar onBack={() => {
navigate(-1)
}}>
发布房源
</NavBar>
<Form
colon
form={form}
onFinish={onFinish}
footer={
<div style={{ margin: '16px 16px 0' }}>
<Button round nativeType='submit' type='primary' block>
提交
</Button>
</div>
}
>
<Form.Item
isLink
name='community'
label='小区名称'
trigger='onConfirm'
onClick={() => {
navigate('/rent/search')
}}
>
<Picker
popup
columns={[]}
>
{val => val || '请输入小区名称'}
</Picker>
</Form.Item>
<Form.Item name='prices' label='租金'>
<Input placeholder='请输入租金'/>¥/月
{/* <Input/> */}
</Form.Item>
<Form.Item name='sizes' label='建筑面积'>
<Input placeholder='请输入建筑面积'/>m²
{/* <Input /> */}
</Form.Item>
<Form.Item
isLink
name='roomType'
label='户型'
trigger='onConfirm'
onClick={(_, action) => {
action.current?.open()
}}
>
<Picker
popup
columns={[
'一室',
'二室',
'三室',
'四室',
'四室+',
]}
values={[
]}
>
{val => val || '请选择'}
</Picker>
</Form.Item>
<Form.Item
isLink
name='floor'
label='所在楼层'
trigger='onConfirm'
onClick={(_, action) => {
action.current?.open()
}}
>
<Picker
popup
columns={[
'高楼层',
'中楼层',
'低楼层'
]}
>
{val => val || '请选择'}
</Picker>
</Form.Item>
<Form.Item
isLink
name='oriented'
label='朝向'
trigger='onConfirm'
onClick={(_, action) => {
action.current?.open()
}}
>
<Picker
popup
columns={[
'东',
'西',
'南',
'北',
'东南',
'东北',
'西南',
'西北'
]}
>
{val => val || '请选择'}
</Picker>
</Form.Item>
<Form.Item name='title' label='房屋标题'>
<Input.TextArea rows={3} autoSize maxLength={140} showWordLimit placeholder='请输入标题'/>
</Form.Item>
<Form.Item
name='uploader'
label='房屋图像'
>
<Uploader />
</Form.Item>
<Form.Item
name='supporting'
label='房屋配置'
>
</Form.Item>
<Form.Item
name='description'
label='房屋描述'
>
<Input.TextArea rows={3} autoSize maxLength={140} showWordLimit placeholder='请输入房屋描述信息'/>
</Form.Item>
</Form>
</div>
)
}
.rent-add{
background-color: #f6f5f6;
}
src/views/Rent/Search/index.jsx
import React from 'react'
import { useNavigate } from 'react-router-dom';
import { NavBar, Search } from 'react-vant'
import request from '../../../service/request'
export default function RSearch() {
const navigate = useNavigate()
async function search(e) {
let data = await request.get('/area/info?name='+e)
console.log(data);
}
function back(){
navigate(-1)
}
return (
<div>
<NavBar leftArrow={false} backArrow={false} title={<Search placeholder="请输入搜索关键词" onSearch={e=>search(e)}/>} rightText='取消' onClickRight={back}>
</NavBar>
</div>
)
}