张延森 4 anni fa
parent
commit
f7a50bd900

+ 75
- 0
src/components/Picker/index.vue Vedi File

@@ -0,0 +1,75 @@
1
+<template>
2
+  <div>
3
+    <van-cell :title="title">
4
+      <div class="picker-item-body" @click="showPopup = true">{{value}}</div>
5
+    </van-cell>
6
+    <van-popup v-model:show="showPopup" position="bottom">
7
+      <van-picker
8
+        :title="title"
9
+        :columns="columns"
10
+        @confirm="onConfirm"
11
+        @cancel="onCancel"
12
+      />
13
+    </van-popup>
14
+  </div>
15
+</template>
16
+
17
+<script>
18
+import { Cell, Popup, Picker } from 'vant'
19
+import { computed, ref } from 'vue'
20
+
21
+export default {
22
+  components: {
23
+    [Cell.name]: Cell,
24
+    [Popup.name]: Popup,
25
+    [Picker.name]: Picker,
26
+  },
27
+  props: {
28
+    options: Array,
29
+    title: String,
30
+    placeholder: String,
31
+    modelValue: undefined,
32
+  },
33
+  emits: ['update:modelValue'],
34
+  setup(props, { emit }) {
35
+    const showPopup = ref(false)
36
+
37
+    const value = computed(() => {
38
+      if (props.modelValue === undefined || props.modelValue === null) {
39
+        return props.placeholder
40
+      }
41
+
42
+      return ((props.options || []).filter(x => x.value === props.modelValue)[0] || {}).text
43
+    })
44
+
45
+    const columns = computed(() => {
46
+      return (props.options || []).map(x => x.text)
47
+    })
48
+
49
+    const onConfirm = (value, index) => {
50
+      const val = ((props.options || [])[index] || {}).value
51
+      emit('update:modelValue', val)
52
+      showPopup.value = false
53
+    };
54
+
55
+    const onCancel = () => showPopup.value = false;
56
+
57
+    return {
58
+      value,
59
+      columns,
60
+      showPopup,
61
+      onConfirm,
62
+      onCancel
63
+    }
64
+  }
65
+}
66
+</script>
67
+
68
+<style lang="less" scoped>
69
+.picker-item-body {
70
+  cursor: pointer;
71
+  width: 100%;
72
+  height: 100%;
73
+  text-align: left;
74
+}
75
+</style>

+ 34
- 53
src/components/queryCompents/areaQuery/index.vue Vedi File

@@ -1,36 +1,32 @@
1 1
 <template>
2 2
   <div class="areaQuery">
3
-
4
-        <van-field
5
-          v-model="state.value"
6
-          readonly
7
-          clickable
8
-          :name="name"
9
-          :label="label"
10
-          placeholder="请选择"
11
-          @click="state.showCascader = true"
3
+    <van-row :gutter="12">
4
+      <van-col span="12">
5
+        <Picker
6
+          title="区县"
7
+          :options="roomDistrictOptions"
8
+          v-model="val1"
12 9
         />
13
-        <van-popup v-model:show="state.showCascader" position="bottom">
14
-          <van-cascader
15
-            :options="options"
16
-            @finish="onConfirm"
17
-            @close="state.showCascader = false"
18
-          />
19
-        </van-popup>
10
+      </van-col>
11
+      <van-col span="12">
12
+        
13
+      </van-col>
14
+      </van-row>
20 15
     </div>
21 16
 </template>
22 17
 
23 18
 <script>
24
-import { reactive } from 'vue';
25
-import {  Field, Popup, Cascader } from "vant";
19
+import { computed, ref } from 'vue';
20
+import { Col, Row } from "vant";
21
+import { useModel } from '@zjxpcyc/vue-tiny-store'
22
+import Picker from '../../Picker'
26 23
 
27 24
 export default {
28 25
   name: "areaQuery",
29 26
   components: {
30
-    [Field.name]: Field,
31
-    [Popup.name]: Popup,
32
-    [Cascader.name]: Cascader,
33
-    // [Picker.name]: Popup,
27
+    [Row.name]: Row,
28
+    [Col.name]: Col,
29
+    Picker,
34 30
   },
35 31
   props: {
36 32
     name:String,
@@ -40,40 +36,25 @@ export default {
40 36
   },
41 37
 
42 38
   setup() {
43
-    const state = reactive({
44
-      value: '',
45
-      showCascader:false,
46
-      
47
-    });
48
-
49
-    const options = [
50
-      {
51
-        text: '浙江省',
52
-        value: '330000',
53
-        children: [{ text: '杭州市', value: '330100' }],
54
-      },
55
-      {
56
-        text: '江苏省',
57
-        value: '320000',
58
-        children: [{ text: '南京市', value: '320100' }],
59
-      },
60
-    ];
61
-
62
-    const onConfirm = ({selectedOptions}) => {
63
-      state.showCascader = false;
39
+    const val1 = ref()
40
+    const val2 = ref()
64 41
 
65
-      state.value = selectedOptions.map((option) => option.text).join('/')
66
-
67
-      console.log(selectedOptions.map((option) => option.text).join('/'),'333333')
68
-        // .filter((item) => !!item)
69
-        // .map((item) => item.name)
70
-        // .join('/');
71
-    };
42
+    const { dicts, getBusinessCity } = useModel('dicts')
43
+    // 楼盘
44
+    // 区位
45
+    const roomDistrict = dicts.roomDistrict
46
+    if (!roomDistrict) {
47
+      getBusinessCity(1)
48
+    }
72 49
 
50
+    const roomDistrictOptions = computed(() => {
51
+      return (roomDistrict || []).map(x => ({...x, text: x.label}))
52
+    })
53
+    
73 54
     return {
74
-      state,
75
-      options,
76
-      onConfirm,
55
+      val1,
56
+      val2,
57
+      roomDistrictOptions,
77 58
     };
78 59
   },
79 60
 };

+ 1
- 2
src/layout/index.vue Vedi File

@@ -1,9 +1,8 @@
1 1
 <template>
2 2
   <div class="layout">
3 3
     <div>
4
-<router-view />
4
+      <router-view />
5 5
     </div>
6
-    
7 6
 
8 7
     <van-tabbar route>
9 8
       <van-tabbar-item replace to="/home" icon="home-o">首页</van-tabbar-item>

+ 7
- 7
src/router.js Vedi File

@@ -4,7 +4,8 @@ import {
4 4
 } from 'vue-router';
5 5
 
6 6
 
7
-const routes = [{
7
+const routes = [
8
+    {
8 9
         name: 'notFound',
9 10
         path: '/:path(.*)+',
10 11
         redirect: {
@@ -20,9 +21,12 @@ const routes = [{
20 21
         }
21 22
     },
22 23
     {
24
+        path: '/',
25
+        redirect: '/home',
23 26
         name: 'layout',
24 27
         component: () => import('./layout'),
25
-        children: [{
28
+        children: [
29
+            {
26 30
                 path: '/home',
27 31
                 component: () => import('./view/home'),
28 32
                 meta: {
@@ -111,12 +115,8 @@ router.beforeEach((to, from, next) => {
111 115
     if (title) {
112 116
         document.title = title;
113 117
     }
114
-    // if (to.name !== 'login' && !isAuthenticated) next({
115
-    //     name: 'login'
116
-    // })
117
-    // else 
118
-    next()
119 118
 
119
+    next()
120 120
 });
121 121
 
122 122
 export {

+ 2
- 0
src/store/index.js Vedi File

@@ -3,12 +3,14 @@ import loading from './models/loading'
3 3
 import shiro from './models/shiro'
4 4
 import dicts from './models/dicts'
5 5
 import user from './models/user'
6
+import room from './models/room'
6 7
 
7 8
 const store = createStore({
8 9
   loading,
9 10
   shiro,
10 11
   dicts,
11 12
   user,
13
+  room,
12 14
 })
13 15
 
14 16
 export default store

+ 31
- 0
src/store/models/room.js Vedi File

@@ -0,0 +1,31 @@
1
+import { reactive, ref } from "vue"
2
+import request from '@/utils/request'
3
+
4
+export default () => {
5
+  const loading = ref(false)
6
+  const list = ref([])
7
+  const page = reactive({})
8
+
9
+  const getList = data => {
10
+    loading.value = true
11
+    request({
12
+      loadingId: 'room.list',
13
+      url: '/room/list',
14
+      data: {
15
+        pageNo: 1,
16
+        pageSize: 10,
17
+        ...data,
18
+      }
19
+    }).then(res => {
20
+      const { pageNo, pageSize, endRow, result } = res || {}
21
+      Object.assign(page, {pageNo, pageSize, endRow})
22
+      list.value = pageNo <= 1 ? result : list.value.concat(list.value)
23
+      loading.value = false
24
+    }).catch(e => {
25
+      console.error(e)
26
+      loading.value = false
27
+    })
28
+  }
29
+
30
+  return {list, page, getList, loading}
31
+}

+ 5
- 9
src/utils/request/index.js Vedi File

@@ -2,18 +2,14 @@ import axios from 'axios'
2 2
 import {
3 3
   router
4 4
 } from '../../router'
5
-import {
6
-  useModel
7
-} from '@zjxpcyc/vue-tiny-store'
5
+import store from '../../store'
8 6
 
9 7
 // request 拦截器
10 8
 const requestInterceptor = config => {
11
-  if (config.loadingId) {
12
-    const {
13
-      setLoading
14
-    } = useModel('loading')
9
+  const loading = store.getState('loading')
15 10
 
16
-    config.setLoading = loading => setLoading(config.loadingId, loading)
11
+  if (config.loadingId) {
12
+    config.setLoading = state => loading.setLoading(config.loadingId, state)
17 13
     config.setLoading(true)
18 14
   }
19 15
 
@@ -64,6 +60,7 @@ const responseInterceptor = response => {
64 60
 
65 61
 // 错误处理
66 62
 const handleError = type => error => {
63
+  console.error(error)
67 64
   if (error.config.setLoading) {
68 65
     error.config.setLoading(false)
69 66
   }
@@ -74,7 +71,6 @@ const handleError = type => error => {
74 71
   } else {
75 72
     const errorMessage = error.message || error.msg || error
76 73
     console.error(`[${type}] ${errorMessage}`)
77
-    console.error(error)
78 74
     return Promise.reject(errorMessage)
79 75
   }
80 76
 }

+ 8
- 4
src/view/home/index.vue Vedi File

@@ -2,10 +2,10 @@
2 2
   <div class="home">
3 3
     <van-tabs
4 4
       v-model:active="active"
5
-      background="#e6e4e4"
6
-      color="#d75e3a"
5
+      background="#d75e3a"
6
+      color="#fff"
7 7
       line-width="30%"
8
-      title-active-color="#d75e3a"
8
+      title-active-color="#fff"
9 9
     >
10 10
       <van-tab title="二手房"><Secondhand /></van-tab>
11 11
       <van-tab title="租房"> <Renting /></van-tab>
@@ -38,4 +38,8 @@ export default {
38 38
 </script>
39 39
 
40 40
 <!-- Add "scoped" attribute to limit CSS to this component only -->
41
-<style scoped></style>
41
+<style scoped>
42
+/deep/ .van-tab {
43
+  color: #000;
44
+}
45
+</style>

+ 10
- 0
src/view/secondhand/components/secondhandmorescreen/index.vue Vedi File

@@ -116,6 +116,8 @@ import {
116 116
   Icon,
117 117
   Popover,
118 118
 } from "vant";
119
+import { useModel } from '@zjxpcyc/vue-tiny-store'
120
+
119 121
 import {
120 122
   AreaQuery,
121 123
   DemandQuery,
@@ -155,6 +157,14 @@ export default {
155 157
   },
156 158
 
157 159
   setup() {
160
+    const { dicts, getBusinessCity } = useModel('dicts')
161
+    // 楼盘
162
+    // 区位
163
+    const roomDistrict = dicts.roomDistrict
164
+    if (!roomDistrict) {
165
+      getBusinessCity(1)
166
+    }
167
+
158 168
     const state = reactive({
159 169
       housetype: [],
160 170
       renovation: [],

+ 27
- 37
src/view/secondhand/index.vue Vedi File

@@ -2,15 +2,16 @@
2 2
   <div class="secondhand">
3 3
     <SecondHandScreen  @click="()=>{}" @onShowMore="onShowMore" />
4 4
     <div>
5
+      <van-progress color="#d75e3a" :show-pivot="false" :stroke-width="1" :percentage="percent" />
5 6
       <van-list
6 7
         class="secondhand-main"
7
-        v-model:loading="state.loading"
8
-        :finished="state.finished"
8
+        v-model:loading="loading"
9
+        :finished="finished"
9 10
         finished-text="没有更多了"
10 11
         @load="onLoad"
11 12
       >
12 13
         <SecondHandCard
13
-          v-for="item in state.list"
14
+          v-for="item in list"
14 15
           :key="item.id"
15 16
           :datas="item"
16 17
           @click="toDetail()"
@@ -28,13 +29,13 @@
28 29
 
29 30
 <script>
30 31
 // import Vue from 'vue';
31
-import { DropdownMenu, DropdownItem, List, Popup } from "vant";
32
+import { useModel } from '@zjxpcyc/vue-tiny-store'
33
+import { DropdownMenu, DropdownItem, List, Popup, Progress } from "vant";
32 34
 import secondhandscreen from "./components/secondhandscreen";
33 35
 import secondhandmorescreen from "./components/secondhandmorescreen";
34 36
 import secondhandcard from "./components/secondhandcard";
35
-import { reactive, ref } from "vue";
37
+import { computed, onMounted, ref } from "vue";
36 38
 import { router } from "../../router";
37
-import request from "../../utils/request";
38 39
 
39 40
 export default {
40 41
   name: "secondhand",
@@ -43,6 +44,7 @@ export default {
43 44
     [DropdownItem.name]: DropdownItem,
44 45
     [List.name]: List,
45 46
     [Popup.name]: Popup,
47
+    [Progress.name]: Progress,
46 48
     SecondHandScreen: secondhandscreen,
47 49
     SecondHandCard: secondhandcard,
48 50
     SecondHandMoreScreen: secondhandmorescreen,
@@ -53,45 +55,25 @@ export default {
53 55
 
54 56
   setup(props) {
55 57
     const moreShow = ref(false);
58
+    const { list, loading, page, getList } = useModel('room')
59
+
60
+    const finished = computed(() => page.pageNo && page.pageNo === page.endRow)
61
+    const percent = computed(() => page.pageNo ? (page.pageNo * 100 / page.endRow) : 100)
56 62
 
57 63
     const onShowMore = () => {
58 64
       console.log("22");
59 65
       moreShow.value = true;
60 66
       console.log(moreShow, "22");
61 67
     };
62
-    const state = reactive({
63
-      list: [],
64
-      loading: false,
65
-      finished: false,
66
-    });
67
-
68
-    const pageInfo = reactive({
69
-      pageNo: 1,
70
-      pageSize: 10,
71
-    });
72
-
73
-    
74 68
 
75 69
     const onLoad = () => {
76
-      // 异步更新数据
77
-      // setTimeout 仅做示例,真实场景中一般为 ajax 请求
78
-      state.loading = true;
79
-      request({
80
-        url: "/room/list",
81
-        data: { ...pageInfo },
82
-      }).then((res) => {
83
-        console.log(res, "res");
84
-        state.list.push(...res.result);
85
-
86
-        state.loading = false;
87
-        pageInfo.pageNo += 1;
88
-
89
-        // 数据全部加载完成
90
-        // if (state.list.length >= 40) {
91
-        //   state.finished = true;
92
-        // }
93
-      });
70
+      // if (!loading.value) {
71
+        getList({
72
+          pageNo: page.pageNo + 1
73
+        })
74
+      // }
94 75
     };
76
+  
95 77
     const toDetail = () => {
96 78
       console.log(props, router, "333");
97 79
       router.push("/secondhand/detail");
@@ -110,8 +92,16 @@ export default {
110 92
 
111 93
     // getData();
112 94
 
95
+    onMounted(() => {
96
+      // getList()
97
+    })
98
+
113 99
     return {
114
-      state,
100
+      list,
101
+      loading,
102
+      percent,
103
+      page,
104
+      finished,
115 105
       onLoad,
116 106
       moreShow,
117 107
       onShowMore,

+ 1
- 0
vue.config.js Vedi File

@@ -7,6 +7,7 @@ module.exports = {
7 7
     config.resolve.alias.set("@", path.resolve("src"));
8 8
   },
9 9
   devServer: {
10
+    port: 9000,
10 11
     disableHostCheck: true,
11 12
     proxy: {
12 13
       '/mp': {