张延森 4 vuotta sitten
vanhempi
commit
770f44f910

+ 83
- 0
src/components/NumberRange/index.vue Näytä tiedosto

@@ -0,0 +1,83 @@
1
+<template>
2
+  <div class="number-range-box">
3
+    <div class="number-item">
4
+      <input class="number-input" placeholder="请输入" type="number" v-model="num1">
5
+    </div>
6
+    <div class="number-space">-</div>
7
+    <div class="number-item">
8
+      <input class="number-input" placeholder="请输入" type="number" v-model="num2">
9
+    </div>
10
+  </div>
11
+</template>
12
+
13
+<script>
14
+import {Cell} from 'vant'
15
+import { watch, ref } from 'vue'
16
+
17
+export default {
18
+  components: {
19
+    [Cell.name]: Cell,
20
+  },
21
+  props: {
22
+    title: String,
23
+    modelValue: Array,
24
+  },
25
+  emits: ['update:modelValue'],
26
+  setup(props, {emit}) {
27
+    const num1 = ref()
28
+    const num2 = ref()
29
+
30
+    watch(num1, (nw, od) => {
31
+      if (nw != od) {
32
+        emit('update:modelValue', [nw - 0, num2.value])
33
+      }
34
+    })
35
+    watch(num2, (nw, od) => {
36
+      if (nw != od) {
37
+        emit('update:modelValue', [num1.value, nw - 0])
38
+      }
39
+    })
40
+
41
+    watch(props.modelValue, (nw) => {
42
+      if (!nw || !nw.length) {
43
+        num1.value = undefined
44
+        num2.value = undefined
45
+        return
46
+      }
47
+
48
+      num1.value = nw[0]
49
+      num2.value = nw[1]
50
+    }, {immediate: true})
51
+
52
+    return {num1, num2}
53
+  }
54
+}
55
+</script>
56
+
57
+<style lang="less" scoped>
58
+.number-range-box {
59
+  display: flex;
60
+  align-items: center;
61
+  line-height: inherit;
62
+  text-align: left;
63
+
64
+  .number-item {
65
+    width: 100px;
66
+    flex: auto;
67
+  }
68
+
69
+  .number-space {
70
+    flex: none;
71
+    margin: 0 4px;
72
+  }
73
+
74
+  .number-input {
75
+    display: block;
76
+    box-sizing: border-box;
77
+    line-height: inherit;
78
+    outline: none;
79
+    border: none;
80
+    width: 100%;
81
+  }
82
+}
83
+</style>

+ 43
- 10
src/components/Picker/index.vue Näytä tiedosto

@@ -1,18 +1,33 @@
1 1
 <template>
2 2
   <div>
3
-    <div class="picker-item-body" @click="showPopup = true">{{text}}</div>
3
+    <div class="picker-item-body" @click="showPopup = true">
4
+      <span :class="{'picker-place-holder': isEmptyValue}">{{text}}</span>
5
+    </div>
4 6
     <van-popup v-model:show="showPopup" position="bottom">
5
-      <van-picker
6
-        :columns="columns"
7
-        @confirm="onConfirm"
8
-        @cancel="onCancel"
9
-      />
7
+      <template v-if="!loading">
8
+        <van-picker
9
+          :columns="columns"
10
+          @confirm="onConfirm"
11
+          @cancel="onCancel"
12
+        >
13
+        </van-picker>
14
+      </template>
15
+      <template v-else>
16
+        <van-picker
17
+          @confirm="onConfirm"
18
+          @cancel="onCancel"
19
+        >
20
+          <template #title>
21
+            <van-loading color="rgb(215, 94, 58)">请稍候...</van-loading>
22
+          </template>
23
+        </van-picker>
24
+      </template>
10 25
     </van-popup>
11 26
   </div>
12 27
 </template>
13 28
 
14 29
 <script>
15
-import { Popup, Picker } from 'vant'
30
+import { Popup, Picker, Loading } from 'vant'
16 31
 import { computed, ref, toRaw, unref } from 'vue'
17 32
 import { isEmpty } from '@/utils'
18 33
 
@@ -20,6 +35,7 @@ export default {
20 35
   components: {
21 36
     [Popup.name]: Popup,
22 37
     [Picker.name]: Picker,
38
+    [Loading.name]: Loading,
23 39
   },
24 40
   props: {
25 41
     options: Array,
@@ -30,12 +46,21 @@ export default {
30 46
   setup(props, { emit }) {
31 47
     const showPopup = ref(false)
32 48
 
49
+    const isEmptyValue = computed(() => {
50
+      return isEmpty(props.modelValue) || isEmpty(toRaw(props.modelValue)) || isEmpty(unref(props.modelValue))
51
+    })
52
+
33 53
     const text = computed(() => {
34
-      if (isEmpty(props.modelValue) || isEmpty(toRaw(props.modelValue)) || isEmpty(unref(props.modelValue))) {
54
+      if (isEmptyValue.value) {
35 55
         return props.placeholder
36 56
       }
37 57
 
38
-      return ((props.options || []).filter(x => x.value === props.modelValue)[0] || {}).text
58
+      const targetItem = (props.options || []).filter(x => x.value === props.modelValue)[0]
59
+      if (!targetItem) {
60
+        return props.modelValue
61
+      }
62
+
63
+      return targetItem.text
39 64
     })
40 65
 
41 66
     const columns = computed(() => {
@@ -50,12 +75,16 @@ export default {
50 75
 
51 76
     const onCancel = () => showPopup.value = false;
52 77
 
78
+    const loading = computed(() => !props.options.length)
79
+
53 80
     return {
54 81
       text,
55 82
       columns,
56 83
       showPopup,
57 84
       onConfirm,
58
-      onCancel
85
+      onCancel,
86
+      loading,
87
+      isEmptyValue,
59 88
     }
60 89
   }
61 90
 }
@@ -68,4 +97,8 @@ export default {
68 97
   height: 100%;
69 98
   text-align: left;
70 99
 }
100
+
101
+.picker-place-holder {
102
+  color: #aaa;
103
+}
71 104
 </style>

+ 1
- 1
src/store/models/dicts.js Näytä tiedosto

@@ -126,7 +126,7 @@ export default () => {
126 126
       url: '/comm/dict',
127 127
       params: { groupCode: key }
128 128
     }).then(res => {
129
-      dicts[key] = res
129
+      dicts[key] = (res || []).map(x => ({text: x.name, value: x.code}))
130 130
     })
131 131
   }
132 132
 

+ 261
- 102
src/view/secondhand/components/secondhandmorescreen/index.vue Näytä tiedosto

@@ -1,7 +1,7 @@
1 1
 <template>
2 2
   <div class="secondhandmorescreen">
3 3
     <van-search
4
-      v-model="serchValue"
4
+      v-model="searchValue"
5 5
       placeholder="请输入搜索关键词"
6 6
       :actions="searchActions"
7 7
       @select="onSearchSelect"
@@ -25,41 +25,102 @@
25 25
     <div>
26 26
       <van-form @submit="onSubmit">
27 27
         <van-cell-group title="区位">
28
-          <AreaQuery v-model="roomArea"></AreaQuery>
28
+        <van-row :gutter="12">
29
+          <van-col span="12">
30
+            <van-field label="区县">
31
+              <template #input>
32
+                <Picker
33
+                  placeholder="选择区县"
34
+                  :options="roomDistrictOptions"
35
+                  v-model="formData.roomDistrict"
36
+                />
37
+              </template>
38
+            </van-field>
39
+          </van-col>
40
+          <van-col span="12">
41
+            <van-field label="商圈">
42
+              <template #input>
43
+                <Picker
44
+                  placeholder="选择商圈"
45
+                  :options="roomBussinesOptions"
46
+                  v-model="formData.roomBussines"
47
+                />
48
+              </template>
49
+            </van-field>
50
+          </van-col>
51
+        </van-row>
29 52
         </van-cell-group>
30 53
         <van-cell-group title="房间要求">
31
-          <van-field name="number">
54
+          <van-field label="楼层" ex>
32 55
             <template #input>
33
-              <DemandQuery></DemandQuery>
56
+              <NumberRange v-model="roomFloors" />
57
+            </template>
58
+          </van-field>
59
+          <van-field label="面积">
60
+            <template #input>
61
+              <NumberRange v-model="roomSQ" />
62
+            </template>
63
+            <template #extra>㎡</template>
64
+          </van-field>
65
+          <van-field label="总价">
66
+            <template #input>
67
+              <NumberRange v-model="roomPrices" />
68
+            </template>
69
+            <template #extra>万</template>
70
+          </van-field>
71
+          <van-field label="户型">
72
+            <template #input>
73
+              <Picker
74
+                placeholder="请选择户型"
75
+                :options="roomTypeOptions"
76
+                v-model="formData.roomType"
77
+              />
78
+            </template>
79
+          </van-field>
80
+          <van-field label="装修">
81
+            <template #input>
82
+              <Picker
83
+                placeholder="请选择装修类型"
84
+                :options="decorationOptions"
85
+                v-model="formData.decoration"
86
+              />
87
+            </template>
88
+          </van-field>
89
+          <van-field label="房源状态">
90
+            <template #input>
91
+              <Picker
92
+                placeholder="请选择房源状态"
93
+                :options="roomStatusOptions"
94
+                v-model="formData.roomStatus"
95
+              />
96
+            </template>
97
+          </van-field>
98
+          <van-field label="实勘状态">
99
+            <template #input>
100
+              <Picker
101
+                placeholder="请选择实勘状态"
102
+                :options="rescStatusOptions"
103
+                v-model="formData.rescStatus"
104
+              />
34 105
             </template>
35 106
           </van-field>
36
-        </van-cell-group>
37
-        <van-cell-group title="户型">
38
-          <CheeckButtomQuery
39
-            v-model="state.housetype"
40
-            :options="housetypeoptions"
41
-          ></CheeckButtomQuery>
42
-        </van-cell-group>
43
-        <van-cell-group title="装修">
44
-          <CheeckButtomQuery
45
-            v-model="state.renovation"
46
-            :options="housetypeoptions"
47
-          ></CheeckButtomQuery>
48
-        </van-cell-group>
49
-        <van-cell-group title="房源状态">
50
-          <CheeckButtomQuery
51
-            v-model="state.housetype"
52
-            :options="housetypeoptions"
53
-          ></CheeckButtomQuery>
54
-        </van-cell-group>
55
-        <van-cell-group title="实勘状态">
56
-          <CheeckButtomQuery
57
-            v-model="state.housetype"
58
-            :options="housetypeoptions"
59
-          ></CheeckButtomQuery>
60 107
         </van-cell-group>
61 108
         <van-cell-group title="房间位置">
62
-          <PositionQuery></PositionQuery>
109
+          <van-row :gutter="12">
110
+            <van-col span="12">
111
+              <van-field label="楼栋" v-model="formData.roomBuild" placeholder="请输入" />
112
+            </van-col>
113
+            <van-col span="12">
114
+              <van-field label="单元" v-model="formData.roomUnit" placeholder="请输入" />
115
+            </van-col>
116
+          </van-row>
117
+          <van-row :gutter="12">
118
+            <van-col span="12">
119
+              <van-field label="房号" v-model="formData.roomFloor" placeholder="请输入" />
120
+            </van-col>
121
+            <van-col span="12">
122
+            </van-col>
123
+          </van-row>
63 124
         </van-cell-group>
64 125
 
65 126
         <div style="margin-top: 16px;">
@@ -67,7 +128,7 @@
67 128
             <van-action-bar-icon
68 129
               icon="replay"
69 130
               text="重置"
70
-              @click="onClickIcon"
131
+              @click="handleReset"
71 132
             />
72 133
 
73 134
             <van-action-bar-button
@@ -76,18 +137,6 @@
76 137
               native-type="submit"
77 138
             />
78 139
           </van-action-bar>
79
-          <!-- <van-row justify="center">
80
-            <van-col span="6">
81
-              <van-button block icon="replay" type="primary"
82
-                >重置</van-button
83
-              ></van-col
84
-            >
85
-            <van-col span="18">
86
-              <van-button round block type="primary" native-type="submit"
87
-                >确定</van-button
88
-              ></van-col
89
-            >
90
-          </van-row> -->
91 140
         </div>
92 141
       </van-form>
93 142
     </div>
@@ -98,7 +147,7 @@
98 147
 </template>
99 148
 
100 149
 <script>
101
-import { computed, reactive, ref } from "vue";
150
+import { computed, reactive, ref, watch } from "vue";
102 151
 import {
103 152
   Col,
104 153
   Row,
@@ -116,14 +165,10 @@ import {
116 165
   Icon,
117 166
   Popover,
118 167
 } from "vant";
119
-// import { useModel } from '@zjxpcyc/vue-tiny-store'
168
+import { useModel } from '@zjxpcyc/vue-tiny-store'
120 169
 
121
-import {
122
-  AreaQuery,
123
-  DemandQuery,
124
-  CheeckButtomQuery,
125
-  PositionQuery,
126
-} from "../../../../components/queryCompents";
170
+import Picker from "@/components/Picker";
171
+import NumberRange from "@/components/NumberRange";
127 172
 
128 173
 export default {
129 174
   name: "secondhandmorescreen",
@@ -143,11 +188,8 @@ export default {
143 188
     [ActionBarButton.name]: ActionBarButton,
144 189
     [Icon.name]: Icon,
145 190
     [Popover.name]: Popover,
146
-
147
-    AreaQuery,
148
-    DemandQuery,
149
-    CheeckButtomQuery,
150
-    PositionQuery,
191
+    Picker,
192
+    NumberRange,
151 193
   },
152 194
   props: {
153 195
     // options: [],
@@ -155,29 +197,141 @@ export default {
155 197
   data() {
156 198
     return {};
157 199
   },
158
-emits:["onBack"],
200
+  emits:["back", 'search'],
159 201
   setup(props,{emit}) {
160
-    // const { dicts, getBusinessCity } = useModel('dicts')
202
+    const formData = reactive({
203
+      // 楼盘
204
+      estateName: undefined,
205
+      // 房源
206
+      roomCodeId: undefined,
207
+      // 业主电话
208
+      ownerTel: undefined,
209
+      // 区县
210
+      roomDistrict: undefined,
211
+      // 商圈
212
+      roomBussines: undefined,
213
+      // 楼层1
214
+      floorMin: undefined,
215
+      // 楼层2
216
+      floorMax: undefined,
217
+      // 面积1
218
+      sqMin: undefined,
219
+      // 面积2
220
+      sqMax: undefined,
221
+      // 总价1 -- 注意单词拼写
222
+      pirceMin: undefined,
223
+      // 总价2 -- 注意单词拼写
224
+      priceMax: undefined,
225
+      // 户型
226
+      roomType: undefined,
227
+      // 装修
228
+      decoration: undefined,
229
+      // 房源状态
230
+      roomStatus: undefined,
231
+      // 实勘状态
232
+      rescStatus: undefined,
233
+      // 楼栋
234
+      roomBuild: undefined,
235
+      // 单元
236
+      roomUnit: undefined,
237
+      // 房号
238
+      roomFloor: undefined,
239
+    })
240
+
241
+    const { dicts, getBusinessCity, getDict } = useModel('dicts')
242
+    // 区县
243
+    const roomDistrictOptions = computed(() => {
244
+      const roomDistrictDict = dicts.roomDistrict
245
+      if (!roomDistrictDict) {
246
+        getBusinessCity(1)
247
+      }
248
+      return (roomDistrictDict || []).map(x => ({...x, text: x.label}))
249
+    })
250
+    // 商圈 - 依据区县联动
251
+    const roomBussinesOptions = computed(() => {
252
+      if (!formData.roomDistrict) {
253
+        return []
254
+      }
255
+
256
+      const roomBussinesDict = dicts.roomBussines
257
+      return (roomBussinesDict || []).map(x => ({...x, text: x.label}))
258
+    })
161 259
     
162
-    const roomDistrict = ref()
163
-    const roomBussines = ref()
164
-    const roomArea = computed({
165
-      get: () => ({roomDistrict: roomDistrict.value, roomBussines: roomBussines.value}),
166
-      set: val => {
167
-        roomDistrict.value = val.roomDistrict
168
-        roomBussines.value = val.roomBussines
260
+    watch(
261
+      () => formData.roomDistrict,
262
+      (nw) => {
263
+        dicts.roomBussines = []
264
+        formData.roomBussines = undefined
265
+        getBusinessCity(2, nw)
266
+      }
267
+    )
268
+
269
+    // 楼层
270
+    const roomFloors = computed({
271
+      get: () => [formData.floorMin, formData.floorMax],
272
+      set: (nw) => {
273
+        formData.floorMin = nw[0]
274
+        formData.floorMax = nw[1]
275
+      }
276
+    })
277
+
278
+    // 面积
279
+    const roomSQ = computed({
280
+      get: () => [formData.sqMin, formData.sqMax],
281
+      set: (nw) => {
282
+        formData.sqMin = nw[0]
283
+        formData.sqMax = nw[1]
169 284
       }
170 285
     })
171 286
 
287
+    // 总价
288
+    const roomPrices = computed({
289
+      get: () => [formData.pirceMin, formData.priceMax],
290
+      set: (nw) => {
291
+        formData.pirceMin = nw[0]
292
+        formData.priceMax = nw[1]
293
+      }
294
+    })
295
+
296
+    // 户型
297
+    const roomTypeOptions = computed(() => {
298
+      return dicts.roomType
299
+    })
300
+
301
+    // 装修
302
+    const decorationOptions = computed(() => {
303
+      const decorationDict = dicts.decoration || []
304
+      if (!decorationDict.length) {
305
+        getDict('decoration')
306
+      }
307
+
308
+      return decorationDict
309
+    })
310
+
311
+    // 房源状态
312
+    const roomStatusOptions = computed(() => {
313
+      const roomStatusDict = dicts.roomStatus || []
314
+      if (!roomStatusDict.length) {
315
+        getDict('roomStatus')
316
+      }
317
+
318
+      return roomStatusDict
319
+    })
172 320
 
321
+    // 实勘状态
322
+    const rescStatusOptions = computed(() => {
323
+      return dicts.rescStatus
324
+    })
325
+    
173 326
     const state = reactive({
174 327
       housetype: [],
175 328
       renovation: [],
176 329
     });
177
-    const serchValue = ref("");
330
+
331
+    const searchValue = ref("");
178 332
     const searchType = ref("楼盘");
179 333
     const showPopover = ref(false);
180
-     const phoneShow = ref(false);
334
+    const phoneShow = ref(false);
181 335
 
182 336
     // 通过 actions 属性来定义菜单选项
183 337
     const searchActions = [
@@ -185,62 +339,63 @@ emits:["onBack"],
185 339
       { text: "房源", value: "2" },
186 340
       { text: "业主电话", value: "3" },
187 341
     ];
188
-    const onSearchSelect = (action) => {
189
-      console.log("housetypeChange", action);
190 342
 
343
+    const onSearchSelect = (action) => {
191 344
       searchType.value = action.text;
345
+      searchValue.value = undefined
346
+      formData.estateName = undefined
347
+      formData.roomCodeId = undefined
348
+      formData.ownerTel = undefined
192 349
     };
193 350
 
194
-    const onHousetypeChange = (values) => {
195
-      console.log("housetypeChange", values);
351
+    watch(searchValue, (nw) => {
352
+      switch(searchType.value) {
353
+        case '楼盘':
354
+          formData.estateName = nw
355
+          break
356
+        case '房源':
357
+          formData.roomCodeId = nw
358
+          break
359
+        default:
360
+          formData.ownerTel = nw
361
+      }
362
+    })
196 363
 
197
-      state.housetype = values;
198
-    };
199
-    const onSubmit = (values) => {
200
-      console.log(state, "submit", values);
364
+    const onSubmit = () => {
365
+      emit('search', formData)
201 366
     };
202 367
 
203 368
    const onBack = ()=>{
204
-           console.log('onBack');
205
-     emit("onBack", 333);
369
+     emit("back");
206 370
    }
207 371
 
208
-    const housetypeoptions = [
209
-      {
210
-        title: "1室",
211
-        value: "a",
212
-      },
213
-      {
214
-        title: "2室",
215
-        value: "b",
216
-      },
217
-      {
218
-        title: "3室",
219
-        value: "c",
220
-      },
221
-      {
222
-        title: "3室及以上",
223
-        value: "d",
224
-      },
225
-      {
226
-        title: "全部",
227
-        value: "all",
228
-      },
229
-    ];
372
+   const handleReset = () => {
373
+     Object.keys(formData).forEach(k => {
374
+       formData[k] = undefined
375
+     })
376
+   }
230 377
 
231 378
     return {
232
-      roomArea,
379
+      formData,
380
+      roomDistrictOptions,
381
+      roomBussinesOptions,
382
+      roomFloors,
383
+      roomSQ,
384
+      roomPrices,
385
+      roomTypeOptions,
386
+      decorationOptions,
387
+      roomStatusOptions,
388
+      rescStatusOptions,
233 389
       phoneShow,
234
-      serchValue,
390
+      searchValue,
235 391
       searchType,
236 392
       state,
237 393
       onSubmit,
238
-      housetypeoptions,
239
-      onHousetypeChange,
240 394
       showPopover,
241 395
       searchActions,
242 396
       onSearchSelect,
243 397
       onBack,
398
+      handleReset,
244 399
     };
245 400
   },
246 401
 };
@@ -252,4 +407,8 @@ emits:["onBack"],
252 407
   text-align: left;
253 408
   background-color: #f4f4f4;
254 409
 }
410
+
411
+:deep(.van-field__label) {
412
+  width: 4.8em;
413
+}
255 414
 </style>

+ 15
- 7
src/view/secondhand/index.vue Näytä tiedosto

@@ -22,7 +22,7 @@
22 22
       v-model:show="moreShow"
23 23
       position="right"
24 24
       :style="{ width: '100%', height: '100%' }"
25
-      ><SecondHandMoreScreen  @onBack="moreShow=false"/>
25
+      ><SecondHandMoreScreen  @back="moreShow=false" @search="handleMoreSearch"/>
26 26
     </van-popup>
27 27
   </div>
28 28
 </template>
@@ -34,7 +34,7 @@ import { DropdownMenu, DropdownItem, List, Popup, Progress } from "vant";
34 34
 import secondhandscreen from "./components/secondhandscreen";
35 35
 import secondhandmorescreen from "./components/secondhandmorescreen";
36 36
 import secondhandcard from "./components/secondhandcard";
37
-import { computed, onMounted, reactive, ref } from "vue";
37
+import { computed, onMounted, ref } from "vue";
38 38
 import { router } from "../../router";
39 39
 
40 40
 export default {
@@ -56,17 +56,15 @@ export default {
56 56
   setup(props) {
57 57
     const moreShow = ref(false);
58 58
     const { list, loading, page, getList } = useModel('room')
59
-    const queryData=reactive({
59
+    // const queryData=reactive({
60
+
61
+    // })
60 62
 
61
-    })
62
-console.log(queryData)
63 63
     const finished = computed(() => page.pageNo && page.pageNo === page.endRow)
64 64
     const percent = computed(() => page.pageNo ? (page.pageNo * 100 / page.endRow) : 100)
65 65
 
66 66
     const onShowMore = () => {
67
-      
68 67
       moreShow.value = true;
69
-    
70 68
     };
71 69
 
72 70
     const onLoad = () => {
@@ -100,6 +98,15 @@ console.log(queryData)
100 98
       console.log(query,'query')
101 99
     }
102 100
 
101
+    const handleMoreSearch = searchParams => {
102
+      moreShow.value = false
103
+      list.value = []
104
+      getList({
105
+        pageNo: 1,
106
+        ...searchParams,
107
+      })
108
+    }
109
+
103 110
     onMounted(() => {
104 111
       // getList()
105 112
     })
@@ -115,6 +122,7 @@ console.log(queryData)
115 122
       onShowMore,
116 123
       toDetail,
117 124
       onSearch,
125
+      handleMoreSearch,
118 126
       // options,
119 127
       // getData,
120 128
     };