230320a303 11 months ago
parent
commit
b2932bb9fd

+ 3 - 0
src/api/room.js

@@ -81,6 +81,9 @@ export default {
   apieshouserecordlist: params => { // 二手房 房源 房源跟进列表
     return request('/api/eshouse/record/list', params, 'loading')
   },
+  apieshouserecordadd: params => { // 二手房 房源 房源跟进 添加
+    return request('/api/eshouse/record/add', params, 'loading')
+  },
   apirenthouselist: params => { // 二手房 出租 列表
     return request('/api/rent/house/list', params, 'loading')
   },

+ 2 - 0
src/app.jsx

@@ -139,6 +139,7 @@ class App extends Component {
         pages: [
           'estate',
           'list',
+          'list2',
           'listMy',
           'listed',
           'rentlist',
@@ -155,6 +156,7 @@ class App extends Component {
           'follow/list',
           'follow/user',
           'follow/room',
+          'follow/roomAdd',
           'follow/add',
           'follow/history',
           'follow/lineup',

+ 18 - 0
src/assets/css/search-top.scss

@@ -52,6 +52,9 @@
     &.col-1 {
       width: 100%;
     }
+    &.col-2 {
+      width: 50%;
+    }
     &.col-3 {
       width: 33.33%;
     }
@@ -67,6 +70,14 @@
       }
     }
     &.cur {
+      &.col-2 {
+        .stn-label {
+          width: 100%;
+        }
+        .stn-sign {
+          display: none;
+        }
+      }
       .stn-label {
         color: $mainColor;
       }
@@ -108,6 +119,13 @@
         height: calc(450px + 300px);
       }
     }
+    &.show2 {
+      height: 340px;
+      border-bottom: 1PX solid #f2f2f2;
+      &.more {
+        height: calc(340px + 300px);
+      }
+    }
   }
   .stc-wrap {
     display: flex;

BIN
src/assets/img/icon_upload_audio.png


+ 9 - 8
src/pagesHouse/indexDtl.jsx

@@ -176,7 +176,8 @@ class Index extends Component {
         // if (this.subChat) this.subChat.getData(curObj.estate_sale || [], {name: curObj.estate_name, id: curObj.id})
         if (this.subChat) this.subChat.getData({name: curObj.estate_name, id: curObj.id}, 'estateDtl')
         if (this.subMoreHouse) this.subMoreHouse.getData(curObj.estate_compete || [])
-        if (this.subRooms) this.subRooms.getData(curObj.old_house_list || [])
+        let roomlist = curObj.old_house_list || []
+        if (this.subRooms) this.subRooms.getData(roomlist.length > 1 ? roomlist.slice(0, 2) : roomlist)
         if (this.subChannel) this.subChannel.getData(curObj.estate_channel || [])
         if (bc) bc()
       })
@@ -364,7 +365,7 @@ class Index extends Component {
         {
           curObj.estate_tag === '二手'
           ?
-          <Navigator url={`/pagesRoom/list?estate_id=${curId}&estate_name=${curObj.estate_name}`} className="de-op">
+          <Navigator url={`/pagesRoom/list2?estate_id=${curId}&estate_name=${curObj.estate_name}`} className="de-op">
             <Image className="i" src={icon2} />
             <View className="t">二手房源</View>
           </Navigator>
@@ -760,7 +761,7 @@ class Index extends Component {
       <View className="dtl-options">
         <View className="do-title">
           <View className="t">洪楼房源</View>
-          <Navigator url={'/pagesRoom/list?estate_id=' + curObj.id + '&estate_name=' + curObj.estate_name} className="r">查看更多{' >'}</Navigator>
+          <Navigator url={'/pagesRoom/list2?estate_id=' + curObj.id + '&estate_name=' + curObj.estate_name} className="r">查看更多{' >'}</Navigator>
         </View>
         <Rooms onRef={this.refRooms} />
       </View>
@@ -859,7 +860,6 @@ class Index extends Component {
     const lotteryObj = curObj.estate_lottery || {}
     const { userInfo } = this.state
     const uInfo = userInfo || Taro.getStorageSync('APP_userInfo')
-    console.log(uInfo.is_sale)
     return (
       <View className={uInfo.is_sale == 1 ? 'scoped-entry-yh' : 'scoped-entry-yh hide'}>
         <Navigator url={`/pagesRoom/roomPrice2?eId=${curObj.id}&name=${curObj.estate_name}&id=${lotteryObj.id}`} className="sey-wrap">
@@ -1150,6 +1150,10 @@ class Index extends Component {
               : ''
             }
             {this.renderEntry()}
+            {
+              (curObj.old_house_list && curObj.old_house_list.length > 0)
+              && this.renderRooms()
+            }
             {this.renderOptionsInfo()}
             {
               curObj.remarked
@@ -1157,10 +1161,7 @@ class Index extends Component {
               this.renderDesc()
             }
             {this.renderProductType()}
-            {
-              (curObj.old_house_list && curObj.old_house_list.length > 0)
-              && this.renderRooms()
-            }
+            
             {
               (curObj.estate_compete && curObj.estate_compete.length > 0)
               && this.renderMoreHouse()

+ 133 - 44
src/pagesMore/center/uploadRoom2.jsx

@@ -8,6 +8,7 @@ import './uploadRoom2.scss'
 
 import qiniuUploader from '@utils/qiniuUploader'
 import { TaroCropper } from 'taro-cropper'
+import { arrToObj } from '@utils'
 
 class Index extends Component {
 
@@ -41,6 +42,8 @@ class Index extends Component {
       imgArr: [],
       cutImgTempUrl: '',
       cutImgShow: false,
+      curProductTypeName: '',
+      productHouseList: [],
     }
   }
   config = {
@@ -63,45 +66,52 @@ class Index extends Component {
         Taro.setNavigationBarTitle({
           title: cObj.sale_user.sale_name + '-编辑房源'
         })
-        this.setState({
-          dtlObj: cObj,
-          formObj: {
-            id: cObj.id,
-            hide_status: cObj.hide_status || '1',
-            estate_id: cObj.estate_id || '',
-            estate_name: cObj.estate_name || '',
-            title: cObj.title || '',
-            house_no: cObj.house_no || '',
-            delivery_at: cObj.delivery_at || '',
-            price: cObj.price || '',
-            area: cObj.area || '',
-            full_year: cObj.full_year || '',
-            floor: cObj.floor || '',
-            storeys: cObj.storeys || '',
-            is_dec: cObj.is_dec || '',
-            is_elevator: cObj.is_elevator || '',
-            owner: cObj.owner || '',
-            custom_tag: cObj.custom_tag || '',
-            owner_phone: cObj.owner_phone || '',
-            introduce: cObj.introduce || '',
-            remarked: cObj.remarked || '',
-            record: cObj.record || '',
-            pri_image: cObj.pri_image || '',
-            house_img: cObj.house_img || '',
-            position: cObj.position || '',
-            floor_price: cObj.floor_price || '',
-            video: cObj.video || '',
-          },
-          imgArr: (cObj.images && cObj.images.length > 0) ? cObj.images.split(',') : [],
-          addr1: addr[0],
-          addr2: addr[1],
-          addr3: addr[2],
-          hType1: hType[0],
-          hType2: hType[1],
-          hType3: hType[2],
-          sRate1: sRate[0],
-          sRate2: sRate[1],
-        })
+        if (cObj.estate_id) {
+          this.getPtData(cObj.estate_id)
+        }
+        setTimeout(() => {
+          this.setState({
+            dtlObj: cObj,
+            formObj: {
+              id: cObj.id,
+              hide_status: cObj.hide_status || '1',
+              estate_id: cObj.estate_id || '',
+              estate_name: cObj.estate_name || '',
+              title: cObj.title || '',
+              house_no: cObj.house_no || '',
+              delivery_at: cObj.delivery_at || '',
+              price: cObj.price || '',
+              area: cObj.area || '',
+              full_year: cObj.full_year || '',
+              floor: cObj.floor || '',
+              storeys: cObj.storeys || '',
+              is_dec: cObj.is_dec || '',
+              is_elevator: cObj.is_elevator || '',
+              owner: cObj.owner || '',
+              custom_tag: cObj.custom_tag || '',
+              owner_phone: cObj.owner_phone || '',
+              introduce: cObj.introduce || '',
+              remarked: cObj.remarked || '',
+              record: cObj.record || '',
+              pri_image: cObj.pri_image || '',
+              house_img: cObj.house_img || '',
+              position: cObj.position || '',
+              floor_price: cObj.floor_price || '',
+              video: cObj.video || '',
+              product_type: cObj.product_type || '',
+            },
+            curProductTypeName: `${cObj.product_type}-${cObj.house_type.replace(/-/g, '')}`,
+            imgArr: (cObj.images && cObj.images.length > 0) ? cObj.images.split(',') : [],
+            addr1: addr[0],
+            addr2: addr[1],
+            addr3: addr[2],
+            hType1: hType[0],
+            hType2: hType[1],
+            hType3: hType[2],
+            sRate1: sRate[0],
+            sRate2: sRate[1],
+          })
+        }, 1000)
       })
     }
   }
@@ -124,6 +134,10 @@ class Index extends Component {
   saveHandle (pStr) {
     const { formObj, imgArr, addr1, addr2, addr3, hType1, hType2, hType3, sRate1, sRate2, dtlObj } = this.state
     let house_no = ''
+    if (!formObj.product_type) {
+      Taro.$msg('请选择产品规格')
+      return
+    }
     if (addr1 && addr2 && addr3) {
       house_no = `${addr1}-${addr2}-${addr3}`
     } else {
@@ -144,6 +158,7 @@ class Index extends Component {
     let params = {
       estate_id: formObj.estate_id,
       title: formObj.title,
+      product_type: formObj.product_type,
       house_no,
       delivery_at: formObj.delivery_at,
       house_type,
@@ -196,6 +211,50 @@ class Index extends Component {
     }
   }
 
+  estateChange (key, val) {
+    let { formObj } = this.state
+    if (val && formObj[key] !== val) {
+      this.getPtData(val)
+    }
+    formObj[key] = val
+    this.setState({
+      formObj
+    })
+  }
+  getPtData (id) {
+    Taro.api.house.admestatedetail({id}).then(res => {
+      let productHouseList = []
+      const dictData = Taro.getStorageSync('dictData')
+      const ptObj = arrToObj(dictData.product_type)
+      const htObj = arrToObj(dictData.house_type)
+      const list = res.area_data || []
+      list.forEach(one => {
+        const htList = one.house_type_list || []
+        htList.forEach(two => {
+          productHouseList.push({
+            key: `${ptObj[one.product_type_val]}-${htObj[two.house_type_val]}`,
+            val: `${one.product_type_val}-${two.house_type_val}`
+          })
+        })
+      })
+      this.setState({
+        productHouseList
+      })
+    })
+  }
+  ptChange (key, val) {
+    const ptArr = val.split('-')
+    const htSub = ptArr[1].split('')
+    let { formObj } = this.state
+    formObj.product_type = ptArr[0]
+    this.setState({
+      formObj,
+      curProductTypeName: val,
+      hType1: htSub[0],
+      hType2: htSub[1],
+      hType3: htSub[2],
+    })
+  }
   baseFormChange (key, val) {
     let { formObj } = this.state
     formObj[key] = val
@@ -499,15 +558,25 @@ class Index extends Component {
   }
 
 
+
+  linkAddRecord () {
+    const {id} = this.$router.params
+    Taro.navigateTo({
+      url: '/pagesRoom/follow/roomAdd?id=' + id,
+    })
+  }
+
+
   render () {
     const {id} = this.$router.params
-    const { formObj, imgArr, dtlObj } = this.state
+    const { formObj, imgArr, dtlObj, curProductTypeName, productHouseList } = this.state
     const dictData = Taro.getStorageSync('dictData')
     const roomDecMoreOptions = {arr: dictData.room_dec}
     const houseRoomYearMoreOptions = {arr: dictData.house_room_year}
     const yesnoMoreOptions = {arr: [...dictData.sys_yesno]}
     const hideStatusoMoreOptions = {arr: [...dictData.hide_status]}
     const roomPositionMoreOptions = {arr: [...dictData.room_position]}
+    const ptMoreOptions = {arr: [...productHouseList]}
     const addIcon = require('@img/icon_upload_img.png')
     const addIcon2 = require('@img/icon_upload_video.png')
     const closeIcon = require('@img/icon_g_close.png')
@@ -525,7 +594,6 @@ class Index extends Component {
       opVal: 'id',
       skey: 'estate_name',
     }
-    
     return (
       <View className="l-box">
         {/* {this.renderCutImg()} */}
@@ -548,9 +616,25 @@ class Index extends Component {
             keyStr2="请选择"
             typeStr="radio"
             moreOptions={moreEstateOptions}
-            bc={this.baseFormChange.bind(this)}
+            bc={this.estateChange.bind(this)}
           />
         }
+        {
+          formObj.estate_id
+          ?
+          <View className="l-floor-pos2">
+            <LFormGroup
+              val={curProductTypeName}
+              valStr="curProductTypeName"
+              keyStr="产品(必填)"
+              keyStr2="请选择"
+              typeStr="select"
+              moreOptions={ptMoreOptions}
+              bc={this.ptChange.bind(this)}
+            />
+          </View>
+          : ''
+        }
         {/* <View className="l-floor-pos2">
           {
             formObj.estate_name
@@ -839,7 +923,7 @@ class Index extends Component {
             placeholder='仅编辑查看,房源内部备注信息(300字以内)'
           />
         </View>
-        <View className="scoped-box">
+        {/* <View className="scoped-box">
           <View className="sb-title">跟进记录备注</View>
           <AtTextarea
             value={formObj.record}
@@ -848,11 +932,16 @@ class Index extends Component {
             height={200}
             placeholder='单次业务员跟进的备注,跟进记录中展示'
           />
-        </View>
+        </View> */}
         <View className="l-floor-footer t2">
           <View className="lff-flex">
             <View className="lff-btn full" onClick={this.saveHandle.bind(this)}>提交</View>
           </View>
+          <View className="lff-flex" style="padding-top: 10px;padding-bottom: 16px;position:relative;">
+            <View className="lff-btn full t2" onClick={this.linkAddRecord.bind(this)}>添加跟进记录
+            </View>
+            <View className="scoped-footer-btn-tips">创建人15天未跟进信息,房源将进入自由池,解除锁定</View>
+          </View>
           {
             id 
             ?

+ 12 - 0
src/pagesMore/center/uploadRoom2.scss

@@ -142,4 +142,16 @@
   &.show {
     height: 100%;
   }
+}
+
+
+.scoped-footer-btn-tips {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  text-align: center;
+  font-size: 22rpx;
+  color: #369af7;
+  font-weight: bold;
 }

+ 73 - 5
src/pagesRoom/follow/room.jsx

@@ -38,10 +38,11 @@ class Index extends Component {
     Taro.api.room.apieshousedetail({id: curId}).then(res => {
       this.setState({ roomObj: res || '' })
     })
+  }
+  componentDidShow () {
     this.getDataList()
   }
 
-  componentDidShow () { }
 
   componentDidHide () { }
 
@@ -64,8 +65,8 @@ class Index extends Component {
       params.es_house_id = curId
     }
     Taro.api.room.apieshouserecordlist(params).then(res => {
-      console.log(res)
       const curData = res.list || []
+      console.log(curData)
       let isListEnd = false
       if (curData.length > 0) {
         if (page === 1) {
@@ -123,17 +124,77 @@ class Index extends Component {
         onScrollToLower={this.onScrollToLower.bind(this)}
       >
         <View className="scoped-list">
-          <AtTimeline 
+          {
+            dataList.map((item) => {
+              const imgArr = item.record_image ? item.record_image.split(',') : []
+              return (
+                <View className="sl-item" key={item.id}>
+                  <View className="p1">{item.title}</View>
+                  {
+                    imgArr.length > 0
+                    ?
+                    <View className="sl-img">
+                      {
+                        imgArr.map((img, i) => {
+                          return (
+                            <Image key={i} className="img" src={img+'_plus'} onClick={this.previewImageHandle.bind(this, img, imgArr)}></Image>
+                          )
+                        })
+                      }
+                    </View> 
+                    : ''
+                  }
+                  {
+                    item.record_video
+                    ?
+                    <Video
+                      src={item.record_video}
+                      controls={true}
+                      autoplay={false}
+                      className="sl-video"
+                    />
+                    : ''
+                  }
+                  {
+                    item.record_audio
+                    ?
+                    <Audio
+                      className="sl-audio"
+                      src={item.record_audio}
+                      controls={true}
+                      autoplay={false}
+                      loop={false}
+                      muted={true}
+                      initialTime='30'
+                    />
+                    : ''
+                  }
+                  <View className="p2">{item.create_at}</View>
+                </View>
+              )
+            })
+          }
+          {/* <AtTimeline 
             pending 
             items={dataList}
           >
-          </AtTimeline>
+          </AtTimeline> */}
         </View>
         <ListMore isListEnd={isListEnd} isListLoading={isListLoading} isListEmpty={isListEmpty} />
       </ScrollView>
     )
   }
 
+  previewImageHandle (img, arr) {
+    let nArr = arr.map(item => {
+      return item + '_plus'
+    })
+    Taro.previewImage({
+      current: img+ '_plus',
+      urls: nArr
+    })
+  }
+
 
   renderTop () {
     const { roomObj } = this.state
@@ -150,12 +211,19 @@ class Index extends Component {
             {saleUser.sale_phone}[{saleUser.sale_name}]
           </View>
           <View className="p3">{saleUser.create_at}</View>
-          {/* <Image className="st-img" onClick={this.copyHandle.bind(this)} src={roomObj.avatar}></Image> */}
+          <View className="p-btn" onClick={this.linkAddRecord.bind(this)}>添加跟进</View>
         </View>
       </View>
     )
   }
 
+  linkAddRecord () {
+    const {id} = this.$router.params
+    Taro.navigateTo({
+      url: '/pagesRoom/follow/roomAdd?id=' + id,
+    })
+  }
+
  
   copyHandle () {
     const { userInfoObj } = this.state

+ 41 - 1
src/pagesRoom/follow/room.scss

@@ -50,6 +50,16 @@
       font-size: 26px;
       color: #999;
     }
+    .p-btn {
+      display: inline-block;
+      vertical-align: middle;
+      padding: 6rpx 20rpx;
+      border-radius: 10rpx;
+      color: #fff;
+      background-color: $mainColor;
+      margin-top: 10rpx;
+      font-size: 24rpx;
+    }
     .st-img {
       position: absolute;
       top: 20px;
@@ -76,6 +86,36 @@
   }
 }
 .scoped-list {
-  padding: 10px 30px;
+  .sl-item {
+    @include itemBox(20rpx);
+    .p1 {
+      color: #101010;
+      font-size: 28rpx;
+    }
+    .p2 {
+      color: #999;
+      font-size: 24rpx;
+    }
+    .sl-video {
+      width: 100%;
+      height: 300rpx;
+      margin: 10rpx 0;
+    }
+    .sl-audio {
+      width: 100%;
+      height: auto;
+    }
+    .sl-img {
+      padding: 20rpx 0 6rpx;
+      .img {
+        display: inline-block;
+        vertical-align: middle;
+        width: 200rpx;
+        height: 200rpx;
+        margin-left: 10rpx;
+        margin-bottom: 10rpx;
+      }
+    }
+  }
 }
 

+ 579 - 0
src/pagesRoom/follow/roomAdd.jsx

@@ -0,0 +1,579 @@
+import Taro, { Component } from '@tarojs/taro'
+import { View } from '@tarojs/components'
+import { AtTextarea }  from 'taro-ui'
+import LFormGroup from '@/c/lform/formGroup'
+const HLKEY = '654mca0l38b489d9'
+const CJ = require('crypto-js')
+import './roomAdd.scss'
+
+import qiniuUploader from '@utils/qiniuUploader'
+import { TaroCropper } from 'taro-cropper'
+
+class Index extends Component {
+
+  onShareAppMessage() {
+    return {
+      title: `添加房源跟进记录`,
+    }
+  }
+  onShareTimeline () {
+    return {
+      title: `添加房源跟进记录`,
+    }
+  }
+
+
+  constructor (props) {
+    super(props)
+    this.state = {
+      addr1: '',
+      addr2: '',
+      addr3: '',
+      hType1: '',
+      hType2: '',
+      hType3: '',
+      sRate1: '',
+      sRate2: '',
+      formObj: {
+        hide_status: '1',
+      },
+      dtlObj: {},
+      imgArr: [],
+      cutImgTempUrl: '',
+      cutImgShow: false,
+      curProductTypeName: '',
+      productHouseList: [],
+    }
+  }
+  config = {
+    navigationBarTitleText: '上传房源',
+  }
+
+  componentWillMount () {
+    Taro.$AHU(this)
+  }
+
+  componentDidMount() {
+    const {id} = this.$router.params
+    if (id) {
+      Taro.api.room.apieshousedetail({id}).then(res => {
+        let cObj = res || {}
+        Taro.setNavigationBarTitle({
+          title: cObj.title
+        })
+        this.setState({
+          dtlObj: cObj,
+        })
+      })
+    }
+  }
+
+
+
+
+
+  saveHandle () {
+    const { formObj, imgArr, dtlObj } = this.state
+    const {id} = this.$router.params
+    let apiStr = 'apieshouserecordadd'
+    let params = {
+      es_house_id: id,
+      record_video: formObj.video || '',
+      record_image: imgArr.join(','),
+      record_audio: formObj.record_audio || '',
+      remark: formObj.remark || '',
+    }
+    if (params.remark) {
+      Taro.api.room[apiStr](params).then(res => {
+        Taro.$msgConfirm('操作成功', () => {
+          Taro.navigateBack({
+            delta: 1
+          })
+        }, () => {
+          Taro.navigateBack({
+            delta: 1
+          })
+        })
+      })
+    } else {
+      if (!params.remark) Taro.$msg('备注必填')
+    }
+  }
+
+
+  baseFormChange (key, val) {
+    let { formObj } = this.state
+    formObj[key] = val
+    this.setState({
+      formObj
+    })
+  }
+
+
+  initQiniu() {
+    Taro.api.other.apiuploadvideotoken().then(res => {
+      let options = {
+          // bucket所在区域,这里是华北区。ECN, SCN, NCN, NA, ASG,分别对应七牛云的:华东,华南,华北,北美,新加坡 5 个区域
+          region: 'SCN',
+  
+          // 获取uptoken方法三选一即可,执行优先级为:uptoken > uptokenURL > uptokenFunc。三选一,剩下两个置空。推荐使用uptokenURL,详情请见 README.md
+          // 由其他程序生成七牛云uptoken,然后直接写入uptoken
+          uptoken: res.token,
+          // 从指定 url 通过 HTTP GET 获取 uptoken,返回的格式必须是 json 且包含 uptoken 字段,例如: {"uptoken": "0MLvWPnyy..."}
+          // uptokenURL: 'https://[yourserver.com]/api/uptoken',
+          // // uptokenFunc 这个属性的值可以是一个用来生成uptoken的函数,详情请见 README.md
+          // uptokenFunc: function () { 
+          // 		// do something
+          // 		return qiniuUploadToken;
+          // },
+  
+          // bucket 外链域名,下载资源时用到。如果设置,会在 success callback 的 res 参数加上可以直接使用的 fileURL 字段。否则需要自己拼接
+          domain: res.domain,
+          // qiniuShouldUseQiniuFileName 如果是 true,则文件的 key 由 qiniu 服务器分配(全局去重)。如果是 false,则文件的 key 使用微信自动生成的 filename。出于初代sdk用户升级后兼容问题的考虑,默认是 false。
+          // 微信自动生成的 filename较长,导致fileURL较长。推荐使用{qiniuShouldUseQiniuFileName: true} + "通过fileURL下载文件时,自定义下载名" 的组合方式。
+          // 自定义上传key 需要两个条件:1. 此处shouldUseQiniuFileName值为false。 2. 通过修改qiniuUploader.upload方法传入的options参数,可以进行自定义key。(请不要直接在sdk中修改options参数,修改方法请见demo的index.js)
+          // 通过fileURL下载文件时,文件自定义下载名,请参考:七牛云“对象存储 > 产品手册 > 下载资源 > 下载设置 > 自定义资源下载名”(https://developer.qiniu.com/kodo/manual/1659/download-setting)。本sdk在README.md的"常见问题"板块中,有"通过fileURL下载文件时,自定义下载名"使用样例。
+          shouldUseQiniuFileName: false
+      };
+      // 将七牛云相关配置初始化进本sdk
+      qiniuUploader.init(options);
+    })
+  }
+
+
+
+  audioHandle () {
+    const userInfo = Taro.getStorageSync('APP_userInfo') || {}
+    this.initQiniu()
+    const that = this
+    Taro.chooseMessageFile({
+      count: 1, // 最大可以选择的文件个数
+      type: 'audio', // 限制类型为音频
+      success: function(res) {
+          
+          
+          const f = res.tempFiles[0]
+          // console.log(f.tempFilePath.split('.')[1])
+          let { formObj } = that.state
+          qiniuUploader.upload(f.path, (suc) => {
+            console.log(suc)
+            formObj.record_audio = suc.fileURL
+            that.setState({
+              formObj
+            })
+          }, (error) => {
+            console.error('error: ' + JSON.stringify(error));
+          },
+            // 此项为qiniuUploader.upload的第四个参数options。若想在单个方法中变更七牛云相关配置,可以使用上述参数。如果不需要在单个方法中变更七牛云相关配置,则可使用 null 作为参数占位符。推荐填写initQiniu()中的七牛云相关参数,然后此处使用null做占位符。
+            // 若想自定义上传key,请把自定义key写入此处options的key值。如果在使用自定义key后,其它七牛云配置参数想维持全局配置,请把此处options除key以外的属性值置空。
+            // 启用options参数请记得删除null占位符
+            {
+              key: `${userInfo.phone}-${+new Date()}${f.path.split('.').length > 0 ? '.'+f.path.split('.')[1] : ''}`,
+            },
+            // null,
+            (progress) => {
+                console.log('上传进度', progress.progress);
+                console.log('已经上传的数据长度', progress.totalBytesSent);
+                console.log('预期需要上传的数据总长度', progress.totalBytesExpectedToSend);
+            }, (cancelTask) => {
+              console.log(cancelTask)
+            }
+          );
+          
+      },
+      fail: function(err) {
+        console.log('选择文件失败', err);
+      }
+    });
+
+
+    Taro.chooseMedia({
+      count: 1,
+      mediaType: ['video'], // ['mix'], // ['video'],
+      sourceType: ['album', 'camera'],
+      maxDuration: 30,
+      camera: 'back',
+      success(res) {
+        const f = res.tempFiles[0]
+        // console.log(f.tempFilePath.split('.')[1])
+        let { formObj } = that.state
+        qiniuUploader.upload(f.tempFilePath, (suc) => {
+          formObj.video = suc.fileURL
+          that.setState({
+            formObj
+          })
+        }, (error) => {
+          console.error('error: ' + JSON.stringify(error));
+        },
+          // 此项为qiniuUploader.upload的第四个参数options。若想在单个方法中变更七牛云相关配置,可以使用上述参数。如果不需要在单个方法中变更七牛云相关配置,则可使用 null 作为参数占位符。推荐填写initQiniu()中的七牛云相关参数,然后此处使用null做占位符。
+          // 若想自定义上传key,请把自定义key写入此处options的key值。如果在使用自定义key后,其它七牛云配置参数想维持全局配置,请把此处options除key以外的属性值置空。
+          // 启用options参数请记得删除null占位符
+          {
+            key: `${userInfo.phone}-${+new Date()}${f.tempFilePath.split('.').length > 0 ? '.'+f.tempFilePath.split('.')[1] : ''}`,
+          },
+          // null,
+          (progress) => {
+              console.log('上传进度', progress.progress);
+              console.log('已经上传的数据长度', progress.totalBytesSent);
+              console.log('预期需要上传的数据总长度', progress.totalBytesExpectedToSend);
+          }, (cancelTask) => {
+            console.log(cancelTask)
+          }
+        );
+
+        
+      }
+    })
+  }
+
+  viviHandle () {
+    const userInfo = Taro.getStorageSync('APP_userInfo') || {}
+    this.initQiniu()
+    const that = this
+    Taro.chooseMedia({
+      count: 1,
+      mediaType: ['video'], // ['mix'], // ['video'],
+      sourceType: ['album', 'camera'],
+      maxDuration: 30,
+      camera: 'back',
+      success(res) {
+        const f = res.tempFiles[0]
+        // console.log(f.tempFilePath.split('.')[1])
+        let { formObj } = that.state
+        qiniuUploader.upload(f.tempFilePath, (suc) => {
+          formObj.video = suc.fileURL
+          that.setState({
+            formObj
+          })
+        }, (error) => {
+          console.error('error: ' + JSON.stringify(error));
+        },
+          // 此项为qiniuUploader.upload的第四个参数options。若想在单个方法中变更七牛云相关配置,可以使用上述参数。如果不需要在单个方法中变更七牛云相关配置,则可使用 null 作为参数占位符。推荐填写initQiniu()中的七牛云相关参数,然后此处使用null做占位符。
+          // 若想自定义上传key,请把自定义key写入此处options的key值。如果在使用自定义key后,其它七牛云配置参数想维持全局配置,请把此处options除key以外的属性值置空。
+          // 启用options参数请记得删除null占位符
+          {
+            key: `${userInfo.phone}-${+new Date()}${f.tempFilePath.split('.').length > 0 ? '.'+f.tempFilePath.split('.')[1] : ''}`,
+          },
+          // null,
+          (progress) => {
+              console.log('上传进度', progress.progress);
+              console.log('已经上传的数据长度', progress.totalBytesSent);
+              console.log('预期需要上传的数据总长度', progress.totalBytesExpectedToSend);
+          }, (cancelTask) => {
+            console.log(cancelTask)
+          }
+        );
+
+        
+      }
+    })
+  }
+
+  dealImgHandle (key, moreStr) {
+    this.uploadComImg((val) => {
+      let { formObj } = this.state
+      formObj[key] = val
+      this.setState({
+        formObj
+      })
+    }, 1, moreStr)
+  }
+
+  addImg () {
+    this.uploadComImg((arr) => {
+      let { imgArr } = this.state
+      imgArr = [...imgArr, ...arr]
+      this.setState({
+        imgArr
+      })
+    }, 9)
+  }
+  uploadComImg (bc, count, moreStr) {
+    const that = this
+    Taro.chooseMedia({
+      count: count ? count : 1, // 默认9
+      mediaType: ['image'],
+      sizeType: ['compressed'],  // original
+      sourceType: ['album', 'camera'],
+      success: function (res) {
+        const tempFiles = res.tempFiles
+        if (tempFiles.length > 0) {
+          let imgBcArr = []
+          tempFiles.forEach((p, i) => {
+            that.diyUploadFile(p.tempFilePath, moreStr).then(url => {
+              imgBcArr.push(url)
+              if (bc && imgBcArr.length === tempFiles.length) {
+                bc(imgBcArr)
+              }
+            })
+          })
+        }
+      }
+    })
+  }
+  diyUploadFile (filePath, moreStr) {
+    return new Promise((resolve, reject) => {
+      let token = Taro.getStorageSync('APP_token')
+      let url = `https://api.honglouplus.com/api/upload/cloudpir`
+      if (moreStr === 'noSign') url = `https://api.honglouplus.com/api/upload/cloud`
+      Taro.uploadFile({
+        url,
+        filePath,
+        name: 'upload',
+        formData: {
+          'token': token
+        },
+        success (res){
+          const msg = res.data || ''
+          const key = CJ.enc.Utf8.parse(HLKEY)
+          const bytes = CJ.AES.decrypt(msg, key, {
+            mode: CJ.mode.ECB,
+            padding: CJ.pad.Pkcs7
+          })
+          const originalText = bytes.toString(CJ.enc.Utf8)
+          const cData = JSON.parse(originalText)
+          const curImg =  cData.data.url || ''
+          resolve(curImg)
+        }
+      })
+    })
+  }
+  delImg (index) {
+    let { imgArr } = this.state
+    imgArr.splice(index, 1)
+    this.setState({
+      imgArr
+    })
+  }
+  previewImageHandle (current, arr) {
+    const { imgArr } = this.state
+    let nArr = imgArr.map(item => {
+      return item + '_plus'
+    })
+    Taro.previewImage({
+      current,
+      urls: nArr
+    })
+  }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+  renderCutImg () {
+    const { cutImgTempUrl } = this.state
+    const { cutImgShow } = this.state
+    return (
+      <View className={cutImgShow ? 'scoped-ci-popup show' : 'scoped-ci-popup'}>
+        <TaroCropper
+          src={cutImgTempUrl}
+          cropperWidth={375}
+          cropperHeight={250}
+          fullScreen
+          onCut={this.cutHandle.bind(this)}
+        />
+      </View>
+    )
+  }
+  cutHandle (filePath) {
+    let { formObj } = this.state
+    let token = Taro.getStorageSync('APP_token')
+    const that = this
+    Taro.uploadFile({
+      url: `https://api.honglouplus.com/api/upload/cloudpir`,
+      filePath,
+      name: 'upload',
+      formData: {
+        'token': token
+      },
+      success (res){
+        const msg = res.data || ''
+        const key = CJ.enc.Utf8.parse(HLKEY)
+        const bytes = CJ.AES.decrypt(msg, key, {
+          mode: CJ.mode.ECB,
+          padding: CJ.pad.Pkcs7
+        })
+        const originalText = bytes.toString(CJ.enc.Utf8)
+        const cData = JSON.parse(originalText)
+        formObj.pri_image = cData.data.url || ''
+        that.setState({
+          cutImgShow: false,
+          formObj,
+        })
+      }
+    })
+  }
+  openCutImg () {
+    Taro.chooseMedia({
+      count: 1,
+      mediaType: ['image'],
+      sizeType: ['compressed'],
+      sourceType: ['album', 'camera'],
+    }).then(res => {
+      this.setState({
+        cutImgTempUrl: res.tempFilePaths[0],
+        cutImgShow: true,
+      })
+    })
+  }
+
+
+  renderTop () {
+    const { dtlObj } = this.state
+    const suObj = dtlObj.sale_user || {}
+    return (
+      <View className="scoped-header">
+        <View className="p1">{suObj.sale_name}({suObj.sale_phone})</View>
+        <View className="p1">{dtlObj.estate_name}[{dtlObj.house_no}]</View>
+      </View>
+    )
+  }
+
+  render () {
+    const { formObj, imgArr } = this.state
+    const addIcon = require('@img/icon_upload_img.png')
+    const addIcon2 = require('@img/icon_upload_video.png')
+    const addIcon3 = require('@img/icon_upload_audio.png')
+    const closeIcon = require('@img/icon_g_close.png')
+    const imgItems = imgArr.map((src, index) => {
+      return (
+        <View className="si-op" key={index}>
+          <Image src={src + '_plus'} className="img" onClick={this.previewImageHandle.bind(this, src + '_plus')} />
+          <Image src={closeIcon} className="i" onClick={this.delImg.bind(this, index)}/>
+        </View>
+      )
+    })
+    return (
+      <View className="l-box">
+        
+        {this.renderTop()}
+
+        <View className='scoped-has-right'>
+          <View className="scoped-box">
+            <View className="sb-title">跟进证明的视频
+              {
+                formObj.video
+                ?
+                <View className="s4" onClick={() => {
+                  this.setState({
+                    formObj: {
+                      ...formObj,
+                      video: ''
+                    }
+                  })
+                }}>清除当前视频</View>
+                : ''
+              }
+            </View>
+            
+              {
+                formObj.video
+                ?
+                <View className="scoped-audio">
+                  <View className="si-op">
+                    <Video
+                      src={formObj.video}
+                      controls={true}
+                      autoplay={false}
+                      className="img"
+                    />
+                  </View>
+                </View>
+                :
+                <View className="scoped-img">
+                  <View className="si-op" onClick={this.viviHandle.bind(this)}>
+                    <Image src={addIcon2} className="img"/>
+                  </View>
+                </View>
+              }
+          </View>
+        </View>
+        <View className='scoped-has-right'>
+          <View className="scoped-box">
+            <View className="sb-title">跟进证明的录音
+              {
+                formObj.record_audio
+                ?
+                <View className="s4" onClick={() => {
+                  this.setState({
+                    formObj: {
+                      ...formObj,
+                      record_audio: ''
+                    }
+                  })
+                }}>清除当前录音</View>
+                : ''
+              }
+            </View>
+              {
+                formObj.record_audio
+                ?
+                <View className="scoped-audio">
+                  <View className="si-op">
+                    <Audio
+                      src={formObj.record_audio}
+                      controls={true}
+                      autoplay={false}
+                      loop={false}
+                      muted={true}
+                      initialTime='30'
+                    />
+                  </View>
+                </View>
+                :
+                <View className="scoped-img">
+                  <View className="si-op" onClick={this.audioHandle.bind(this)}>
+                    <Image src={addIcon3} className="img"/>
+                  </View>
+                </View>
+              }
+            
+          </View>
+        </View>
+        <View className="scoped-box">
+          <View className="sb-title">跟进证明的图片
+            <View className="s">(最多9张)</View>
+          </View>
+          <View className="scoped-img">
+            {imgItems}
+            {
+              imgArr.length < 9
+              &&
+              <View className="si-op" onClick={this.addImg.bind(this)}>
+                <Image src={addIcon} className="img"/>
+              </View>
+            }
+          </View>
+        </View>
+        <View className="scoped-box">
+          <View className="sb-title">备注</View>
+          <AtTextarea
+            value={formObj.remark}
+            onChange={this.baseFormChange.bind(this, 'remark')}
+            maxLength={300}
+            height={200}
+            placeholder='备注信息'
+          />
+        </View>
+        <View className="l-floor-footer t2">
+          <View className="lff-flex">
+            <View className="lff-btn full" onClick={this.saveHandle.bind(this)}>添加跟进</View>
+          </View>
+        </View>
+      </View>
+    )
+  }
+}
+
+export default Index

+ 177 - 0
src/pagesRoom/follow/roomAdd.scss

@@ -0,0 +1,177 @@
+@import '@css/mixin.scss';
+.scoped-box {
+  padding: 20px 20px 0;
+  .sb-title {
+    font-size: 30px;
+    color: #333;
+    padding-bottom: 20px;
+    font-weight: bold;
+    padding-left: 10px;
+    .s {
+      display: inline-block;
+      font-size: 24px;
+      color: #999;
+      font-weight: normal;
+    }
+    .s4 {
+      display: inline-block;
+      font-size: 24px;
+      color: #f00;
+      font-weight: normal;
+      font-weight: bold;
+    }
+  }
+}
+.at-textarea {
+  border: 1PX solid #f2f2f2;
+}
+.at-textarea__textarea {
+  font-size: 28px;
+  color: #333;
+}
+
+.scoped-img {
+  .si-op {
+    display: inline-block;
+    vertical-align: middle;
+    width: 200px;
+    height: 200px;
+    margin-right: 30px;
+    margin-bottom: 30px;
+    position: relative;
+    border: 1PX solid #f2f2f2;
+    .img {
+      width: 200px;
+      height: 200px;
+    }
+    .i {
+      position: absolute;
+      top: -20px;
+      right: -20px;
+      width: 40px;
+      height: 40px;
+    }
+  }
+}
+
+
+
+
+
+
+
+.scoped-addr-box {
+  position: absolute;
+  right: 20px;
+  top: 0;
+  width: 70%;
+  z-index: 2;
+  background: #fff;
+  display: flex;
+  height: 90px;
+  // border-bottom: 1PX solid #f2f2f2;
+  .i {
+    flex: 3;
+    font-size: 28px;
+    line-height: 90px;
+    text-align: right;
+    height: 90px;
+    padding-right: 10px;
+  }
+  .t {
+    flex: 2;
+    font-size: 28px;
+    color: #999;
+    height: 90px;
+    line-height: 90px;
+  }
+}
+
+.scoped-floor-height-box {
+  position: absolute;
+  right: 20px;
+  top: 0;
+  width: 50%;
+  background: #fff;
+  display: flex;
+  height: 90px;
+  z-index: 2;
+  .i {
+    flex: 2;
+    font-size: 28px;
+    line-height: 90px;
+    height: 90px;
+    text-align: center;
+  }
+  .t {
+    flex: 1;
+    font-size: 28px;
+    color: #999;
+    line-height: 90px;
+    height: 90px;
+    text-align: center;
+  }
+}
+
+.scoped-estate-name {
+  position: absolute;
+  right: 20px;
+  top: 0;
+  width: 70%;
+  background: #fff;
+  height: 90px;
+  line-height: 90px;
+  text-align: right;
+  z-index: 9;
+}
+
+
+.scoped-has-right {
+  position: relative;
+  .shr-r {
+    position: absolute;
+    right: 20px;
+    top: 0;
+  }
+}
+
+.scoped-ci-popup {
+  position: fixed;
+  z-index: 99999;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  height: 0;
+  width: 100%;
+  overflow: hidden;
+  background: #000;
+  &.show {
+    height: 100%;
+  }
+}
+
+
+.scoped-footer-btn-tips {
+  position: absolute;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  text-align: center;
+  font-size: 22rpx;
+  color: #369af7;
+  font-weight: bold;
+}
+
+
+
+
+
+
+.scoped-header {
+  padding: 30rpx;
+}
+.scoped-audio {
+  width: 100%;
+  height: auto;
+}

+ 699 - 0
src/pagesRoom/list2.jsx

@@ -0,0 +1,699 @@
+import Taro, { Component } from '@tarojs/taro'
+import { View, Image, Text, Navigator } from '@tarojs/components'
+
+import { AtSearchBar } from 'taro-ui'
+import ListMore from '@/c/pageDataList/listMore'
+import MultiSelect from '@/c/lform/MultiSelect'
+import './list.scss'
+import { arrToObj } from '@utils'
+
+class Index extends Component {
+
+  onShareAppMessage() {
+    return {
+      title: '来看看南昌的这些优质房源',
+    }
+  }
+  onShareTimeline () {
+    return {
+      title: '洪楼Plus,专注南昌本地房地产市场,让买房,更省心!',
+    }
+  }
+
+  constructor (props) {
+    super(props)
+    const { estate_id } = this.$router.params
+    let estateIdCur = []
+    if (estate_id) estateIdCur = [estate_id]
+    this.state = {
+      searchKey: '',
+      page_size: 10,
+      page: 1,
+      isListEnd: false,
+      isListLoading: false,
+      isListEmpty: false,
+      dataList: [],
+      curNav: 1,
+      isDShow: false,
+      curObj: {},
+      searchIndex: -1,
+      searchText1: '',
+      searchText5: '',
+      searchText3: '',
+      searchText4: '',
+      searchText5: '',
+      curPos: 'area_type',
+      curAreaType: [],
+      curProductTypeName: [],
+      curHouseTypeRange: [],
+      houseAreaCur: [],
+      productTypeCur: [],
+      isEstateShow: false,
+      estateIdCur,
+      productHouseList: [],
+      curPhObj: {},
+      curSortObj: {key: '默认排序',val: ["update_at","DESC"]},
+    }
+  }
+
+  config = {
+    navigationBarTitleText: '优质房源',
+  }
+
+  componentWillMount () {
+    Taro.$AHU(this)
+    const { estate_id, estate_name } = this.$router.params
+    Taro.setNavigationBarTitle({
+      title: estate_name
+    })
+    if (estate_id) {
+      this.getDataList()
+      Taro.api.house.admestatedetail({id: estate_id}).then(res => {
+        let productHouseList = []
+        const dictData = Taro.getStorageSync('dictData')
+        const ptObj = arrToObj(dictData.product_type)
+        const htObj = arrToObj(dictData.house_type)
+        const list = res.area_data || []
+        list.forEach(one => {
+          const htList = one.house_type_list || []
+          htList.forEach(two => {
+            console.log()
+            productHouseList.push({
+              key: `${ptObj[one.product_type_val]}-${htObj[two.house_type_val]}[${two.area_list.map(o => o.area + '㎡').join(',')}]`,
+              val: `${one.product_type_val}-${two.house_type_val}`
+            })
+          })
+        })
+        this.setState({
+          productHouseList
+        })
+      })
+    }
+    
+
+    // 把文件删除后再写进,防止超过最大范围而无法写入
+    const fsm = wx.getFileSystemManager();  //文件管理器
+    fsm.readdir({  // 获取文件列表
+      dirPath: Taro.env.USER_DATA_PATH,// 当时写入的文件夹
+      success(res){
+        res.files.forEach((el) => { // 遍历文件列表里的数据
+          // 删除存储的垃圾数据
+          fsm.unlink({
+            filePath: `${Taro.env.USER_DATA_PATH}/${el}`, // 这里注意。文件夹也要加上,如果直接文件名的话会无法找到这个文件
+            fail(e){
+              console.log('readdir文件删除失败:',e)
+            }
+          });
+        })
+      }
+    })
+
+    
+  }
+
+  componentDidShow () { }
+
+  componentDidHide () { }
+
+  renderSearch () {
+    const { searchKey } = this.state
+    return (
+      <AtSearchBar
+        value={searchKey}
+        fixed={true}
+        placeholder="请输入房源关键字"
+        onChange={this.onSeachChange.bind(this)}
+        onActionClick={this.onSelectActionClick.bind(this)}
+        onClear={this.onClearHandle.bind(this)}
+      />
+    )
+  }
+  onSeachChange (value) {
+    this.setState({
+      searchKey: value
+    })
+  }
+  onClearHandle () {
+    this.setState({
+      searchKey: '',
+      page: 1
+    }, () => {
+      this.getDataList()
+    })
+  }
+  onSelectActionClick () {
+    this.setState({
+      page: 1,
+    }, () => {
+      this.getDataList()
+    })
+  }
+
+
+  searchIndex5Render () {
+    const { curSortObj } = this.state
+    const edIcon = require('@img/images/icon_g_ed.png')
+    const list = [
+      {key: '默认排序',val: ["update_at","DESC"]},
+      {key: '最新发布',val: ["create_at","DESC"]},
+      {key: '总价从低到高',val: ["price","ASC"]},
+      {key: '总价从高到低',val: ["price","DESC"]},
+      {key: '单价从低到高',val: ["unit_price","ASC"]},
+      {key: '单价从高到低',val: ["unit_price","DESC"]},
+      {key: '面积从低到高',val: ["area","ASC"]},
+      {key: '面积从高到低',val: ["area","DESC"]},
+    ]
+    const curItemViews = list.map(item =>{
+      let curClassName = "stc-op"
+      if (curSortObj.key === item.key) {
+        curClassName = "stc-op cur"
+      }
+      return (
+        <View className={curClassName} key={item.val} onClick={this.sortHandle.bind(this, item)}>{item.key}
+          <Image className="img" src={edIcon} />
+        </View>
+      )
+    })
+    return (
+      <View className="stc-wrap">
+        <View className="stc-item">
+          {curItemViews}
+        </View>
+      </View>
+    )
+  }
+  sortHandle (obj) {
+    if (obj === 'all') {
+      this.setState({
+        curSortObj: {},
+        searchText5: '',
+      }, () => {
+        this.searchComGetData()
+      })
+    } else {
+      this.setState({
+        curSortObj: obj,
+        searchText5: obj.key,
+      }, () => {
+        this.searchComGetData()
+      })
+    }
+  }
+
+  searchIndex3Render () {
+    const { curPhObj, productHouseList } = this.state
+    const edIcon = require('@img/images/icon_g_ed.png')
+    const curItemViews = productHouseList.map(item =>{
+      let curClassName = "stc-op"
+      if (curPhObj.val === item.val) {
+        curClassName = "stc-op cur"
+      }
+      return (
+        <View className={curClassName} key={item.val} onClick={this.productHouseHandle.bind(this, item)}>{item.key}
+          <Image className="img" src={edIcon} />
+        </View>
+      )
+    })
+    let allClassName = curPhObj.val ? 'stc-op' : 'stc-op cur'
+    return (
+      <View className="stc-wrap">
+        <View className="stc-item">
+          <View className={allClassName} onClick={this.productHouseHandle.bind(this, 'all')}>不限</View>
+          {curItemViews}
+        </View>
+      </View>
+    )
+  }
+  productHouseHandle (obj) {
+    if (obj === 'all') {
+      this.setState({
+        curPhObj: {},
+        searchText3: '',
+      }, () => {
+        this.searchComGetData()
+      })
+    } else {
+      this.setState({
+        curPhObj: obj,
+        searchText3: obj.key,
+      }, () => {
+        this.searchComGetData()
+      })
+    }
+    // if (curOp === 'all') {
+    //   this.setState({
+    //     curHouseTypeRange: []
+    //   })
+    // } else {
+    //   let { curHouseTypeRange } = this.state
+    //   let ed = false
+    //   let curI = 0
+    //   curHouseTypeRange.forEach((item, index) => {
+    //     if (curOp.val === item) {
+    //       ed = true
+    //       curI = index
+    //     }
+    //   })
+    //   if (ed) {
+    //     curHouseTypeRange.splice(curI, 1)
+    //   } else {
+    //     curHouseTypeRange.push(curOp.val)
+    //   }
+    //   this.setState({
+    //     curHouseTypeRange
+    //   })
+    // }
+  }
+  searchComGetData () {
+    this.setState({
+      page: 1,
+      searchIndex: -1,
+    }, () => {
+      this.getDataList()
+    })
+  }
+
+
+  searchIndex4Render () {
+    const dictData = Taro.getStorageSync('dictData')
+    // 房屋面积
+    const { houseAreaCur } = this.state
+    const house_area = dictData.house_area || []
+    const houseAreaViews = house_area.map(item =>{
+      let curClassName = "mp-op"
+      houseAreaCur.forEach(curVal =>{
+        if (curVal === item.val) {
+          curClassName = "mp-op cur"
+        }
+      })
+      return (
+        <View className={curClassName} key={item.val} onClick={this.comSelectHandle.bind(this, item, 'houseAreaCur')}>{item.key}</View>
+      )
+    })
+    const houseAreaAllClassName = houseAreaCur.length === 0 ? 'mp-op cur' : 'mp-op'
+    // 产品类型
+    const { productTypeCur } = this.state
+    const product_type = dictData.product_type || []
+    const productTypeViews = product_type.map(item =>{
+      let curClassName = "mp-op"
+      productTypeCur.forEach(curVal =>{
+        if (curVal === item.val) {
+          curClassName = "mp-op cur"
+        }
+      })
+      return (
+        <View className={curClassName} key={item.val} onClick={this.comSelectHandle.bind(this, item, 'productTypeCur')}>{item.key}</View>
+      )
+    })
+    const productTypeAllClassName = productTypeCur.length === 0 ? 'mp-op cur' : 'mp-op'
+    return (
+      <View className="more-pane">
+        {/* <View className="mp-item">
+          <View className="mp-title">房源面积</View>
+          <View className="mp-content">
+            <View className={houseAreaAllClassName} onClick={this.comSelectHandle.bind(this, 'all', 'houseAreaCur')}>不限</View>
+            {houseAreaViews}
+          </View>
+        </View> */}
+        {/* <View className="mp-item">
+          <View className="mp-title">产品类型</View>
+          <View className="mp-content">
+            <View className={productTypeAllClassName} onClick={this.comSelectHandle.bind(this, 'all', 'productTypeCur')}>不限</View>
+            {productTypeViews}
+          </View>
+        </View> */}
+      </View>
+    )
+  }
+  comSelectHandle (curOp, str) {
+    if (curOp === 'all') {
+      this.setState({
+        [str]: []
+      })
+    } else {
+      const state = this.state
+      let curStr = state[str]
+      let ed = false
+      let curI = 0
+      curStr.forEach((item, index) => {
+        if (curOp.val === item) {
+          ed = true
+          curI = index
+        }
+      })
+      if (ed) {
+        curStr.splice(curI, 1)
+      } else {
+        curStr.push(curOp.val)
+      }
+      this.setState({
+        [str]: curStr
+      })
+    }
+  }
+
+
+  renderTop () {
+    const { searchIndex, searchText1, searchText5, searchText3, searchText4 } = this.state
+    const { estate_name } = this.$router.params
+    return (
+      <View className="l-search-top t2">
+        <View className="st-nav">
+          <View className={(searchIndex === 3 || searchText3) ? 'stn-op col-2 cur' : 'stn-op col-2'} onClick={this.searchNavHandle.bind(this, 3)}>
+            <View className="stn-label">{searchText3 || '户型'}</View>
+            <View className="stn-sign"></View>
+          </View>
+          <View className={(searchIndex === 5 || searchText5) ? 'stn-op col-2 cur' : 'stn-op col-2'} onClick={this.searchNavHandle.bind(this, 5)}>
+            <View className="stn-label">{searchText5 || '更多'}</View>
+            <View className="stn-sign"></View>
+          </View>
+          {/* <View className={(searchIndex === 4 || searchText4) ? 'stn-op col-2 cur' : 'stn-op col-2'} onClick={this.searchNavHandle.bind(this, 4)}>
+            <View className="stn-label">{searchText4 || '更多'}</View>
+            <View className="stn-sign"></View>
+          </View> */}
+        </View>
+        <View className={searchIndex > 0 ? searchIndex === 4 ? 'st-content show2 more' : 'st-content show2' : 'st-content'}>
+          {
+            searchIndex === 3
+            &&
+            this.searchIndex3Render()
+          }
+          {
+            searchIndex === 5
+            &&
+            this.searchIndex5Render()
+          }
+          {/* {
+            searchIndex === 4
+            &&
+            this.searchIndex4Render()
+          } */}
+          {/* <View className="l-floor-footer t2">
+            <View className="lff-flex">
+              <View className="lff-btn t3" onClick={this.resetHandle.bind(this)} >重置</View>
+              <View className="lff-btn" onClick={this.saveHandle.bind(this)}>搜索</View>
+            </View>
+          </View> */}
+        </View>
+      </View>
+    )
+  }
+  searchNavHandle (index) {
+    // if (index === 5) {
+    //   this.openMSPopup()
+    //   return
+    // }
+    let { searchIndex } = this.state
+    searchIndex = index === searchIndex ? -1 : index
+    this.setState({
+      searchIndex
+    })
+  }
+  resetHandle () {
+    const { searchIndex } = this.state
+    if (searchIndex === 1) {
+      this.setState({
+        searchText1: '',
+        curPos: 'area_type',
+      })
+    }
+    if (searchIndex === 3) {
+      this.setState({
+        searchText3: '',
+        curHouseTypeRange: [],
+      })
+    }
+    if (searchIndex === 4) {
+      this.setState({
+        searchText4: '',
+        houseAreaCur: [],
+        productTypeCur: [],
+      })
+    }
+  }
+  saveHandle () {
+    const dictData = Taro.getStorageSync('dictData')
+    const {
+      searchIndex,
+      curPhObj,
+    } = this.state
+    // if (searchIndex === 4) {
+    //   let tagArr = []
+    //   houseAreaCur.forEach(v => {
+    //     tagArr.push(arrToObj(dictData.house_area)[v])
+    //   })
+    //   productTypeCur.forEach(v => {
+    //     tagArr.push(arrToObj(dictData.product_type)[v])
+    //   })
+    //   if (tagArr) {
+    //     this.setState({
+    //       searchText4: tagArr.join(',')
+    //     })
+    //   }
+    // }
+    this.setState({
+      page: 1,
+      searchIndex: -1,
+    }, () => {
+      this.getDataList()
+    })
+  }
+
+
+
+
+
+  openMSPopup (e) {
+    this.setState({
+      isEstateShow: true,
+      searchIndex: -1,
+    })
+  }
+  dealMSPopup (curVal, curCheckedArr) {
+    this.closeMSPopup()
+    if (curVal && curCheckedArr) {
+      const nameArr = curCheckedArr.map(item =>{
+        return item.estate_name
+      })
+      this.setState({
+        estateIdCur: curVal,
+        searchText5: nameArr.join(','),
+        page: 1,
+      }, () => {
+        this.getDataList()
+      })
+    } else {
+      this.setState({
+        estateIdCur: [],
+        searchText5: '',
+      })
+    }
+  }
+  closeMSPopup () {
+    this.setState({
+      isEstateShow: false,
+    })
+  }
+
+
+
+
+
+
+
+  getDataList () {
+    let { page_size, page, dataList, isListEmpty } = this.state
+    const { searchKey } = this.state
+    const {
+      estateIdCur,
+      curPhObj,
+      curSortObj,
+    } = this.state
+    let apiStr = 'apieshouselist'
+    let params = {
+      page,
+      page_size,
+      title: searchKey,
+      estate_id: estateIdCur.join(','),
+    }
+    if (curPhObj.val) {
+      const phArr = curPhObj.val.split('-')
+      // params.product_type = phArr[0]
+      params.house_type = phArr[1]
+    }
+    if (curSortObj.val) {
+      params.order_by = JSON.stringify(curSortObj.val)
+    }
+    Taro.api.room[apiStr](params).then(res => {
+      const curData = res.list || []
+      let isListEnd = false
+      if (curData.length > 0) {
+        if (page === 1) {
+          dataList = curData
+        } else {
+          dataList = dataList.concat(curData)
+        }
+        if (curData.length === page_size && res.total !== curData.length) {
+          isListEnd = false
+        } else {
+          isListEnd = true
+        }
+      }
+      if (curData.length === 0 && page === 1) {
+        isListEmpty = true
+        dataList = []
+      } else {
+        isListEmpty = false
+      }
+      this.setState({
+        dataList,
+        isListEnd,
+        isListEmpty,
+        isListLoading: false
+      })
+    })
+  }
+  onScrollToLower (e) {
+    let { isListEnd, isListLoading, page } = this.state
+    if (!isListEnd && !isListLoading) {
+      page++
+      this.setState({
+        page,
+        isListLoading: true
+      }, () => {
+        this.getDataList()
+      })
+    }
+  }
+
+  renderList () {
+    const { dataList, isListEnd, isListLoading, isListEmpty } = this.state
+    const hpV = require('@img/icon_hp_v.png')
+    const itemsList = dataList.map((item, index) => {
+      let FHstr = '未知楼层'
+      if (item.floor) {
+        const FH = Number(item.floor) || 1
+        const H = Number(item.storeys) || 1
+        if (FH > H * 0.6666) {
+          FHstr = '中高层'
+        } else if (FH > H * 0.33333) {
+          FHstr = '中楼层'
+        } else {
+          FHstr = '中低层'
+        }
+        if (FH === 1) FHstr = '一楼'
+        if (FH === H) FHstr = '顶楼'
+      }
+      let houseTypeStr = '未知户型'
+      if (item.house_type) {
+        let arr = item.house_type.split('-')
+        houseTypeStr = `${arr[0]}室${arr[1]}厅${arr[2]}卫`
+      }
+      const cTagStr = item.custom_tag || ''
+      const tagViews = cTagStr.split(',').map((tag, tagIndex) => {
+        return (
+          <View className="s" key={tagIndex}>{tag}</View>
+        )
+      })
+      return (
+        <View className="lhl-item col-1" key={index} onClick={this.linkHandle.bind(this, item)}>
+          <View className="lhl-img">
+            {
+              item.video
+              ?
+              <View className="vr-icon">
+                <Image src={hpV} className="i i1" />
+              </View>
+              : ''
+            }
+            <Image src={item.pri_image + '_xs'} className="img" />
+            <View className="f-t">{houseTypeStr} | {parseInt(item.area)}㎡</View>
+          </View>
+          <View className="lhl-info">
+            <View className="lhl-p1">{item.title}</View>
+            <View className="lhl-p2">{item.price}万
+              <View className="sub">单价:{parseInt(item.price * 10000 / item.area)}元/平</View>
+            </View>
+            <View className="lhl-p3">{FHstr}-{item.estate_name}</View>
+            <View className="lhl-sign">
+              {tagViews}
+            </View>
+          </View>
+        </View>
+      )
+    })
+    return (
+      <ScrollView
+        className='l-scroll-view'
+        scrollY
+        scrollWithAnimation
+        scrollTop="0"
+        lowerThreshold="30"
+        onScrollToLower={this.onScrollToLower.bind(this)}
+      >
+        <View className="l-house-list">
+          {itemsList}
+        </View>
+        <ListMore isListEnd={isListEnd} isListLoading={isListLoading} isListEmpty={isListEmpty} />
+      </ScrollView>
+    )
+  }
+
+
+  linkHandle (item) {
+    Taro.navigateTo({
+      url: `/pagesRoom/dtl?id=${item.id}`
+    })
+    // const appUserInfo = Taro.getStorageSync('APP_userInfo')
+    // if (appUserInfo.is_sale == 1) {
+    //   Taro.navigateTo({
+    //     url: `/pagesMore/center/uploadRoom2?id=${item.id}`
+    //   })
+    // } else {
+    //   Taro.navigateTo({
+    //     url: `/pagesRoom/dtl?id=${item.id}`
+    //   })
+    // }
+  }
+
+  linkMyRoom () {
+    Taro.reLaunch({
+      url: '/pagesRoom/listMy'
+    })
+  }
+  renderGoMy () {
+    const icon = require('@img/images/icon_my_room.png')
+    return (
+      <Image className="g-go-home" src={icon} onClick={this.linkMyRoom.bind(this)}/>
+    )
+  }
+
+
+  render () {
+    const { estateIdCur, isEstateShow } = this.state
+    const { estate_id } = this.$router.params
+    const estateMoreOptions = {skey: 'estate_name', api: `room.apiestatehouselist`, opKey: 'estate_name', opVal: 'estate_id'}
+    const appUserInfo = Taro.getStorageSync('APP_userInfo')
+    let isSale = false
+    if (appUserInfo.is_sale == 1) {
+      isSale = true
+    }
+    return (
+      <View className="l-box">
+        { isSale ? this.renderGoMy() : '' }
+        {this.renderSearch()}
+        {this.renderTop()}
+        {this.renderList()}
+        {
+          estate_id
+          ?
+          ''
+          :
+          <MultiSelect val={estateIdCur} moreOptions={estateMoreOptions} isShow={isEstateShow} initUpdate="no" bc={this.dealMSPopup.bind(this)} close={this.closeMSPopup.bind(this)}/>
+        }
+      </View>
+    )
+  }
+}
+
+export default Index

+ 31 - 0
src/pagesRoom/list2.scss

@@ -0,0 +1,31 @@
+@import '@css/mixin.scss';
+@import '@css/house-list.scss';
+@import '@css/search-top.scss';
+.l-box {
+  padding-top: calc(84px + 90px);
+}
+.l-scroll-view {
+  height: calc(100vh - 84px - 90px);
+  box-sizing: border-box;
+}
+.scoped-fixed {
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  z-index: 99;
+  background-color: #fff;
+}
+
+
+.lhl-info {
+  width: 300px;
+}
+
+
+.l-house-list .lhl-img {
+  height: 170rpx;
+  .img {
+    height: 170rpx;
+  }
+}

+ 4 - 2
src/pagesRoom/roomPrice2.jsx

@@ -50,9 +50,11 @@ class Index extends Component {
       const buildingNumList = res.list || []
       this.setState({
         buildingNumList,
-        curObj: buildingNumList[curNav]
+        curObj: buildingNumList[curNav] || {},
       }, () => {
-        this.getRoomList()
+        if (buildingNumList.length > 0) {
+          this.getRoomList()
+        }
       })
     })
   }