好客租房App显示页面

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>
    )
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值