浏览代码

首次提交

AyaoJies 1 年之前
父节点
当前提交
9982370fe0
共有 100 个文件被更改,包括 9388 次插入0 次删除
  1. 47 0
      .gitignore
  2. 22 0
      AyaoJies-app/house-master/.gitignore
  3. 21 0
      AyaoJies-app/house-master/LICENSE
  4. 77 0
      AyaoJies-app/house-master/README.md
  5. 0 0
      AyaoJies-app/house-master/docs/.keep
  6. 0 0
      AyaoJies-app/house-master/docs/image/.keep
  7. 二进制
      AyaoJies-app/house-master/docs/image/house_qrcode.png
  8. 二进制
      AyaoJies-app/house-master/docs/image/manage1.png
  9. 二进制
      AyaoJies-app/house-master/docs/image/share.jpg
  10. 3 0
      AyaoJies-app/house-master/house-life/.eslintignore
  11. 19 0
      AyaoJies-app/house-master/house-life/.hbuilderx/launch.json
  12. 18 0
      AyaoJies-app/house-master/house-life/App.vue
  13. 21 0
      AyaoJies-app/house-master/house-life/LICENSE
  14. 52 0
      AyaoJies-app/house-master/house-life/common/http.interceptor.js
  15. 129 0
      AyaoJies-app/house-master/house-life/common/utils/appUpdate.js
  16. 156 0
      AyaoJies-app/house-master/house-life/common/utils/searchData.js
  17. 68 0
      AyaoJies-app/house-master/house-life/common/utils/tip.js
  18. 21 0
      AyaoJies-app/house-master/house-life/common/utils/wxGetAddress.js
  19. 180 0
      AyaoJies-app/house-master/house-life/components/likeFx/likeFx.vue
  20. 237 0
      AyaoJies-app/house-master/house-life/components/uni/u-city-select.vue
  21. 353 0
      AyaoJies-app/house-master/house-life/components/zy/addAllHouse.vue
  22. 348 0
      AyaoJies-app/house-master/house-life/components/zy/addSubHouse.vue
  23. 856 0
      AyaoJies-app/house-master/house-life/components/zy/filterDropdown.vue
  24. 31 0
      AyaoJies-app/house-master/house-life/libs/amap-wx.130.js
  25. 39 0
      AyaoJies-app/house-master/house-life/main.js
  26. 161 0
      AyaoJies-app/house-master/house-life/manifest.json
  27. 298 0
      AyaoJies-app/house-master/house-life/pages.json
  28. 189 0
      AyaoJies-app/house-master/house-life/pages/center/center.vue
  29. 321 0
      AyaoJies-app/house-master/house-life/pages/center/heart.vue
  30. 258 0
      AyaoJies-app/house-master/house-life/pages/center/history.vue
  31. 397 0
      AyaoJies-app/house-master/house-life/pages/center/order.vue
  32. 47 0
      AyaoJies-app/house-master/house-life/pages/center/tips.vue
  33. 243 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/cityList.vue
  34. 417 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/index.vue
  35. 0 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/js/city.js
  36. 0 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/js/getFirstLetter.js
  37. 25 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/js/qqmap-wx-jssdk.min.js
  38. 191 0
      AyaoJies-app/house-master/house-life/pages/chooseAddress/search.vue
  39. 47 0
      AyaoJies-app/house-master/house-life/pages/content/content.vue
  40. 138 0
      AyaoJies-app/house-master/house-life/pages/detail/addHouse.vue
  41. 592 0
      AyaoJies-app/house-master/house-life/pages/detail/detail.vue
  42. 136 0
      AyaoJies-app/house-master/house-life/pages/detail/evalList.vue
  43. 326 0
      AyaoJies-app/house-master/house-life/pages/detail/preHouse.vue
  44. 434 0
      AyaoJies-app/house-master/house-life/pages/index/index.vue
  45. 198 0
      AyaoJies-app/house-master/house-life/pages/location/location.vue
  46. 176 0
      AyaoJies-app/house-master/house-life/pages/login/account.vue
  47. 144 0
      AyaoJies-app/house-master/house-life/pages/login/code.vue
  48. 327 0
      AyaoJies-app/house-master/house-life/pages/login/login.vue
  49. 116 0
      AyaoJies-app/house-master/house-life/pages/login/problem.vue
  50. 145 0
      AyaoJies-app/house-master/house-life/pages/notice/notice.vue
  51. 142 0
      AyaoJies-app/house-master/house-life/pages/profile/aboutMe.vue
  52. 91 0
      AyaoJies-app/house-master/house-life/pages/profile/avatar.vue
  53. 119 0
      AyaoJies-app/house-master/house-life/pages/profile/password.vue
  54. 118 0
      AyaoJies-app/house-master/house-life/pages/profile/profile.vue
  55. 58 0
      AyaoJies-app/house-master/house-life/pages/profile/setting.vue
  56. 143 0
      AyaoJies-app/house-master/house-life/pages/search/search.vue
  57. 305 0
      AyaoJies-app/house-master/house-life/pages/search/searchList.vue
  58. 25 0
      AyaoJies-app/house-master/house-life/pages/webview/webview.vue
  59. 二进制
      AyaoJies-app/house-master/house-life/static/center-selected.png
  60. 二进制
      AyaoJies-app/house-master/house-life/static/center.png
  61. 363 0
      AyaoJies-app/house-master/house-life/static/common/js/touch-emulator.js
  62. 二进制
      AyaoJies-app/house-master/house-life/static/empty/default.png
  63. 二进制
      AyaoJies-app/house-master/house-life/static/favicon.ico
  64. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover1.png
  65. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover2.png
  66. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover3.png
  67. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover4.png
  68. 0 0
      AyaoJies-app/house-master/house-life/static/img/index/cover_2022/.keep
  69. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover1.png
  70. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover2.png
  71. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover3.png
  72. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover4.png
  73. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/swiper/swiper.jpg
  74. 二进制
      AyaoJies-app/house-master/house-life/static/img/index/swiper/swiper2.png
  75. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/1.png
  76. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/10.png
  77. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/11.png
  78. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/12.png
  79. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/13.png
  80. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/14.png
  81. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/15.png
  82. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/16.png
  83. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/17.png
  84. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/18.png
  85. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/19.png
  86. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/2.png
  87. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/20.png
  88. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/21.png
  89. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/22.png
  90. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/23.png
  91. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/24.png
  92. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/25.png
  93. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/26.png
  94. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/27.png
  95. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/28.png
  96. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/29.png
  97. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/3.png
  98. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/30.png
  99. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/31.png
  100. 二进制
      AyaoJies-app/house-master/house-life/static/img/likeFx/32.png

+ 47 - 0
.gitignore

@@ -0,0 +1,47 @@
+######################################################################
+# Build Tools
+
+.gradle
+/build/
+!gradle/wrapper/gradle-wrapper.jar
+
+target/
+!.mvn/wrapper/maven-wrapper.jar
+
+######################################################################
+# IDE
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+nbproject/private/
+build/*
+nbbuild/
+dist/
+nbdist/
+.nb-gradle/
+
+######################################################################
+# Others
+*.log
+*.xml.versionsBackup
+*.swp
+
+!*/build/*.java
+!*/build/*.html
+!*/build/*.xml
+rebel.xml
+
+/source-admin/src/main/resources/*.yml

+ 22 - 0
AyaoJies-app/house-master/.gitignore

@@ -0,0 +1,22 @@
+# Build and Release Folders
+bin-debug/
+bin-release/
+[Oo]bj/
+[Bb]in/
+
+# Other files and folders
+.settings/
+
+# Executables
+*.swf
+*.air
+*.ipa
+*.apk
+
+# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
+# should NOT be excluded as they contain compiler settings and other important
+# information for Eclipse / Flash Builder.
+/RuoYi/log.path_IS_UNDEFINED
+/RuoYi/ruoyi-admin/target
+/RuoYi/ruoyi-common/target
+config.js

+ 21 - 0
AyaoJies-app/house-master/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2021 詹Sir
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 77 - 0
AyaoJies-app/house-master/README.md

@@ -0,0 +1,77 @@
+```
+🕙 分享是一种美德,右上随手点个 🌟 Star,谢谢
+```
+
+### 平台简介
+
+多端适用的租房小程序,带管理员后台。是一个完整的项目,可以直接使用。
+
+1、使用Uniapp开发的前台,基于 Vue.js 开发所有前端应用的框架,开发者编写一套代码,可发布到iOS、Android、Web(响应式)、以及各种小程序
+
+2、使用[  **开源字节快速开发平台**  ](https://gitee.com/open-source-byte/source-vue)开发的后台
+,基于SpringBoot的权限管理系统,易读易懂、界面简洁美观。 核心技术采用Spring、MyBatis、Spring Security,系统功能完善,代码结构清晰
+
+### 在线体验
+
+- 官网地址:https://sourcebyte.vip
+- 开发文档:http://doc.sourcebyte.vip
+- 后台地址:http://boot.sourcebyte.vip
+- 小程序(打开微信扫一扫)
+
+<img src="https://sourcebyte.vip/profile/customer/site/news/qrcode.jpg"  width="220px" alt="小程序演示"/>
+
+***温馨提醒***
+
+1. 本项目仅适用于学习交流,并且`不提供无偿的`、 `不提供无偿的`、 `不提供无偿的` 维护修改服务(但可提issue)***
+2. 本项目不在任何平台出售,如有发现请积极举报
+3. 为了更好的体验,友情提示此项目是一个全栈项目,熟练掌握后你就比较牛掰了,认真刻苦的掌握它,累觉不爱ღ( ´・ᴗ・` )比心
+4. 不要只是白嫖,如果帮到你了麻烦***点个Star***
+5. 发现有问题?欢迎加入下方交流群一起探讨,或者直接提Issues
+
+### 项目简介
+
+本项目是2022年6月份左右的产物,花了大概两年时间做完。
+
+>
+项目虽然没有做的很完整,但是整体的数据架构还算是可以的,可以很容易进行功能完善和添加新功能。里面还有很多可以完善的地方,比如 `房源详情页`
+页面可以做的更加精细一些,可以添加`地图找房` 之类的功能等。
+
+原本是别人找我帮一家中介小店写的一个租房小程序,对方没给设计图、也没有提具体需求,只是让我凭感觉来做。在项目快完成的时候,介绍的那个人跑路了,所以就没有后续了,想着与其直接删除还不如开源分享给大家一起讨论学习。
+
+这个项目的经历也让我明白了一些事情,就是如果别人委托自己帮做项目的时候,不管项目的规模如何,在接受委托前一定要考虑清楚。特别是没有付定金的这种委托,一定要谨慎,不要期望那种说你先做着后面再谈钱,哪怕是跟你认识的人也是一样要谨慎。还有就是不提明确需求的也不要轻易接受,这种人很容易中途变卦的。如果不想清楚的话,就会浪费时间又浪费精力。
+
+> 本程序已经经过测试,可以直接使用,界面可以自己进行修改。本人热爱全栈,热爱vue,热爱java,热爱编程。
+> 由于本人的精力有限,还有很多地方没法完善,望指正!
+
+### 部分截图
+
+#### 1. 前台截图
+
+<img src="https://sourcebyte.vip/profile/customer/git/house-main1.png" width="100%" />
+<img src="https://sourcebyte.vip/profile/customer/git/house-main2.png" width="100%" />
+<img src="https://sourcebyte.vip/profile/customer/git/house-main3.png" width="100%" />
+
+#### 2. 后台截图
+
+![输入图片说明](https://gitee.com/open-source-byte/source-mall/raw/master/doc/5.png)
+![输入图片说明](https://gitee.com/open-source-byte/house/raw/master/docs/image/manage1.png)
+
+### 作者信息
+
+1. 作者:詹Sir
+2. 邮箱:261648947@qq.com
+
+### 关于技术栈
+
+* 前端技术栈 Uniapp、ES6、vue、vuex、vue-router、vue-cli、axios、element-ui
+* 后端技术栈 SpringBoot、MyBatis、Spring Security、Jwt、Redis、Mysql
+
+### QQ交流群
+
+|                                          1群(851042670)                                          |                                          2群(522723115)                                          |                                          3群(862649072)                                          |
+|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|:-----------------------------------------------------------------------------------------------:|
+| <img src="https://gitee.com/open-source-byte/source-vue/raw/master/doc/qq01.png" width="200px"> | <img src="https://gitee.com/open-source-byte/source-vue/raw/master/doc/qq02.png" width="200px"> | <img src="https://gitee.com/open-source-byte/source-vue/raw/master/doc/qq03.png" width="200px"> | 
+
+### 结语
+
+欢迎一起探讨,如果你觉得还可以,可以给我点一个star

+ 0 - 0
AyaoJies-app/house-master/docs/.keep


+ 0 - 0
AyaoJies-app/house-master/docs/image/.keep


二进制
AyaoJies-app/house-master/docs/image/house_qrcode.png


二进制
AyaoJies-app/house-master/docs/image/manage1.png


二进制
AyaoJies-app/house-master/docs/image/share.jpg


+ 3 - 0
AyaoJies-app/house-master/house-life/.eslintignore

@@ -0,0 +1,3 @@
+unpackage
+node_modules
+uview-ui

+ 19 - 0
AyaoJies-app/house-master/house-life/.hbuilderx/launch.json

@@ -0,0 +1,19 @@
+{
+  // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
+  // launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
+  "version": "0.0",
+  "configurations": [
+    {
+      "default": {
+        "launchtype": "remote"
+      },
+      "h5": {
+        "launchtype": "remote"
+      },
+      "mp-weixin": {
+        "launchtype": "remote"
+      },
+      "type": "uniCloud"
+    }
+  ]
+}

+ 18 - 0
AyaoJies-app/house-master/house-life/App.vue

@@ -0,0 +1,18 @@
+<script>
+export default {
+  onLaunch: function () {
+    console.log('App Launch')
+  },
+  onShow: function () {
+    console.log('App Show')
+  },
+  onHide: function () {
+    console.log('App Hide')
+  }
+}
+</script>
+
+<style lang="scss">
+@import "uview-ui/index.scss";
+/*每个页面公共css */
+</style>

+ 21 - 0
AyaoJies-app/house-master/house-life/LICENSE

@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2020 www.uviewui.com
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.

+ 52 - 0
AyaoJies-app/house-master/house-life/common/http.interceptor.js

@@ -0,0 +1,52 @@
+// 这里的vm,就是我们在vue文件里面的this,所以我们能在这里获取vuex的变量,比如存放在里面的token
+// 同时,我们也可以在此使用getApp().globalData,如果你把token放在getApp().globalData的话,也是可以使用的
+import config from "./config.js" // 全局配置文件
+const install = (Vue, vm) => {
+    Vue.prototype.$u.http.setConfig({
+        // baseUrl打包app时放开,h5模式下会和vue.config.js代理冲突,导致失效
+        baseUrl: config.baseUrl,
+
+    });
+    // 请求拦截,配置Token等参数
+    Vue.prototype.$u.http.interceptor.request = (config) => {
+        // config.header.Token = '5d33018e653d897fc259b42cf022c1b3';
+        // 方式一,存放在vuex的token,假设使用了uView封装的vuex方式,见:https://uviewui.com/components/globalVariable.html
+        // 自定义token头
+        // config.header.Authorization = vm.vuex_token;
+        return config;
+    };
+    // 响应拦截,判断状态码是否通过
+    Vue.prototype.$u.http.interceptor.response = (res) => {
+        // 如果把originalData设置为了true,这里得到将会是服务器返回的所有的原始数据
+        // 判断可能变成了res.statueCode,或者res.data.code之类的,请打印查看结果
+        if (res.code == 200) {
+            return res;
+        } else if (res.code == 301) {
+            vm.$u.toast('警告:' + res.msg);
+            return false;
+        } else if (res.code == 401) {
+            uni.reLaunch({
+                url: '../login/login'
+            })
+            vm.$u.toast('认证失败,请重新登录')
+            return false;
+        } else if (res.code == 403) {
+            uni.reLaunch({
+                url: '../login/login'
+            })
+            vm.$u.toast('认证失败,请重新登录')
+            return false;
+        } else if (res.code == 500) {
+            vm.$u.toast('错误:' + res.msg);
+            return false;
+        } else {
+            // 其他情况都认为是不合法的
+            vm.$u.toast('警告:' + res.msg);
+            return false;
+        }
+    };
+}
+
+export default {
+    install
+}

+ 129 - 0
AyaoJies-app/house-master/house-life/common/utils/appUpdate.js

@@ -0,0 +1,129 @@
+import config from "./config.js"
+//APP更新
+export default function appUpdate() {
+    console.log('start');
+    let baseUrl = config.baseUrl;
+    let version = config.version;
+    console.log(baseUrl);
+    // 打包时全局配置中设置该版本号
+    console.log(version);
+    console.log('开始更新');
+    var url = baseUrl + '/api/checkVersion'
+    // uni.request({
+    // 	url: url, //检查更新的服务器地址
+    // 	success: (res) => {
+    // 		let remoteVersion = res.data.obj.title
+    // 		plus.runtime.getProperty(plus.runtime.appid, function(wgtinfo) {
+    // 			let client_version = wgtinfo.version
+
+    // 			let needUpdated = false;
+
+    // 			var flag_update = needUpdated
+    // 			var flag_hot = false;
+    // 			if (flag_update) {
+    // 				let downUrl = host + '/appController.do?download&Token=' + token + '&id=' + res.data.obj.id
+    // 				// 提醒用户更新
+    // 				uni.showModal({
+    // 					title: '更新提示',
+    // 					showCancel: false,
+    // 					content: res.data.obj.des,
+    // 					success: (e) => {
+
+    // 						if (e.confirm) {
+
+    // 							if (plus.os.name.toLowerCase() == 'ios') {
+    // 								// 跳转到下载页面
+    // 								plus.runtime.openURL(downUrl)
+    // 							} else {
+    // 								var dtask = plus.downloader.createDownload(
+    // 									downUrl, {},
+    // 									function(d, status) {
+    // 										uni.showToast({
+    // 											title: '下载完成',
+    // 											mask: false,
+    // 											duration: 1000
+    // 										});
+    // 										// 下载完成
+    // 										if (status == 200) {
+    // 											plus.runtime.install(plus.io.convertLocalFileSystemURL(d.filename), {}, e => e, function(error) {
+    // 												uni.showToast({
+    // 													title: '安装失败-01',
+    // 													mask: false,
+    // 													duration: 1500
+    // 												});
+    // 											})
+    // 										} else {
+    // 											uni.showToast({
+    // 												title: '更新失败-02',
+    // 												mask: false,
+    // 												duration: 1500
+    // 											});
+    // 										}
+    // 									});
+    // 								try {
+    // 									dtask.start(); // 开启下载的任务
+    // 									var prg = 0;
+    // 									var showLoading = plus.nativeUI.showWaiting("正在下载"); //创建一个showWaiting对象
+    // 									dtask.addEventListener('statechanged', function(
+    // 										task,
+    // 										status
+    // 									) {
+    // 										// 给下载任务设置一个监听 并根据状态  做操作
+    // 										switch (task.state) {
+    // 											case 1:
+    // 												showLoading.setTitle("正在下载");
+    // 												break;
+    // 											case 2:
+    // 												showLoading.setTitle("已连接到服务器");
+    // 												break;
+    // 											case 3:
+    // 												prg = parseInt(
+    // 													(parseFloat(task.downloadedSize) /
+    // 														parseFloat(task.totalSize)) *
+    // 													100
+    // 												);
+    // 												// showLoading.setTitle("  正在下载" + prg + "%  ");
+    // 												showLoading.setTitle("  正在下载中...");
+    // 												break;
+    // 											case 4:
+    // 												plus.nativeUI.closeWaiting();
+    // 												//下载完成
+    // 												break;
+    // 										}
+    // 									});
+    // 								} catch (err) {
+    // 									plus.nativeUI.closeWaiting();
+    // 									uni.showToast({
+    // 										title: '更新失败-03',
+    // 										mask: false,
+    // 										duration: 1500
+    // 									});
+    // 								}
+    // 							}
+    // 						}
+    // 					}
+    // 				})
+    // 			} else if (flag_hot) {
+    // 				uni.downloadFile({
+    // 					url: res.data.wgtUrl,
+    // 					success: (downloadResult) => {
+    // 						console.log(downloadResult.tempFilePath)
+    // 						if (downloadResult.statusCode === 200) {
+    // 							plus.nativeUI.toast(`正在热更新!${res.data.versionCode}`);
+    // 							plus.runtime.install(downloadResult.tempFilePath, {
+    // 								force: false
+    // 							}, function() {
+    // 								plus.nativeUI.toast("热更新成功");
+    // 								plus.runtime.restart();
+    // 							}, function(e) {
+    // 								console.log(e)
+    // 								plus.nativeUI.toast(`热更新失败:${e.message}`);
+    // 							});
+    // 						}
+    // 					}
+    // 				});
+    // 			}
+    // 		});
+    // 	}
+    // })
+}

+ 156 - 0
AyaoJies-app/house-master/house-life/common/utils/searchData.js

@@ -0,0 +1,156 @@
+//0.0.4版本起 返回结果将有两部分组成:
+/*
+{
+	index:[],	//旧版本的下标数组形式
+	value:[]	//菜单中的valve,结构和下标结果数组一样,只是把下标替换成了value而已
+}
+*/
+// 以下演示数据中,我故意把value设置成跟name一样,只是为了方便演示,使示例更加易懂,实际使用时候value应该是一个标识,给后台识别所用的.
+// 数据较长,请仔细查看。
+export default [{
+    "name": '小区',
+    "type": 'hierarchy',
+    "submenu": [
+        {
+            "name": "不限",
+            "value": ""
+        },
+    ]
+},
+    {
+        "name": '方式',
+        "type": 'hierarchy',
+        "submenu": [
+            {
+                "name": "不限",
+                "value": ""
+            },
+            {
+                "name": "整租",
+                "value": "0"
+            },
+            {
+                "name": "合租",
+                "value": "1"
+            },
+        ]
+    },
+    {
+        "name": '租金',
+        "type": 'hierarchy',
+        "submenu": [
+            {
+                "name": "不限",
+                "value": ""
+            },
+            {
+                "name": "<1000元",
+                "value": "1000"
+            },
+            {
+                "name": "1000-1500元",
+                "value": "1500"
+            },
+            {
+                "name": "1500-2000元",
+                "value": "2000"
+            },
+            {
+                "name": "2000-3000元",
+                "value": "3000"
+            },
+            {
+                "name": "3000-4500元",
+                "value": "4500"
+            },
+            {
+                "name": "<6000元",
+                "value": "6000"
+            }
+        ]
+    },
+    {
+        "name": '筛选',
+        "type": 'radio',
+        "submenu": [{
+            "name": "居室",
+            "submenu": [{
+                "name": "一室",
+                "value": "一室"
+            },
+                {
+                    "name": "二室",
+                    "value": "二室"
+                },
+                {
+                    "name": "三室",
+                    "value": "三室"
+                },
+                {
+                    "name": "四室",
+                    "value": "四室"
+                }
+            ]
+        },
+            {
+                "name": "装修",
+                "submenu": [
+                    {
+                        "name": "简装",
+                        "value": "简装",
+                    },
+                    {
+                        "name": "中装",
+                        "value": "中装",
+                    },
+                    {
+                        "name": "精装修",
+                        "value": "精装修"
+                    },
+                    {
+                        "name": "豪装",
+                        "value": "豪装"
+                    }
+                ]
+            },
+            {
+                "name": "房屋亮点",
+                "submenu": [
+                    {
+                        "name": "独卫",
+                        "value": "独卫"
+                    },
+                    {
+                        "name": "独立阳台",
+                        "value": "独立阳台"
+                    },
+                    {
+                        "name": "精装修",
+                        "value": "精装修"
+                    },
+                    {
+                        "name": "智能锁",
+                        "value": "智能锁"
+                    },
+                    {
+                        "name": "可短租",
+                        "value": "可短租"
+                    },
+                    {
+                        "name": "首次出租",
+                        "value": "首次出租"
+                    },
+                    {
+                        "name": "免物业费",
+                        "value": "免物业费"
+                    },
+                    {
+                        "name": "民用水电",
+                        "value": "民用水电"
+                    },
+                ]
+            }
+        ]
+    }
+]
+

+ 68 - 0
AyaoJies-app/house-master/house-life/common/utils/tip.js

@@ -0,0 +1,68 @@
+// 不含icon提示框
+const toast = str => {
+    return new Promise((resolve, reject) => {
+        uni.showToast({
+            title: str,
+            icon: "none",
+            duration: 3000,
+            success: () => {
+                setTimeout(() => {
+                    resolve
+                }, 3000)
+            }
+        })
+    })
+};
+// 成功提示框
+const successToast = str => {
+    return new Promise((resolve, reject) => {
+        uni.showToast({
+            title: str,
+            icon: "success",
+            duration: 3000,
+            success: () => {
+                setTimeout(() => {
+                    resolve()
+                }, 3000)
+            }
+        })
+    })
+};
+// loading
+const showLoading = () => {
+    return new Promise((resolve, reject) => {
+        uni.showLoading({
+            success: () => {
+                resolve()
+            }
+        })
+    })
+};
+// tipLoading ==>提示loading
+const tipLoading = str => {
+    return new Promise((resolve, reject) => {
+        uni.showLoading({
+            title: str,
+            success: () => {
+                resolve()
+            }
+        })
+    })
+};
+// 隐藏loading
+const hideLoading = () => {
+    return new Promise((resolve, reject) => {
+        uni.hideLoading({
+            success: () => {
+                resolve()
+            }
+        })
+    })
+};
+export default {
+    toast: toast,
+    successToast: successToast,
+    showLoading: showLoading,
+    tipLoading: tipLoading,
+    hideLoading: hideLoading,
+}

+ 21 - 0
AyaoJies-app/house-master/house-life/common/utils/wxGetAddress.js

@@ -0,0 +1,21 @@
+// import amapFile from '../../libs/amap-wx.130.js'
+
+// const myAmapFun = new amapFile.AMapWX({
+// 	// 申请的高德key值
+// 	key: '4ef3b3b42d8bb823529908dc93414127'
+// }); //创建一个实例化对象
+
+// export default function wxGetAddress({longitude,latitude}) {
+//     //根据传递进来经纬度进行反解析,调用的是高德给的方法
+// 	return new Promise((resolve, reject) => {
+// 		myAmapFun.getRegeo({
+// 			location: `${longitude},${latitude}`,
+// 			success: (res) => {
+// 				resolve(res[0])
+// 			},
+// 			fail: (err) => {
+// 				resolve(null)
+// 			}
+// 		})
+// 	})
+// }

+ 180 - 0
AyaoJies-app/house-master/house-life/components/likeFx/likeFx.vue

@@ -0,0 +1,180 @@
+<template>
+  <view class="">
+    <canvas :style="'width:' + width + 'px;height:' + height + 'px'" canvas-id="bubble" class="like-fx"></canvas>
+  </view>
+</template>
+
+<script>
+export default {
+  name: 'LikeFx',
+  data() {
+    return {
+      queue: {},
+      ctx: null,
+      timer: 0
+    }
+  },
+  props: {
+    height: {
+      type: Number,
+      default: 1920
+    },
+    width: {
+      type: Number,
+      default: 375
+    }
+  },
+  mounted() {
+    this.ctx = uni.createCanvasContext("bubble")
+    this.queue = {}
+    console.log('likeFx mounted');
+  },
+  destroyed() {
+    console.log('likeFx destoryed');
+    this.clearTimer()
+  },
+  methods: {
+    /**点赞 */
+    likeClick() {
+      console.log('开始点赞啦');
+      const image = "/static/img/likeFx/" + this.getRandomInt(1, 33) + ".png";
+      const anmationData = {
+        id: new Date().getTime(),
+        timer: 0,
+        opacity: 0,
+        pathData: this.generatePathData(),
+        image: image,
+        factor: {
+          // speed: 0.0009, // 运动速度,值越小越慢
+          // t: 0.4//  贝塞尔函数系数,当为0,就是从无到有,这时候屏幕高度也要调一下
+          speed: 0.0006, // 运动速度,值越小越慢
+          t: 0.6 //  贝塞尔函数系数,当为0,就是从无到有,这时候屏幕高度也要调一下
+        }
+      };
+      if (Object.keys(this.queue).length > 0) {
+        this.queue[anmationData.id] = anmationData;
+      } else {
+        this.queue[anmationData.id] = anmationData;
+        this.bubbleAnimate();
+      }
+
+      // console.log(image, this.queue);
+    },
+    /**获取最大最小随机值 */
+    getRandom(min, max) {
+      return Math.random() * (max - min) + min;
+    },
+    /**获取最大最小之前随机值的整数 */
+    getRandomInt(min, max) {
+      return Math.floor(Math.random() * (max - min + 1)) + min;
+    },
+    /**获取图片路径 */
+    generatePathData() {
+      let width = this.width,
+          height = this.height;
+      const p0 = {
+        x: 0.72 * width,
+        y: height
+      };
+      const p1 = {
+        x: this.getRandom(0.22 * width, 0.33 * width),
+        y: this.getRandom(0.5 * height, 0.75 * height)
+      };
+      const p2 = {
+        x: this.getRandom(0, 0.88 * width),
+        y: this.getRandom(0.25 * height, 0.5 * height)
+      };
+      const p3 = {
+        x: this.getRandom(0, 0.88 * width),
+        y: this.getRandom(0, 0.125 * height)
+      };
+      return [p0, p1, p2, p3];
+    },
+    /**更新图片的最新运动路径 */
+    updatePath(data, factor) {
+      const p0 = data[0];
+      const p1 = data[1];
+      const p2 = data[2];
+      const p3 = data[3];
+
+      const t = factor.t;
+
+      /*计算多项式系数 (下同)*/
+      const cx1 = 3 * (p1.x - p0.x);
+      const bx1 = 3 * (p2.x - p1.x) - cx1;
+      const ax1 = p3.x - p0.x - cx1 - bx1;
+
+      const cy1 = 3 * (p1.y - p0.y);
+      const by1 = 3 * (p2.y - p1.y) - cy1;
+      const ay1 = p3.y - p0.y - cy1 - by1;
+
+      const x = ax1 * (t * t * t) + bx1 * (t * t) + cx1 * t + p0.x;
+      const y = ay1 * (t * t * t) + by1 * (t * t) + cy1 * t + p0.y;
+      // console.log(data, x, y);
+      return {
+        x,
+        y
+      };
+    },
+    /**点赞动画 */
+    bubbleAnimate() {
+      let width = this.width,
+          height = this.height;
+      Object.keys(this.queue).forEach(key => {
+        const anmationData = this.queue[+key];
+        const {
+          x,
+          y
+        } = this.updatePath(
+            anmationData.pathData,
+            anmationData.factor
+        );
+        const speed = anmationData.factor.speed;
+        anmationData.factor.t += speed;
+
+        var curWidth = 30;
+        curWidth = (height - y) / 1.5;
+        curWidth = Math.min(30, curWidth);
+
+        var curAlpha = anmationData.opacity;
+        curAlpha = y / (0.3 * height); //消失的高度适当调一下
+        curAlpha = Math.min(1, curAlpha);
+        this.ctx.globalAlpha = curAlpha;
+        this.ctx.drawImage(anmationData.image, x - curWidth / 2, y, curWidth, curWidth);
+        // this.ctx.setFillStyle('red')
+        // this.ctx.fillRect(x - curWidth / 2, y, 50, 50)
+        if (anmationData.factor.t > 1) {
+          delete this.queue[anmationData.id];
+        }
+        if (y > height) {
+          delete this.queue[anmationData.id];
+        }
+      });
+      this.ctx.draw();
+      if (Object.keys(this.queue).length > 0) {
+        this.timer = setTimeout(() => {
+          this.bubbleAnimate();
+        }, 5);
+      } else {
+        this.clearTimer()
+        this.ctx.draw(); // 清空画面
+      }
+    },
+    clearTimer() {
+      if (this.timer) {
+        clearTimeout(this.timer)
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.like-fx {
+  position: fixed;
+  right: 0;
+  z-index: 1024;
+  pointer-events: none;
+  /* background-color: red; */
+}
+</style>

+ 237 - 0
AyaoJies-app/house-master/house-life/components/uni/u-city-select.vue

@@ -0,0 +1,237 @@
+<template>
+  <u-popup v-model="value" :closeable="true" :mask="true" :maskCloseAble="maskCloseAble" :popup="false" :safe-area-inset-bottom="true"
+           :z-index="uZIndex" close-icon-color="#ffffff" mode="bottom" @close="close">
+    <u-tabs v-if="value" ref="tabs" :current="tabsIndex" :is-scroll="true" :list="genTabsList"
+            @change="tabsChange"></u-tabs>
+    <view class="area-box">
+      <view :class="{ 'change':isChange }" class="u-flex">
+        <view class="area-item">
+          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
+            <scroll-view :scroll-y="true" style="height: 100%">
+              <u-cell-group>
+                <u-cell-item v-for="(item,index) in provinces" :key="index" :arrow="false" :index="index"
+                             :title="item.label"
+                             @click="provinceChange">
+                  <u-icon v-if="isChooseP&&province===index" slot="right-icon" name="checkbox-mark" size="34"></u-icon>
+                </u-cell-item>
+              </u-cell-group>
+            </scroll-view>
+          </view>
+        </view>
+        <view class="area-item">
+          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
+            <scroll-view :scroll-y="true" style="height: 100%">
+              <u-cell-group v-if="isChooseP">
+                <u-cell-item v-for="(item,index) in citys" :key="index" :arrow="false" :index="index"
+                             :title="item.label"
+                             @click="cityChange">
+                  <u-icon v-if="isChooseC&&city===index" slot="right-icon" name="checkbox-mark" size="34"></u-icon>
+                </u-cell-item>
+              </u-cell-group>
+            </scroll-view>
+          </view>
+        </view>
+
+        <view class="area-item">
+          <view class="u-padding-10 u-bg-gray" style="height: 100%;">
+            <scroll-view :scroll-y="true" style="height: 100%">
+              <u-cell-group v-if="isChooseC">
+                <u-cell-item v-for="(item,index) in areas" :key="index" :arrow="false" :index="index"
+                             :title="item.label"
+                             @click="areaChange">
+                  <u-icon v-if="isChooseA&&area===index" slot="right-icon" name="checkbox-mark" size="34"></u-icon>
+                </u-cell-item>
+              </u-cell-group>
+            </scroll-view>
+          </view>
+        </view>
+      </view>
+    </view>
+  </u-popup>
+</template>
+
+<script>
+import provinces from "uview-ui/libs/util/province.js";
+import citys from "uview-ui/libs/util/city.js";
+import areas from "uview-ui/libs/util/area.js";
+
+/**
+ * city-select 省市区级联选择器
+ * @property {String Number} z-index 弹出时的z-index值(默认1075)
+ * @property {Boolean} mask-close-able 是否允许通过点击遮罩关闭Picker(默认true)
+ * @property {String} default-region 默认选中的地区,中文形式
+ * @property {String} default-code 默认选中的地区,编号形式
+ */
+export default {
+  name: 'u-city-select',
+  props: {
+    // 通过双向绑定控制组件的弹出与收起
+    value: {
+      type: Boolean,
+      default: false
+    },
+    // 默认显示的地区,可传类似["河北省", "秦皇岛市", "北戴河区"]
+    defaultRegion: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    // 默认显示地区的编码,defaultRegion和areaCode同时存在,areaCode优先,可传类似["13", "1303", "130304"]
+    areaCode: {
+      type: Array,
+      default() {
+        return [];
+      }
+    },
+    // 是否允许通过点击遮罩关闭Picker
+    maskCloseAble: {
+      type: Boolean,
+      default: true
+    },
+    // 弹出的z-index值
+    zIndex: {
+      type: [String, Number],
+      default: 0
+    }
+  },
+  data() {
+    return {
+      cityValue: "",
+      isChooseP: false, //是否已经选择了省
+      province: 0, //省级下标
+      provinces: provinces,
+      isChooseC: false, //是否已经选择了市
+      city: 0, //市级下标
+      citys: citys[0],
+      isChooseA: false, //是否已经选择了区
+      area: 0, //区级下标
+      areas: areas[0][0],
+      tabsIndex: 0,
+    }
+  },
+  mounted() {
+    this.init();
+  },
+  computed: {
+    isChange() {
+      return this.tabsIndex > 1;
+    },
+    genTabsList() {
+      let tabsList = [{
+        name: "请选择"
+      }];
+      if (this.isChooseP) {
+        tabsList[0]['name'] = this.provinces[this.province]['label'];
+        tabsList[1] = {
+          name: "请选择"
+        };
+      }
+      if (this.isChooseC) {
+        tabsList[1]['name'] = this.citys[this.city]['label'];
+        tabsList[2] = {
+          name: "请选择"
+        };
+      }
+      if (this.isChooseA) {
+        tabsList[2]['name'] = this.areas[this.area]['label'];
+      }
+      return tabsList;
+    },
+    uZIndex() {
+      // 如果用户有传递z-index值,优先使用
+      return this.zIndex ? this.zIndex : this.$u.zIndex.popup;
+    }
+  },
+  methods: {
+    init() {
+      if (this.areaCode.length == 3) {
+        this.setProvince("", this.areaCode[0]);
+        this.setCity("", this.areaCode[1]);
+        this.setArea("", this.areaCode[2]);
+      } else if (this.defaultRegion.length == 3) {
+        this.setProvince(this.defaultRegion[0], "");
+        this.setCity(this.defaultRegion[1], "");
+        this.setArea(this.defaultRegion[2], "");
+      }
+      ;
+    },
+    setProvince(label = "", value = "") {
+      this.provinces.map((v, k) => {
+        if (value ? v.value == value : v.label == label) {
+          this.provinceChange(k);
+        }
+      })
+    },
+    setCity(label = "", value = "") {
+      this.citys.map((v, k) => {
+        if (value ? v.value == value : v.label == label) {
+          this.cityChange(k);
+        }
+      })
+    },
+    setArea(label = "", value = "") {
+      this.areas.map((v, k) => {
+        if (value ? v.value == value : v.label == label) {
+          this.isChooseA = true;
+          this.area = k;
+        }
+      })
+    },
+    close() {
+      this.$emit('input', false);
+    },
+    tabsChange(index) {
+      this.tabsIndex = index;
+    },
+    provinceChange(index) {
+      this.isChooseP = true;
+      this.isChooseC = false;
+      this.isChooseA = false;
+      this.province = index;
+      this.citys = citys[index];
+      this.tabsIndex = 1;
+    },
+    cityChange(index) {
+      this.isChooseC = true;
+      this.isChooseA = false;
+      this.city = index;
+      this.areas = areas[this.province][index];
+      this.tabsIndex = 2;
+    },
+    areaChange(index) {
+      this.isChooseA = true;
+      this.area = index;
+      let result = {};
+      result.province = this.provinces[this.province];
+      result.city = this.citys[this.city];
+      result.area = this.areas[this.area];
+      this.$emit('city-change', result);
+      this.close();
+    }
+  }
+
+}
+</script>
+<style lang="scss">
+.area-box {
+  width: 100%;
+  overflow: hidden;
+  height: 800 rpx;
+
+  > view {
+    width: 150%;
+    transition: transform 0.3s ease-in-out 0s;
+    transform: translateX(0);
+
+    &.change {
+      transform: translateX(-33.3333333%);
+    }
+  }
+
+  .area-item {
+    width: 33.3333333%;
+    height: 800 rpx;
+  }
+}
+</style>

+ 353 - 0
AyaoJies-app/house-master/house-life/components/zy/addAllHouse.vue

@@ -0,0 +1,353 @@
+<template>
+  <view>
+    <scroll-view class="scroll-wrapper" scroll-y="true">
+      <view>
+        <view class="wrap">
+          <u-form ref="uForm">
+            <u-form-item :label-position="labelPosition" label="户型" label-width="150" required>
+              <u-input v-model="houseTypeVo" :border="border" :select-open="selectShow" placeholder="请选择户型"
+                       type="select" @click="selectShow = true"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="面积" label-width="150" required>
+              <u-input v-model="model.houseArea" :border="border" placeholder="请输入面积" type="number"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="租金" label-width="150" required>
+              <u-input v-model="model.price" :border="border" placeholder="请输入租金" type="number"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="起租日期" label-width="150">
+              <view class="dateBtn" @click="dateClick">
+                {{ dateLabel }}
+                <u-icon name="arrow-right"></u-icon>
+              </view>
+            </u-form-item>
+            <view class="custom-gap"></view>
+            <u-form-item :label-position="labelPosition" label="房源图片" label-width="150" required>
+              <u-upload
+                  ref="uUpload" :action="action" :auto-upload="true" :custom-btn="true" :max-size="10 * 1024 * 1024"
+                  :size-type="siteType" height="160" max-count="9" width="160">
+                <view slot="addBtn" class="slot-btn" hover-class="slot-btn__hover" hover-stay-time="150">
+                  <u-icon :color="$u.color['lightColor']" name="plus" size="60"></u-icon>
+                </view>
+              </u-upload>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="房源描述" label-width="150">
+              <u-input v-model="model.introduce" :border="border" placeholder="请填写房屋描述" type="textarea"/>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="房源亮点" label-width="150" required>
+              <u-checkbox-group :width="radioCheckWidth" :wrap="radioCheckWrap" @change="checkboxGroupChange">
+                <u-checkbox v-for="(item, index) in checkboxList" :key="index" v-model="item.checked" :name="item.name">
+                  {{ item.name }}
+                </u-checkbox>
+              </u-checkbox-group>
+            </u-form-item>
+          </u-form>
+        </view>
+      </view>
+    </scroll-view>
+    <u-select v-model="selectShow" :list="selectList" mode="mutil-column" @confirm="selectConfirm"></u-select>
+    <u-action-sheet v-model="actionSheetShow" :list="actionSheetList" @click="actionSheetCallback"></u-action-sheet>
+    <u-calendar v-model="show" :mode="mode" max-date="2100-01-01" @change="changeDate"></u-calendar>
+    <view class="bottom-btn">
+      <u-button type="primary" @click="submit">提交</u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  props: {
+    model: Object
+  },
+  data() {
+    return {
+      houseTypeVo: '',
+      show: false,
+      mode: 'date',
+      selectList: [
+        [
+          {
+            value: '一室',
+            label: '一室'
+          },
+          {
+            value: '二室',
+            label: '二室'
+          },
+          {
+            value: '三室',
+            label: '三室'
+          },
+          {
+            value: '四室',
+            label: '四室'
+          }
+        ],
+        [
+          {
+            value: '',
+            label: ''
+          },
+          {
+            value: '一厅',
+            label: '一厅'
+          },
+          {
+            value: '二厅',
+            label: '二厅'
+          },
+          {
+            value: '三厅',
+            label: '三厅'
+          }
+        ],
+        [
+          {
+            value: '',
+            label: ''
+          },
+          {
+            value: '一卫',
+            label: '一卫'
+          },
+          {
+            value: '二卫',
+            label: '二卫'
+          }
+        ],
+      ],
+      border: false,
+      check: false,
+      selectStatus: 'close',
+      checkboxList: [
+        {
+          name: '看房方便',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '独卫',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '独立阳台',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '智能锁',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '可短租',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '首次出租',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '免物业费',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '民用水电',
+          checked: false,
+          disabled: false
+        }
+      ],
+      actionSheetList: [
+        {
+          text: '电梯房'
+        },
+        {
+          text: '楼梯房'
+        }
+      ],
+      selectShow: false,
+      radioCheckWidth: 'auto',
+      radioCheckWrap: false,
+      labelPosition: 'left',
+      errorType: ['toast'],
+      actionSheetShow: false,
+      dateLabel: '随时入住',
+      // 服务器地址
+      action: config.staticUrl + '/common/upload',
+      siteType: ['compressed'],
+    };
+  },
+  watch: {
+    model: {
+      handler(newName, oldName) {
+        this.houseTypeVo = newName.houseType
+        // 回显房源亮点
+        if (this.model.featureList) {
+          this.checkboxList.forEach(item => {
+            this.model.featureList.forEach(feature => {
+              if (feature.feature == item.name) {
+                item.checked = true
+              }
+            })
+          })
+        }
+      },
+      immediate: true,
+      deep: true
+    }
+  },
+  methods: {
+    submit() {
+      if (this.$u.test.isEmpty(this.model.houseType)) {
+        return this.$mytip.toast('请选择户型')
+      }
+      if (this.$u.test.isEmpty(this.model.houseArea)) {
+        return this.$mytip.toast('请输入面积')
+      }
+      if (this.$u.test.isEmpty(this.model.price)) {
+        return this.$mytip.toast('请输入租金')
+      }
+      let files = [];
+      // 通过filter,筛选出上传进度为100的文件(因为某些上传失败的文件,进度值不为100,这个是可选的操作)
+      files = this.$refs.uUpload.lists.filter(val => {
+        return val.progress == 100;
+      })
+      if (this.$u.test.isEmpty(files)) {
+        return this.$mytip.toast('请至少选择一张房源图片')
+      }
+      let imageList = files.map(val => {
+        return {
+          imageName: val.response.realName,
+          imagePath: val.response.fileName,
+          imgUrl: val.response.url,
+          imageSize: val.file.size
+        }
+      })
+      this.model.imageList = imageList
+      if (this.$u.test.isEmpty(this.model.featureList)) {
+        return this.$mytip.toast('请至少选择一个房源亮点')
+      }
+      let url = "api/houseApi/saveHouse";
+      if (this.model.id) {
+        url = "api/houseApi/updateHouse";
+      }
+      this.model.publishId = uni.getStorageSync('lifeData').vuex_user.user.userId;
+      this.$u.post(url, this.model).then(data => {
+        // uni.$emit('findIndexHouseList', {});
+        // this.$u.route({
+        // 	type: 'tab',url: '/pages/index/index'
+        // })
+        this.$u.route({
+          url: 'pages/center/order',
+        })
+      });
+    },
+    // 选择类型回调
+    selectConfirm(e) {
+      this.model.houseType = ''
+      e.map((val, index) => {
+        if (index == 0) {
+          this.model.houseNum = val.label;
+        } else if (index == 1) {
+          this.model.houseHall = val.label;
+        } else if (index == 2) {
+          this.model.toiletNum = val.label;
+        }
+        this.model.houseType += val.label;
+        this.houseTypeVo = this.model.houseType
+      })
+    },
+    // 点击actionSheet回调
+    actionSheetCallback(index) {
+      uni.hideKeyboard();
+      this.model.stepType = this.actionSheetList[index].text;
+    },
+    // checkbox选择发生变化
+    checkboxGroupChange(e) {
+      let featureList = e.map(val => {
+        return {
+          feature: val
+        }
+      })
+      this.model.featureList = featureList
+    },
+    borderChange(index) {
+      this.border = !index;
+    },
+    labelPositionChange(index) {
+      this.labelPosition = index == 0 ? 'left' : 'top';
+    },
+    codeChange(text) {
+      this.codeTips = text;
+    },
+    dateClick() {
+      this.show = true
+    },
+    changeDate(e) {
+      this.model.startDate = e.result
+      this.dateLabel = e.result
+    }
+  }
+};
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+
+.wrap {
+  padding: 30 rpx;
+}
+
+.scroll-wrapper {
+  position: absolute;
+  left: 0 rpx;
+  right: 0 rpx;
+  top: 0 rpx;
+  bottom: 120 rpx;
+}
+
+.bottom-btn {
+  position: fixed;
+  bottom: 8 rpx;
+  width: 100%;
+  padding: 30 rpx;
+  border-top: 1 rpx solid #ccc;
+  background-color: #FFFFFF;
+}
+
+.dateBtn {
+  position: absolute;
+  right: 0 rpx;
+  top: 10 rpx;
+  color: #606266;
+}
+
+.slot-btn {
+  width: 160 rpx;
+  height: 160 rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: rgb(244, 245, 246);
+  border-radius: 10 rpx;
+}
+
+.slot-btn__hover {
+  background-color: rgb(235, 236, 238);
+}
+
+.custom-gap {
+  width: 1000 rpx;
+  height: 10 rpx;
+  margin: 0 -200rpx 0 -200rpx;
+  background-color: rgb(235, 236, 238);
+}
+</style>

+ 348 - 0
AyaoJies-app/house-master/house-life/components/zy/addSubHouse.vue

@@ -0,0 +1,348 @@
+<template>
+  <view>
+    <scroll-view class="scroll-wrapper" scroll-y="true">
+      <view>
+        <view class="wrap">
+          <u-form ref="uForm">
+            <u-form-item :label-position="labelPosition" label="出租房间" label-width="150" required>
+              <u-input v-model="roomLabelVo" :border="border" :select-open="selectShow" placeholder="请选择出租房间"
+                       type="select" @click="selectShow = true"></u-input>
+            </u-form-item>
+
+            <u-form-item :label-position="labelPosition" label="房间号" label-width="150" required>
+              <u-input v-model="model.roomCode" :border="border" placeholder="如 A01..." type="text"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="房屋面积" label-width="150" required>
+              <u-input v-model="model.roomArea" :border="border" placeholder="请输入房屋面积" type="number"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="朝向" label-width="150">
+              <u-input v-model="directionVo" :border="border" :select-open="directionShow" placeholder="请选择朝向"
+                       type="select" @click="directionShow = true"></u-input>
+            </u-form-item>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="租金" label-width="150" required>
+              <u-input v-model="model.price" :border="border" placeholder="请输入租金" type="number"></u-input>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="起租日期" label-width="150">
+              <view class="dateBtn" @click="dateClick">
+                {{ dateLabel }}
+                <u-icon name="arrow-right"></u-icon>
+              </view>
+            </u-form-item>
+            <view class="custom-gap"></view>
+            <u-form-item :label-position="labelPosition" label="房源图片" label-width="150" required>
+              <u-upload
+                  ref="uUpload" :action="action" :auto-upload="true" :custom-btn="true" :max-size="10 * 1024 * 1024"
+                  :size-type="siteType" height="160" max-count="9" width="160">
+                <view slot="addBtn" class="slot-btn" hover-class="slot-btn__hover" hover-stay-time="150">
+                  <u-icon :color="$u.color['lightColor']" name="plus" size="60"></u-icon>
+                </view>
+              </u-upload>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="房源描述" label-width="150">
+              <u-input v-model="model.introduce" :border="border" placeholder="请填写房屋描述" type="textarea"/>
+            </u-form-item>
+            <u-form-item :label-position="labelPosition" label="房源亮点" label-width="150" required>
+              <u-checkbox-group :width="radioCheckWidth" :wrap="radioCheckWrap" @change="checkboxGroupChange">
+                <u-checkbox v-for="(item, index) in checkboxList" :key="index" v-model="item.checked" :name="item.name">
+                  {{ item.name }}
+                </u-checkbox>
+              </u-checkbox-group>
+            </u-form-item>
+          </u-form>
+        </view>
+      </view>
+    </scroll-view>
+    <u-select v-model="selectShow" :list="selectList" mode="single-column" @confirm="selectConfirm"></u-select>
+    <u-select v-model="directionShow" :list="directionList" mode="single-column" @confirm="directionConfirm"></u-select>
+    <u-action-sheet v-model="actionSheetShow" :list="actionSheetList" @click="actionSheetCallback"></u-action-sheet>
+    <u-calendar v-model="show" :mode="mode" max-date="2100-01-01" @change="changeDate"></u-calendar>
+    <view class="bottom-btn">
+      <u-button type="primary" @click="submit">提交</u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  props: {
+    model: Object
+  },
+  data() {
+    return {
+      roomLabelVo: '',
+      directionVo: '',
+      show: false,
+      mode: 'date',
+      selectList: [
+        {
+          value: '1',
+          label: '主卧'
+        },
+        {
+          value: '2',
+          label: '次卧'
+        }
+      ],
+      directionList: [
+        {
+          value: '东',
+          label: '东'
+        },
+        {
+          value: '南',
+          label: '南'
+        },
+        {
+          value: '西',
+          label: '西'
+        },
+        {
+          value: '北',
+          label: '北'
+        },
+      ],
+      border: false,
+      check: false,
+      checkboxList: [
+        {
+          name: '看房方便',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '独卫',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '独立阳台',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '智能锁',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '可短租',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '首次出租',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '免物业费',
+          checked: false,
+          disabled: false
+        },
+        {
+          name: '民用水电',
+          checked: false,
+          disabled: false
+        }
+      ],
+      actionSheetList: [
+        {
+          text: '电梯房'
+        },
+        {
+          text: '楼梯房'
+        }
+      ],
+      selectShow: false,
+      directionShow: false,
+      radioCheckWidth: 'auto',
+      radioCheckWrap: false,
+      labelPosition: 'left',
+      errorType: ['toast'],
+      actionSheetShow: false,
+      dateLabel: '随时入住',
+      // 图片服务器地址
+      action: config.staticUrl + '/common/upload',
+      siteType: ['compressed'],
+    };
+  },
+  watch: {
+    model: {
+      handler(newName, oldName) {
+        this.roomLabelVo = newName.roomLabel
+        // 回显房源亮点
+        if (this.model.featureList) {
+          this.checkboxList.forEach(item => {
+            this.model.featureList.forEach(feature => {
+              if (feature.feature == item.name) {
+                item.checked = true
+              }
+            })
+          })
+          this.directionVo = newName.direction
+        }
+      },
+      immediate: true,
+      deep: true
+    }
+  },
+  methods: {
+    submit() {
+      if (this.$u.test.isEmpty(this.model.roomType)) {
+        return this.$mytip.toast('请选择租房间')
+      }
+      if (this.$u.test.isEmpty(this.model.roomCode)) {
+        return this.$mytip.toast('请输入房间号')
+      }
+      if (this.$u.test.isEmpty(this.model.roomArea)) {
+        return this.$mytip.toast('请输入房屋面积')
+      }
+      // if(this.$u.test.isEmpty(this.model.direction)){
+      // 	return this.$mytip.toast('请输入朝向')
+      // }
+      if (this.$u.test.isEmpty(this.model.price)) {
+        return this.$mytip.toast('请输入租金')
+      }
+      let files = [];
+      // 通过filter,筛选出上传进度为100的文件(因为某些上传失败的文件,进度值不为100,这个是可选的操作)
+      files = this.$refs.uUpload.lists.filter(val => {
+        return val.progress == 100;
+      })
+      if (this.$u.test.isEmpty(files)) {
+        return this.$mytip.toast('请至少选择一张房源图片')
+      }
+      let imageList = files.map(val => {
+        return {
+          imageName: val.response.realName,
+          imagePath: val.response.fileName,
+          imgUrl: val.response.url,
+          imageSize: val.file.size
+        }
+      })
+      this.model.imageList = imageList
+      if (this.$u.test.isEmpty(this.model.featureList)) {
+        return this.$mytip.toast('请至少选择一个房源亮点')
+      }
+      let url = "api/houseApi/saveHouse";
+      if (this.model.id) {
+        url = "api/houseApi/updateHouse";
+      }
+      this.model.publishId = uni.getStorageSync('lifeData').vuex_user.user.userId;
+      this.$u.post(url, this.model).then(data => {
+        // uni.$emit('findIndexHouseList', {});
+        // this.$u.route({
+        // 	type: 'tab',url: '/pages/index/index'
+        // })
+        this.$u.route({
+          url: 'pages/center/order',
+        })
+      });
+    },
+    // 选择类型回调
+    selectConfirm(e) {
+      this.model.roomLabel = ''
+      this.model.roomType = ''
+      e.map((val, index) => {
+        this.model.roomLabel += val.label;
+        this.model.roomType += val.value;
+      })
+      this.roomLabelVo = this.model.roomLabel
+    },
+    directionConfirm(e) {
+      e.map((val, index) => {
+        this.model.direction = val.label;
+        this.directionVo = val.label;
+      })
+    },
+    // 点击actionSheet回调
+    actionSheetCallback(index) {
+      uni.hideKeyboard();
+      this.model.stepType = this.actionSheetList[index].text;
+    },
+    // checkbox选择发生变化
+    checkboxGroupChange(e) {
+      let featureList = e.map(val => {
+        return {
+          feature: val
+        }
+      })
+      this.model.featureList = featureList
+    },
+    borderChange(index) {
+      this.border = !index;
+    },
+    labelPositionChange(index) {
+      this.labelPosition = index == 0 ? 'left' : 'top';
+    },
+    codeChange(text) {
+      this.codeTips = text;
+    },
+    dateClick() {
+      this.show = true
+    },
+    changeDate(e) {
+      this.model.startDate = e.result
+      this.dateLabel = e.result
+    }
+  }
+};
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+
+.wrap {
+  padding: 30 rpx;
+}
+
+.scroll-wrapper {
+  position: absolute;
+  left: 0 rpx;
+  right: 0 rpx;
+  top: 0 rpx;
+  bottom: 120 rpx;
+}
+
+.bottom-btn {
+  position: fixed;
+  bottom: 8 rpx;
+  width: 100%;
+  padding: 30 rpx;
+  border-top: 1 rpx solid #ccc;
+  background-color: #FFFFFF;
+}
+
+.dateBtn {
+  position: absolute;
+  right: 0 rpx;
+  top: 10 rpx;
+  color: #606266;
+}
+
+.slot-btn {
+  width: 160 rpx;
+  height: 160 rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: rgb(244, 245, 246);
+  border-radius: 10 rpx;
+}
+
+.slot-btn__hover {
+  background-color: rgb(235, 236, 238);
+}
+
+.custom-gap {
+  width: 1000 rpx;
+  height: 10 rpx;
+  margin: 0 -200rpx 0 -200rpx;
+  background-color: rgb(235, 236, 238);
+}
+</style>

+ 856 - 0
AyaoJies-app/house-master/house-life/components/zy/filterDropdown.vue

@@ -0,0 +1,856 @@
+<template>
+  <view :class="{'setDropdownBottom':maskVisibility}" :style="{'top':menuTop+'rpx'}" class="HMfilterDropdown"
+        @touchmove.stop.prevent="discard" @tap.stop="discard">
+    <view class="nav">
+      <block v-for="(item,index) in menu" :key="index">
+        <view :class="{'on':showPage==index}" class="first-menu" @tap="togglePage(index)">
+          <text class="name">{{ item.name }}</text>
+          <text :style="'transform:rotate('+triangleDeg[index]+'deg);'" class="iconfont triangle"></text>
+        </view>
+      </block>
+    </view>
+    <view :class="{'show':isShowMask,'hide':maskVisibility!=true}" class="mask" @tap="togglePage(showPage)"></view>
+    <block v-for="(page,page_index) in subData" :key="page_index">
+      <view :class="{'show':showPage==page_index,'hide':pageState[page_index]!=true}" class="sub-menu-class">
+        <block v-if="page.type=='hierarchy'&& page.submenu.length>0">
+          <scroll-view :class="[activeMenuArr[page_index].length>1?'first':'alone']" :scroll-into-view="'first_id'+firstScrollInto"
+                       :scroll-y="true" class="sub-menu-list">
+            <block v-for="(sub,index) in page.submenu" :key="index">
+              <view :id="'first_id'+index" :class="{'on':activeMenuArr[page_index][0]==index}"
+                    class="sub-menu"
+                    @tap="selectHierarchyMenu(page_index,index,null,null)">
+                <view class="menu-name">
+                  <text>{{ sub.name }}</text>
+                  <text class="iconfont selected"></text>
+                </view>
+              </view>
+            </block>
+          </scroll-view>
+          <block v-for="(sub,index) in page.submenu" :key="index">
+            <scroll-view v-if="activeMenuArr[page_index][0]==index&&sub.submenu.length>0" :scroll-into-view="'second_id'+secondScrollInto"
+                         :scroll-y="true"
+                         class="sub-menu-list not-first">
+              <block v-for="(sub_second,second_index) in sub.submenu" :key="second_index">
+                <view :id="'second_id'+second_index" :class="{'on':activeMenuArr[page_index][1]==second_index}"
+                      class="sub-menu">
+                  <view class="menu-name"
+                        @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,null)">
+                    <text>{{ sub_second.name }}</text>
+                    <text class="iconfont selected"></text>
+                  </view>
+                  <view v-if="sub_second.submenu&&sub.submenu.length>0&&sub_second.submenu.length>0"
+                        class="more-sub-menu">
+                    <block v-for="(sub2,sub2_index) in sub_second.submenu" :key="sub2_index">
+                      <text v-if="sub_second.showAllSub || (sub2_index<8)"
+                            :class="{'on':activeMenuArr[page_index][1]==second_index&&activeMenuArr[page_index][2]==sub2_index}"
+                            @tap="selectHierarchyMenu(page_index,activeMenuArr[page_index][0],second_index,sub2_index)">
+                        {{ sub2.name }}
+                      </text>
+                      <text v-if="sub_second.showAllSub!=true && sub2_index==8 && sub_second.submenu.length>9"
+                            @tap="showMoreSub(second_index)">更多
+                        <text
+                            class="iconfont triangle"></text>
+                      </text>
+                    </block>
+                  </view>
+                </view>
+              </block>
+            </scroll-view>
+          </block>
+        </block>
+        <block v-if="page.type=='filter'">
+          <view class="filter">
+            <scroll-view :scroll-y="true" class="menu-box">
+              <view v-for="(box,box_index) in page.submenu" :key="box_index" class="box">
+                <view class="title">{{ box.name }}</view>
+                <view class="labels">
+                  <view v-for="(label,label_index) in box.submenu" :key="label_index"
+                        :class="{'on':label.selected}"
+                        @tap="selectFilterLabel(page_index,box_index,label_index)">{{ label.name }}
+                  </view>
+                </view>
+              </view>
+            </scroll-view>
+            <view class="btn-box">
+              <view class="reset" @tap="resetFilterData(page_index)">重置</view>
+              <view class="submit" @tap="setFilterData(page_index)">确定</view>
+            </view>
+          </view>
+        </block>
+        <block v-if="page.type=='radio'">
+          <view class="filter">
+            <scroll-view :scroll-y="true" class="menu-box">
+              <view v-for="(box,box_index) in page.submenu" :key="box_index" class="box">
+                <view class="title">{{ box.name }}</view>
+                <view class="labels">
+                  <view v-for="(label,label_index) in box.submenu" :key="label_index"
+                        :class="{'on':label.selected}"
+                        @tap="selectRadioLabel(page_index,box_index,label_index)">{{ label.name }}
+                  </view>
+                </view>
+              </view>
+            </scroll-view>
+            <view class="btn-box">
+              <view class="reset" @tap="resetFilterData(page_index)">重置</view>
+              <view class="submit" @tap="setFilterData(page_index)">确定</view>
+            </view>
+          </view>
+        </block>
+      </view>
+    </block>
+  </view>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      subData: [], //菜单数据
+      menu: [], //顶部横条数据
+      showPage: -1, //菜单页面显示/隐藏动画控制
+      pageState: [], //页面的状态
+      activeMenuArr: [], //UI状态
+      shadowActiveMenuArr: [], //记录选中
+      defaultActive: [],
+      triangleDeg: [], //小三角形的翻转动画控制
+      isShowMask: false, //遮罩层显示/隐藏动画控制
+      maskVisibility: false, //遮罩层显示/隐藏状态
+      //滚动区域定位
+      firstScrollInto: 0,
+      secondScrollInto: 0,
+      componentTop: 0,//组件top
+      isReadNewSelect: false
+    }
+  },
+  props: {
+    menuTop: {
+      value: Number,
+      default: false
+    },
+    filterData: {
+      value: Array,
+      default: []
+    },
+    defaultSelected: {
+      value: Array,
+      default: []
+    },
+    updateMenuName: {
+      value: Boolean,
+      default: true
+    },
+    dataFormat: {
+      value: String,
+      default: 'Array'
+    }
+  },
+  watch: {
+    filterData: {
+      handler() {
+        this.initMenu(); //filterData重新赋值初始化菜单
+      },
+      immediate: true
+    },
+    defaultSelected(newVal) {
+
+      if (newVal.length == 0) {
+        return;
+      }
+      this.defaultActive = JSON.parse(JSON.stringify(newVal));
+      this.activeMenuArr = JSON.parse(JSON.stringify(newVal));
+      this.shadowActiveMenuArr = JSON.parse(JSON.stringify(newVal));
+      if (this.updateMenuName) {
+        this.setMenuName();
+      }
+    }
+  },
+  methods: {
+    initMenu() {
+
+      let tmpMenuActiveArr = [];
+      let tmpMenu = [];
+      for (let i = 0; i < this.filterData.length; i++) {
+        let tmpitem = this.filterData[i];
+        tmpMenu.push({
+          //如果没有设置name,则取第一个菜单作为menu.name,filter类型则将"筛选"作为menu.name
+          name: tmpitem.name || (tmpitem.type == "filter" ? "筛选" : tmpitem.submenu[0].name),
+          type: tmpitem.type
+        });
+        //初始化选中项数组-ui状态
+        tmpMenuActiveArr.push(this.processActive(tmpitem));
+        //初始化角度数组
+        this.triangleDeg.push(0);
+        //初始化控制显示状态数组
+        this.pageState.push(false);
+        //递归处理子菜单数据
+        tmpitem = this.processSubMenu(tmpitem);
+        this.filterData[i] = tmpitem;
+      }
+      this.menu = tmpMenu;
+      //初始化选中项数组
+      tmpMenuActiveArr = this.defaultActive.length > 0 ? this.defaultActive : this.activeMenuArr.length > 0 ? this.activeMenuArr : tmpMenuActiveArr;
+      this.defaultActive = [];
+      this.activeMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
+      this.shadowActiveMenuArr = JSON.parse(JSON.stringify(tmpMenuActiveArr));
+      //加载菜单数据
+      this.subData = this.filterData;
+      //设定顶部菜单名字
+      if (this.updateMenuName) {
+        this.setMenuName();
+      }
+    },
+    setMenuName() {
+      for (var i = 0; i < this.activeMenuArr.length; i++) {
+        let row = this.activeMenuArr[i];
+        if (this.subData[i].type == 'hierarchy') {
+          if (typeof (row[0]) == 'number') {
+            let tmpsub = this.subData[i].submenu[row[0]];
+            if (row.length > 1) {
+              tmpsub = tmpsub.submenu[row[1]];
+              if (row.length > 2) {
+                tmpsub = tmpsub.submenu[row[2]];
+              }
+            }
+            this.menu[i].name = tmpsub.name;
+          } else {
+            this.menu[i].name = this.subData[i].name;
+          }
+        }
+      }
+    },
+    //展开更多
+    showMoreSub(index) {
+      this.subData[this.showPage].submenu[this.activeMenuArr[this.showPage][0]].submenu[index].showAllSub = true;
+      this.$forceUpdate();
+    },
+    //选中
+    selectHierarchyMenu(page_index, level1_index, level2_index, level3_index) {
+      //读取记录
+      if (level1_index != null && level2_index == null && level3_index == null && this.shadowActiveMenuArr[page_index][0] ==
+          level1_index) {
+        this.activeMenuArr.splice(page_index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[page_index])));
+      } else {
+        this.activeMenuArr[page_index].splice(0, 1, level1_index);
+        (level2_index != null || this.activeMenuArr[page_index].length >= 2) && this.activeMenuArr[page_index].splice(1, 1, level2_index) || this.activeMenuArr[page_index].splice(1, 1);
+        (level3_index != null || this.activeMenuArr[page_index].length >= 3) && this.activeMenuArr[page_index].splice(2, 1, level3_index) || this.activeMenuArr[page_index].splice(2, 1);
+      }
+      //写入结果
+      if (level3_index != null || level2_index != null || (level1_index != null && this.subData[page_index].submenu[level1_index].submenu.length == 0)
+      ) {
+        let sub = this.subData[page_index].submenu[level1_index].submenu[level2_index];
+        if (this.updateMenuName) {
+          this.menu[page_index].name = (level3_index != null && sub.submenu[level3_index].name) || (level2_index != null && sub.name) || this.subData[page_index].submenu[level1_index].name;
+        }
+        this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
+        this.togglePage(this.showPage);
+      }
+    },
+    //写入结果,筛选
+    setFilterData(page_index) {
+      this.shadowActiveMenuArr[page_index] = JSON.parse(JSON.stringify(this.activeMenuArr[page_index]));
+      this.togglePage(this.showPage);
+    },
+    //重置结果和ui,筛选
+    resetFilterData(page_index) {
+      let tmpArr = [];
+      let level = this.shadowActiveMenuArr[page_index].length;
+      while (level > 0) {
+        tmpArr.push([]);
+        let box = this.subData[page_index].submenu[level - 1].submenu;
+        for (let i = 0; i < box.length; i++) {
+          this.subData[page_index].submenu[level - 1].submenu[i].selected = false;
+        }
+        level--;
+      }
+      this.activeMenuArr[page_index] = JSON.parse(JSON.stringify(tmpArr));
+      this.$forceUpdate();
+    },
+    //选中筛选类label-UI状态
+    selectFilterLabel(page_index, box_index, label_index) {
+      let find_index = this.activeMenuArr[page_index][box_index].indexOf(label_index);
+      if (find_index > -1) {
+        this.activeMenuArr[page_index][box_index].splice(find_index, 1);
+        this.subData[page_index].submenu[box_index].submenu[label_index].selected = false;
+      } else {
+        this.activeMenuArr[page_index][box_index].push(label_index);
+        this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
+      }
+      this.$forceUpdate();
+    },
+    //选中单选类label-UI状态
+    selectRadioLabel(page_index, box_index, label_index) {
+
+      let activeIndex = this.activeMenuArr[page_index][box_index][0];
+      if (activeIndex == label_index) {
+        this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
+        this.activeMenuArr[page_index][box_index][0] = null;
+      } else {
+        if (activeIndex != null && activeIndex < this.subData[page_index].submenu[box_index].submenu.length) {
+          this.subData[page_index].submenu[box_index].submenu[activeIndex].selected = false;
+        }
+
+        this.subData[page_index].submenu[box_index].submenu[label_index].selected = true;
+        this.activeMenuArr[page_index][box_index][0] = label_index;
+      }
+      this.$forceUpdate();
+    },
+    //菜单开关
+    togglePage(index) {
+      if (index == this.showPage) {
+        this.hidePageLayer(true);
+        this.hideMask();
+        this.showPage = -1;
+      } else {
+        if (this.showPage > -1) {
+          this.hidePageLayer(false);
+        }
+        this.showPageLayer(index);
+        this.showMask();
+      }
+    },
+    //hide遮罩层
+    hideMask() {
+      this.isShowMask = false;
+      setTimeout(() => {
+        this.maskVisibility = false;
+      }, 200);
+    },
+    //show遮罩层
+    showMask() {
+      this.maskVisibility = true;
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.isShowMask = true;
+        }, 0);
+      })
+    },
+    //hide菜单页
+    hidePageLayer(isAnimation) {
+      this.triangleDeg[this.showPage] = 0;
+      let tmpIndex = this.showPage;
+      if (isAnimation) {
+        setTimeout(() => {
+          this.pageState.splice(tmpIndex, 1, false);
+        }, 200);
+        this.confirm();
+      } else {
+        this.pageState.splice(tmpIndex, 1, false)
+      }
+      this.firstScrollInto = null;
+      this.secondScrollInto = null;
+    },
+    confirm() {
+      let index = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
+      let value = JSON.parse(JSON.stringify(this.shadowActiveMenuArr));
+
+      //对结果做一下处理
+      index.forEach((item, i) => {
+        if (typeof (item[0]) == 'object') {
+          //针对筛选结果过一个排序
+          item.forEach((s, j) => {
+            if (s != null) {
+              s.sort((val1, val2) => {
+                return val1 - val2;
+              });
+              item[j] = s;
+              s.forEach((v, k) => {
+                value[i][j][k] = (v == null || v >= this.subData[i].submenu[j].submenu.length) ? null : this.subData[i].submenu[j].submenu[v].value;
+                if (this.subData[i].type == 'radio' && value[i][j][k] == null) {
+                  value[i][j] = [];
+                  index[i][j] = [];
+                }
+              });
+            }
+          });
+        } else {
+          let submenu = this.subData[i].submenu[item[0]];
+          value[i][0] = submenu.value;
+          if (value[i].length >= 2 && item[1] != null) {
+            if (submenu.submenu.length > 0) {
+              submenu = submenu.submenu[item[1]];
+              value[i][1] = submenu.hasOwnProperty('value') ? submenu.value : null;
+            } else {
+              value[i][1] = null
+            }
+            if (value[i].length >= 3 && item[2] != null) {
+              if (submenu.submenu.length > 0) {
+                submenu = submenu.submenu[item[2]];
+                value[i][2] = submenu.hasOwnProperty('value') ? submenu.value : null;
+              } else {
+                value[i][2] = null;
+              }
+            }
+          }
+        }
+        index[i] = item;
+
+      });
+      // 输出
+      this.$emit('confirm', {
+        index: index,
+        value: value
+      });
+    },
+    //show菜单页
+    showPageLayer(index) {
+      this.processPage(index);
+      this.pageState.splice(index, 1, true);
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.showPage = index;
+        }, 0);
+      })
+      this.triangleDeg[index] = 180;
+    },
+    reloadActiveMenuArr() {
+      for (let i = 0; i < this.filterData.length; i++) {
+        let tmpitem = this.filterData[i];
+        let tmpArr = this.processActive(tmpitem);
+        tmpitem = this.processSubMenu(tmpitem);
+        if (this.activeMenuArr[i].length != tmpArr.length) {
+          this.filterData[i] = tmpitem;
+          this.activeMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
+          this.shadowActiveMenuArr.splice(i, 1, JSON.parse(JSON.stringify(tmpArr)));
+        }
+      }
+      this.subData = this.filterData;
+      this.$forceUpdate();
+    },
+    processPage(index) {
+      //check UI控制数组,结果数组,防止传入数据层级和UI控制数组不同步
+      this.reloadActiveMenuArr();
+      //重置UI控制数组
+      this.activeMenuArr.splice(index, 1, JSON.parse(JSON.stringify(this.shadowActiveMenuArr[index])));
+      if (this.menu[index].type == 'filter') {
+        //重载筛选页选中状态
+        let level = this.shadowActiveMenuArr[index].length;
+        for (let i = 0; i < level; i++) {
+          let box = this.subData[index].submenu[i].submenu;
+          for (let j = 0; j < box.length; j++) {
+            if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
+              this.subData[index].submenu[i].submenu[j].selected = true;
+            } else {
+              this.subData[index].submenu[i].submenu[j].selected = false;
+            }
+          }
+        }
+      } else if (this.menu[index].type == 'hierarchy') {
+        this.$nextTick(() => {
+          setTimeout(() => {
+            //滚动到选中项
+            this.firstScrollInto = parseInt(this.activeMenuArr[index][0]);
+            this.secondScrollInto = parseInt(this.activeMenuArr[index][1]);
+          }, 0);
+        })
+      } else if (this.menu[index].type == 'radio') {
+        //重载筛选页选中状态
+        let level = this.shadowActiveMenuArr[index].length;
+        for (let i = 0; i < level; i++) {
+          let box = this.subData[index].submenu[i].submenu;
+          for (let j = 0; j < box.length; j++) {
+            if (this.shadowActiveMenuArr[index][i].indexOf(j) > -1) {
+              this.subData[index].submenu[i].submenu[j].selected = true;
+            } else {
+              this.subData[index].submenu[i].submenu[j].selected = false;
+            }
+          }
+        }
+      }
+    },
+    processActive(tmpitem) {
+      let tmpArr = []
+      if (tmpitem.type == 'hierarchy' && tmpitem.hasOwnProperty('submenu') && tmpitem.submenu.length > 0) {
+        let level = this.getMaxFloor(tmpitem.submenu);
+        while (level > 0) {
+          tmpArr.push(null);
+          level--;
+        }
+      } else if (tmpitem.type == 'filter') {
+        let level = tmpitem.submenu.length;
+        while (level > 0) {
+          tmpArr.push([]);
+          level--;
+        }
+      } else if (tmpitem.type == 'radio') {
+        let level = tmpitem.submenu.length;
+        while (level > 0) {
+          tmpArr.push([]);
+          level--;
+        }
+      }
+      return tmpArr;
+    },
+    processSubMenu(menu) {
+      if (menu.hasOwnProperty('submenu') && menu.submenu.length > 0) {
+        for (let i = 0; i < menu.submenu.length; i++) {
+          menu.submenu[i] = this.processSubMenu(menu.submenu[i]);
+        }
+      } else {
+        menu.submenu = [];
+      }
+      return menu;
+    },
+    //计算菜单层级
+    getMaxFloor(treeData) {
+      let floor = 0
+      let max = 0
+
+      function each(data, floor) {
+        data.forEach(e => {
+          max = floor > max ? floor : max;
+          if (e.hasOwnProperty('submenu') && e.submenu.length > 0) {
+            each(e.submenu, floor + 1)
+          }
+        })
+      }
+
+      each(treeData, 1)
+      return max;
+    },
+    discard() {
+
+    }
+  }
+}
+</script>
+<style lang="scss">
+.HMfilterDropdown {
+  flex-shrink: 0;
+  width: 100%;
+  // position: absolute;
+  // z-index: 997;
+  flex-wrap: nowrap;
+  display: flex;
+  flex-direction: row;
+  // top: var(--window-top);
+  overflow-y: hidden;
+
+  &.setDropdownBottom {
+    height: 1500 rpx;
+  }
+
+  view {
+    display: flex;
+    flex-wrap: nowrap;
+  }
+}
+
+.region {
+  flex: 1;
+  height: 44px;
+}
+
+.nav {
+  width: 100%;
+  height: 44px;
+  border-bottom: solid 1 rpx #eee;
+  z-index: 12;
+  background-color: #ffffff;
+  flex-direction: row;
+
+  .first-menu {
+    width: 100%;
+    font-size: 15px;
+    color: #757575;
+    flex-direction: row;
+    align-items: center;
+    justify-content: center;
+    transition: color .2s linear;
+
+    &.on {
+      color: #2979ff;
+
+      .iconfont {
+        color: #2979ff;
+      }
+    }
+
+    .name {
+      height: 20px;
+      text-align: center;
+      text-overflow: clip;
+      overflow: hidden;
+    }
+
+    .iconfont {
+      width: 13px;
+      height: 13px;
+      align-items: center;
+      justify-content: center;
+      transition: transform .2s linear, color .2s linear;
+    }
+  }
+}
+
+.sub-menu-class {
+  width: 100%;
+  position: absolute;
+  left: 0;
+  transform: translate3d(0, - 100%, 0);
+  max-height: 345px;
+  background-color: #ffffff;
+  z-index: 11;
+  box-shadow: 0 5px 5px rgba(0, 0, 0, .1);
+  overflow: hidden;
+  flex-direction: row;
+  transition: transform .15s linear;
+
+  &.hide {
+    display: none;
+  }
+
+  &.show {
+    transform: translate3d(0, calc(44px + 1rpx), 0);
+  }
+}
+
+.sub-menu-list {
+  width: 100%;
+  height: 345px;
+  flex-direction: column;
+
+  .sub-menu {
+    min-height: 44px;
+    font-size: 13px;
+    flex-direction: column;
+    padding-right: 15px;
+
+    > .menu-name {
+      padding-left: 20px;
+      height: 44px;
+      flex-direction: row;
+      align-items: center;
+      justify-content: space-between;
+
+      > .iconfont {
+        display: none;
+        font-size: 18px;
+        color: #2979ff;
+      }
+    }
+  }
+
+  &.first {
+    flex-shrink: 0;
+    width: 236 rpx;
+    background-color: #f0f0f0;
+
+    .sub-menu {
+      padding-left: 15px;
+
+      &.on {
+        background-color: #fff;
+      }
+    }
+  }
+
+  &.alone {
+    max-height: 345px;
+    min-height: 120px;
+    height: auto;
+
+    .sub-menu {
+      min-height: calc(44px - 1rpx);
+      margin-left: 15px;
+      border-bottom: solid 1 rpx #e5e5e5;
+
+      &.on {
+        color: #2979ff;
+
+        > .menu-name {
+          > .iconfont {
+            display: block;
+          }
+        }
+      }
+    }
+  }
+
+  &.not-first {
+    .sub-menu {
+      min-height: calc(44px - 1rpx);
+      margin-left: 15px;
+      border-bottom: solid 1 rpx #e5e5e5;
+
+      > .menu-name {
+        height: calc(44px - 1rpx);
+
+        > .iconfont {
+          display: none;
+          font-size: 18px;
+          color: #2979ff;
+        }
+      }
+
+      &.on {
+        color: #2979ff;
+
+        > .menu-name {
+          > .iconfont {
+            display: block;
+          }
+        }
+      }
+
+      .more-sub-menu {
+        flex-direction: row;
+        flex-wrap: wrap;
+        padding-bottom: 9px;
+
+        > text {
+          height: 30px;
+          border-radius: 3px;
+          background-color: #f5f5f5;
+          color: #9b9b9b;
+          margin-bottom: 6px;
+          margin-right: 6px;
+          text-align: center;
+          line-height: 30px;
+          border: solid #f5f5f5 1 rpx;
+          flex: 0 0 calc(33.33% - 6px);
+          overflow: hidden;
+          font-size: 12px;
+
+          &:nth-child(3n) {
+            margin-right: 0;
+          }
+
+          &.on {
+            border-color: #f6c8ac;
+            color: #2979ff;
+          }
+
+          .iconfont {
+            color: #9b9b9b;
+          }
+        }
+      }
+    }
+  }
+}
+
+.filter {
+  width: 100%;
+  height: 345px;
+  display: flex;
+  flex-direction: column;
+  justify-content: space-between;
+  align-items: center;
+
+  .menu-box {
+    width: 698 rpx;
+    height: calc(345px - 75px);
+    flex-shrink: 1;
+
+    .box {
+      width: 100%;
+      margin-top: 16px;
+      flex-direction: column;
+
+      .title {
+        width: 100%;
+        font-size: 13px;
+        color: #888;
+      }
+
+      .labels {
+        flex-direction: row;
+        flex-wrap: wrap;
+
+        .on {
+          border-color: #2979ff;
+          background-color: #2979ff;
+          color: #fff;
+        }
+
+        > view {
+          width: 148 rpx;
+          height: 30px;
+          border: solid 1 rpx #adadad;
+          border-radius: 2px;
+          margin-right: 15px;
+          margin-top: 8px;
+          font-size: 12px;
+          flex-direction: row;
+          justify-content: center;
+          align-items: center;
+
+          &:nth-child(4n) {
+            margin-right: 0;
+          }
+        }
+      }
+    }
+  }
+
+  .btn-box {
+    flex-shrink: 0;
+    width: 698 rpx;
+    height: 75px;
+    flex-direction: row !important;
+    align-items: center;
+    justify-content: space-between;
+
+    > view {
+      width: 320 rpx;
+      height: 42px;
+      border-radius: 42px;
+      border: 2 rpx solid #2979ff;
+      align-items: center;
+      justify-content: center;
+    }
+
+    .reset {
+      color: #2979ff;
+    }
+
+    .submit {
+      color: #fff;
+      background-color: #2979ff;
+    }
+  }
+}
+
+.mask {
+  z-index: 10;
+  position: fixed;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  background-color: rgba(0, 0, 0, 0);
+  transition: background-color .15s linear;
+
+  &.show {
+    background-color: rgba(0, 0, 0, 0.5);
+  }
+
+  &.hide {
+    display: none;
+  }
+}
+
+/* 字体图标 */
+@font-face {
+  font-family: "HM-FD-font";
+  src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAALAAAsAAAAABpQAAAJzAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCDBgp4gQIBNgIkAwwLCAAEIAWEbQc5G8sFERWMIbIfCbbzqA4hp7InSBibVsYGb4J42o82b3e/nJlHMw/NHbGOlwKJRCRpwzPtpAECCOZubdqxjYpQLMlVg+70/08edrgQOtx2ukpVyApZn+dyehPoQObHo3O85rYx9vOjXoBxQIHugW2yIkqIW2QXcScu4jwE8CSWbKSmrqUHFwOaJoCsLM5P4haSGIxRcRHshrUGucLCVcfqI3AZfV/+USguKCwNmtsxVztDxU/n55C+3W0Z4QQpEOTNFqCBbMCAjDUWB9CIwWk87aa70cYgqLkyd3dEmm+18R8eKATEBrV7A5CulBT8dKiWOYZk412XNcDdKSEKSGODnyKIDl+dmVt9/Dx4pu/xyeutkMlHISGPTsPCnoTNP9nOT6wTtDdlO6dPr47efvj942lkYuQzrhMKEjq9N6y98P3340gmlJ/RStUD6F31CAEEPtUW94/7rf+7XgaAz57X0ZHXAGsFFwVgw38yALuMb0IBbVyNamFYEw4oKMDTj3AHRQP5Pt4dci9VwSVkRNQh5r7CLskZadhsWHhRDBsXczk8ZYk3ewnCxmQeQKa3BOHvA8XXO2j+vqRhf7CE+sPmn4anvoL29JLa4qqaUQkmoK+QG2osCckq7txi2leK86aIPyJ3eQZ8xytXYmyQ51jQndJAxIJlqiGSLsOqImiZCjTiZCJt6Lq26U2OoXqwUo0hRaAE0K5AziANy/uLVeXzWyjVqyjcoeupjxDr5MMDn8MDkLG9Aenu5ZrOSSoghAUsRmogkkahSoWAtnlUARnCkY3It0Iu7mWhdmd9Z/19BwBP6GidEi0G56opckXTGZVSPxgAAAA=');
+}
+
+.iconfont {
+  font-family: "HM-FD-font" !important;
+  font-size: 13px;
+  font-style: normal;
+  color: #757575;
+
+  &.triangle {
+    &:before {
+      content: "\e65a";
+    }
+  }
+
+  &.selected {
+    &:before {
+      content: "\e607";
+    }
+  }
+}
+</style>

+ 31 - 0
AyaoJies-app/house-master/house-life/libs/amap-wx.130.js

@@ -0,0 +1,31 @@
+function AMapWX(a){this.key=a.key;this.requestConfig={key:a.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"};this.MeRequestConfig={key:a.key,serviceName:"https://restapi.amap.com/rest/me"}}
+AMapWX.prototype.getWxLocation=function(a,b){wx.getLocation({type:"gcj02",success:function(c){c=c.longitude+","+c.latitude;wx.setStorage({key:"userLocation",data:c});b(c)},fail:function(c){wx.getStorage({key:"userLocation",success:function(d){d.data&&b(d.data)}});a.fail({errCode:"0",errMsg:c.errMsg||""})}})};
+AMapWX.prototype.getMEKeywordsSearch=function(a){if(!a.options)return a.fail({errCode:"0",errMsg:"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570"});var b=a.options,c=this.MeRequestConfig,d={key:c.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"};b.layerId&&(d.layerId=b.layerId);b.keywords&&(d.keywords=b.keywords);b.city&&(d.city=b.city);b.filter&&(d.filter=b.filter);b.sortrule&&(d.sortrule=b.sortrule);b.pageNum&&(d.pageNum=b.pageNum);b.pageSize&&(d.pageSize=b.pageSize);b.sig&&(d.sig=
+b.sig);wx.request({url:c.serviceName+"/cpoint/datasearch/local",data:d,method:"GET",header:{"content-type":"application/json"},success:function(e){(e=e.data)&&e.status&&"1"===e.status&&0===e.code?a.success(e.data):a.fail({errCode:"0",errMsg:e})},fail:function(e){a.fail({errCode:"0",errMsg:e.errMsg||""})}})};
+AMapWX.prototype.getMEIdSearch=function(a){if(!a.options)return a.fail({errCode:"0",errMsg:"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570"});var b=a.options,c=this.MeRequestConfig,d={key:c.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"};b.layerId&&(d.layerId=b.layerId);b.id&&(d.id=b.id);b.sig&&(d.sig=b.sig);wx.request({url:c.serviceName+"/cpoint/datasearch/id",data:d,method:"GET",header:{"content-type":"application/json"},success:function(e){(e=e.data)&&e.status&&"1"===e.status&&
+0===e.code?a.success(e.data):a.fail({errCode:"0",errMsg:e})},fail:function(e){a.fail({errCode:"0",errMsg:e.errMsg||""})}})};
+AMapWX.prototype.getMEPolygonSearch=function(a){if(!a.options)return a.fail({errCode:"0",errMsg:"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570"});var b=a.options,c=this.MeRequestConfig,d={key:c.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"};b.layerId&&(d.layerId=b.layerId);b.keywords&&(d.keywords=b.keywords);b.polygon&&(d.polygon=b.polygon);b.filter&&(d.filter=b.filter);b.sortrule&&(d.sortrule=b.sortrule);b.pageNum&&(d.pageNum=b.pageNum);b.pageSize&&(d.pageSize=b.pageSize);
+b.sig&&(d.sig=b.sig);wx.request({url:c.serviceName+"/cpoint/datasearch/polygon",data:d,method:"GET",header:{"content-type":"application/json"},success:function(e){(e=e.data)&&e.status&&"1"===e.status&&0===e.code?a.success(e.data):a.fail({errCode:"0",errMsg:e})},fail:function(e){a.fail({errCode:"0",errMsg:e.errMsg||""})}})};
+AMapWX.prototype.getMEaroundSearch=function(a){if(!a.options)return a.fail({errCode:"0",errMsg:"\u7f3a\u5c11\u5fc5\u8981\u53c2\u6570"});var b=a.options,c=this.MeRequestConfig,d={key:c.key,s:"rsx",platform:"WXJS",appname:a.key,sdkversion:"1.2.0",logversion:"2.0"};b.layerId&&(d.layerId=b.layerId);b.keywords&&(d.keywords=b.keywords);b.center&&(d.center=b.center);b.radius&&(d.radius=b.radius);b.filter&&(d.filter=b.filter);b.sortrule&&(d.sortrule=b.sortrule);b.pageNum&&(d.pageNum=b.pageNum);b.pageSize&&
+(d.pageSize=b.pageSize);b.sig&&(d.sig=b.sig);wx.request({url:c.serviceName+"/cpoint/datasearch/around",data:d,method:"GET",header:{"content-type":"application/json"},success:function(e){(e=e.data)&&e.status&&"1"===e.status&&0===e.code?a.success(e.data):a.fail({errCode:"0",errMsg:e})},fail:function(e){a.fail({errCode:"0",errMsg:e.errMsg||""})}})};
+AMapWX.prototype.getGeo=function(a){var b=this.requestConfig,c=a.options;b={key:this.key,extensions:"all",s:b.s,platform:b.platform,appname:this.key,sdkversion:b.sdkversion,logversion:b.logversion};c.address&&(b.address=c.address);c.city&&(b.city=c.city);c.batch&&(b.batch=c.batch);c.sig&&(b.sig=c.sig);wx.request({url:"https://restapi.amap.com/v3/geocode/geo",data:b,method:"GET",header:{"content-type":"application/json"},success:function(d){(d=d.data)&&d.status&&"1"===d.status?a.success(d):a.fail({errCode:"0",
+errMsg:d})},fail:function(d){a.fail({errCode:"0",errMsg:d.errMsg||""})}})};
+AMapWX.prototype.getRegeo=function(a){function b(d){var e=c.requestConfig;wx.request({url:"https://restapi.amap.com/v3/geocode/regeo",data:{key:c.key,location:d,extensions:"all",s:e.s,platform:e.platform,appname:c.key,sdkversion:e.sdkversion,logversion:e.logversion},method:"GET",header:{"content-type":"application/json"},success:function(g){if(g.data.status&&"1"==g.data.status){g=g.data.regeocode;var h=g.addressComponent,f=[],k=g.roads[0].name+"\u9644\u8fd1",m=d.split(",")[0],n=d.split(",")[1];if(g.pois&&
+g.pois[0]){k=g.pois[0].name+"\u9644\u8fd1";var l=g.pois[0].location;l&&(m=parseFloat(l.split(",")[0]),n=parseFloat(l.split(",")[1]))}h.provice&&f.push(h.provice);h.city&&f.push(h.city);h.district&&f.push(h.district);h.streetNumber&&h.streetNumber.street&&h.streetNumber.number?(f.push(h.streetNumber.street),f.push(h.streetNumber.number)):f.push(g.roads[0].name);f=f.join("");a.success([{iconPath:a.iconPath,width:a.iconWidth,height:a.iconHeight,name:f,desc:k,longitude:m,latitude:n,id:0,regeocodeData:g}])}else a.fail({errCode:g.data.infocode,
+errMsg:g.data.info})},fail:function(g){a.fail({errCode:"0",errMsg:g.errMsg||""})}})}var c=this;a.location?b(a.location):c.getWxLocation(a,function(d){b(d)})};
+AMapWX.prototype.getWeather=function(a){function b(g){var h="base";a.type&&"forecast"==a.type&&(h="all");wx.request({url:"https://restapi.amap.com/v3/weather/weatherInfo",data:{key:d.key,city:g,extensions:h,s:e.s,platform:e.platform,appname:d.key,sdkversion:e.sdkversion,logversion:e.logversion},method:"GET",header:{"content-type":"application/json"},success:function(f){if(f.data.status&&"1"==f.data.status)if(f.data.lives){if((f=f.data.lives)&&0<f.length){f=f[0];var k={city:{text:"\u57ce\u5e02",data:f.city},
+weather:{text:"\u5929\u6c14",data:f.weather},temperature:{text:"\u6e29\u5ea6",data:f.temperature},winddirection:{text:"\u98ce\u5411",data:f.winddirection+"\u98ce"},windpower:{text:"\u98ce\u529b",data:f.windpower+"\u7ea7"},humidity:{text:"\u6e7f\u5ea6",data:f.humidity+"%"}};k.liveData=f;a.success(k)}}else f.data.forecasts&&f.data.forecasts[0]&&a.success({forecast:f.data.forecasts[0]});else a.fail({errCode:f.data.infocode,errMsg:f.data.info})},fail:function(f){a.fail({errCode:"0",errMsg:f.errMsg||""})}})}
+function c(g){wx.request({url:"https://restapi.amap.com/v3/geocode/regeo",data:{key:d.key,location:g,extensions:"all",s:e.s,platform:e.platform,appname:d.key,sdkversion:e.sdkversion,logversion:e.logversion},method:"GET",header:{"content-type":"application/json"},success:function(h){if(h.data.status&&"1"==h.data.status){h=h.data.regeocode;if(h.addressComponent)var f=h.addressComponent.adcode;else h.aois&&0<h.aois.length&&(f=h.aois[0].adcode);b(f)}else a.fail({errCode:h.data.infocode,errMsg:h.data.info})},
+fail:function(h){a.fail({errCode:"0",errMsg:h.errMsg||""})}})}var d=this,e=d.requestConfig;a.city?b(a.city):d.getWxLocation(a,function(g){c(g)})};
+AMapWX.prototype.getPoiAround=function(a){function b(e){e={key:c.key,location:e,s:d.s,platform:d.platform,appname:c.key,sdkversion:d.sdkversion,logversion:d.logversion};a.querytypes&&(e.types=a.querytypes);a.querykeywords&&(e.keywords=a.querykeywords);wx.request({url:"https://restapi.amap.com/v3/place/around",data:e,method:"GET",header:{"content-type":"application/json"},success:function(g){if(g.data.status&&"1"==g.data.status){if((g=g.data)&&g.pois){for(var h=[],f=0;f<g.pois.length;f++){var k=0==
+f?a.iconPathSelected:a.iconPath;h.push({latitude:parseFloat(g.pois[f].location.split(",")[1]),longitude:parseFloat(g.pois[f].location.split(",")[0]),iconPath:k,width:22,height:32,id:f,name:g.pois[f].name,address:g.pois[f].address})}a.success({markers:h,poisData:g.pois})}}else a.fail({errCode:g.data.infocode,errMsg:g.data.info})},fail:function(g){a.fail({errCode:"0",errMsg:g.errMsg||""})}})}var c=this,d=c.requestConfig;a.location?b(a.location):c.getWxLocation(a,function(e){b(e)})};
+AMapWX.prototype.getStaticmap=function(a){function b(e){c.push("location="+e);a.zoom&&c.push("zoom="+a.zoom);a.size&&c.push("size="+a.size);a.scale&&c.push("scale="+a.scale);a.markers&&c.push("markers="+a.markers);a.labels&&c.push("labels="+a.labels);a.paths&&c.push("paths="+a.paths);a.traffic&&c.push("traffic="+a.traffic);e="https://restapi.amap.com/v3/staticmap?"+c.join("&");a.success({url:e})}var c=[];c.push("key="+this.key);var d=this.requestConfig;c.push("s="+d.s);c.push("platform="+d.platform);
+c.push("appname="+d.appname);c.push("sdkversion="+d.sdkversion);c.push("logversion="+d.logversion);a.location?b(a.location):this.getWxLocation(a,function(e){b(e)})};
+AMapWX.prototype.getInputtips=function(a){var b=Object.assign({},this.requestConfig);a.location&&(b.location=a.location);a.keywords&&(b.keywords=a.keywords);a.type&&(b.type=a.type);a.city&&(b.city=a.city);a.citylimit&&(b.citylimit=a.citylimit);wx.request({url:"https://restapi.amap.com/v3/assistant/inputtips",data:b,method:"GET",header:{"content-type":"application/json"},success:function(c){c&&c.data&&c.data.tips&&a.success({tips:c.data.tips})},fail:function(c){a.fail({errCode:"0",errMsg:c.errMsg||
+""})}})};
+AMapWX.prototype.getDrivingRoute=function(a){var b=Object.assign({},this.requestConfig);a.origin&&(b.origin=a.origin);a.destination&&(b.destination=a.destination);a.strategy&&(b.strategy=a.strategy);a.waypoints&&(b.waypoints=a.waypoints);a.avoidpolygons&&(b.avoidpolygons=a.avoidpolygons);a.avoidroad&&(b.avoidroad=a.avoidroad);wx.request({url:"https://restapi.amap.com/v3/direction/driving",data:b,method:"GET",header:{"content-type":"application/json"},success:function(c){c&&c.data&&c.data.route&&a.success({paths:c.data.route.paths,
+taxi_cost:c.data.route.taxi_cost||""})},fail:function(c){a.fail({errCode:"0",errMsg:c.errMsg||""})}})};
+AMapWX.prototype.getWalkingRoute=function(a){var b=Object.assign({},this.requestConfig);a.origin&&(b.origin=a.origin);a.destination&&(b.destination=a.destination);wx.request({url:"https://restapi.amap.com/v3/direction/walking",data:b,method:"GET",header:{"content-type":"application/json"},success:function(c){c&&c.data&&c.data.route&&a.success({paths:c.data.route.paths})},fail:function(c){a.fail({errCode:"0",errMsg:c.errMsg||""})}})};
+AMapWX.prototype.getTransitRoute=function(a){var b=Object.assign({},this.requestConfig);a.origin&&(b.origin=a.origin);a.destination&&(b.destination=a.destination);a.strategy&&(b.strategy=a.strategy);a.city&&(b.city=a.city);a.cityd&&(b.cityd=a.cityd);wx.request({url:"https://restapi.amap.com/v3/direction/transit/integrated",data:b,method:"GET",header:{"content-type":"application/json"},success:function(c){c&&c.data&&c.data.route&&(c=c.data.route,a.success({distance:c.distance||"",taxi_cost:c.taxi_cost||
+"",transits:c.transits}))},fail:function(c){a.fail({errCode:"0",errMsg:c.errMsg||""})}})};
+AMapWX.prototype.getRidingRoute=function(a){var b=Object.assign({},this.requestConfig);a.origin&&(b.origin=a.origin);a.destination&&(b.destination=a.destination);wx.request({url:"https://restapi.amap.com/v3/direction/riding",data:b,method:"GET",header:{"content-type":"application/json"},success:function(c){c&&c.data&&c.data.route&&a.success({paths:c.data.route.paths})},fail:function(c){a.fail({errCode:"0",errMsg:c.errMsg||""})}})};module.exports.AMapWX=AMapWX;

+ 39 - 0
AyaoJies-app/house-master/house-life/main.js

@@ -0,0 +1,39 @@
+import Vue from 'vue'
+import App from './App'
+
+Vue.config.productionTip = false
+
+App.mpType = 'app'
+
+// 引入全局uView
+import uView from 'uview-ui'
+
+Vue.use(uView);
+
+// 此处为演示vuex使用,非uView的功能部分
+import store from '@/store';
+
+// 引入uView提供的对vuex的简写法文件
+let vuexStore = require('@/store/$u.mixin.js');
+Vue.mixin(vuexStore);
+
+// 引入uView对小程序分享的mixin封装
+let mpShare = require('uview-ui/libs/mixin/mpShare.js');
+Vue.mixin(mpShare)
+
+const app = new Vue({
+    store,
+    ...App
+})
+
+// http拦截器,将此部分放在new Vue()和app.$mount()之间,才能App.vue中正常使用
+import httpInterceptor from '@/common/http.interceptor.js';
+
+Vue.use(httpInterceptor, app);
+
+// 封装自定义提示框
+import $mytip from 'common/utils/tip.js'
+
+Vue.prototype.$mytip = $mytip
+
+app.$mount()

+ 161 - 0
AyaoJies-app/house-master/house-life/manifest.json

@@ -0,0 +1,161 @@
+{
+  "name": "租部落",
+  "appid": "__UNI__1443B25",
+  "description": "",
+  "versionName": "1.0.1",
+  "versionCode": 1,
+  "transformPx": false,
+  /* 5+App特有相关 */
+  "app-plus": {
+    "safearea": {
+      "bottom": {
+        "offset": "none"
+      }
+    },
+    "usingComponents": true,
+    "nvueCompiler": "uni-app",
+    "compilerVersion": 3,
+    "splashscreen": {
+      "alwaysShowBeforeRender": true,
+      "waiting": true,
+      "autoclose": true,
+      "delay": 0
+    },
+    /* 模块配置 */
+    "modules": {
+      "Geolocation": {},
+      "Maps": {}
+    },
+    /* 应用发布信息 */
+    "distribute": {
+      /* android打包配置 */
+      "android": {
+        "permissions": [
+          "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+          "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+          "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+          "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CAMERA\"/>",
+          "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+          "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+          "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+          "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+          "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+          "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+          "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+          "<uses-feature android:name=\"android.hardware.camera\"/>",
+          "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+          "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
+        ]
+      },
+      /* ios打包配置 */
+      "ios": {},
+      /* SDK配置 */
+      "sdkConfigs": {
+        "ad": {},
+        "geolocation": {
+          "amap": {
+            "__platform__": [
+              "ios",
+              "android"
+            ],
+            "appkey_ios": "4d5c8dc6215470a552a13671f1e45f99",
+            "appkey_android": "4d5c8dc6215470a552a13671f1e45f99"
+          }
+        },
+        "maps": {
+          "amap": {
+            "appkey_ios": "4d5c8dc6215470a552a13671f1e45f99",
+            "appkey_android": "4d5c8dc6215470a552a13671f1e45f99"
+          }
+        }
+      },
+      "icons": {
+        "android": {
+          "hdpi": "unpackage/res/icons/72x72.png",
+          "xhdpi": "unpackage/res/icons/96x96.png",
+          "xxhdpi": "unpackage/res/icons/144x144.png",
+          "xxxhdpi": "unpackage/res/icons/192x192.png"
+        },
+        "ios": {
+          "appstore": "unpackage/res/icons/1024x1024.png",
+          "ipad": {
+            "app": "unpackage/res/icons/76x76.png",
+            "app@2x": "unpackage/res/icons/152x152.png",
+            "notification": "unpackage/res/icons/20x20.png",
+            "notification@2x": "unpackage/res/icons/40x40.png",
+            "proapp@2x": "unpackage/res/icons/167x167.png",
+            "settings": "unpackage/res/icons/29x29.png",
+            "settings@2x": "unpackage/res/icons/58x58.png",
+            "spotlight": "unpackage/res/icons/40x40.png",
+            "spotlight@2x": "unpackage/res/icons/80x80.png"
+          },
+          "iphone": {
+            "app@2x": "unpackage/res/icons/120x120.png",
+            "app@3x": "unpackage/res/icons/180x180.png",
+            "notification@2x": "unpackage/res/icons/40x40.png",
+            "notification@3x": "unpackage/res/icons/60x60.png",
+            "settings@2x": "unpackage/res/icons/58x58.png",
+            "settings@3x": "unpackage/res/icons/87x87.png",
+            "spotlight@2x": "unpackage/res/icons/80x80.png",
+            "spotlight@3x": "unpackage/res/icons/120x120.png"
+          }
+        }
+      }
+    }
+  },
+  /* 快应用特有相关 */
+  "quickapp": {},
+  /* 小程序特有相关 */
+  "mp-weixin": {
+    "appid": "wxe822f409c1cf5a78",
+    "setting": {
+      "urlCheck": false,
+      "minified": true
+    },
+    "usingComponents": true,
+    "permission": {
+      "scope.userLocation": {
+        "desc": "您的位置将用于绑定您的区域"
+      }
+    },
+    "requiredPrivateInfos": [
+      "getLocation",
+      "onLocationChange",
+      "startLocationUpdateBackground",
+      "chooseAddress"
+    ]
+  },
+  "mp-alipay": {
+    "usingComponents": true
+  },
+  "mp-baidu": {
+    "usingComponents": true
+  },
+  "mp-toutiao": {
+    "usingComponents": true
+  },
+  "h5": {
+    "template": "template.h5.html",
+    "router": {
+      "mode": "hash",
+      "base": "/house/"
+    },
+    "title": "租房",
+    "domain": "8.136.213.245",
+    "sdkConfigs": {
+      "maps": {
+        "qqmap": {
+          "key": "FALBZ-J2G3I-ZY5GX-5ATUZ-GHOOZ-YVFAR"
+        }
+      }
+    }
+  }
+}

+ 298 - 0
AyaoJies-app/house-master/house-life/pages.json

@@ -0,0 +1,298 @@
+{
+  "easycom": {
+    "^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
+  },
+  "pages": [
+    //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
+    {
+      "path": "pages/index/index",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "首页",
+        "enablePullDownRefresh": true,
+        "app-plus": {
+          "pullToRefresh": {
+            "support": true,
+            "color": "#2979ff",
+            //小圈圈的颜色
+            "style": "circle"
+            //小圈圈的样式
+          }
+        }
+      }
+    },
+    {
+      "path": "pages/center/center",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "我的"
+      }
+    },
+    {
+      "path": "pages/login/login",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "密码登录",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/login/code",
+      "style": {
+        // "navigationStyle": "custom" ,// 隐藏系统导航栏
+        "navigationBarTitleText": "获取验证码",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/login/account",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "短信登录",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/login/problem",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "常见问题",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/profile/setting",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/profile/profile",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/profile/password",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "修改密码",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/search/search",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/location/location",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "选择城市"
+      }
+    },
+    {
+      "path": "pages/notice/notice",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "通知公告"
+      }
+    },
+    {
+      "path": "pages/content/content",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "资讯"
+      }
+    },
+    {
+      "path": "pages/profile/aboutMe",
+      "style": {
+        "navigationBarTitleText": "关于我",
+        "enablePullDownRefresh": false,
+        "navigationStyle": "custom"
+        // 隐藏系统导航栏
+      }
+    },
+    {
+      "path": "pages/search/searchList",
+      "style": {
+        "navigationBarTitleText": "房源列表",
+        "enablePullDownRefresh": true,
+        // "navigationStyle": "custom" ,// 隐藏系统导航栏
+        "app-plus": {
+          "pullToRefresh": {
+            "support": true,
+            "color": "#2979ff",
+            //小圈圈的颜色
+            "style": "circle"
+            //小圈圈的样式
+          }
+        }
+      }
+    },
+    {
+      "path": "pages/detail/detail",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "房源详情",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/detail/addHouse",
+      "style": {
+        "navigationBarTitleText": "房源",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/detail/preHouse",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "预增房源",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/center/tips",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "避坑指南"
+      }
+    },
+    {
+      "path": "pages/center/order",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "我的委托",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/center/heart",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "收藏",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/center/history",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "浏览记录",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/profile/avatar",
+      "style": {
+        "navigationStyle": "custom",
+        // 隐藏系统导航栏
+        "navigationBarTitleText": "设置头像",
+        "enablePullDownRefresh": false
+      }
+    },
+    {
+      "path": "pages/chooseAddress/index",
+      "style": {
+        "navigationBarBackgroundColor": "#f8f8f8",
+        "navigationBarTitleText": "地图",
+        "backgroundColorTop": "#f8f8f8",
+        "backgroundColorBottom": "#ffffff"
+      }
+    },
+    {
+      "path": "pages/chooseAddress/search",
+      "style": {
+        "navigationBarTitleText": "地址搜索"
+      }
+    },
+    {
+      "path": "pages/chooseAddress/cityList",
+      "style": {
+        "navigationBarTitleText": "选择城市"
+      }
+    },
+    {
+      "path": "pages/webview/webview",
+      "style": {
+        "navigationBarTitleText": "开源字节"
+      }
+    },
+    {
+      "path": "pages/detail/evalList",
+      "style": {
+        "navigationBarTitleText": "房源评价",
+        "enablePullDownRefresh": false
+      }
+    }
+  ],
+  "globalStyle": {
+    "navigationBarTextStyle": "black",
+    "navigationBarTitleText": "World",
+    "navigationBarBackgroundColor": "#ffffff",
+    "backgroundColor": "#ffffff"
+  },
+  "tabBar": {
+    "color": "#909399",
+    "selectedColor": "#2979ff",
+    // "borderStyle": "#909399",
+    "borderStyle": "white",
+    "backgroundColor": "#ffffff",
+    "list": [
+      {
+        "pagePath": "pages/index/index",
+        "iconPath": "static/index.png",
+        "selectedIconPath": "static/index-selected.png",
+        "text": "首页"
+      },
+      {
+        "pagePath": "pages/center/center",
+        "iconPath": "static/center.png",
+        "selectedIconPath": "static/center-selected.png",
+        "text": "我的"
+      }
+    ]
+  },
+  "condition": {
+    //模式配置,仅开发期间生效
+    "current": 0,
+    //当前激活的模式(list 的索引项)
+    "list": [
+      {
+        "name": "",
+        //模式名称
+        "path": "",
+        //启动页面,必选
+        "query": ""
+        //启动参数,在页面的onLoad函数里面得到
+      }
+    ]
+  }
+}

+ 189 - 0
AyaoJies-app/house-master/house-life/pages/center/center.vue

@@ -0,0 +1,189 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="false" title="我的"></u-navbar>
+    <view class="u-flex user-box u-p-l-30 u-p-r-20 u-p-t-30 u-p-b-30">
+      <view class="u-flex" @click="profile">
+        <view class="u-m-r-20">
+          <u-avatar :src="avatar" size="140"></u-avatar>
+        </view>
+        <view class="u-flex-1">
+          <view class="u-font-18 u-p-b-20">{{ vuex_user.user.userName }}</view>
+          <view class="u-font-14 u-tips-color">昵称:{{ vuex_user.user.nickName }}</view>
+        </view>
+      </view>
+    </view>
+    <view class="center-nav">
+      <u-row>
+        <u-col v-for="(item,index) in navList" :key="index" span="3" text-align="center">
+          <view v-if="item.name=='问题反馈'">
+            <!-- 调用微信反馈功能 -->
+            <button class="clearBtn" hover-class="none" open-type="feedback" style="background-color: #FFFFFF;"
+                    type="default">
+              <u-icon :name="item.icon" color="#909399" size="50"></u-icon>
+              <view class="tabName" style="padding-top: 15rpx;">{{ item.name }}</view>
+            </button>
+          </view>
+          <view v-else @click="clickNav(item.url)">
+            <u-icon :name="item.icon" color="#909399" size="50"></u-icon>
+            <view class="tabName">{{ item.name }}</view>
+          </view>
+        </u-col>
+      </u-row>
+    </view>
+
+    <view class="u-m-t-20">
+      <u-cell-group>
+        <!-- <u-cell-item icon="integral" title="实名认证" @click="setting"></u-cell-item> -->
+        <u-cell-item icon="setting" title="个人中心" @click="setting"></u-cell-item>
+      </u-cell-group>
+    </view>
+
+    <view class="u-m-t-20">
+      <u-cell-group>
+        <u-cell-item :arrow="false" icon="level" title="技术支持" value="18720989281"
+                     @click="callPhoneNumber"></u-cell-item>
+        <u-cell-item icon="question-circle" title="常见问题" @click="problem"></u-cell-item>
+        <u-cell-item icon="star" title="关于我们" @click="aboutMe"></u-cell-item>
+      </u-cell-group>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      avatar: uni.getStorageSync('lifeData').vuex_user.user.avatar.includes(config.staticUrl) ? uni.getStorageSync('lifeData').vuex_user.user.avatar : config.staticUrl + uni.getStorageSync('lifeData').vuex_user.user.avatar,
+      show: true,
+      navList: [
+        {name: "浏览记录", icon: "checkmark-circle", url: "pages/center/history"},
+        {name: "我的收藏", icon: "heart", url: "pages/center/heart"},
+        {name: "我的委托", icon: "order", url: "pages/center/order"},
+        {name: "问题反馈", icon: "info-circle"}
+      ],
+    }
+  },
+  onLoad() {
+    uni.$on('updateAvatar', (obj) => {
+      // 获取数据
+      this.updateAvatar();
+    })
+  },
+  onUnload() {
+    // 移除监听事件
+    uni.$off('updateAvatar');
+  },
+  onShow() {
+    // 检查token
+    this.checkToken();
+  },
+  methods: {
+    logout() {
+      // 登录成功修改token与用户信息
+      this.$u.vuex('vuex_token', '');
+      this.$u.vuex('vuex_user', {});
+      this.$u.route('/pages/login/login')
+    },
+    profile() {
+      this.$u.route('/pages/profile/profile')
+    },
+    setting() {
+      this.$u.route('/pages/profile/setting')
+    },
+    //拨打固定电话
+    callPhoneNumber() {
+      uni.makePhoneCall({
+        phoneNumber: "18720989281",
+      });
+    },
+    problem() {
+      this.$u.route({
+        url: 'pages/login/problem'
+      })
+    },
+    // 关于作者
+    aboutMe() {
+      this.$u.route('/pages/profile/aboutMe')
+    },
+    checkToken() {
+      // 判断是否有token
+      let lifeData = uni.getStorageSync('lifeData');
+      let token = lifeData.vuex_token
+      if (!token) {
+        // 没有token 则跳转到登录
+        return uni.reLaunch({
+          url: '../login/login'
+        })
+      } else {
+        // 判断Token是否有效
+        let url = "/api/profile/isExpiration";
+        this.$u.get(url, {
+          token: token
+        }).then(obj => {
+          if (obj.data) {
+            // 没有token过期则跳转到登录
+            return uni.reLaunch({
+              url: '../login/login'
+            })
+          }
+        });
+      }
+    },
+    code() {
+      this.$mytip.toast('敬请期待')
+    },
+    clickNav(url) {
+      if (url) {
+        this.$u.route(url);
+      } else {
+        this.$mytip.toast('敬请期待')
+      }
+    },
+    updateAvatar() {
+      this.avatar = uni.getStorageSync('lifeData').vuex_user.user.avatar.includes(config.staticUrl) ? uni.getStorageSync('lifeData').vuex_user.user.avatar : config.staticUrl + uni.getStorageSync('lifeData').vuex_user.user.avatar
+    },
+  }
+}
+</script>
+
+<style lang="scss">
+.user-box {
+  background-color: #fff;
+  justify-content: space-between;
+}
+
+.center-nav {
+  background-color: #FFFFFF;
+  margin-top: 30 rpx;
+  padding: 30 rpx 0;
+  border-radius: 8px;
+
+  .tabName {
+    color: #606266;
+    font-size: 26 rpx;
+    padding-top: 10 rpx;
+  }
+}
+
+.qiandao {
+  color: #606266;
+  font-size: 24 rpx;
+  margin-right: 24 rpx;
+  margin-top: 54 rpx;
+  justify-content: center;
+  align-items: center;
+}
+
+.clearBtn {
+  margin: 0;
+  padding: 0;
+  line-height: 1;
+  background-color: #FFFFFF;
+}
+
+.clearBtn::after {
+  position: unset !important;
+  border: unset;
+}
+</style>

+ 321 - 0
AyaoJies-app/house-master/house-life/pages/center/heart.vue

@@ -0,0 +1,321 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="收藏"></u-navbar>
+    <view class="wrap">
+      <scroll-view scroll-y style="height: 100%;width: 100%;">
+        <view class="page-box">
+          <view v-if="heartList.length === 0">
+            <view class="centre">
+              <image :src="empty" mode=""></image>
+              <view class="explain">
+                您还没有收藏的房源
+                <view class="tips">可以去逛逛</view>
+              </view>
+              <view class="btn" @click="goHome">首页</view>
+            </view>
+          </view>
+          <view v-for="(item, index) in heartList"
+                v-else :key="index" class="order"
+                @click="viewImage(item.id)">
+            <view class="top">
+              <view class="left">
+                <view class="store">{{ item.code }}</view>
+                <u-icon :size="26" color="rgb(203,203,203)" name="arrow-right"></u-icon>
+              </view>
+            </view>
+            <view class="item">
+              <view class="left">
+                <image :src="item.image" mode="aspectFill"></image>
+              </view>
+              <view class="content">
+                <view class="title u-line-2">
+                  {{ item.villageName }}
+                  {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+                </view>
+                <view class="price">¥{{ item.price }}</view>
+                <view class="type">
+                  {{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ | {{ item.decoration }}
+                </view>
+              </view>
+            </view>
+            <view class="bottom">
+              <view class="evaluate btn" @click="viewImage(item.id)">查看</view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      empty: '/static/empty/default.png',
+      heartList: [],
+      pageNum: 1,
+      pageSize: 100,
+    };
+  },
+  onLoad() {
+    this.findHeartList();
+  },
+  methods: {
+    findHeartList() {
+      let url = "/api/houseApi/findHouseHeartList";
+      let lifeData = uni.getStorageSync('lifeData');
+      let vuex_user = lifeData.vuex_user
+      this.$u.get(url, {
+            userId: vuex_user.user.userId,
+            pageNum: this.pageNum,
+            pageSize: this.pageSize,
+            orderByColumn: 'update_time,create_time',
+            isAsc: 'desc'
+          }
+      ).then(result => {
+        const data = result.rows;
+        this.houseList = data;
+        for (let i = 0; i < this.houseList.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = this.houseList[i]
+          if (!item.faceUrl.includes(config.staticUrl)) {
+            item.image = config.staticUrl + item.faceUrl
+          } else {
+            item.image = item.faceUrl
+          }
+          if (item.type == 0) {
+            item.type = '整租'
+          } else if (item.type == 1) {
+            item.type = '合租'
+          }
+          if (item.roomType == 1) {
+            item.roomType = '主卧'
+          } else if (item.roomType == 2) {
+            item.roomType = '次卧'
+          } else {
+            item.roomType = '未知'
+          }
+          if (this.$u.test.isEmpty(item.houseNum)) {
+            item.houseNum = ''
+          }
+          if (this.$u.test.isEmpty(item.houseHall)) {
+            item.houseHall = ''
+          }
+          if (this.$u.test.isEmpty(item.toiletNum)) {
+            item.toiletNum = ''
+          }
+          this.heartList.push(item);
+        }
+      });
+    },
+    goHome() {
+      uni.switchTab({
+        url: '/pages/index/index'
+      })
+    },
+    viewImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/detail',
+        params: {
+          houseId: houseId
+        }
+      })
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f2f2f2;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+.container {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+
+  .empty {
+    overflow: hidden;
+
+    .tip {
+      color: #909399;
+    }
+
+    .btn {
+      color: #fff;
+      background-color: #2979ff;
+      width: 200 rpx;
+      padding: 15 rpx 28 rpx;
+      border-radius: 130 rpx;
+      margin: 30 rpx 0 0 100 rpx;
+    }
+  }
+}
+
+.order {
+  width: 710 rpx;
+  background-color: #ffffff;
+  margin: 20 rpx auto;
+  border-radius: 20 rpx;
+  box-sizing: border-box;
+  padding: 20 rpx;
+  font-size: 28 rpx;
+
+  .top {
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .store {
+        // margin: 0 10rpx;
+        font-size: 32 rpx;
+      }
+    }
+
+    .right {
+      color: #2979ff;
+    }
+  }
+
+  .item {
+    display: flex;
+    margin: 20 rpx 0 0 0;
+
+    .left {
+      margin-right: 30 rpx;
+
+      image {
+        width: 150 rpx;
+        height: 150 rpx;
+        border-radius: 10 rpx;
+      }
+    }
+
+    .content {
+      .title {
+        font-weight: bold;
+        font-size: 28 rpx;
+        line-height: 50 rpx;
+      }
+
+      .price {
+        margin: 10 rpx 0;
+        font-size: 30 rpx;
+      }
+
+      .type {
+        margin: 10 rpx 0;
+        font-size: 24 rpx;
+        color: $u-tips-color;
+      }
+
+      .desc {
+        margin: 10 rpx 0;
+        font-size: 24 rpx;
+        color: $u-tips-color;
+      }
+    }
+  }
+
+  .bottom {
+    display: flex;
+    margin-top: 20 rpx;
+    padding: 0 10 rpx;
+    justify-content: flex-end;
+    align-items: center;
+
+    .btn {
+      margin-left: 20 rpx;
+      line-height: 52 rpx;
+      width: 160 rpx;
+      border-radius: 26 rpx;
+      border: 2 rpx solid $u-border-color;
+      font-size: 26 rpx;
+      text-align: center;
+      color: $u-type-info-dark;
+    }
+
+    .evaluate {
+      color: $u-tips-color;
+    }
+  }
+}
+
+.centre {
+  text-align: center;
+  margin: 200 rpx auto;
+  font-size: 32 rpx;
+
+  image {
+    width: 164 rpx;
+    height: 164 rpx;
+    border-radius: 50%;
+    margin-bottom: 20 rpx;
+  }
+
+  .tips {
+    font-size: 24 rpx;
+    color: #999999;
+    margin-top: 20 rpx;
+  }
+
+  .btn {
+    margin: 80 rpx auto;
+    width: 200 rpx;
+    border-radius: 32 rpx;
+    line-height: 64 rpx;
+    color: #ffffff;
+    font-size: 26 rpx;
+    background-image: linear-gradient(to left, #2979ff, rgba(#2979ff, 0.6));
+  }
+}
+
+.wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - var(--window-top));
+  width: 100%;
+}
+
+.swiper-box {
+  flex: 1;
+}
+
+.swiper-item {
+  height: 100%;
+}
+
+.buttom {
+  .loginType {
+    font-size: 14px;
+    position: fixed;
+    right: 30 rpx;
+    bottom: 120 rpx;
+    width: 60px;
+    height: 60px;
+    padding: 4px;
+    cursor: pointer;
+    background: #FFF;
+    text-align: center;
+    line-height: 60px;
+    border-radius: 100%;
+    -webkit-box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+    box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+  }
+}
+</style>

+ 258 - 0
AyaoJies-app/house-master/house-life/pages/center/history.vue

@@ -0,0 +1,258 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="浏览记录">
+      <view slot="right" class="u-nav-slot" @click="clearHistory">
+        <u-icon name="trash"></u-icon>
+        清除
+      </view>
+    </u-navbar>
+    <scroll-view scroll-y style="height: 100%;width: 100%;">
+      <view class="page-box">
+        <view v-if="houseHistory.length === 0">
+          <view class="centre">
+            <image :src="empty" mode=""></image>
+            <view class="explain">
+              您还没有浏览过的房源
+              <view class="tips">可以去逛逛</view>
+            </view>
+            <view class="btn" @click="goHome">首页</view>
+          </view>
+        </view>
+        <view v-for="(item, index) in houseHistory" v-else :key="index" class="order"
+              @click="clickImage(item.id)">
+          <view class="top">
+            <view class="left">
+              <view class="store">{{ item.code }}</view>
+              <u-icon :size="26" color="rgb(203,203,203)" name="arrow-right"></u-icon>
+            </view>
+          </view>
+          <view class="item">
+            <view class="left">
+              <image :src="item.faceUrl" mode="aspectFill"></image>
+            </view>
+            <view class="content">
+              <view class="title u-line-2">
+                {{ item.villageName }}
+                {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+              </view>
+              <view class="price">¥{{ item.price }}</view>
+              <view class="type">
+                {{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ | {{ item.decoration }}
+              </view>
+            </view>
+          </view>
+          <view class="bottom">
+            <view class="evaluate btn" @click="clickImage(item.id)">查看</view>
+          </view>
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      empty: '/static/empty/default.png',
+      houseHistory: uni.getStorageSync('houseHistory').reverse()
+    };
+  },
+  onLoad() {
+
+  },
+  methods: {
+    clickImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/detail',
+        params: {
+          houseId: houseId
+        }
+      })
+    },
+    goHome() {
+      uni.switchTab({
+        url: '/pages/index/index'
+      })
+    },
+    clearHistory() {
+      // 清除搜索记录
+      uni.showModal({
+        title: '提示',
+        content: '是否清除浏览记录?',
+        cancelText: '取消',
+        confirmText: '确认',
+        success: res => {
+          if (res.confirm) {
+            uni.removeStorageSync('houseHistory');
+            this.houseHistory = []
+            this.$mytip.toast('清除成功')
+          }
+        }
+      });
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f2f2f2;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+.u-nav-slot {
+  color: $u-tips-color;
+  font-weight: normal;
+  font-size: 28 rpx;
+  margin-right: 30 rpx;
+}
+
+.container {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+
+  .empty {
+    overflow: hidden;
+
+    .tip {
+      color: #909399;
+    }
+
+    .btn {
+      color: #fff;
+      background-color: #909399;
+      width: 200 rpx;
+      padding: 15 rpx 28 rpx;
+      border-radius: 130 rpx;
+      margin: 30 rpx 0 0 100 rpx;
+    }
+  }
+}
+
+.order {
+  width: 710 rpx;
+  background-color: #ffffff;
+  margin: 20 rpx auto;
+  border-radius: 20 rpx;
+  box-sizing: border-box;
+  padding: 20 rpx;
+  font-size: 28 rpx;
+
+  .top {
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .store {
+        // margin: 0 10rpx;
+        font-size: 32 rpx;
+      }
+    }
+
+    .right {
+      color: #2979ff;
+    }
+  }
+
+  .item {
+    display: flex;
+    margin: 20 rpx 0 0;
+
+    .left {
+      margin-right: 30 rpx;
+
+      image {
+        width: 150 rpx;
+        height: 150 rpx;
+        border-radius: 10 rpx;
+      }
+    }
+
+    .content {
+      .title {
+        font-weight: bold;
+        font-size: 28 rpx;
+        line-height: 50 rpx;
+      }
+
+      .price {
+        margin: 10 rpx 0;
+        font-size: 30 rpx;
+      }
+
+      .type {
+        margin: 10 rpx 0;
+        font-size: 24 rpx;
+        color: $u-tips-color;
+      }
+    }
+  }
+
+  .bottom {
+    display: flex;
+    // margin-top: 40rpx;
+    padding: 0 10 rpx;
+    justify-content: flex-end;
+    align-items: center;
+
+    .btn {
+      margin-left: 20 rpx;
+      line-height: 52 rpx;
+      width: 160 rpx;
+      border-radius: 26 rpx;
+      border: 2 rpx solid $u-border-color;
+      font-size: 26 rpx;
+      text-align: center;
+      color: $u-type-info-dark;
+    }
+
+    .evaluate {
+      color: $u-tips-color;
+      border-color: $u-tips-color;
+    }
+  }
+}
+
+.centre {
+  text-align: center;
+  margin: 200 rpx auto;
+  font-size: 32 rpx;
+
+  image {
+    width: 164 rpx;
+    height: 164 rpx;
+    border-radius: 50%;
+    margin-bottom: 20 rpx;
+  }
+
+  .tips {
+    font-size: 24 rpx;
+    color: #999999;
+    margin-top: 20 rpx;
+  }
+
+  .btn {
+    margin: 80 rpx auto;
+    width: 200 rpx;
+    border-radius: 32 rpx;
+    line-height: 64 rpx;
+    color: #ffffff;
+    font-size: 26 rpx;
+    background-image: linear-gradient(to left, #2979ff, rgba(#2979ff, 0.6));
+  }
+}
+</style>

+ 397 - 0
AyaoJies-app/house-master/house-life/pages/center/order.vue

@@ -0,0 +1,397 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="我的委托"></u-navbar>
+    <view class="wrap">
+      <view class="u-tabs-box">
+        <u-tabs-swiper ref="tabs" :current="current" :is-scroll="false" :list="list" activeColor="#2979ff"
+                       swiperWidth="750" @change="change"></u-tabs-swiper>
+      </view>
+      <swiper :current="swiperCurrent" class="swiper-box" @animationfinish="animationfinish" @transition="transition">
+        <swiper-item v-for="(swiper,i) in orderList" :key="i" class="swiper-item">
+          <scroll-view scroll-y style="height: 100%;width: 100%;">
+            <view class="page-box">
+              <view v-if="swiper.length === 0">
+                <view class="centre">
+                  <image :src="empty" mode=""></image>
+                  <view class="explain">
+                    您还没有相关的房源
+                    <view class="tips">可以去委托房源</view>
+                  </view>
+                  <view class="btn" @click="publishHouse">委托房源</view>
+                </view>
+              </view>
+              <view v-for="(item, index) in swiper"
+                    v-else :key="index" class="order">
+                <view class="top">
+                  <view class="left">
+                    <view class="store">{{ item.code }}</view>
+                    <u-icon :size="26" color="rgb(203,203,203)" name="arrow-right"></u-icon>
+                  </view>
+                </view>
+                <view class="item">
+                  <view class="left">
+                    <image :src="item.image" mode="aspectFill"></image>
+                  </view>
+                  <view class="content">
+                    <view class="title u-line-2">
+                      {{ item.villageName }}
+                      {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+                    </view>
+                    <view class="price">¥{{ item.price }}</view>
+                    <view class="type">
+                      {{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ |
+                      {{ item.decoration }}
+                    </view>
+                  </view>
+                </view>
+                <view class="bottom">
+                  <view v-if="item.state == 0" class="evaluate btn" @click.stop="clickImage(item.id)">修改</view>
+                  <view v-else class="evaluate btn" @click.stop="viewImage(item.id)">查看</view>
+                </view>
+              </view>
+            </view>
+          </scroll-view>
+        </swiper-item>
+      </swiper>
+    </view>
+    <view class="buttom">
+      <view class="loginType">
+        <view class="wechat item">
+          <view class="icon">
+            <u-icon color="#999" name="server-man" size="60" @click="server"></u-icon>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      empty: '/static/empty/default.png',
+      orderList: [[], [], [], []],
+      list: [
+        {
+          name: '待审核'
+        },
+        {
+          name: '待出租',
+          // count: 1
+        },
+        {
+          name: '已出租'
+        },
+        {
+          name: '已下架',
+        }
+      ],
+      current: 0,
+      swiperCurrent: 0,
+      tabsHeight: 0,
+      dx: 0,
+      pageNum: 1,
+      pageSize: 100,
+    };
+  },
+  onLoad() {
+    this.getOrderList(0);
+    this.getOrderList(1);
+    this.getOrderList(2);
+    this.getOrderList(3);
+  },
+  methods: {
+    login() {
+      this.$u.route('/pages/login/login')
+    },
+    // 页面数据
+    getOrderList(idx) {
+      this.findHouseList(idx)
+    },
+    // tab栏切换
+    change(index) {
+      this.swiperCurrent = index;
+      this.orderList[index] = []
+      this.getOrderList(index);
+    },
+    transition({detail: {dx}}) {
+      this.$refs.tabs.setDx(dx);
+    },
+    animationfinish({detail: {current}}) {
+      this.$refs.tabs.setFinishCurrent(current);
+      this.swiperCurrent = current;
+      this.current = current;
+    },
+    findHouseList(idx) {
+      let url = "/api/houseApi/findHouseRoomList";
+      let defaultData = {
+        state: idx,
+        publishId: uni.getStorageSync('lifeData').vuex_user.user.userId,
+        villageCity: uni.getStorageSync('lifeData').vuex_city,
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        orderByColumn: 'update_time,create_time',
+        isAsc: 'desc'
+      }
+      this.$u.get(url, {...defaultData, ...this.searchData}).then(result => {
+        const data = result.rows;
+        this.houseList = data;
+        for (let i = 0; i < this.houseList.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = this.houseList[i]
+          if (!item.faceUrl.includes(config.staticUrl)) {
+            item.image = config.staticUrl + item.faceUrl
+          } else {
+            item.image = item.faceUrl
+          }
+          if (item.type == 0) {
+            item.type = '整租'
+          } else if (item.type == 1) {
+            item.type = '合租'
+          }
+          if (item.roomType == 1) {
+            item.roomType = '主卧'
+          } else if (item.roomType == 2) {
+            item.roomType = '次卧'
+          } else {
+            item.roomType = '未知'
+          }
+          if (this.$u.test.isEmpty(item.houseNum)) {
+            item.houseNum = ''
+          }
+          if (this.$u.test.isEmpty(item.houseHall)) {
+            item.houseHall = ''
+          }
+          if (this.$u.test.isEmpty(item.toiletNum)) {
+            item.toiletNum = ''
+          }
+          this.orderList[idx].push(item);
+        }
+      });
+    },
+    publishHouse() {
+      this.$u.route('/pages/detail/preHouse');
+    },
+    server() {
+      // window.open ('https://sourcebyte.cn')
+      uni.makePhoneCall({
+        phoneNumber: "18720989281",
+      });
+    },
+    clickImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/preHouse',
+        params: {
+          houseId: houseId
+        }
+      })
+    },
+    viewImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/detail',
+        params: {
+          houseId: houseId
+        }
+      })
+    }
+  }
+};
+</script>
+
+<style>
+/* #ifndef H5 */
+page {
+  height: 100%;
+  background-color: #f2f2f2;
+}
+
+/* #endif */
+</style>
+
+<style lang="scss" scoped>
+.container {
+  width: 100%;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  text-align: center;
+
+  .empty {
+    overflow: hidden;
+
+    .tip {
+      color: #909399;
+    }
+
+    .btn {
+      color: #fff;
+      background-color: #2979ff;
+      width: 200 rpx;
+      padding: 15 rpx 28 rpx;
+      border-radius: 130 rpx;
+      margin: 30 rpx 0 0 100 rpx;
+    }
+  }
+}
+
+.order {
+  width: 710 rpx;
+  background-color: #ffffff;
+  margin: 20 rpx auto;
+  border-radius: 20 rpx;
+  box-sizing: border-box;
+  padding: 20 rpx;
+  font-size: 28 rpx;
+
+  .top {
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .store {
+        // margin: 0 10rpx;
+        font-size: 32 rpx;
+      }
+    }
+
+    .right {
+      color: #2979ff;
+    }
+  }
+
+  .item {
+    display: flex;
+    margin: 20 rpx 0 0 0;
+
+    .left {
+      margin-right: 30 rpx;
+
+      image {
+        width: 150 rpx;
+        height: 150 rpx;
+        border-radius: 10 rpx;
+      }
+    }
+
+    .content {
+      .title {
+        font-weight: bold;
+        font-size: 28 rpx;
+        line-height: 50 rpx;
+      }
+
+      .price {
+        margin: 10 rpx 0;
+        font-size: 30 rpx;
+      }
+
+      .type {
+        margin: 10 rpx 0;
+        font-size: 24 rpx;
+        color: $u-tips-color;
+      }
+
+      .desc {
+        margin: 10 rpx 0;
+        font-size: 24 rpx;
+        color: $u-tips-color;
+      }
+    }
+  }
+
+  .bottom {
+    display: flex;
+    margin-top: 20 rpx;
+    padding: 0 10 rpx;
+    justify-content: flex-end;
+    align-items: center;
+
+    .btn {
+      margin-left: 20 rpx;
+      line-height: 52 rpx;
+      width: 160 rpx;
+      border-radius: 26 rpx;
+      border: 2 rpx solid $u-border-color;
+      font-size: 26 rpx;
+      text-align: center;
+      color: $u-type-info-dark;
+    }
+
+    .evaluate {
+      // color: #2979ff;
+      // border-color: #2979ff;
+      color: $u-tips-color;
+      border-color: $u-tips-color;
+    }
+  }
+}
+
+.centre {
+  text-align: center;
+  margin: 200 rpx auto;
+  font-size: 32 rpx;
+
+  image {
+    width: 164 rpx;
+    height: 164 rpx;
+    border-radius: 50%;
+    margin-bottom: 20 rpx;
+  }
+
+  .tips {
+    font-size: 24 rpx;
+    color: #999999;
+    margin-top: 20 rpx;
+  }
+
+  .btn {
+    margin: 80 rpx auto;
+    width: 200 rpx;
+    border-radius: 32 rpx;
+    line-height: 64 rpx;
+    color: #ffffff;
+    font-size: 26 rpx;
+    background-image: linear-gradient(to left, #2979ff, rgba(#2979ff, 0.6));
+  }
+}
+
+.wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - var(--window-top));
+  width: 100%;
+}
+
+.swiper-box {
+  flex: 1;
+}
+
+.swiper-item {
+  height: 100%;
+}
+
+.buttom {
+  .loginType {
+    font-size: 14px;
+    position: fixed;
+    right: 30 rpx;
+    bottom: 120 rpx;
+    width: 60px;
+    height: 60px;
+    padding: 4px;
+    cursor: pointer;
+    background: #FFF;
+    text-align: center;
+    line-height: 60px;
+    border-radius: 100%;
+    -webkit-box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+    box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+  }
+}
+</style>

+ 47 - 0
AyaoJies-app/house-master/house-life/pages/center/tips.vue

@@ -0,0 +1,47 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" :title="title"></u-navbar>
+    <view class="u-content">
+      <u-parse :autosetTitle="true"
+               :html="content"
+               :selectable="true"
+               :show-with-animation="true"
+      ></u-parse>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      title: '避坑指南',
+      content: ``
+    }
+  },
+  onLoad() {
+    let url = "/api/cmsApi/getServiceItemByAjax?type=租房避坑指南"
+    this.$u.get(url).then(res => {
+      // console.log(res.data.content);
+      this.content = res.data.content
+    });
+  },
+}
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+.u-content {
+  // margin:0 10rpx;
+  // padding: 24rpx;
+  font-size: 34 rpx;
+  color: $u-main-color;
+  line-height: 1.8;
+  white-space: pre-wrap !important;
+}
+</style>
+

+ 243 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/cityList.vue

@@ -0,0 +1,243 @@
+<template>
+  <view>
+    <view class="list">
+      <view v-for="(keyItem, keyIndex) in renderList" :key="keyIndex" class="keyList">
+        <view :id="'keyword' + keyItem.key" class="keyword">
+          <text>{{ keyItem.key === 'AAA' ? '热门地区' : keyItem.key }}</text>
+        </view>
+        <view v-for="(item, index) in keyItem.list" :key="index" class="item b-b" @click="chooseCity(item)">
+          <text>{{ item.label }}</text>
+        </view>
+      </view>
+    </view>
+
+    <view class="key-list column" @click.stop.prevent="stopPrevent">
+      <view
+          v-for="(item, index) in renderList"
+          :key="index"
+          :class="{active: index === keywordCurrent}"
+          class="key-item"
+          @click="onKeywordClick(index)"
+      >
+        <text>{{ item.key === 'AAA' ? '#' : item.key }}</text>
+      </view>
+    </view>
+
+    <view :class="{show: keyChanged}" class="key-show center">
+      <text>{{ keywordCurrentName }}</text>
+    </view>
+  </view>
+</template>
+
+<script>
+import getFirstLetter from './js/getFirstLetter.js'
+import cityData from './js/city'
+
+const _anchorList = [];
+let _onKeywordClicking = false;
+let _timer = 0;
+export default {
+  data() {
+    return {
+      keyChanged: false,
+      keywordCurrentName: '',
+      keywordCurrent: 0, //当前索引
+      renderList: [],
+      list: [],
+    }
+  },
+  onPageScroll(e) {
+    if (_onKeywordClicking) {
+      return;
+    }
+    const top = e.scrollTop;
+    for (let i = 0; i < _anchorList.length; i++) {
+      if (top > _anchorList[i]) {
+        this.keywordCurrent = i;
+      }
+    }
+  },
+  watch: {
+    keywordCurrent(val) {
+      this.keywordCurrentName = this.renderList[val].key;
+      if (_timer) {
+        clearTimeout(_timer);
+      }
+      this.keyChanged = true;
+      _timer = setTimeout(() => {
+        this.keyChanged = false;
+      }, 500)
+    }
+  },
+  onLoad(options) {
+    this.initList();
+  },
+  methods: {
+    chooseCity(item) {
+      const pages = getCurrentPages();
+      const prePage = (pages[pages.length - 2]).$vm;
+      prePage.city = item.label;
+      prePage.searchList();
+      uni.navigateBack();
+    },
+    //初始化列表
+    initList() {
+      const list = cityData;
+      const tempData = {};
+      list.forEach(item => {
+        let key = getFirstLetter.getLetter(item.label).firstletter;
+        if (!tempData[key]) {
+          tempData[key] = [];
+        }
+        tempData[key].push(item);
+      })
+      //排序用
+      const tempKeyList = [];
+      for (let key in tempData) {
+        tempKeyList.push(key);
+      }
+      tempKeyList.sort();
+      const renderList = [];
+      tempKeyList.forEach(keyword => {
+        for (let key in tempData) {
+          if (key == keyword) {
+            renderList.push({
+              key,
+              list: tempData[key]
+            })
+          }
+        }
+      })
+      this.renderList = renderList;
+      //生成右侧索引
+      setTimeout(() => {
+        this.calcAnchor();
+      }, 500)
+    },
+    //计算锚点高度
+    calcAnchor() {
+      const list = this.renderList;
+      let size = {};
+      const placeFillHeight = this.systemInfo.navigationBarHeight + this.systemInfo.statusBarHeight;
+
+      list.forEach(async item => {
+        let size = await this.getElSize('keyword' + item.key);
+        item.top = size.top;
+        _anchorList.push(size.top);
+      })
+    },
+    //右侧索引点击
+    onKeywordClick(index) {
+      _onKeywordClicking = true;
+      setTimeout(() => {
+        _onKeywordClicking = false;
+      }, 500)
+      this.keywordCurrent = index;
+      uni.pageScrollTo({
+        scrollTop: this.renderList[index].top
+      })
+    },
+    //获得元素的size
+    getElSize(id) {
+      return new Promise(res => {
+        let el = uni.createSelectorQuery().select('#' + id);
+        el.boundingClientRect(data => {
+          res(data);
+        }).exec();
+      });
+    }
+
+  }
+}
+</script>
+
+<style>
+page {
+  background-color: #f7f7f7;
+}
+</style>
+<style lang="scss" scoped>
+.key-show {
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  z-index: 95;
+  transform: translate(-50%, -50%);
+  width: 80 rpx;
+  height: 80 rpx;
+  background-color: #2979ff;
+  border-radius: 100 rpx;
+  font-size: 40 rpx;
+  font-weight: 600;
+  color: #fff;
+  opacity: 0;
+
+  &.show {
+    opacity: 1;
+  }
+}
+
+.keyList {
+  position: relative;
+
+  .keyword {
+    position: sticky;
+    left: 0;
+    top: var(--window-top);
+    z-index: 95;
+    padding-top: 6 rpx;
+    padding-left: 30 rpx;
+    width: 100%;
+    height: 66 rpx;
+    line-height: 60 rpx;
+    font-size: 28 rpx;
+    color: #333;
+    font-weight: 700;
+    background-color: #f7f7f7;
+  }
+
+  .item {
+    padding-left: 30 rpx;
+    line-height: 80 rpx;
+    font-size: 28 rpx;
+    color: #333;
+    background-color: #fff;
+
+    &:after {
+      left: 30 rpx;
+    }
+
+    .cn-name {
+      margin-left: 12 rpx;
+      color: #666;
+    }
+  }
+}
+
+/* 右侧索引 */
+.key-list {
+  position: fixed;
+  right: 0;
+  top: 50%;
+  z-index: 96;
+  padding-right: 20 rpx;
+  padding-left: 40 rpx;
+  transform: translateY(-50%);
+
+  .key-item {
+    width: 40 rpx;
+    height: 40 rpx;
+    margin-bottom: 2 rpx;
+    text-align: center;
+    line-height: 40 rpx;
+    font-size: 26 rpx;
+    color: #333;
+    border-radius: 100 rpx;
+  }
+
+  .active {
+    background-color: #2979ff;
+    color: #fff;
+  }
+}
+</style>

+ 417 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/index.vue

@@ -0,0 +1,417 @@
+<template>
+  <view class='app'>
+    <!-- 当前选择地址 -->
+    <view class="current-address row b-b">
+      <view class="left">
+        <view class="row">
+          <text class="red">[当前]</text>
+          <text class="title">{{ currentAddress.title }}</text>
+        </view>
+        <text class="addr clamp">{{ currentAddress.address }}</text>
+      </view>
+      <!-- 搜索图标 -->
+      <image
+          class="ser-icon"
+          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAYAAAA6/NlyAAAENElEQVRoQ+2a/1XcMAzHlQkKExQmaJmAMgHtBJQJqkzQMsGpExQm6HWCHhMUJihMUJjAfd97znuucc6Sklxf4PwXjzixPtYPS/I19MJG88J4aQf83DW+0/BOw89sByY3aWbea5rmDREdhBAO0v1rmmYVQrgXkbtt7eskwMz8lojOiOgdEeHv2nggolXTNMvFYnFVmzzk+ajAbduehhA4gnrlArwQ0VcRwd+jjlGAo0YXA0FzsDW4iFyMSTwYmJk/E9GXDULdEtGSiOCnqa/uRXOHX78nolc937ghog9j+bkbGMGIiKDVjwVB7+MmLLVmGa0E7gDfL2n7REQAP2i4gCPsz0JAWoOKyKVXKmaGxmExJfDzId+GTF5gwCICp+MHtK3VaG1DmBlmjo1LTR1+PUjTZmBmRgT9lAl8ISKb/LjGV3wezRz+/zqZAOhD78aagOOuf8+kaxFKXUSKl6L7INilml6JyIni9SdT1MBx4V/ImJKvXIlIKWh5ZOl9J2p6lUG7/NkCDJPFEdSNWxHRZFGjwDMzIjhOhW64TFsFHLX7m4hwFHUDwQO7vrXBzFjvOFnQrGUtMMz2W7LQtYjkUXpycGbGmjghunEnIoeWhbXAiJSnyYePxkgCLIJ2c5kZyQeqr26YZKkCR3P+kyyAcu6fMs8juPedgi+bjkQNcG5GW4nMfRsSMzHEk26Y3EsDnEdnJPIw8f82MrN+EJF9rTAaYKR3aV679eicw+TRWkSqHN03qhMLR8G+N63TaqE2j5ndSjADW3azJrj3OTPnbqa2urkC5wUMiglVI1ADnJ/B6t30arD23tQ+7DafmuDe51MD52nlpOVgbRMKidDo5zCyqvSgvxGRo5pgUz0v1ORo56KSUo2qD+MrzIyAkHYd1EFCJYVh0pAjCctogXM/NuWvBp6NU2NaiSZEV6Y+ikhaslaX0gLnZo3iG1WK6iioSqGcUNCuOa9XAUezzrMb82JKruK0QtHwiHaTNeuzAOdahmDmjoMHuqcP7nIrNXDUcu7L+LepAHcCo1OKPnU3XNpVB61UyELHYXBzfNMmMDNaS3ln1L3JJg1HLcO00WbJbwSQkLivWHLoDdc5gxIfM3CERns27xPjEYAh0KB73bZtz0IIKBDyI8fctMs30gVcgXZfaMeuJHrfmzqilyJy7okFLh/O/BnmjWoq7SKmU5bxdxzId59cdcbffxyHEBCQAKltDrqh3RrOwEvRu08JAAeYJkO6jgGrdH3qgh4FOAlmffe6Vgt8cs9cyLLWMcNq3qMBd0QxI0L1AjNNCw4NNO6YcRlZvMIZA3p04IKPd75ZCkTd7z5w/am6pxoKPSmwRqWeOUOgZwkcY0ZezODf1WbAbIH7oGtt5FkDF6Cr/a3ZA0fodWDU5PLPAtgS+HbAlt2a49ydhueoNYvMOw1bdmuOc/8C4xLETHORTG0AAAAASUVORK5CYII="
+          @click="navTo('search?city='+curCity)"
+      ></image>
+    </view>
+    <!-- 补充详细地址 -->
+    <view class="confirm-wrap row">
+      <!-- <input class="input" placeholder="补充详细地址:楼号、门牌等(选填)" placeholder-class="placeholder" v-model="room" @confirm='submit'></input> -->
+      <view class="btn" @click="submit">确定</view>
+    </view>
+    <map
+        id="map"
+        :latitude="map.latitude"
+        :longitude="map.longitude"
+        :scale="15"
+        :show-location="true"
+        class="map"
+        @regionchange="onRegionchange"
+    >
+      <cover-image class="map-center-icon"
+                   src="https://7478-tx-cloud-mix-mall-d6944c-1302673523.tcb.qcloud.la/5bfbd58b18200d8e16f6b17a02e6ed9.png"></cover-image>
+    </map>
+    <!-- 结果集 -->
+    <scroll-view class="addr-list-scroll" scroll-y>
+      <view class="addr-list">
+        <view v-for="(item, index) in list" :key="index" class="addr-item b-b row" @click="chooseAddress(index)">
+          <view class="left">
+            <text class="title">{{ item.title }}</text>
+            <text class="addr">{{ item.address }}</text>
+          </view>
+          <icon v-if='checked === index' class="icon_circle" color="#2979ff" size="18" type="success"/>
+        </view>
+      </view>
+    </scroll-view>
+  </view>
+</template>
+
+<script>
+const QQMapWX = require('./js/qqmap-wx-jssdk.min.js')
+const qqmapsdk = new QQMapWX({
+  key: 'FALBZ-J2G3I-ZY5GX-5ATUZ-GHOOZ-YVFAR'
+})
+let _mapCtx = null;
+export default {
+  data() {
+    return {
+      curCity: '',
+      mapStatus: 1,
+      map: {
+        longitude: 116.39742,
+        latitude: 39.909,
+      },
+      room: '', //补充地址 门牌号、房间号
+      list: [], //地址列表
+      checked: 0, //当前选择选择地址下标
+      tempAddress: null, //编辑或者搜索到地址时,需要手动将结果添加到poi集
+    }
+  },
+  computed: {
+    currentAddress() {
+      if (this.list.length === 0) {
+        return {};
+      }
+      return this.list[this.checked];
+    }
+  },
+  created() {
+    _mapCtx = uni.createMapContext('map');
+  },
+  onNavigationBarButtonTap() {
+    this.submit();
+  },
+  async onLoad(options) {
+    //编辑地址时参数
+    let optionData = options.data;
+    let lng, lat;
+    if (optionData) {
+      //编辑地址时
+      this.tempAddress = JSON.parse(optionData);
+      this.room = this.tempAddress.room;
+      lng = this.tempAddress.location.lng;
+      lat = this.tempAddress.location.lat;
+    } else {
+      //没有传坐标时获取用户当前定位
+      const userLocation = await this.getLocation();
+      lng = +userLocation.longitude;
+      lat = +userLocation.latitude;
+    }
+    this.map = {
+      longitude: lng,
+      latitude: lat
+    }
+    this.position = {
+      longitude: lng,
+      latitude: lat
+    }
+    this.getAddressList(1)
+  },
+  methods: {
+    //确定选择
+    submit() {
+      const {currentAddress, room} = this;
+      const {ad_info, address, location, title} = currentAddress;
+      // this.$util.prePage().setAddress(Object.assign({}, {
+      // 	ad_info, address, location, title,room
+      // }));
+      uni.$emit('changeAddressConfig', address, location.lng, location.lat);
+      uni.navigateBack();
+    },
+    //获取poi列表
+    getAddressList(s = 0) {
+      //在ios下防止搜索返回时多次加载地址列表的问题
+      if (this.isSetTempAddress === 1) {
+        return;
+      }
+      qqmapsdk.reverseGeocoder({
+        location: {
+          latitude: this.position.latitude,
+          longitude: this.position.longitude
+        },
+        get_poi: 1,
+        poi_options: "page_size=30;page_index=1",
+        success: res => {
+          res.result.pois.forEach(poi => {
+            if (!poi.ad_info) {
+              poi.ad_info = {
+                adcode: poi.adcode,
+                city: poi.city,
+                district: poi.district,
+                province: poi.province
+              }
+            }
+          })
+          //有搜索结果时,手动追加到列表顶部
+          if (this.tempAddress) {
+            if (this.tempAddress.title != res.result.pois[0].title) {
+              if (!this.tempAddress.ad_info) {
+                this.tempAddress.ad_info = {
+                  adcode: this.tempAddress.adcode,
+                  city: this.tempAddress.city,
+                  district: this.tempAddress.district,
+                  province: this.tempAddress.province
+                }
+              }
+              res.result.pois.unshift(this.tempAddress);
+            }
+            this.tempAddress = null;
+            this.isSetTempAddress = 1;
+            setTimeout(() => {
+              this.isSetTempAddress = 0;
+            }, 500)
+          }
+          if (s) {
+            const ad_info = res.result.pois[0].ad_info;
+            this.curCity = ad_info.city || '';
+            res.result.pois[0].select = 1
+            this.list = res.result.pois;
+            this.checked = 0;
+          } else {
+            this.list = res.result.pois;
+          }
+        },
+        fail: err => {
+          console.log(err)
+        }
+      })
+    },
+    //地图区域改变
+    onRegionchange(e) {
+      clearTimeout(this.timer)
+      this.timer = setTimeout(() => {
+        //h5 end  安卓 regionchange
+        if (e.type === 'end' || e.type === 'regionchange') {
+          _mapCtx.getCenterLocation({
+            success: res => {
+              this.position = {
+                latitude: res.latitude,
+                longitude: res.longitude
+              }
+              if (this.mapStatus == 1) { // 防止地图点击时 进行多次加载
+                this.getAddressList(1)
+              }
+            },
+            fail: err => {
+              console.log(err);
+            }
+          })
+        }
+      }, 200)
+    },
+    //地址列表点击
+    chooseAddress(index) {
+      let list = this.list
+      this.map = {
+        longitude: list[index].location.lng,
+        latitude: list[index].location.lat
+      }
+      this.checked = index;
+      this.mapStatus = 0;
+      //防止ios下触发多次加载列表的bug
+      clearTimeout(this.mapStatusTimer);
+      this.mapStatusTimer = setTimeout(() => {
+        this.mapStatus = 1;
+      }, 1000)
+    },
+    //获取用户定位
+    getLocation() {
+      return new Promise(resolve => {
+        // #ifndef H5
+        uni.getLocation({
+          type: 'gcj02',
+          success: res => {
+            resolve({
+              longitude: res.longitude,
+              latitude: res.latitude
+            })
+          },
+          err: err => {
+            console.log(err)
+            resolve({
+              longitude: 116.39742,
+              latitude: 39.909,
+            })
+          },
+          complete(res) {
+            console.log(res);
+          }
+        })
+        // #endif
+        // #ifdef H5
+        //h5的定位没有写,这里直接默认天安门,可以根据项目需求使用对应jssdk获取定位
+        resolve({
+          longitude: 116.39742,
+          latitude: 39.909,
+        })
+        // #endif
+      })
+    },
+    navTo(url) {
+      uni.navigateTo({
+        url
+      })
+    }
+  }
+}
+</script>
+
+<style>
+page {
+  height: 100%;
+  background: #F6F6F6;
+}
+</style>
+<style lang="scss" scoped>
+.app {
+  display: flex;
+  flex-direction: column;
+  height: 100%;
+  overflow: hidden;
+}
+
+.row {
+  display: flex;
+  align-items: center;
+}
+
+.b-b {
+  position: relative;
+
+  &:after {
+    position: absolute;
+    z-index: 3;
+    left: 0;
+    top: auto;
+    bottom: 0;
+    right: 0;
+    height: 0;
+    content: '';
+    transform: scaleY(.5);
+    border-bottom: 1px solid #e5e5e5;
+  }
+}
+
+.clamp {
+  /* #ifdef APP-PLUS-NVUE */
+  lines: 1;
+  /* #endif */
+  /* #ifndef APP-PLUS-NVUE */
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+  display: block;
+  /* #endif */
+}
+
+.current-address {
+  height: 120 rpx;
+  padding: 0 24 rpx;
+  background-color: #fff;
+
+  .left {
+    width: 634 rpx;
+  }
+
+  .red {
+    flex-shrink: 0;
+    margin-right: 6 rpx;
+    font-size: 28 rpx;
+    color: #2979ff;
+    line-height: 36 rpx;
+  }
+
+  .title {
+    font-size: 28 rpx;
+    color: #333;
+    font-weight: bold;
+    line-height: 36 rpx;
+  }
+
+  .addr {
+    width: 700 rpx;
+    margin-top: 12 rpx;
+    font-size: 24 rpx;
+    color: #909399;
+    line-height: 1.4;
+  }
+
+  .ser-icon {
+    flex-shrink: 0;
+    width: 66 rpx;
+    height: 66 rpx;
+    padding: 12 rpx 4 rpx 12 rpx 20 rpx;
+  }
+}
+
+.confirm-wrap {
+  height: 88 rpx;
+  padding: 0 24 rpx;
+  background-color: #fff;
+
+  .input {
+    flex: 1;
+    font-size: 28 rpx;
+    color: #303133;
+  }
+
+  .btn {
+    width: 700 rpx;
+    padding: 0 25 rpx;
+    font-size: 26 rpx;
+    color: #fff;
+    height: 60 rpx;
+    line-height: 60 rpx;
+    background-color: #2979ff;
+    border-radius: 100 rpx;
+    text-align: center;
+  }
+}
+
+.map {
+  width: 750 rpx;
+  height: 700 rpx;
+
+  .map-center-icon {
+    position: absolute;
+    left: 339 rpx;
+    top: 264 rpx;
+    width: 72 rpx;
+    height: 72 rpx;
+  }
+}
+
+.addr-list-scroll {
+  flex: 1;
+  overflow: hidden;
+
+  .addr-list {
+    background-color: #fff;
+  }
+
+  .addr-item {
+    padding: 24 rpx;
+  }
+
+  .left {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding-right: 50 rpx;
+  }
+
+  .title {
+    font-size: 28 rpx;
+    color: #303133;
+  }
+
+  .addr {
+    margin-top: 10 rpx;
+    font-size: 24 rpx;
+    color: #909399;
+    line-height: 1.4;
+  }
+}
+</style>

文件差异内容过多而无法显示
+ 0 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/js/city.js


文件差异内容过多而无法显示
+ 0 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/js/getFirstLetter.js


文件差异内容过多而无法显示
+ 25 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/js/qqmap-wx-jssdk.min.js


+ 191 - 0
AyaoJies-app/house-master/house-life/pages/chooseAddress/search.vue

@@ -0,0 +1,191 @@
+<template>
+  <view class='app'>
+    <view class="search-wrap">
+      <view class="city" @click="navTo('cityList?city='+city)">
+        <image class="icon"
+               src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAYAAAA7MK6iAAAC70lEQVRIS8VW7VXcMBDctQsAKshRQYRcAJcKIBUAFQAVhFSQowKggpAKuBTgRVcBRwWQAiTljZ/Ek235436hf3e2NTuzO7vL9EmHPwmXZgMrpRZlWZ4Q0dJ7v2TmfQTtvX9n5jURra21D8aY9zlkJoGVUvtFUVwS0VUEG7oYQRDRyjl3OxXAKLBSSpVleUdEKrDbENG9c84Q0TYEsCiKAs/Pmflr+M9Yay+MMXgvewaBAVoUxVNg+c9ae2qMgaSDp6qqUwRGRHtg75w7MsbEAFvfZYEhb1mWT2Dqvd8455ZT0sVbQ2rWgT2Yf8t9mwXWWt8w8w8iAtNF90NcHmVFYLnnZVmCKZj/FJGbrkw94BDxCyT23l+ICKRrTnj2i5nP04u898j7dRqA1ho5vwuSH3aD6wEnH2xEpCmqCBrlhxKwT3i0BDMi6smqtTZQpksA3/WAq6p6JKIT7/2tiFxFYK31ipkvvfd/nXMotMavQYVHZj4e+oaI/tR1jcL7ODnGKIzjUBQfVVxVFYD2rLUHAzl9g6wicpCotIRKCFZEoMwo8JaZv6TAoWu95C5IFIkBI5+NhZRSEbiVtqzUWuse42CvN+SxruujnJFjPlNFEuBZjBvgrg201j0lMpK+isgiUaGx5Vypo4cf6rr+sE3HHt9jFwOroih+5+xXVRWseJbzcs7HMS+tQgGLeFFOaiJqBRrejwWJ7tVqt0Odq5E15z8wD5OqGQjoXJhIaaPB/4lCLflj0KMt03u/FZHDAYajf8eamN0yky4Ve+21iKx2AZ/q9Vk7JRXZ9Fr8ttZivA3O1jSoMMOfQxpavX60gaQPk/a5DbN1dK0J7fOZmWGpXpucDTx3tibpmT3D5+xcWH9ghTiBeitNZ0XCDFdDm8doVXcLKVzcgIf5OtRAXsPkmqyHScZJW8S2GVca+LepdGZuRueuK9Js4CSPADxLVcEcds7dzN3LRu005ltskynjuq6xPOx0dmK8080TL38a8H+fVUE94KTW6AAAAABJRU5ErkJggg=="></image>
+        <text>{{ city }}</text>
+        <image class="c-icon"
+               src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAvElEQVQ4T+3TwQ3CMAwF0G9lAQbgwgRlhEgegBEQm3UEFrCUEWACLgzAAlaQpQa1EJxK9MChvaVKXp3vmrDwQwt7WMHfE31lGGPchBBuAM4icppDM3MP4KCqu5TSw85MmsLMFyLqcs59CzWMiI4556uI7EsBE3CoMrXQMaaqsVT3UaG9aKEeVgU9tIV9BWuo5V0ye7/muIHupJTrA+iICNYAD3MrLF8d0LutVXU7bkDt11pnec7A+Xv+P8Mn98h9FeV7S88AAAAASUVORK5CYII="></image>
+      </view>
+      <input auto-focus class="input" focus maxlength="30" placeholder="请输入地址关键字搜索" @confirm='bindConfirm'
+             @input="bindConfirm"></input>
+    </view>
+
+    <view class="addr-list">
+      <view v-for="(item, index) in list" :key="index" class="addr-item b-b" @click="confirm(item)">
+        <text class="title">{{ item.title }}</text>
+        <text class="addr">{{ item.address }}</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+const QQMapWX = require('./js/qqmap-wx-jssdk.min.js')
+var qqmapsdk = new QQMapWX({
+  key: 'FALBZ-J2G3I-ZY5GX-5ATUZ-GHOOZ-YVFAR'
+})
+export default {
+  data() {
+    return {
+      city: '',
+      keyword: '',
+      list: []
+    }
+  },
+  onLoad(options) {
+    uni.setNavigationBarTitle({
+      title: '搜索地址'
+    })
+    this.city = options.city || '';
+  },
+  methods: {
+    //选择地址
+    confirm(item) {
+      const pages = getCurrentPages()
+      const prePages = pages[pages.length - 2].$vm
+
+      prePages.tempAddress = item;
+      prePages.position = {
+        longitude: item.location.lng,
+        latitude: item.location.lat,
+      }
+      prePages.map = {
+        longitude: item.location.lng,
+        latitude: item.location.lat,
+      }
+      // #ifdef H5 || MP-WEIXIN
+      prePages.getAddressList(1); //h5没触发地图regionchange事件,需要手动调用获取新地址列表。微信小程序开发工具自动触发,真机不触发,同样需要调用一下。
+      // #endif
+      uni.navigateBack({
+        delta: 1
+      })
+    },
+    //搜索地址
+    searchList() {
+      qqmapsdk.getSuggestion({
+        keyword: this.keyword,
+        policy: 1, //默认0,常规策略  policy=1:本策略主要用于收货地址、上门服务地址的填写,
+        page_size: 20, //每页条目数,最大限制为20条,默认值10
+        page_index: 1,
+        region: this.city || '全国',
+        success: res => {
+          this.list = res.data;
+        },
+        fail: err => {
+          this.list = [];
+        }
+      })
+    },
+    bindConfirm(e) {
+      this.keyword = e.detail.value;
+      this.searchList()
+    },
+    navTo(url) {
+      uni.navigateTo({
+        url
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+view {
+  box-sizing: border-box;
+}
+
+.app {
+  padding-top: 100 rpx;
+}
+
+.search-wrap {
+  position: fixed;
+  left: 0;
+  top: var(--window-top);
+  z-index: 90;
+  display: flex;
+  background-color: #fff;
+  align-items: center;
+  width: 100%;
+  height: 100 rpx;
+  padding: 0 30 rpx;
+  background-color: #fff;
+
+  .city {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 30 rpx;
+    color: #333;
+  }
+
+  .icon {
+    width: 34 rpx;
+    height: 34 rpx;
+    margin-right: 4 rpx;
+  }
+
+  .c-icon {
+    width: 22 rpx;
+    height: 22 rpx;
+    margin-left: 4 rpx;
+  }
+
+  .input {
+    flex: 1;
+    margin-left: 16 rpx;
+    padding: 0 28 rpx;
+    height: 70 rpx;
+    line-height: 70 rpx;
+    font-size: 30 rpx;
+    color: #333;
+    background-color: #f5f5f5;
+    border-radius: 100 rpx;
+  }
+}
+
+.addr-list {
+  background-color: #fff;
+
+  .addr-item {
+    display: flex;
+    flex-direction: column;
+    padding: 24 rpx 30 rpx;
+    position: relative;
+
+    &:after {
+      position: absolute;
+      z-index: 3;
+      left: 0;
+      top: auto;
+      bottom: 0;
+      right: 0;
+      height: 0;
+      content: '';
+      transform: scaleY(.5);
+      border-bottom: 1px solid #e5e5e5;
+    }
+  }
+
+  .left {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding-right: 50 rpx;
+  }
+
+  .title {
+    font-size: 28 rpx;
+    color: #303133;
+  }
+
+  .addr {
+    margin-top: 10 rpx;
+    font-size: 24 rpx;
+    color: #909399;
+    line-height: 1.4;
+  }
+}
+</style>

+ 47 - 0
AyaoJies-app/house-master/house-life/pages/content/content.vue

@@ -0,0 +1,47 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" :title="title"></u-navbar>
+    <view class="u-content">
+      <u-parse :autosetTitle="true"
+               :html="content"
+               :selectable="true"
+               :show-with-animation="true"></u-parse>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      title: '资讯',
+      content: ``
+    }
+  },
+  onLoad(option) {
+    let id = option.id
+    let url = "/api/notice/getNotice/" + id;
+    this.$u.get(url).then(res => {
+      this.title = res.data.noticeTitle
+      this.content = res.data.noticeContent
+    });
+  },
+}
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+.u-content {
+  margin: 0 10 rpx;
+  padding: 24 rpx;
+  font-size: 34 rpx;
+  color: $u-main-color;
+  line-height: 1.8;
+  white-space: pre-wrap !important;
+}
+</style>
+

+ 138 - 0
AyaoJies-app/house-master/house-life/pages/detail/addHouse.vue

@@ -0,0 +1,138 @@
+<template>
+  <view>
+    <view class="wrap">
+      <view class="u-tabs-box">
+        <u-tabs-swiper ref="tabs" :current="current" :is-scroll="false" :list="tabList" bar-width="120"
+                       swiperWidth="750" @change="change"></u-tabs-swiper>
+      </view>
+      <swiper :current="swiperCurrent" class="swiper-box" @animationfinish="animationfinish" @transition="transition">
+        <swiper-item class="swiper-item">
+          <add-all-house :model="model"></add-all-house>
+        </swiper-item>
+        <swiper-item class="swiper-item">
+          <add-sub-house :model="model"></add-sub-house>
+        </swiper-item>
+      </swiper>
+    </view>
+  </view>
+</template>
+
+<script>
+
+import addAllHouse from '@/components/zy/addAllHouse.vue'
+import addSubHouse from '@/components/zy/addSubHouse.vue'
+
+export default {
+  components: {
+    addAllHouse, addSubHouse
+  },
+  data() {
+    return {
+      tabList: [{name: '整租'}, {name: '合租'}],
+      current: 0,
+      swiperCurrent: 0,
+      tabsHeight: 0,
+      // 房源对象
+      model: null,
+    };
+  },
+  onLoad: function (option) {
+    this.model = JSON.parse(option.room)
+  },
+  methods: {
+    // tab栏切换
+    change(index) {
+      this.swiperCurrent = index;
+    },
+    transition({detail: {dx}}) {
+      this.$refs.tabs.setDx(dx);
+    },
+    animationfinish({detail: {current}}) {
+      this.$refs.tabs.setFinishCurrent(current);
+      this.swiperCurrent = current;
+      this.current = current;
+      this.model.type = current;
+    }
+  }
+};
+</script>
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+.tabSwiper {
+  width: 710 rpx;
+  background-color: #ffffff;
+  margin: 20 rpx auto;
+  border-radius: 20 rpx;
+  box-sizing: border-box;
+  padding: 20 rpx;
+  font-size: 28 rpx;
+
+  .top {
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .title {
+        margin: 0 10 rpx;
+        font-size: 32 rpx;
+        font-weight: bold;
+      }
+    }
+
+    .right {
+      color: $u-tips-color;
+    }
+  }
+
+  .item {
+    display: flex;
+    margin: 20 rpx 0 0;
+
+    .left {
+      margin-right: 20 rpx;
+
+      image {
+        width: 200 rpx;
+        height: 200 rpx;
+        border-radius: 10 rpx;
+      }
+    }
+
+    .content {
+      .title {
+        font-size: 28 rpx;
+        line-height: 50 rpx;
+      }
+    }
+
+    .right {
+      margin-left: 10 rpx;
+      padding-top: 20 rpx;
+      text-align: right;
+    }
+  }
+}
+
+.wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - var(--window-top));
+  width: 100%;
+}
+
+.swiper-box {
+  flex: 1;
+}
+
+.swiper-item {
+  height: 100%;
+}
+
+</style>

+ 592 - 0
AyaoJies-app/house-master/house-life/pages/detail/detail.vue

@@ -0,0 +1,592 @@
+<template>
+  <view class="u-margin-left-20 u-margin-right-20">
+    <u-navbar :border-bottom="false" :custom-back="goHome" :is-back="true"
+              back-text="返回" title="房源"></u-navbar>
+    <view>
+      <u-swiper :height="750" :interval="5000" :list="swiperlist" effect3d effect3d-previous-margin="20" mode="number"
+                @click="clickImg"></u-swiper>
+    </view>
+    <view class="item u-margin-top-5">
+      <view class="item-title">
+        {{ room.type == '整租' ? room.houseNum + room.houseHall + room.toiletNum : room.roomType }}
+      </view>
+      <view class="item-price">¥{{ room.price }}/月</view>
+    </view>
+    <view class="item" style="display: flex;align-items: center;flex-wrap: wrap;">
+      <view v-for="(item,index) in tagList" :key="index"
+            style="background-color: #f5f5f5;color: #606266;margin-right: 15rpx;
+			  margin-top: 15rpx;padding: 0 10rpx;height: 60rpx;line-height: 60rpx;">
+        {{ item.title }}
+      </view>
+    </view>
+    <!-- 小程序通讯 -->
+    <button class="clearBtn" open-type="contact" type="default">
+      <u-cell-group>
+        <u-cell-item title="服务费另计" value="在线咨询"></u-cell-item>
+      </u-cell-group>
+    </button>
+    <view v-if="room.introduce">
+      <u-gap bg-color="#f8f8f8" height="10"></u-gap>
+      <u-card :border="false" :head-border-bottom="false" padding="0" title="房源介绍" title-size="38">
+        <view slot="body" class="u-padding-top-45 item">
+          {{ room.introduce }}
+        </view>
+      </u-card>
+    </view>
+    <u-gap bg-color="#f8f8f8" height="1"></u-gap>
+    <view style="position: relative;">
+      <u-card :border="false" :head-border-bottom="false" padding="0" title="小区介绍" title-size="38">
+        <view slot="body" class="u-padding-top-45">
+          <view class="u-flex" style="justify-content: space-between;">
+            <view class="item">
+              <view>建筑年份:{{ village.year }}</view>
+              <view>建筑类型:{{ village.type }}</view>
+              <view>绿化率:{{ village.green }}%</view>
+            </view>
+            <image
+                mode="widthFix"
+                src="https://img11.360buyimg.com/n7/jfs/t1/94448/29/2734/524808/5dd4cc16E990dfb6b/59c256f85a8c3757.jpg"
+                style="width: 250rpx;height: 200rpx;"></image>
+          </view>
+        </view>
+      </u-card>
+    </view>
+    <u-gap bg-color="#f8f8f8" height="1"></u-gap>
+    <view style="position: relative;">
+      <u-card :border="false" :head-border-bottom="false" :title="room.villageName" padding="0" title-size="38">
+        <view slot="body" class="u-padding-top-45">
+          <map :latitude="latitude" :longitude="longitude">
+            <cover-view style='width:100%;height:100%;' @click="clickMap"></cover-view>
+          </map>
+          <view
+              style="margin-top: 30rpx;padding-left: 10rpx;height:80rpx;
+					line-height: 80rpx;background-color: #fdfdfd;border-radius: 6px;
+					display: flex;justify-content: space-between;
+					padding-right: 10rpx;color: #909399;
+					"
+              @click="clickMap">
+            <view>
+              <u-icon color="#909399" name="map" size="30"></u-icon>
+              <text style="margin-left: 8rpx;">
+                房源直线距离约 {{ distance }} km
+              </text>
+            </view>
+            <view>
+              <text style="margin-right: 3rpx;">
+                导航
+              </text>
+              <u-icon color="#909399" name="arrow-right" size="30"></u-icon>
+            </view>
+          </view>
+          <view style="margin-top: 20rpx;margin-left: 10rpx;font-size: 10px;
+							color: #909399">
+            *数据仅供参考,请以实际看房为准
+          </view>
+        </view>
+      </u-card>
+    </view>
+    <u-gap bg-color="#f8f8f8" height="1"></u-gap>
+    <view style="position: relative;">
+      <u-card :border="false" :head-border-bottom="false" padding="0" title="服务介绍" title-size="38">
+        <view slot="body" class="u-padding-top-35">
+          <u-cell-group :border="false">
+            <u-cell-item :arrow="false" :border-bottom="false" hover-class="none" icon="heart"
+                         title="承诺-四大租住承诺,安心有保障"></u-cell-item>
+            <u-cell-item :arrow="false" :border-bottom="false" hover-class="none" icon="level"
+                         title="品质-两类品质保障,入住更无忧"></u-cell-item>
+            <u-cell-item :arrow="false" :border-bottom="false" hover-class="none" icon="star"
+                         title="服务-两项日常服务,生活超便捷"></u-cell-item>
+            <u-cell-item :arrow="false" :border-bottom="false" hover-class="none" icon="rmb"
+                         title="付款-多种付款方式,支付更灵活"></u-cell-item>
+          </u-cell-group>
+        </view>
+      </u-card>
+    </view>
+    <u-gap bg-color="#f8f8f8" height="1"></u-gap>
+    <view style="position: relative;">
+      <u-card :border="false" :head-border-bottom="false" padding="0" title="房源评价" title-size="38">
+        <view slot="body" class="u-padding-top-50 u-padding-bottom-50">
+          <u-cell-group :border="false">
+            {{ evaluate }}
+            <text style="float: right;color: #909399;font-size: 13px;">{{ credt }}</text>
+          </u-cell-group>
+        </view>
+        <view slot="foot" style="padding-top: 30rpx;float: right;">
+          <u-icon name="chat-fill"></u-icon>
+          <text style="text-align: center;font-size: 12px;margin-left: 5rpx;" @click="moreEval">
+            更多评价({{ evalsize }})
+          </text>
+        </view>
+      </u-card>
+    </view>
+    <u-gap bg-color="#f8f8f8" height="10"></u-gap>
+    <view style="position: relative;padding-bottom: 50rpx;">
+      <u-card :border="false" :head-border-bottom="false" padding="0" title="经纪人" title-size="38">
+        <view slot="body" class="u-padding-top-45">
+          <view class="u-flex">
+            <view class="u-m-r-20">
+              <u-avatar :src="room.agentAvatar" size="80"></u-avatar>
+            </view>
+            <view class="u-flex-1">
+              <view class="u-font-16 u-p-b-40">{{ room.agentName }}</view>
+              <!-- <view class="u-font-12 u-p-b-10">{{user.agentPhone}}</view> -->
+            </view>
+          </view>
+          <view class="arrow-right" @click="clickItem">
+            <view class="phone">
+              <u-icon class="u-p-l-10" color="#d1d1d1" name="phone"
+                      size="40"
+              ></u-icon>
+            </view>
+          </view>
+        </view>
+      </u-card>
+      <view class="item">
+        <u-divider>开源字节为您服务</u-divider>
+      </view>
+    </view>
+    <view class="navigation">
+      <view class="left">
+        <button class="clearBtn" open-type="contact" style="font-size: 14px;color: #6a6a6a;"
+                type="default">
+          <view class="item">
+            <u-icon :size="40" name="server-fill"></u-icon>
+            <view class="text">客服</view>
+          </view>
+        </button>
+        <view class="item" @click="heartHouse">
+          <u-icon v-if="!room.heart" :size="40" name="heart"></u-icon>
+          <u-icon v-if="room.heart" :size="40" color="#ff9900" name="heart-fill"></u-icon>
+          <view class="text">收藏</view>
+        </view>
+        <button class="clearBtn" open-type="share" style="font-size: 14px;color: #6a6a6a;"
+                type="default">
+          <view class="item">
+            <u-icon :size="40" name="zhuanfa"></u-icon>
+            <view class="text">分享</view>
+          </view>
+        </button>
+      </view>
+      <view class="right" @click="clickItem">
+        <view class="btn">联系经纪人</view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      room: {
+        villageName: '',
+        houseNum: '',
+        houseHall: '',
+        toiletNum: '',
+        roomType: '',
+        direction: '',
+        price: '',
+        introduce: '',
+        heart: false,
+      },
+      village: {
+        year: '',
+        type: '',
+        green: '',
+      },
+      swiperlist: [],
+      tagList: [],
+      //评价列表
+      evaluList: [],
+      user: {},
+      longitude: 120.14,
+      latitude: 30.35,
+      distance: 0,
+      //自己的评论
+      ownevalu: '',
+      houseId: null,
+      evalsize: 0,
+      havem: false,
+      evaluate: '',
+      credt: ''
+    }
+  },
+  onLoad: function (option) {
+    let houseId = option.houseId //上个页面传递的参数。
+    this.houseId = houseId
+    // 渲染当前房源信息
+    this.findHouseById(houseId);
+
+    // // 在页面中定义激励视频广告
+    // let videoAd = null
+    // // 在页面onLoad回调事件中创建激励视频广告实例
+    // if (wx.createRewardedVideoAd) {
+    //   videoAd = wx.createRewardedVideoAd({
+    // 	adUnitId: 'adunit-8cd5789a01a51891'
+    //   })
+    //   videoAd.onLoad(() => {
+    // 	  console.log('激励视频 成功加载广告')
+    //   })
+    //   videoAd.onError((err) => {})
+    //   videoAd.onClose((res) => {
+    // 	  console.log('激励视频 成功关闭广告')
+    //   })
+    // }
+    // // 用户触发广告后,显示激励视频广告
+    // if (videoAd) {
+    //   videoAd.show().catch(() => {
+    // 	// 失败重试
+    // 	videoAd.load()
+    // 	  .then(() => videoAd.show())
+    // 	  .catch(err => {
+    // 		console.log('激励视频 广告显示失败')
+    // 	  })
+    //   })
+    // }
+  },
+  methods: {
+    heartHouse() {
+      // 判断是否有userId
+      let lifeData = uni.getStorageSync('lifeData');
+      let vuex_user = lifeData.vuex_user
+      if (!vuex_user) {
+        // 没有userId 则跳转到登录
+        return uni.reLaunch({
+          url: '../login/login'
+        })
+      }
+      // 收藏
+      let url = "api/houseApi/saveHeart";
+      this.$u.post(url, {
+        heart: this.room.heart,
+        houseId: this.room.id,
+        userId: vuex_user.user.userId,
+      }).then(result => {
+        this.room.heart = !this.room.heart
+        this.$mytip.toast(result.msg)
+      });
+    },
+    goHome() {
+      uni.reLaunch({
+        url: '../index/index'
+      })
+    },
+    clickItem() {
+      //拨打固定电话
+      uni.makePhoneCall({
+        phoneNumber: this.room.agentPhone,
+      });
+    },
+    findHouseById(houseId) {
+      let url = "api/houseApi/findHouseById";
+      this.$u.get(url, {
+        id: houseId
+      }).then(result => {
+        let room = result.data
+        if (room.type == 0) {
+          room.type = '整租'
+        } else if (room.type == 1) {
+          room.type = '合租'
+        }
+        if (room.roomType == 1) {
+          room.roomType = '主卧'
+        } else if (room.roomType == 2) {
+          room.roomType = '次卧'
+        } else {
+          room.roomType = '未知'
+        }
+
+        if (this.$u.test.isEmpty(room.houseNum)) {
+          room.houseNum = ''
+        }
+        if (this.$u.test.isEmpty(room.houseHall)) {
+          room.houseHall = ''
+        }
+        if (this.$u.test.isEmpty(room.toiletNum)) {
+          room.toiletNum = ''
+        }
+        if (this.$u.test.isEmpty(room.floor)) {
+          room.floor = ''
+        } else {
+          room.floor = room.floor + '层'
+        }
+        this.swiperlist = room.imageList.map(val => {
+          let imgUrl = val.imgUrl
+          if (!imgUrl.includes(config.staticUrl)) {
+            imgUrl = config.staticUrl + val.imgUrl
+          } else {
+            imgUrl = val.imgUrl
+          }
+          return {
+            title: val.imageName,
+            image: imgUrl
+          }
+        })
+        this.tagList = room.featureList.map(val => {
+          return {
+            title: val.feature,
+          }
+        })
+        if (!room.agentAvatar.includes(config.staticUrl)) {
+          room.agentAvatar = config.staticUrl + room.agentAvatar
+        }
+        this.user = room.user
+        this.village = room.village
+        this.room = room
+        // 判断是否收藏
+        this.selectHouseHeart(houseId);
+        //查询房源评价
+        this.selectHouseEvals(houseId);
+
+        // 分享自定义标题与图片
+        let shareTitle = ''
+        if (room.type == '整租') {
+          shareTitle = this.village.name + " " + this.room.houseNum + this.room.houseHall + this.room.toiletNum + " " + this.room.decoration + " ¥" + this.room.price + "/月"
+        } else {
+          shareTitle = this.village.name + " " + room.roomType + " " + this.room.decoration + " ¥" + this.room.price + "/月"
+        }
+        this.$u.mpShare = {
+          title: shareTitle, // 默认为小程序名称,可自定义
+          // 支持PNG及JPG,默认为当前页面的截图
+          imageUrl: this.room.faceUrl,
+        }
+
+        // 添加到浏览历史
+        let houseHistory = uni.getStorageSync('houseHistory')
+        if (!houseHistory) {
+          houseHistory = []
+        }
+        // 如果超过20个了,则删除最后一个
+        if (houseHistory.length >= 20) {
+          houseHistory.pop()
+        }
+        houseHistory.push(this.room)
+        // 数据去重
+        const keyArr = [];
+        houseHistory.forEach((element, index) => {
+          keyArr.push(element.code);  // 通过code来判断
+        });
+        const newArr = [];
+        const newKey = new Set(keyArr);  // key去重
+        newKey.forEach(item => {
+          const index = keyArr.findIndex(item2 => item2 === item);
+          newArr.push(houseHistory[index]);
+        })
+        uni.setStorageSync('houseHistory', newArr)
+
+        // 经纬度
+        this.longitude = room.longitude
+        this.latitude = room.latitude
+        // 计算距离
+        let lat1 = 39.909
+        let lng1 = 116.39742
+        let lat2 = this.latitude
+        let lng2 = this.longitude
+        uni.getLocation({
+          type: 'gcj02',
+          success: res => {
+            lat1 = res.latitude
+            lng1 = res.longitude
+            this.distance = this.getDistance(lat1, lng1, lat2, lng2);
+          }
+        })
+      });
+    },
+    selectHouseHeart(houseId) {
+      // 判断是否有userId
+      let lifeData = uni.getStorageSync('lifeData');
+      let vuex_user = lifeData.vuex_user
+      if (vuex_user) {
+        let url = "api/houseApi/selectHouseHeart";
+        this.$u.get(url, {
+          houseId: houseId,
+          userId: vuex_user.user.userId,
+        }).then(result => {
+          this.room.heart = result.data
+        });
+      }
+    },
+    selectHouseEvals(houseId) {
+      let url = "api/houseApi/selectHouseEvals";
+      this.$u.get(url, {
+        houseId: houseId,
+        pageNum: 1,
+        pageSize: 1
+      }).then(result => {
+        if (result.total > 0) {
+          this.evaluate = result.rows[0].evaluate;
+          if (this.evaluate.length > 30) {
+            this.evaluate = this.evaluate.substring(0, 30) + "......";
+          }
+          this.credt = result.rows[0].createTime;
+          this.havem = true;
+          this.evalsize = result.total;
+        }
+      });
+    },
+    moreEval() {
+      this.$u.route({
+        url: '/pages/detail/evalList',
+        params: {
+          houseId: this.houseId
+        }
+      })
+    },
+    clickImg(index) {
+      let imgArr = this.swiperlist.map(val => {
+        return val.image
+      })
+      console.log(imgArr);
+      // 预览图片
+      uni.previewImage({
+        current: index,
+        urls: imgArr
+      });
+    },
+    clickMap(e) {
+      uni.openLocation({
+        longitude: Number(this.longitude),
+        latitude: Number(this.latitude),
+        name: this.room.villageName,
+        address: this.room.address
+      })
+    },
+    getDistance(lat1, lng1, lat2, lng2) {
+      lat1 = lat1 || 0;
+      lng1 = lng1 || 0;
+      lat2 = lat2 || 0;
+      lng2 = lng2 || 0;
+      var rad1 = lat1 * Math.PI / 180.0;
+      var rad2 = lat2 * Math.PI / 180.0;
+      var a = rad1 - rad2;
+      var b = lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0;
+      var r = 6378137;
+      var distance = r * 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(rad1) * Math.cos(rad2) * Math.pow(Math.sin(b / 2), 2)));
+      return (distance / 1000).toFixed(2);
+    }
+  }
+}
+</script>
+
+<style>
+/* page不能写带scope的style标签中,否则无效 */
+page {
+  background-color: rgb(255, 255, 255);
+}
+</style>
+
+
+<style lang="scss" scoped>
+map {
+  width: 100%;
+  height: 350 rpx;
+}
+
+.item {
+  padding: 25 rpx;
+  line-height: 80 rpx;
+  margin-top: -30rpx;
+}
+
+.item-title {
+  font-size: 42 rpx;
+  color: $u-main-color;
+  font-weight: bold;
+}
+
+.item-price {
+  font-weight: normal;
+  font-size: 45 rpx;
+  color: $u-type-warning;
+}
+
+.item-desc {
+  font-weight: normal;
+  font-size: 36 rpx;
+  color: $u-tips-color;
+}
+
+.arrow-right {
+  position: absolute;
+  top: 80 rpx;
+  right: 28 rpx;
+  font-weight: normal;
+  font-size: 28 rpx;
+  color: $u-tips-color;
+
+  .phone {
+    width: 90 rpx;
+    height: 90 rpx;
+    border-radius: 100%;
+    box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1);
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+}
+
+.wayClass {
+  color: #606266;
+  padding: 30 rpx;
+  line-height: 50 rpx;
+}
+
+.clearBtn {
+  margin: 0;
+  padding: 0;
+  line-height: 1;
+  background-color: #FFFFFF;
+}
+
+.clearBtn::after {
+  position: unset !important;
+  border: unset;
+}
+
+.navigation {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: fixed;
+  left: 0;
+  right: 0;
+  bottom: 0;
+  padding: 0 rpx 15 rpx;
+  background-color: #ffffff;
+  box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.05);
+  z-index: 9999;
+
+  .left {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    margin-top: 38 rpx;
+    font-size: 14px;
+    color: #6a6a6a;
+
+    .item {
+      display: flex;
+
+      .text {
+        margin-left: 4 rpx;
+      }
+    }
+  }
+
+  .right {
+    display: flex;
+    font-size: 28 rpx;
+    align-items: center;
+
+    .btn {
+      line-height: 66 rpx;
+      margin-left: 30 rpx;
+      padding: 5 rpx 50 rpx;
+      color: #ffffff;
+      border-radius: 36 rpx;
+      background-color: #2979ff;
+    }
+  }
+}
+</style>

+ 136 - 0
AyaoJies-app/house-master/house-life/pages/detail/evalList.vue

@@ -0,0 +1,136 @@
+<template>
+  <view>
+    <view class="text">
+      <text style="font-size: 15px;margin-left: 20rpx;">全部评价({{ total }})
+        <text style="float: right;margin-right: 20rpx;font-weight: bold;" @click="inputDialogToggle">添加评价</text>
+      </text>
+    </view>
+    <view v-for="(item,index) in listData" :key="index" class="text" style="padding: 0 20rpx;margin-top: 6rpx;">
+      <view>
+        <text>{{ item.evaluate }}</text>
+      </view>
+      <view style="text-align: right;color: #909399;font-size: 13px;">
+        <text>{{ item.createTime }}</text>
+      </view>
+    </view>
+    <view>
+      <!-- 输入框示例 -->
+      <uni-popup ref="inputDialog" type="dialog">
+        <uni-popup-dialog ref="inputClose" mode="input" title="评价房源" value=""
+                          @confirm="submitEval">
+          <textarea v-model="ownevalu" placeholder="请输入评价"></textarea>
+        </uni-popup-dialog>
+      </uni-popup>
+      </uni-popup>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      houseId: null,
+      listData: [],
+      pageNum: 1,
+      pageSize: 20,
+      scrollTop: 0,
+      reload: false,
+      loadStatus: 'loadmore',
+      status: 'more',
+      total: 0,
+      ownevalu: '',
+      userId: null
+    };
+  },
+  onLoad(option) {
+    this.houseId = option.houseId; //上个页面传递的参数。
+    this.getList();
+  },
+  onPageScroll(e) {
+    this.scrollTop = e.scrollTop;
+  },
+  onReachBottom() {
+    this.loadStatus = 'loading';
+    // 获取数据
+    this.getList()
+  },
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.pageNum = 1
+    this.$refs.uWaterfall.clear();
+    // 获取数据
+    this.getList();
+    // 关闭刷新
+    uni.stopPullDownRefresh();
+  },
+  methods: {
+    getList() {
+      let url = "/api/houseApi/selectHouseEvals";
+      let defaultData = {
+        houseId: this.houseId,
+        pageNum: this.pageNum,
+        pageSize: this.pageSize
+      }
+      this.$u.get(url, {...defaultData}).then(result => {
+        console.log(result);
+        const data = result.rows;
+        this.total = result.total;
+        if (this.pageNum > 0 && data.length < this.pageSize) {
+          this.loadStatus = 'nomore';
+        } else {
+          ++this.pageNum
+          this.loadStatus = 'loadmore';
+        }
+        this.listData = data;
+      });
+    },
+    inputDialogToggle() {
+      // 判断是否有userId
+      let lifeData = uni.getStorageSync('lifeData');
+      let vuex_user = lifeData.vuex_user
+      if (!vuex_user) {
+        // 没有userId 则跳转到登录
+        return uni.reLaunch({
+          url: '../login/login'
+        })
+      }
+      this.userId = vuex_user.userId;
+      this.$refs.inputDialog.open();
+      //判断是否有评价权限
+      // let url = "api/houseApi/checkAuthEvals";
+      // this.$u.get(url, {
+      // 	houseId: this.houseId,
+      // 	userId:this.userId
+
+      // }).then(result => {
+      // 	if(result.code === 200 && result.data.length>0){
+      // 		this.$refs.inputDialog.open();
+      // 	}else{
+      // 		this.$mytip.toast("只有租客才能进行评论!");
+      // 	}
+      // });
+    },
+    submitEval() {
+      let url = "api/houseApi/saveHouseEvals";
+      this.$u.get(url, {
+        houseId: this.houseId,
+        evalu: this.ownevalu,
+        userId: this.userId
+
+      }).then(result => {
+        this.$mytip.toast('评价成功')
+        this.$refs.inputDialog.close()
+        this.getList();
+      });
+    }
+  }
+};
+</script>
+
+<style>
+.text {
+  background-color: #fff;
+  line-height: 80 rpx;
+}
+</style>

+ 326 - 0
AyaoJies-app/house-master/house-life/pages/detail/preHouse.vue

@@ -0,0 +1,326 @@
+<template>
+  <view class="">
+    <!-- #ifndef MP-WEIXIN -->
+    <u-image :src="src" height="350rpx" width="100%"></u-image>
+    <!-- #endif -->
+    <view class="wrap">
+      <u-form ref="uForm" :errorType="errorType" :model="model" :rules="rules">
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="小区名称" label-width="180"
+                     left-icon="map" prop="villageName">
+          <u-input v-model="model.villageName" :border="border" :select-open="selectShow" placeholder="请选择小区(必选)"
+                   type="select" @click="selectShow = true"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" :rightIconStyle="{color:'#d5d5d5'}" label="详细地址"
+                     label-width="180" left-icon="file-text" prop="address"
+                     right-icon="map">
+          <u-input v-model="model.address" :border="border" disabled placeholder="请在地图选择详细地址" type="text"
+                   @click="chooseAddress"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="房牌号" label-width="180"
+                     left-icon="home" prop="houseNo">
+          <u-input v-model="model.houseNo" :border="border" placeholder="请输入门牌号(必填)" type="text"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="装修" label-width="180" left-icon="eye"
+                     prop="decoration">
+          <u-input v-model="model.decoration" :border="border" :select-open="decorationShow" placeholder="请选择装修(必选)"
+                   type="select" @click="decorationShow = true"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="房东姓名" label-width="180"
+                     left-icon="account" prop="ownerName">
+          <u-input v-model="model.ownerName" :border="border" placeholder="请输入房东姓名(必填)" type="text"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="房东电话" label-width="180"
+                     left-icon="phone" prop="owerPhone">
+          <u-input v-model="model.owerPhone" :border="border" maxlength="11" placeholder="请输入房东电话(必填)"
+                   type="number"></u-input>
+        </u-form-item>
+        <u-form-item :label-position="labelPosition" :leftIconStyle="{color:'#d5d5d5'}" label="付款方式" label-width="180"
+                     left-icon="rmb-circle" prop="payType">
+          <u-input v-model="model.payType" :border="border" :select-open="actionSheetShow" placeholder="请选择付款方式(必选)"
+                   type="select" @click="actionSheetShow = true"></u-input>
+        </u-form-item>
+      </u-form>
+      <!-- 流量主-腾讯视频广告 -->
+      <ad ad-theme="white" ad-type="video" unit-id="adunit-c6cdd74f48eed506"></ad>
+      <u-select v-model="selectShow" :list="selectList" mode="single-column" @confirm="selectConfirm"></u-select>
+      <u-select v-model="decorationShow" :list="decorationList" mode="single-column"
+                @confirm="decorationConfirm"></u-select>
+      <u-action-sheet v-model="actionSheetShow" :list="actionSheetList" @click="actionSheetCallback"></u-action-sheet>
+    </view>
+    <view class="bottom-btn">
+      <u-button type="primary" @click="submit">下一步</u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    let that = this;
+    return {
+      src: 'http://img.sccnn.com/bimg/340/02027.jpg',
+      actionSheetShow: false,
+      model: {
+        type: 0,
+        houseType: '',
+        roomLabel: '',
+        villageName: '',
+        villageId: '',
+        address: '',
+        houseNo: '',
+        //装修
+        decoration: '',
+        //房东
+        ownerName: '',
+        //房东电话
+        owerPhone: '',
+        payType: '',
+        createName: uni.getStorageSync('lifeData').vuex_user.userName,
+        publishId: uni.getStorageSync('lifeData').vuex_user.userId,
+        state: 0,
+        longitude: 0,
+        latitude: 0,
+      },
+      selectList: [],
+      decorationList: [
+        {
+          label: '简装',
+          value: '简装'
+        },
+        {
+          label: '中装',
+          value: '中装'
+        },
+        {
+          label: '精装修',
+          value: '精装修'
+        },
+        {
+          label: '豪装',
+          value: '豪装'
+        }
+      ],
+      actionSheetList: [
+        {
+          text: '月付'
+        },
+        {
+          text: '季付'
+        },
+        {
+          text: '半年付'
+        },
+        {
+          text: '年付'
+        }
+      ],
+      rules: {
+        villageName: [
+          {
+            required: true,
+            message: '请选择小区',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        address: [
+          {
+            required: true,
+            message: '请输入详细地址',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        houseNo: [
+          {
+            required: true,
+            message: '请输入门牌号',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        decoration: [
+          {
+            required: true,
+            message: '请选择装修',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        ownerName: [
+          {
+            required: true,
+            message: '请输入房东姓名',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        owerPhone: [
+          {
+            required: true,
+            message: '请输入房东电话',
+            trigger: ['change', 'blur'],
+          }
+        ],
+        payType: [
+          {
+            required: true,
+            message: '请选择付款方式',
+            trigger: ['change', 'blur'],
+          }
+        ],
+      },
+      border: false,
+      check: false,
+      selectShow: false,
+      decorationShow: false,
+      labelPosition: 'left',
+      errorType: ['toast'],
+    };
+  },
+  onLoad(option) {
+    let houseId = option.houseId //上个页面传递的参数。
+    if (houseId) {
+      // 渲染当前房源信息
+      this.findHouseById(houseId);
+    }
+    this.findVillageList()
+
+    // 定位经纬度
+    uni.getLocation({
+      type: 'gcj02',
+      // 当指定 high 时,期望精度值为100m,当指定 best 时期望精度值为20m
+      accuracy: 'best',
+      // 开启高精度定位
+      isHighAccuracy: true,
+      success: (res) => {
+        this.longitude = res.longitude
+        this.latitude = res.latitude
+      }
+    });
+    uni.$on('changeAddressConfig', (address, lon, lat) => {
+      // 获取数据
+      this.changeAddressConfig(address, lon, lat);
+    })
+  },
+  onUnload() {
+    // 移除监听事件
+    uni.$off('changeAddressConfig');
+  },
+  onReady() {
+    this.$refs.uForm.setRules(this.rules);
+  },
+  methods: {
+    changeAddressConfig(address, lon, lat) {
+      this.model.address = address
+      this.model.longitude = lon
+      this.model.latitude = lat
+    },
+    submit() {
+      this.$refs.uForm.validate(valid => {
+        if (valid) {
+          if (!this.$u.test.mobile(this.model.owerPhone)) {
+            return this.$mytip.toast('房东电话请输入手机号码')
+          }
+          return this.$u.route({
+            url: '/pages/detail/addHouse',
+            params: {
+              room: JSON.stringify(this.model)
+            }
+          })
+        } else {
+          console.log('验证失败');
+        }
+      });
+    },
+    selectConfirm(e) {
+      e.map((val, index) => {
+        this.model.villageName = val.label;
+        this.model.villageId = val.value
+      })
+    },
+    decorationConfirm(e) {
+      e.map((val, index) => {
+        this.model.decoration = val.label;
+      })
+    },
+    labelPositionChange(index) {
+      this.labelPosition = index == 0 ? 'left' : 'top';
+    },
+    // 点击actionSheet回调
+    actionSheetCallback(index) {
+      uni.hideKeyboard();
+      this.model.payType = this.actionSheetList[index].text;
+    },
+    findVillageList() {
+      let url = "/api/houseApi/findVillageList";
+      this.$u.get(url, {
+        city: uni.getStorageSync('lifeData').vuex_city,
+        orderByColumn: 'name',
+        isAsc: 'desc'
+      }).then(result => {
+        const data = result.rows
+        for (let i = 0; i < data.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = data[i]
+          this.selectList.push({
+            label: item.name,
+            value: item.id
+          })
+        }
+        return data
+      });
+    },
+    findHouseById(houseId) {
+      let url = "api/houseApi/findHouseById";
+      this.$u.get(url, {
+        id: houseId
+      }).then(result => {
+        let room = result.data
+        this.model = room
+        let houseType = this.model.houseNum + this.model.houseHall + this.model.toiletNum
+        if (houseType == 0) {
+          houseType = ''
+        }
+        this.model.houseType = houseType
+        if (this.model.roomType == 1) {
+          this.model.roomLabel = '主卧'
+        } else if (this.model.roomType == 2) {
+          this.model.roomLabel = '次卧'
+        }
+      });
+    },
+    chooseAddress() {
+      this.$u.route({
+        url: '/pages/chooseAddress/index'
+      })
+    },
+  }
+};
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+.wrap {
+  padding: 30 rpx;
+}
+
+/* #ifdef MP-WEIXIN */
+.bottom-btn {
+  position: fixed;
+  bottom: 8 rpx;
+  width: 100%;
+  padding: 30 rpx;
+  border-top: 1 rpx solid #eee;
+  background-color: #FFFFFF;
+}
+
+/* #endif */
+
+/* #ifndef MP-WEIXIN */
+.bottom-btn {
+  padding: 0 30 rpx 30 rpx 30 rpx;
+  background-color: #FFFFFF;
+}
+
+/* #endif */
+</style>

+ 434 - 0
AyaoJies-app/house-master/house-life/pages/index/index.vue

@@ -0,0 +1,434 @@
+<template>
+  <view class="u-p-l-10 u-p-r-10">
+    <u-navbar :is-back="false">
+      <view style="display: flex;justify-content: center;align-items: center;">
+        <view class="u-p-20" @click="location">
+          {{ vuex_city == '' ? '选择' : vuex_city }}
+          <u-icon class="u-p-l-10" color="#515356" name="arrow-down-fill"></u-icon>
+        </view>
+        <!-- #ifdef MP-WEIXIN -->
+        <u-search v-model="keyword" :clearabled="true" :disabled="true" :show-action="false"
+                  input-align="center"
+                  placeholder="你想住在哪儿" style="width: 380rpx;" @click="search"></u-search>
+        <!-- #endif -->
+        <!-- #ifndef MP-WEIXIN -->
+        <u-search v-model="keyword" :clearabled="true" :disabled="true" :show-action="false"
+                  input-align="center"
+                  placeholder="你想住在哪儿" style="width: 580rpx;" @click="search"></u-search>
+        <!-- #endif -->
+      </view>
+    </u-navbar>
+    <view>
+      <!-- 流量主-腾讯banner广告 -->
+      <!-- <ad unit-id="adunit-fcfdcc4d7095b6b1" ad-intervals="30"></ad> -->
+      <!-- 轮播图 -->
+      <!-- #ifndef MP-WEIXIN -->
+      <!-- <u-swiper :list="swiperList" height="350"></u-swiper> -->
+      <!-- #endif -->
+      <u-swiper :list="swiperList" height="350" @click="moreInfo"></u-swiper>
+    </view>
+    <view>
+      <view class="rowClass">
+        <u-row>
+          <u-col v-for="(item,index) in navList" :key="index" span="3" text-align="center">
+            <view class="u-padding-20" hover-class="hoverClass" @tap="clickNav(item)">
+              <image :src="item.src" mode="widthFix" style="width: 90rpx;height: 90rpx;"></image>
+              <view class="tabName">{{ item.name }}</view>
+            </view>
+          </u-col>
+        </u-row>
+      </view>
+      <u-gap height="10"></u-gap>
+      <view @click="notice">
+        <u-notice-bar :duration="5000" :list="noticeList" bg-color="#fff" border-radius="15"
+                      mode="vertical" more-icon type="primary"></u-notice-bar>
+      </view>
+      <u-gap height="5"></u-gap>
+      <u-waterfall ref="uWaterfall" v-model="flowList">
+        <template v-slot:left="{leftList}">
+          <view v-for="(item, index) in leftList" :key="index" class="demo-warter">
+            <u-lazy-load :image="item.image" :index="index" border-radius="12" threshold="750"
+                         @click="clickImage(item.id)"></u-lazy-load>
+            <view class="item-title">{{ item.villageName }}
+              {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+            </view>
+            <view class="item-price">¥{{ item.price }}</view>
+            <view class="item-desc">{{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ |
+              {{ item.decoration }}
+            </view>
+          </view>
+        </template>
+        <template v-slot:right="{rightList}">
+          <view v-for="(item, index) in rightList" :key="index" class="demo-warter">
+            <u-lazy-load :image="item.image" :index="index" border-radius="10" threshold="750"
+                         @click="clickImage(item.id)"></u-lazy-load>
+            <view class="item-title">{{ item.villageName }}
+              {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+            </view>
+            <view class="item-price">¥{{ item.price }}</view>
+            <view class="item-desc">{{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ |
+              {{ item.decoration }}
+            </view>
+          </view>
+        </template>
+      </u-waterfall>
+    </view>
+    <u-loadmore :status="loadStatus" bg-color="rgb(240, 240, 240)" style="height: 80rpx;line-height: 80rpx;"
+                @loadmore="findHouseList"></u-loadmore>
+    <u-back-top :scroll-top="scrollTop" top="1000"></u-back-top>
+    <u-no-network></u-no-network>
+    <view class="buttom">
+      <view class="loginType">
+        <view class="wechat item">
+          <view class="icon">
+            <u-icon color="#999" name="server-man" size="60" @click="server"></u-icon>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      keyword: '',
+      pageNum: 1,
+      pageSize: 20,
+      scrollTop: 0,
+      houseList: [],
+      swiperList: [
+        {
+          image: '/static/img/index/swiper/swiper2.png',
+          title: '身无彩凤双飞翼,心有灵犀一点通'
+        },
+        {
+          image: '/static/img/index/swiper/swiper.jpg',
+          title: '身无彩凤双飞翼,心有灵犀一点通'
+        },
+      ],
+      noticeList: [],
+      navList: [
+        {name: "整租", src: "/static/img/index/cover_2022/index_cover1.png", type: "0"},
+        {name: "合租", src: "/static/img/index/cover_2022/index_cover2.png", type: "1"},
+        {name: "避坑指南", src: "/static/img/index/cover_2022/index_cover3.png", url: "/pages/center/tips"},
+        {name: "委托房源", src: "/static/img/index/cover_2022/index_cover4.png", type: "2"}
+      ],
+      loadStatus: 'loadmore',
+      flowList: [],
+      uvCode: uni.getStorageSync('uvCode')
+    }
+  },
+  onLoad() {
+    // 检查是否已选择城市,如果未选择,跳转到选择城市页面
+    this.checkCity();
+    // 获取数据
+    this.findHouseList();
+    this.getNoticecList();
+    // 流量统计
+    this.appSysFlowInfo();
+    uni.$on('findIndexHouseList', (obj) => {
+      // 获取数据
+      this.findHouseList(1);
+    })
+  },
+  onUnload() {
+    // 移除监听事件
+    uni.$off('findIndexHouseList');
+  },
+  onPageScroll(e) {
+    this.scrollTop = e.scrollTop;
+  },
+  onReachBottom() {
+    this.loadStatus = 'loading';
+    // 获取数据
+    this.findHouseList()
+  },
+  // 下拉刷新
+  onPullDownRefresh() {
+    // 获取数据
+    this.findHouseList(1);
+    // 关闭刷新
+    uni.stopPullDownRefresh();
+  },
+  methods: {
+    checkCity() {
+      // 检查是否已选择城市,如果未选择,跳转到选择城市页面
+      let lifeData = uni.getStorageSync('lifeData');
+      let vuex_city = lifeData.vuex_city
+      // console.log(vuex_city.length);
+      if (!vuex_city || vuex_city.length == 0) {
+        // 没有token 则跳转到登录
+        return this.$u.route('/pages/location/location');
+      }
+    },
+    location() {
+      this.$u.route({
+        url: 'pages/location/location',
+      })
+    },
+    search() {
+      this.$u.route({
+        url: 'pages/search/search',
+      })
+    },
+    notice() {
+      this.$u.route({
+        url: 'pages/notice/notice'
+      })
+    },
+    findHouseList(type = 0) {
+      if (type == 1) {
+        this.pageNum = 1
+        this.flowList = []
+        this.$refs.uWaterfall.clear();
+      }
+      let url = "/api/houseApi/findHouseRoomList";
+      this.$u.get(url, {
+        state: 1,
+        villageCity: uni.getStorageSync('lifeData').vuex_city,
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        orderByColumn: 'update_time,create_time',
+        isAsc: 'desc'
+      }).then(result => {
+        const data = result.rows;
+        if (this.pageNum > 1 && data.length < this.pageSize) {
+          return this.loadStatus = 'nomore';
+        }
+        this.houseList = data;
+        for (let i = 0; i < this.houseList.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = this.houseList[i]
+          if (!item.faceUrl.includes(config.staticUrl)) {
+            item.image = config.staticUrl + item.faceUrl
+          } else {
+            item.image = item.faceUrl
+          }
+          if (item.type == 0) {
+            item.type = '整租'
+          } else if (item.type == 1) {
+            item.type = '合租'
+          }
+          if (item.roomType == 1) {
+            item.roomType = '主卧'
+          } else if (item.roomType == 2) {
+            item.roomType = '次卧'
+          } else {
+            item.roomType = '未知'
+          }
+          if (this.$u.test.isEmpty(item.houseNum)) {
+            item.houseNum = ''
+          }
+          if (this.$u.test.isEmpty(item.houseHall)) {
+            item.houseHall = ''
+          }
+          if (this.$u.test.isEmpty(item.toiletNum)) {
+            item.toiletNum = ''
+          }
+          this.flowList.push(item);
+        }
+        ++this.pageNum
+        this.loadStatus = 'loadmore';
+      });
+    },
+    clickSearch() {
+      this.$u.route('/pages/search/search');
+    },
+    clickImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/detail',
+        params: {
+          houseId: houseId
+        }
+      })
+    },
+    clickNav(item) {
+      if (item.url) {
+        return this.$u.route(item.url);
+      }
+      if (item.type === "2") {
+        // 判断是否有token
+        let lifeData = uni.getStorageSync('lifeData');
+        let token = lifeData.vuex_token
+        if (!token) {
+          // 没有token 则跳转到登录
+          return uni.reLaunch({
+            url: '../login/login'
+          })
+        } else {
+          // 判断Token是否有效
+          let url = "/api/profile/isExpiration";
+          return this.$u.get(url, {
+            token: token
+          }).then(obj => {
+            if (obj.data) {
+              // 没有token过期则跳转到登录
+              return uni.reLaunch({
+                url: '../login/login'
+              })
+            } else {
+              return this.$u.route('/pages/detail/preHouse');
+            }
+          });
+        }
+      } else if (item.type) {
+        // return this.$u.route('/pages/search/searchList');
+        return this.$u.route({
+          url: '/pages/search/searchList',
+          params: {
+            type: item.type
+          }
+        })
+      }
+    },
+    code() {
+      this.$mytip.toast('请咨询作者')
+    },
+    appSysFlowInfo() {
+      // 流量统计
+      let uvCode = uni.getStorageSync("uvCode");
+      let url = "https://sourcebyte.cn/api/flow/upFlow?type=MINI&uvCode=" + uvCode;
+      uni.request({
+        url: url,
+        method: "POST",
+        success: (res) => {
+          uni.setStorageSync("uvCode", res.data.data);
+        },
+      });
+    },
+    server() {
+      // window.open ('https://sourcebyte.cn')
+      uni.makePhoneCall({
+        phoneNumber: "18720989281",
+      });
+    },
+    getNoticecList() {
+      let url = "/api/notice/findNoticeList";
+      this.$u.get(url, {
+        pageNum: 1,
+        pageSize: 50,
+        orderByColumn: 'create_time',
+        isAsc: 'desc'
+      }).then(obj => {
+        let data = obj.rows
+        data.filter(item => {
+          this.noticeList.push(item.noticeTitle)
+        })
+      });
+    },
+    moreInfo() {
+      uni.navigateToMiniProgram({
+        appId: 'wxbca64173e772915e',// 此为开源字节appid
+        path: '/pages/index/index',// 此为开源字节首页路径
+        envVersion: "release",
+        success: res => {
+          // 打开成功
+          console.log("打开成功", res);
+        },
+        fail: err => {
+          console.log(err);
+        }
+      })
+    },
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.nomore {
+  background-color: $u-bg-color;
+}
+
+.search {
+  width: 54px;
+  height: 44px;
+
+  &:active {
+    background-color: $u-bg-color;
+  }
+}
+
+.rowClass {
+  border-radius: 8px;
+  background-color: rgb(255, 255, 255);
+  margin-top: 10 rpx;
+}
+
+.hoverClass {
+  background-color: #E4E7ED;
+}
+
+.tabName {
+  font-size: 28 rpx;
+  color: $u-main-color;
+}
+
+.demo-warter {
+  border-radius: 8px;
+  margin-top: 3px;
+  background-color: #ffffff;
+  padding: 3px;
+  position: relative;
+}
+
+.u-close {
+  position: absolute;
+  top: 20 rpx;
+  right: 20 rpx;
+}
+
+.item-cover {
+  font-size: 55 rpx;
+  color: $u-type-warning;
+}
+
+.item-title {
+  font-size: 28 rpx;
+  color: $u-main-color;
+  font-weight: bold;
+  padding-top: 5 rpx;
+  padding-left: 10 rpx;
+}
+
+.item-price {
+  font-weight: normal;
+  font-size: 32 rpx;
+  color: $u-type-warning;
+}
+
+.item-desc {
+  font-weight: normal;
+  font-size: 26 rpx;
+  color: $u-tips-color;
+  padding-bottom: 5 rpx;
+  padding-left: 10 rpx;
+}
+
+.item-tag {
+  font-size: 24 rpx;
+  color: $u-tips-color;
+  margin-top: 3px;
+}
+
+.buttom {
+  .loginType {
+    font-size: 14px;
+    position: fixed;
+    right: 30 rpx;
+    bottom: 300 rpx;
+    width: 60px;
+    height: 60px;
+    padding: 4px;
+    cursor: pointer;
+    background: #FFF;
+    text-align: center;
+    line-height: 60px;
+    border-radius: 100%;
+    -webkit-box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+    box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+  }
+}
+</style>

+ 198 - 0
AyaoJies-app/house-master/house-life/pages/location/location.vue

@@ -0,0 +1,198 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="false" title="选择城市"></u-navbar>
+    <view class="selected">
+      <view class="title">
+        已选 :
+        <text style="color: #2979ff;margin-left: 12rpx;">
+          {{ vuex_city == '' ? '请选择城市' : vuex_city }}
+        </text>
+      </view>
+    </view>
+    <view class="location" @click="setLocation">
+      <view class="title">当前定位</view>
+      <view class="body">
+        <view class="left">
+          <image class="img" mode="widthFix" src="../../static/navigate.png"></image>
+          {{ locationCity }}
+        </view>
+        <view class="right">切换城市</view>
+      </view>
+    </view>
+    <view class="hot">
+      <view class="title">热门城市</view>
+      <view class="body">
+        <view v-for="(item,index) in hotList" :key="index" class="tag" @click="clickCity(item)">{{ item }}</view>
+      </view>
+    </view>
+  </view>
+</template>
+<script>
+// import wxGetAddress from '@/common/utils/wxGetAddress.js'
+export default {
+  data() {
+    return {
+      locationCity: '',
+      hotList: ['杭州市', '郑州市', '北京市', '上海市', '广州市', '深圳市']
+    }
+  },
+  onLoad() {
+    this.findLocation()
+  },
+  methods: {
+    clickCity(item) {
+      this.$u.vuex('vuex_city', item);
+      return uni.reLaunch({
+        url: '../index/index'
+      })
+    },
+    setLocation() {
+      this.$u.vuex('vuex_city', this.locationCity);
+      return uni.reLaunch({
+        url: '../index/index'
+      })
+    },
+    findLocation() {
+      let that = this
+      uni.showLoading({title: "定位中....", mask: true})
+      this.$u.get("/api/profile/getRealCity").then(obj => {
+        let cityName = obj.msg
+        if (cityName) {
+          this.locationCity = cityName
+          let lifeData = uni.getStorageSync('lifeData');
+          let vuex_city = lifeData.vuex_city
+          if (!vuex_city) {
+            this.$u.vuex('vuex_city', cityName);
+          }
+          uni.hideLoading();
+        } else {
+          uni.request({
+            // url:'https://pv.sohu.com/cityjson?ie=utf-8',
+            url: 'https://tianqiapi.com/ip?version=v9&appid=23035354&appsecret=8YvlPNrz',
+            success(resp) {
+              let ip = resp.data.ip
+              that.$u.get("/api/profile/getRealCityByIP?ip=" + ip).then(obj => {
+                let cityName = obj.msg
+                if (cityName) {
+                  that.locationCity = cityName
+                  let lifeData = uni.getStorageSync('lifeData');
+                  let vuex_city = lifeData.vuex_city
+                  if (!vuex_city) {
+                    that.$u.vuex('vuex_city', cityName);
+                  }
+                  uni.hideLoading();
+                } else {
+                  that.$mytip.toast('定位失败')
+                }
+                uni.hideLoading();
+              });
+            }
+          })
+        }
+      });
+    }
+    // 微信小程序定位审核太严厉,不使用了。扩展后端接口,使用ip定位
+    // findLocation(){
+    // 	uni.showLoading({title:"定位中....",mask:true})
+    // 	uni.getLocation({
+    // 		type: 'gcj02',
+    // 		success: async res => {
+    // 			let { longitude, latitude } = res;
+    // 			let result = await wxGetAddress({ longitude, latitude });
+    // 			let province = result.regeocodeData.addressComponent.province
+    // 			let cityName = result.regeocodeData.addressComponent.city
+    // 			this.locationCity = cityName
+    // 			let lifeData = uni.getStorageSync('lifeData');
+    // 			let vuex_city = lifeData.vuex_city
+    // 			if(!vuex_city){
+    // 				this.$u.vuex('vuex_city', cityName);
+    // 			}
+    // 			uni.hideLoading();
+    // 		}
+    // 	});
+    // }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.selected {
+  .title {
+    font-size: 30 rpx;
+    color: $u-main-color;
+    margin: 30 rpx 20 rpx;
+    font-weight: 600;
+    margin-left: 30 rpx;
+  }
+}
+
+.location {
+  background: #FFFFFF;
+  border-radius: 18 rpx;
+  padding: 3 rpx 0;
+  margin: 20 rpx;
+
+  .title {
+    font-size: 22 rpx;
+    color: $u-tips-color;
+    margin: 30 rpx 20 rpx;
+  }
+
+  .body {
+    margin: 30 rpx 20 rpx;
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      font-size: 32 rpx;
+      font-weight: 800;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+
+      .img {
+        width: 35 rpx;
+        margin-right: 12 rpx;
+      }
+    }
+
+    .right {
+      color: #2979ff;
+      font-weight: 600;
+      margin-right: 10 rpx;
+    }
+  ;
+  }
+}
+
+.hot {
+  .title {
+    font-size: 30 rpx;
+    color: $u-main-color;
+    margin: 30 rpx 20 rpx;
+    font-weight: 600;
+    margin-left: 30 rpx;
+  }
+
+  .body {
+    background: #FFFFFF;
+    padding-bottom: 15 rpx;
+    border-radius: 18 rpx;
+    margin: 20 rpx;
+
+    .tag {
+      display: inline-block;
+      width: 137 rpx;
+      height: 75 rpx;
+      line-height: 75 rpx;
+      font-size: 26 rpx;
+      color: $u-content-color;
+      margin: 20 rpx 20 rpx 5 rpx 20 rpx;
+      padding: 5 rpx 10 rpx;
+      text-align: center;
+      background-color: $u-bg-color;
+      border-radius: 12 rpx;
+    }
+  }
+}
+</style>

+ 176 - 0
AyaoJies-app/house-master/house-life/pages/login/account.vue

@@ -0,0 +1,176 @@
+<template>
+  <view class="wrap">
+    <view class="content">
+      <view class="title">欢迎登录</view>
+      <input v-model="loginName" class="u-border-bottom" placeholder="请输入手机号" type="number"/>
+      <view class="tips">未注册的手机号验证后自动创建账号</view>
+      <u-button :style="[inputStyle]" class="getCaptcha" @click="submit">获取短信验证码</u-button>
+      <view class="alternative">
+        <view class="account" @click="accountLogin">密码登录</view>
+        <view class="issue" @click="problem">遇到问题</view>
+      </view>
+    </view>
+    <!-- <view class="buttom">
+      <view class="loginType">
+        <view class="wechat item">
+          <view class="icon"><u-icon size="60" name="server-man" color="#999" @click="server"></u-icon></view>
+        </view>
+      </view>
+    </view> -->
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      loginName: ''
+    }
+  },
+  onLoad() {
+    // 在页面中定义激励视频广告
+    let videoAd = null
+    // 在页面onLoad回调事件中创建激励视频广告实例
+    if (wx.createRewardedVideoAd) {
+      videoAd = wx.createRewardedVideoAd({
+        adUnitId: 'adunit-8cd5789a01a51891'
+      })
+      videoAd.onLoad(() => {
+      })
+      videoAd.onError((err) => {
+      })
+      videoAd.onClose((res) => {
+      })
+    }
+    // 用户触发广告后,显示激励视频广告
+    if (videoAd) {
+      videoAd.show().catch(() => {
+        // 失败重试
+        videoAd.load()
+            .then(() => videoAd.show())
+            .catch(err => {
+              console.log('激励视频 广告显示失败')
+            })
+      })
+    }
+  },
+  computed: {
+    // 小程序端无效
+    inputStyle() {
+      let style = {};
+      if (this.loginName && this.$u.test.mobile(this.loginName)) {
+        style.color = "#fff";
+        style.backgroundColor = this.$u.color['primary'];
+      }
+      return style;
+    }
+  },
+  methods: {
+    submit() {
+      if (this.$u.test.mobile(this.loginName)) {
+        this.$u.route({
+          url: 'pages/login/code',
+          params: {
+            loginName: this.loginName
+          }
+        })
+      } else {
+        this.$mytip.toast('请输入有效的手机号码')
+      }
+    },
+    accountLogin() {
+      this.$u.route({
+        url: 'pages/login/login'
+      })
+    },
+    problem() {
+      this.$u.route({
+        url: 'pages/login/problem'
+      })
+    },
+    server() {
+      window.open('https://sourcebyte.cn')
+    }
+  }
+};
+</script>
+
+<style>
+page {
+  overflow: hidden;
+  background-color: #ffffff;
+}
+</style>
+<style lang="scss" scoped>
+.wrap {
+  font-size: 28 rpx;
+
+  .content {
+    width: 600 rpx;
+    margin: 80 rpx auto 0;
+
+    .title {
+      text-align: left;
+      font-size: 60 rpx;
+      font-weight: 500;
+      margin-bottom: 100 rpx;
+    }
+
+    input {
+      text-align: left;
+      margin-bottom: 10 rpx;
+      padding-bottom: 6 rpx;
+    }
+
+    .tips {
+      color: $u-type-info;
+      margin-bottom: 60 rpx;
+      margin-top: 8 rpx;
+    }
+
+    .getCaptcha {
+      background-color: rgba(0, 0, 0, .1);
+      color: $u-tips-color;
+      border: none;
+      font-size: 30 rpx;
+      padding: 12 rpx 0;
+
+      &::after {
+        border: none;
+      }
+    }
+
+    .alternative {
+      color: $u-tips-color;
+      display: flex;
+      justify-content: space-between;
+      margin-top: 30 rpx;
+
+      .account {
+        &:active {
+          background-color: #ededed;
+        }
+      }
+    }
+  }
+
+  .buttom {
+    .loginType {
+      font-size: 14px;
+      position: fixed;
+      right: 50 rpx;
+      bottom: 50 rpx;
+      width: 60px;
+      height: 60px;
+      padding: 4px;
+      cursor: pointer;
+      background: #FFF;
+      text-align: center;
+      line-height: 60px;
+      border-radius: 100%;
+      -webkit-box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+      box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
+    }
+  }
+}
+</style>

+ 144 - 0
AyaoJies-app/house-master/house-life/pages/login/code.vue

@@ -0,0 +1,144 @@
+<template>
+  <view class="wrap">
+    <view class="key-input">
+      <view class="title">输入验证码</view>
+      <view class="tips">验证码已发送至 {{ loginName }}</view>
+      <u-message-input :focus="true" :maxlength="maxlength" :value="value" mode="bottomLine" @change="change"
+                       @finish="finish"></u-message-input>
+      <text :class="{ error: error }">验证码错误,请重新输入</text>
+      <view class="captcha">
+        <text :class="{ noCaptcha: show }" @tap="noCaptcha">收不到验证码点这里</text>
+        <text :class="{ regain: !show }">{{ second }}秒后重新获取验证码</text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      maxlength: 4,
+      value: '',
+      second: 60,
+      show: false,
+      error: false,
+      loginName: ''
+    };
+  },
+  onLoad: function (option) {
+    this.loginName = option.loginName //上个页面传递的参数。
+    // 发送验证码
+    this.getCaptcha()
+    // 倒计时
+    let interval = setInterval(() => {
+      this.second--;
+      if (this.second <= 0) {
+        this.show = true;
+        if (this.value.lenth != 4) {
+          this.error = true;
+        }
+        clearInterval(interval);
+      }
+    }, 1000);
+  },
+  methods: {
+    getCaptcha() {
+      console.log('用户===>' + this.loginName);
+      let url = "/api/captchaSms";
+      this.$u.get(url, {
+        loginName: this.loginName
+      }).then(data => {
+        console.log('验证码发送' + data.send);
+      });
+    },
+    // 收不到验证码选择时的选择
+    noCaptcha() {
+      let that = this
+      uni.showActionSheet({
+        itemList: ['重新获取验证码'],
+        success: function (res) {
+          that.getCaptcha()
+          that.$mytip.toast('验证码发送成功')
+        },
+        fail: function (res) {
+
+        }
+      });
+    },
+    // change事件侦听
+    change(value) {
+      // console.log('change', value);
+    },
+    // 输入完验证码最后一位执行
+    finish(value) {
+      // 登录成功初始化token与用户信息
+      let url = "/api/thirdRegister";
+      this.$u.post(url, {
+        username: this.loginName,
+        code: value
+      }).then(data => {
+        // 登录成功初始化token与用户信息
+        this.$u.vuex('vuex_token', data.token);
+        this.$u.vuex('vuex_user', data.loginUser);
+        uni.switchTab({
+          url: '/pages/index/index'
+        })
+      });
+    }
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.wrap {
+  padding: 80 rpx;
+}
+
+.box {
+  margin: 30 rpx 0;
+  font-size: 30 rpx;
+  color: 555;
+}
+
+.key-input {
+  padding: 30 rpx 0;
+
+  text {
+    display: none;
+  }
+
+  .error {
+    display: block;
+    color: red;
+    font-size: 30 rpx;
+    margin: 20 rpx 0;
+  }
+}
+
+.title {
+  font-size: 50 rpx;
+  color: #333;
+}
+
+.key-input .tips {
+  font-size: 30 rpx;
+  color: #333;
+  margin-top: 20 rpx;
+  margin-bottom: 60 rpx;
+}
+
+.captcha {
+  color: $u-type-warning;
+  font-size: 30 rpx;
+  margin-top: 40 rpx;
+
+  .noCaptcha {
+    display: block;
+  }
+
+  .regain {
+    display: block;
+  }
+}
+</style>

+ 327 - 0
AyaoJies-app/house-master/house-life/pages/login/login.vue

@@ -0,0 +1,327 @@
+<!-- 蓝色登录页面2 -->
+<template>
+  <view>
+    <u-toast ref="uToast"/>
+    <view class="img-a">
+      <view class="t-b">
+        您好,
+        <br/>
+        欢迎使用 开源字节
+      </view>
+    </view>
+    <view class="login-view">
+      <view class="t-login">
+        <form class="cl">
+          <view class="t-a">
+            <text class="txt">手机号</text>
+            <input v-model="username" maxlength="11" name="phone" placeholder="请输入您的手机号" type="number"/>
+          </view>
+          <view class="t-a">
+            <text class="txt">密码</text>
+            <input v-model="password" maxlength="18" name="code" placeholder="请输入您的密码" type="password"/>
+          </view>
+          <button @tap="login()">登 录</button>
+          <view class="reg" @tap="reg()">短信登录</view>
+        </form>
+      </view>
+    </view>
+
+    <!-- #ifdef MP-WEIXIN -->
+    <view class="buttom">
+      <button class="clearBtn" open-type="getPhoneNumber" @getphonenumber="weChatLogin">
+        <view class="loginType">
+          <view class="item">
+            <view class="icon">
+              <u-icon color="rgb(83,194,64)" name="weixin-fill" size="60"></u-icon>
+            </view>
+            微信
+          </view>
+        </view>
+      </button>
+      <!-- <view class="hint">
+        登录代表同意
+        <text class="link">开源字节用户协议、隐私政策,</text>
+        并授权使用您的账号信息(如昵称、头像、收获地址)以便您统一管理
+      </view> -->
+    </view>
+    <!-- #endif -->
+  </view>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      // username: '',
+      // password: '',
+      username: '18720989281',
+      password: '123456',
+    }
+  },
+  // onLoad() {
+  // 	// 在页面中定义激励视频广告
+  // 	let videoAd = null
+  // 	// 在页面onLoad回调事件中创建激励视频广告实例
+  // 	if (wx.createRewardedVideoAd) {
+  // 	  videoAd = wx.createRewardedVideoAd({
+  // 	    adUnitId: 'adunit-8cd5789a01a51891'
+  // 	  })
+  // 	  videoAd.onLoad(() => {})
+  // 	  videoAd.onError((err) => {})
+  // 	  videoAd.onClose((res) => {})
+  // 	}
+  // 	// 用户触发广告后,显示激励视频广告
+  // 	if (videoAd) {
+  // 	  videoAd.show().catch(() => {
+  // 	    // 失败重试
+  // 	    videoAd.load()
+  // 	      .then(() => videoAd.show())
+  // 	      .catch(err => {
+  // 	        console.log('激励视频 广告显示失败')
+  // 	      })
+  // 	  })
+  // 	}
+  // },
+  methods: {
+    login() {
+      if (!this.$u.test.mobile(this.username)) {
+        return this.$refs.uToast.show({
+          title: '手机号不正确',
+          type: 'warning',
+        })
+      }
+      if (!this.password) {
+        return this.$refs.uToast.show({
+          title: '密码不能为空',
+          type: 'warning',
+        })
+      }
+      // 登录json参数,不同于表单参数
+      let url = "/api/thirdLogin";
+      this.$u.post(url, {
+        username: this.username,
+        password: this.password
+      }).then(data => {
+        // 登录成功初始化token与用户信息
+        this.$u.vuex('vuex_token', data.token);
+        this.$u.vuex('vuex_user', data.loginUser);
+        uni.switchTab({
+          url: '/pages/index/index'
+        })
+      });
+    },
+    weChatLogin(e) {
+      let code = e.detail.code;
+      if (code) {
+        uni.showLoading({title: "登录中....", mask: true})
+        let url = "/api/miniWxApi/getPhoneNum?code=" + code;
+        this.$u.get(url).then(res => {
+          let phoneNum = res.phoneNum
+          let weChatUrl = "/api/weChatLogin";
+          this.$u.post(weChatUrl, {
+            username: phoneNum,
+            code: code
+          }).then(data => {
+            uni.hideLoading();
+            // 登录成功初始化token与用户信息
+            this.$u.vuex('vuex_token', data.token);
+            this.$u.vuex('vuex_user', data.loginUser);
+            uni.switchTab({
+              url: '/pages/index/index'
+            })
+          });
+        });
+      } else {
+        this.$mytip.toast('登录失败')
+      }
+    },
+    reg() {
+      this.$u.route({
+        url: 'pages/login/account'
+      })
+    }
+  }
+};
+</script>
+
+
+<style>
+page {
+  background-color: #ffffff;
+}
+</style>
+<style lang="scss" scoped>
+.txt {
+  font-size: 32 rpx;
+  font-weight: bold;
+  color: #333333;
+}
+
+.img-a {
+  width: 100%;
+  height: 450 rpx;
+  background-image: url(https://zhoukaiwen.com/img/loginImg/head.png);
+  background-size: 100%;
+}
+
+.reg {
+  font-size: 28 rpx;
+  color: #fff;
+  height: 90 rpx;
+  line-height: 90 rpx;
+  border-radius: 50 rpx;
+  font-weight: bold;
+  background: #f5f6fa;
+  color: #000000;
+  text-align: center;
+  margin-top: 30 rpx;
+}
+
+.login-view {
+  width: 100%;
+  position: relative;
+  margin-top: -120rpx;
+  background-color: #ffffff;
+  border-radius: 8% 8% 0% 0;
+}
+
+.t-login {
+  width: 600 rpx;
+  margin: 0 auto;
+  font-size: 28 rpx;
+  padding-top: 80 rpx;
+}
+
+.t-login button {
+  font-size: 28 rpx;
+  background: #2796f2;
+  color: #fff;
+  height: 90 rpx;
+  line-height: 90 rpx;
+  border-radius: 50 rpx;
+  font-weight: bold;
+}
+
+.t-login input {
+  height: 90 rpx;
+  line-height: 90 rpx;
+  margin-bottom: 50 rpx;
+  border-bottom: 1px solid #e9e9e9;
+  font-size: 28 rpx;
+}
+
+.t-login .t-a {
+  position: relative;
+}
+
+.t-b {
+  text-align: left;
+  font-size: 42 rpx;
+  color: #ffffff;
+  padding: 130 rpx 0 0 70 rpx;
+  font-weight: bold;
+  line-height: 70 rpx;
+}
+
+.t-login .t-c {
+  position: absolute;
+  right: 22 rpx;
+  top: 22 rpx;
+  background: #5677fc;
+  color: #fff;
+  font-size: 24 rpx;
+  border-radius: 50 rpx;
+  height: 50 rpx;
+  line-height: 50 rpx;
+  padding: 0 25 rpx;
+}
+
+.t-login .t-d {
+  text-align: center;
+  color: #999;
+  margin: 80 rpx 0;
+}
+
+.t-login .t-e {
+  text-align: center;
+  width: 250 rpx;
+  margin: 80 rpx auto 0;
+}
+
+.t-login .t-g {
+  float: left;
+  width: 50%;
+}
+
+.t-login .t-e image {
+  width: 50 rpx;
+  height: 50 rpx;
+}
+
+.t-login .t-f {
+  text-align: center;
+  margin: 150 rpx 0 0 0;
+  color: #666;
+}
+
+.t-login .t-f text {
+  margin-left: 20 rpx;
+  color: #aaaaaa;
+  font-size: 27 rpx;
+}
+
+.t-login .uni-input-placeholder {
+  color: #aeaeae;
+}
+
+.cl {
+  zoom: 1;
+}
+
+.cl:after {
+  clear: both;
+  display: block;
+  visibility: hidden;
+  height: 0;
+  content: '\20';
+}
+
+.buttom {
+  .loginType {
+    display: flex;
+    padding: 140 rpx 0;
+    justify-content: center;
+
+    .item {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      color: $u-tips-color;
+      font-size: 22 rpx;
+    }
+  }
+
+  .hint {
+    position: absolute;
+    bottom: 0;
+    padding: 20 rpx 40 rpx;
+    font-size: 20 rpx;
+    color: $u-tips-color;
+
+    .link {
+      color: #2979ff;
+    }
+  }
+}
+
+.clearBtn {
+  margin: 0;
+  padding: 0;
+  line-height: 1;
+  background-color: #FFFFFF;
+}
+
+.clearBtn::after {
+  position: unset !important;
+  border: unset;
+}
+</style>

+ 116 - 0
AyaoJies-app/house-master/house-life/pages/login/problem.vue

@@ -0,0 +1,116 @@
+<template>
+  <view style="margin: 20rpx;">
+    <u-navbar :border-bottom="false" :is-back="true" title="常见问题"></u-navbar>
+    <u-collapse class="u-p-30">
+      <u-collapse-item v-for="(item, index) in itemList" :key="index" :open="item.open" :title="item.head">
+        {{ item.body }}
+      </u-collapse-item>
+    </u-collapse>
+    <view class="u-m-t-20">
+      <u-button class="u-m-20" plain type="default" @click="server">
+        <u-icon color="#969799" name="level" size="38"></u-icon>
+        前往官网
+      </u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      appUrl: false,
+      url: "https://sourcebyte.cn",
+      itemList: [
+        {
+          head: "初始密码是什么?",
+          body: "初始密码默认为手机号码,为了您的账户安全,请进入个人中心进行修改。",
+          open: false,
+        },
+        {
+          head: "技术支持电话是多少?",
+          body: "联系电话:18720989281",
+          open: false,
+        },
+        {
+          head: "关于我们",
+          body: "我们专注提供专业的软件产品和技术。为合作伙伴提供安全可靠的软件产品与解决方案,共同帮助终端用户实现业务创新、快速发展。",
+          open: true,
+        },
+        {
+          head: "加入我们",
+          body: "邮箱:261648947@qq.com",
+          open: false,
+        },
+      ],
+    }
+  },
+  methods: {
+    server() {
+      let url = "https://sourcebyte.vip"
+      // #ifdef  H5
+      window.open(url, '_blank');
+      // #endif
+      // #ifndef  H5
+      this.$u.route("/pages/webview/webview", {
+        title: '关于我们',
+        src: url
+      });
+      // #endif
+      // if(this.isWeiXinLogin){
+      // 	uni.showToast({
+      // 		icon:'none',
+      // 		title:'www.sourcebyte.cn',
+      // 		duration:5000
+      // 	})
+      // }else{
+      // 	window.open(this.url)
+      // }
+    },
+    download() {
+      this.DownLoadAndroid();
+    },
+    //判断是否微信登陆
+    isWeiXinLogin() {
+      // #ifdef H5
+      let ua = window.navigator.userAgent.toLowerCase()
+      if (ua.match(/MicroMessenger/i) == 'micromessenger') {
+        return true;
+      }
+      // #endif
+      return false;
+    },
+    //安卓下载
+    DownLoadAndroid() {
+      if (this.isWeiXinLogin()) {
+        uni.showToast({
+          icon: 'none',
+          title: '请复制链接,在浏览器中打开下载',
+          duration: 3000
+        })
+        this.appUrl = true;
+        return;
+      }
+      var downloadUrl = 'http://8.136.213.245/profile/apk/yixin.apk'; // 下载地址
+      var urlStr = encodeURI(downloadUrl)
+      // #ifdef APP-PLUS
+      plus.runtime.openURL(urlStr);
+      return;
+      // #endif
+      // #ifdef H5
+      window.open(urlStr);
+      // #endif
+    },
+  }
+};
+</script>
+
+<style>
+page {
+  background: #fff;
+}
+
+.appUrl {
+  padding: 20 rpx;
+}
+</style>

+ 145 - 0
AyaoJies-app/house-master/house-life/pages/notice/notice.vue

@@ -0,0 +1,145 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="通知公告"></u-navbar>
+    <view class="wrap">
+      <scroll-view scroll-y style="height: 100%;width: 100%;">
+        <view class="page-box">
+          <view v-for="(item, index) in dataList" :key="item.id" class="tabSwiper" @click="clickContent(item)">
+            <view class="top">
+              <view class="left">
+                <u-icon :size="35" color="#2979ff" name="bell"></u-icon>
+                <view class="title">{{ item.title }}</view>
+                <u-icon :size="26" color="rgb(203,203,203)" name="arrow-right"></u-icon>
+              </view>
+              <view class="right">{{ item.date }}</view>
+            </view>
+            <view class="item">
+              <view class="content">
+                <view class="title u-line-2">{{ item.content }}</view>
+              </view>
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      pageNum: 1,
+      pageSize: 50,
+      dataList: [],
+    };
+  },
+  onLoad() {
+    this.getNoticecList();
+  },
+  methods: {
+    clickContent(item) {
+      if (item.id) {
+        this.$u.route('/pages/content/content', {
+          id: item.id
+        });
+      }
+    },
+    getNoticecList() {
+      let url = "/api/notice/findNoticeList";
+      this.$u.get(url, {
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        orderByColumn: 'create_time',
+        isAsc: 'desc'
+      }).then(obj => {
+        let data = obj.rows
+        data.filter(item => {
+          this.dataList.push(
+              {
+                id: item.noticeId,
+                title: item.noticeTitle,
+                date: item.createTime,
+                content: item.remark,
+              }
+          )
+        })
+      });
+    }
+  }
+};
+</script>
+<style lang="scss" scoped>
+.tabSwiper {
+  width: 710 rpx;
+  background-color: #ffffff;
+  margin: 20 rpx auto;
+  border-radius: 20 rpx;
+  box-sizing: border-box;
+  padding: 20 rpx;
+  font-size: 28 rpx;
+
+  .top {
+    display: flex;
+    justify-content: space-between;
+
+    .left {
+      display: flex;
+      align-items: center;
+
+      .title {
+        margin: 0 10 rpx;
+        font-size: 32 rpx;
+        font-weight: bold;
+      }
+    }
+
+    .right {
+      color: $u-tips-color;
+    }
+  }
+
+  .item {
+    display: flex;
+    margin: 20 rpx 0 0;
+
+    .left {
+      margin-right: 20 rpx;
+
+      image {
+        width: 200 rpx;
+        height: 200 rpx;
+        border-radius: 10 rpx;
+      }
+    }
+
+    .content {
+      .title {
+        font-size: 28 rpx;
+        line-height: 50 rpx;
+      }
+    }
+
+    .right {
+      margin-left: 10 rpx;
+      padding-top: 20 rpx;
+      text-align: right;
+    }
+  }
+}
+
+.wrap {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - var(--window-top));
+  width: 100%;
+}
+
+.swiper-box {
+  flex: 1;
+}
+
+.swiper-item {
+  height: 100%;
+}
+</style>

+ 142 - 0
AyaoJies-app/house-master/house-life/pages/profile/aboutMe.vue

@@ -0,0 +1,142 @@
+<!-- 关于作者 -->
+<template>
+  <view class="about">
+    <like-fx ref="likeFx" :height="height" :width="width"></like-fx>
+    <view class="titleZ text-center align-center">
+      <text class="text-bold" style="font-size: 28px;">关于我们</text>
+      <view class="contentZ">
+        <text class="text-xl">
+          我们专注提供专业的软件产品和技术。为合作伙伴提供安全可靠的软件产品与解决方案,共同帮助终端用户实现业务创新、快速发展。
+        </text>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import LikeFx from '@/components/likeFx/likeFx.vue'
+
+export default {
+  components: {
+    LikeFx
+  },
+  data() {
+    return {
+      animation_timer: null, // 动画定时器
+      width: 375,
+      height: 1920
+    }
+  },
+  onLoad() {
+    this._startLikeAnimation();
+  },
+  onUnload() {
+    clearTimeout(this.animation_timer)
+  },
+  methods: {
+    _startLikeAnimation() {
+      this.animation_timer = setInterval(() => {
+        this.$refs.likeFx.likeClick()
+      }, 300)
+    }
+  }
+}
+</script>
+
+<style scoped>
+.align-center {
+  text-align: center;
+}
+
+.titleZ {
+  width: 750 rpx;
+  font-size: 42 rpx;
+  margin-top: 60 rpx;
+}
+
+.contentZ {
+  width: 650 rpx;
+  margin: 10 rpx auto 0;
+  text-align: left;
+}
+
+.about-bg {
+  background-size: cover;
+  width: 100vw;
+  height: 100vh;
+  justify-content: center;
+  flex-direction: column;
+  color: #fff;
+}
+
+.edit-fixed {
+  position: fixed;
+  width: 100%;
+  bottom: 0;
+  z-index: 1024;
+  box-shadow: 0 1 rpx 6 rpx rgba(0, 0, 0, 0.1);
+}
+
+.detail-imgs image {
+  width: 100%;
+  float: left;
+  /* height:400rpx; 不定高了*/
+  border: 0;
+  padding: 0;
+  margin: 0
+}
+
+.share-img {
+  position: fixed;
+  padding: 10 rpx;
+  width: 100 rpx;
+  height: 100 rpx;
+  /* top: 680rpx; */
+  bottom: 200 rpx;
+  right: 20 rpx;
+  z-index: 1024;
+  opacity: 0.8;
+  box-shadow: 0 rpx 8 rpx 30 rpx 0 rpx rgba(0, 0, 0, 0.3);
+  border: none;
+}
+
+.about {
+  margin: 0;
+  width: 100%;
+  height: 100vh;
+  padding-top: 20%;
+  color: #fff;
+  background: linear-gradient(-120deg, #F15BB5, #9A5CE5, #01BEFF, #00F5D4);
+  /* background: linear-gradient(-120deg, #0976ea, #c471f5, #f956b6, #ea7e0a); */
+  background-size: 500% 500%;
+  animation: gradientBG 15s ease infinite;
+}
+
+@keyframes gradientBG {
+  0% {
+    background-position: 0% 50%;
+  }
+
+  50% {
+    background-position: 100% 50%;
+  }
+
+  100% {
+    background-position: 0% 50%;
+  }
+}
+
+.container {
+  width: 100%;
+  position: absolute;
+  text-align: center;
+}
+
+.like-fx {
+  position: fixed;
+  right: 0;
+  z-index: 1024;
+  pointer-events: none;
+  /* background-color: red; */
+}
+</style>

+ 91 - 0
AyaoJies-app/house-master/house-life/pages/profile/avatar.vue

@@ -0,0 +1,91 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="设置头像"></u-navbar>
+    <view class="wrap">
+      <u-upload ref="uUpload" :action="action" :auto-upload="true" :custom-btn="true" :max-size="10 * 1024 * 1024"
+                :size-type="siteType" height="690" max-count="1" width="690">
+        <view slot="addBtn" class="slot-btn" hover-class="slot-btn__hover" hover-stay-time="150">
+          <u-icon :color="$u.color['lightColor']" name="plus" size="60"></u-icon>
+        </view>
+      </u-upload>
+      <view class="u-m-t-20 btn">
+        <u-button type="primary" @click="subProfile">提交</u-button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      // 服务器地址
+      action: config.staticUrl + '/common/upload',
+      siteType: ['compressed']
+    };
+  },
+  methods: {
+    subProfile() {
+      let files = [];
+      // 通过filter,筛选出上传进度为100的文件(因为某些上传失败的文件,进度值不为100,这个是可选的操作)
+      files = this.$refs.uUpload.lists.filter(val => {
+        return val.progress == 100;
+      })
+      if (this.$u.test.isEmpty(files)) {
+        return this.$mytip.toast('请选择图片')
+      }
+      let imageList = files.map(val => {
+        return {
+          // imgUrl: val.response.url,
+          imgUrl: val.response.fileName
+        }
+      })
+      let avatar = imageList[0].imgUrl
+      let vuex_user = uni.getStorageSync('lifeData').vuex_user
+      let user = vuex_user.user
+      let userId = user.userId;
+      this.$u.put("api/profile/updateProfile", {
+        userId: userId,
+        avatar: avatar,
+      }).then(data => {
+        // 关闭
+        user.avatar = avatar
+        this.$u.vuex('vuex_user', vuex_user);
+        this.$mytip.toast('头像修改成功')
+        setTimeout(() => {
+          uni.$emit('updateAvatar', {});
+          uni.switchTab({
+            url: '/pages/center/center'
+          })
+        }, 1000);
+      });
+    },
+  }
+};
+</script>
+
+<style>
+page {
+  background-color: #FFFFFF;
+}
+</style>
+<style lang="scss" scoped>
+.wrap {
+  padding: 30 rpx;
+}
+
+.slot-btn {
+  width: 690 rpx;
+  height: 690 rpx;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  background: rgb(244, 245, 246);
+  border-radius: 10 rpx;
+}
+
+.slot-btn__hover {
+  background-color: rgb(235, 236, 238);
+}
+</style>

+ 119 - 0
AyaoJies-app/house-master/house-life/pages/profile/password.vue

@@ -0,0 +1,119 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="修改密码"></u-navbar>
+    <view class="u-m-20">
+      <u-toast ref="uToast"/>
+      <view>
+        <u-cell-group>
+          <u-field
+              v-model="oldpassword"
+              focus
+              icon="lock"
+              iconColor="#d5d5d5"
+              label="旧密码"
+              label-width="180"
+              password
+              placeholder="请填写旧密码"
+          >
+          </u-field>
+          <u-field
+              v-model="newpassword"
+              icon="lock"
+              iconColor="#d5d5d5"
+              label="新密码"
+              label-width="180"
+              password
+              placeholder="请填写新密码"
+          >
+          </u-field>
+          <u-field
+              v-model="password"
+              icon="lock-fill"
+              iconColor="#d5d5d5"
+              label="确认密码"
+              label-width="180"
+              password
+              placeholder="请再次填写密码"
+          >
+          </u-field>
+        </u-cell-group>
+      </view>
+    </view>
+    <view class="btn">
+      <u-button type="primary" @tap="changePasswold">提交</u-button>
+    </view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      oldpassword: '',
+      newpassword: '',
+      password: '',
+    }
+  },
+  methods: {
+    changePasswold() {
+      if (!this.oldpassword) {
+        return this.$mytip.toast('请输入旧密码')
+      }
+      if (!this.newpassword) {
+        return this.$mytip.toast('请输入新密码')
+      }
+      if (!this.password) {
+        return this.$mytip.toast('请确认密码')
+      }
+      if (this.newpassword != this.password) {
+        return this.$mytip.toast('密码不一致,请确认')
+      }
+      let url = "api/profile/updatePwd";
+      let userId = uni.getStorageSync('lifeData').vuex_user.user.userId;
+      this.$u.put(url, {
+        userId: userId,
+        oldPassword: this.oldpassword,
+        newPassword: this.newpassword
+      }).then(data => {
+        //提示后跳转页面
+        this.$mytip.toast('密码修改成功')
+        setTimeout(() => {
+          uni.switchTab({
+            url: '/pages/center/center'
+          })
+        }, 1000);
+      });
+    },
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+page {
+  overflow: hidden;
+}
+
+.logo {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  width: 100%;
+  height: 550 rpx;
+
+  img {
+    text-align: center;
+  }
+}
+
+.version {
+  position: fixed;
+  bottom: 0;
+  width: 100%;
+  text-align: center;
+  padding: 15 rpx;
+}
+
+.btn {
+  margin: 20 rpx;
+}
+</style>

+ 118 - 0
AyaoJies-app/house-master/house-life/pages/profile/profile.vue

@@ -0,0 +1,118 @@
+<template>
+  <view class="u-m-20">
+    <u-navbar :border-bottom="false" :is-back="true" title="个人信息"></u-navbar>
+    <view>
+      <u-cell-group>
+        <u-cell-item :arrow="true" hover-class="none" title="头像" @click="updateAvatar">
+          <u-avatar :src="pic" size="100"></u-avatar>
+        </u-cell-item>
+      </u-cell-group>
+      <u-cell-group>
+        <u-cell-item :arrow="true" hover-class="none" title="昵称" @click="updateName">
+          {{ vuex_user.user.nickName }}
+        </u-cell-item>
+      </u-cell-group>
+    </view>
+
+    <u-modal ref="uModal" v-model="showModel" :async-close="true" title="设置昵称"
+             @confirm="confirmName">
+      <view class="slot-content">
+        <u-input v-model="nickName" :border="false" placeholder="请输入昵称" type="text"/>
+      </view>
+    </u-modal>
+
+    <!-- <view class="u-m-t-20">
+      <u-button type="primary" @click="subProfile">提交</u-button>
+    </view> -->
+
+    <!-- 如果是微信登录小程序,则获取用户的昵称与头像 -->
+    <!-- #ifdef MP-WEIXIN -->
+    <!-- <u-button type="default">使用微信头像与昵称</u-button> -->
+    <!-- #endif -->
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+export default {
+  data() {
+    return {
+      pic: uni.getStorageSync('lifeData').vuex_user.user.avatar.includes(config.staticUrl) ? uni.getStorageSync('lifeData').vuex_user.user.avatar : config.staticUrl + uni.getStorageSync('lifeData').vuex_user.user.avatar,
+      nickName: null,
+      showModel: false,
+    }
+  },
+  methods: {
+    updateName() {
+      this.showModel = true;
+    },
+    confirmName() {
+      if (!this.nickName) {
+        this.showModel = false;
+        return this.$mytip.toast('请输入昵称')
+      }
+      let url = "api/profile/updateProfile";
+      let vuex_user = uni.getStorageSync('lifeData').vuex_user
+      let user = vuex_user.user
+      let userId = user.userId;
+      this.$u.put(url, {
+        userId: userId,
+        nickName: this.nickName,
+      }).then(data => {
+        // 关闭
+        user.nickName = this.nickName
+        this.$u.vuex('vuex_user', vuex_user);
+        this.showModel = false;
+        this.$mytip.toast('昵称修改成功')
+      });
+    },
+    updateAvatar() {
+      this.$u.route('/pages/profile/avatar')
+    },
+    subProfile() {
+      // 1.更新vuex中的用户信息
+      this.$mytip.toast('修改成功')
+      // 2.页面跳转
+      uni.switchTab({
+        url: '/pages/center/center'
+      })
+    },
+    getUserProfile() {
+      // 如果是微信登录小程序,则获取用户的昵称与头像
+      // #ifdef MP-WEIXIN
+      // 此处执行微信才执行
+      // #endif
+      var that = this;
+      uni.getUserProfile({
+        desc: '获取您的微信信息以授权小程序',
+        lang: 'zh_CN',
+        success: UserProfileRes => {
+          console.log(UserProfileRes)
+          uni.login({
+            provider: 'weixin',
+            success: function (loginRes) {
+              let avatarUrl = UserProfileRes.userInfo.avatarUrl; //用户头像
+              let nickName = UserProfileRes.userInfo.nickName; //用户微信名
+              let gender = UserProfileRes.userInfo.gender;//性别
+              console.log(avatarUrl);
+              // 去修改用户的昵称与头像
+            },
+            fail(err) {
+              console.log(err)
+            }
+          });
+        },
+        fail: err => {
+          console.log(err)
+        }
+      })
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.slot-content {
+  padding: 40 rpx;
+}
+</style>

+ 58 - 0
AyaoJies-app/house-master/house-life/pages/profile/setting.vue

@@ -0,0 +1,58 @@
+<template>
+  <view>
+    <u-navbar :border-bottom="false" :is-back="true" title="设置">
+    </u-navbar>
+    <view>
+      <u-cell-group>
+        <u-cell-item title="个人信息" @click="profile"></u-cell-item>
+        <u-cell-item title="修改密码" @click="changePassword"></u-cell-item>
+      </u-cell-group>
+    </view>
+
+    <view class="btn">
+      <u-button plain type="default" @click="logout">退出登录</u-button>
+    </view>
+
+    <view class="version">Version {{ vuex_version }}</view>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {}
+  },
+  onLoad() {
+
+  },
+  methods: {
+    profile() {
+      this.$u.route('/pages/profile/profile')
+    },
+    logout() {
+      // 登录成功修改token与用户信息
+      this.$u.vuex('vuex_token', '');
+      this.$u.vuex('vuex_user', {});
+      return uni.reLaunch({
+        url: '../index/index'
+      })
+    },
+    changePassword() {
+      this.$u.route('/pages/profile/password')
+    }
+  }
+}
+</script>
+
+<style lang="scss">
+.btn {
+  margin: 20 rpx;
+}
+
+.version {
+  position: absolute;
+  bottom: 20 rpx;
+  width: 100%;
+  text-align: center;
+}
+</style>

+ 143 - 0
AyaoJies-app/house-master/house-life/pages/search/search.vue

@@ -0,0 +1,143 @@
+<template>
+  <view class="u-margin-left-20 u-margin-right-20">
+    <u-navbar :border-bottom="false" :is-back="true" title="搜索"></u-navbar>
+    <u-search v-model="keyword" :focus="true" action-text="取消"
+              placeholder="请输入小区" @custom="cancelSearch" @search="clickSearch(value)"></u-search>
+    <!-- 搜索记录 -->
+    <template v-if="historyList.length > 0">
+      <view style="position: relative;">
+        <u-card :border="false" :head-border-bottom="false" padding="0" title="搜索记录" title-size="28">
+          <view slot="body">
+            <u-cell-group :border="false">
+              <u-cell-item v-for="(item,index) in historyList" :key="index" :arrow="false" :border-bottom="false"
+                           :title="item" @click="clickSearchTag(item)">
+                <!-- 	<u-icon slot="icon" size="32" name="search"></u-icon> -->
+              </u-cell-item>
+            </u-cell-group>
+          </view>
+        </u-card>
+        <view class="arrow-right" @click="clearHistory">
+          <u-icon name="trash"></u-icon>
+          清除
+        </view>
+      </view>
+    </template>
+  </view>
+</template>
+<script>
+export default {
+  data() {
+    return {
+      historyList: [],
+      keyword: "",
+    }
+  },
+  onLoad() {
+    // 加载历史记录
+    let history = uni.getStorageSync('searchHistory')
+    this.historyList = history ? JSON.parse(history) : []
+  },
+  onReady() {
+
+  },
+  methods: {
+    clickSearch() {
+      if (this.keyword === '') {
+        return uni.showToast({
+          title: '关键词不能为空',
+          icon: 'none'
+        });
+      } else {
+        uni.hideKeyboard()
+        this.addHistory()
+        this.$u.route({
+          url: '/pages/search/searchList',
+          params: {
+            villageName: this.keyword
+          }
+        })
+      }
+    },
+    // 自定义取消搜索事件
+    cancelSearch() {
+      uni.navigateBack({
+        delta: 1
+      })
+    },
+    clickSearchTag(item) {
+      this.keyword = item
+      this.clickSearch()
+    },
+    // 加入搜索记录
+    addHistory() {
+      let index = this.historyList.indexOf(this.keyword)
+      let history = this.historyList;
+      if (index === -1) {
+        history.unshift(this.keyword)
+      } else {
+        history.unshift(history.splice(index, 1)[0])
+      }
+      uni.setStorageSync('searchHistory', JSON.stringify(history))
+    },
+    clearHistory() {
+      // 清除搜索记录
+      uni.showModal({
+        title: '提示',
+        content: '是否清除搜索历史?',
+        cancelText: '取消',
+        confirmText: '确认',
+        success: res => {
+          if (res.confirm) {
+            uni.removeStorageSync('searchHistory');
+            this.historyList = []
+            this.keyword = ''
+            this.$mytip.toast('清除成功')
+          }
+        }
+      });
+    }
+  }
+}
+</script>
+
+<style>
+page {
+  background: #FFFFFF;
+}
+</style>
+
+<style lang="scss" scoped>
+.item-title {
+  font-size: 28 rpx;
+  color: $u-main-color;
+  font-weight: bold;
+}
+
+.item-price {
+  font-weight: normal;
+  font-size: 35 rpx;
+  color: $u-type-warning;
+  margin-top: 3px;
+}
+
+.item-desc {
+  font-weight: normal;
+  font-size: 26 rpx;
+  color: $u-tips-color;
+}
+
+.item-tag {
+  font-size: 24 rpx;
+  color: $u-tips-color;
+  margin-top: 3px;
+}
+
+.arrow-right {
+  position: absolute;
+  top: 0 rpx;
+  right: 28 rpx;
+  font-weight: normal;
+  font-size: 28 rpx;
+  color: $u-tips-color;
+}
+</style>

+ 305 - 0
AyaoJies-app/house-master/house-life/pages/search/searchList.vue

@@ -0,0 +1,305 @@
+<template>
+  <view>
+    <!-- <u-navbar :is-back="true" title="房源列表" :border-bottom="false"></u-navbar> -->
+    <u-sticky offset-top="0">
+      <view class="sticky">
+        <filterDropdown :defaultSelected="defaultSelected" :filterData="filterData" :menuTop="0" :updateMenuName="true"
+                        dataFormat="Object" @confirm="confirm"></filterDropdown>
+      </view>
+    </u-sticky>
+    <view class="u-p-l-10 u-p-r-10 waterfall">
+      <u-waterfall ref="uWaterfall" v-model="flowList">
+        <template v-slot:left="{leftList}">
+          <view v-for="(item, index) in leftList" :key="index" class="demo-warter">
+            <u-lazy-load :image="item.image" :index="index" border-radius="12" threshold="750"
+                         @click="clickImage(item.id)"></u-lazy-load>
+            <view class="item-title">{{ item.villageName }}
+              {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+            </view>
+            <view class="item-price">¥{{ item.price }}</view>
+            <view class="item-desc">{{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ |
+              {{ item.decoration }}
+            </view>
+          </view>
+        </template>
+        <template v-slot:right="{rightList}">
+          <view v-for="(item, index) in rightList" :key="index" class="demo-warter">
+            <u-lazy-load :image="item.image" :index="index" border-radius="10" threshold="750"
+                         @click="clickImage(item.id)"></u-lazy-load>
+            <view class="item-title">{{ item.villageName }}
+              {{ item.type == '整租' ? item.houseNum + item.houseHall + item.toiletNum : item.roomType }}
+            </view>
+            <view class="item-price">¥{{ item.price }}</view>
+            <view class="item-desc">{{ item.type }} | {{ item.type == '整租' ? item.houseArea : item.roomArea }}㎡ |
+              {{ item.decoration }}
+            </view>
+          </view>
+        </template>
+      </u-waterfall>
+      <u-loadmore :status="loadStatus" bg-color="rgb(240, 240, 240)" style="height: 80rpx;line-height: 80rpx;"
+                  @loadmore="findHouseList"></u-loadmore>
+      <u-back-top :scroll-top="scrollTop" top="1000"></u-back-top>
+      <u-no-network></u-no-network>
+    </view>
+  </view>
+</template>
+
+<script>
+import config from "@/common/config.js" // 全局配置文件
+import searchData from '@/common/utils/searchData.js';//筛选菜单数据
+import filterDropdown from '@/components/zy/filterDropdown.vue';
+
+export default {
+  components: {
+    filterDropdown
+  },
+  data() {
+    return {
+      indexArr: [],
+      valueArr: [],
+      defaultSelected: [],
+      filterData: [],
+      searchData: {},
+      pageNum: 1,
+      pageSize: 20,
+      scrollTop: 0,
+      houseList: [],
+      loadStatus: 'loadmore',
+      flowList: [],
+    }
+  },
+  onLoad(option) {
+    let type = option.type
+    let villageName = option.villageName
+    this.searchData = {}
+    if (type) {
+      this.searchData.type = type
+    }
+    if (villageName) {
+      this.searchData.villageName = villageName
+    }
+    // 获取房源数据
+    this.findHouseList();
+    // 获取小区数据
+    this.findVillageList()
+  },
+  onPageScroll(e) {
+    this.scrollTop = e.scrollTop;
+  },
+  onReachBottom() {
+    this.loadStatus = 'loading';
+    // 获取数据
+    this.findHouseList()
+  },
+  // 下拉刷新
+  onPullDownRefresh() {
+    this.pageNum = 1
+    this.flowList = []
+    this.$refs.uWaterfall.clear();
+    // 获取数据
+    this.findHouseList();
+    // 关闭刷新
+    uni.stopPullDownRefresh();
+  },
+  methods: {
+    findHouseList() {
+      let url = "/api/houseApi/findHouseRoomList";
+      let defaultData = {
+        state: 1,
+        villageCity: uni.getStorageSync('lifeData').vuex_city,
+        pageNum: this.pageNum,
+        pageSize: this.pageSize,
+        orderByColumn: 'update_time,create_time',
+        isAsc: 'desc'
+      }
+      this.$u.get(url, {...defaultData, ...this.searchData}).then(result => {
+        console.log(this.searchData);
+        console.log(result);
+        const data = result.rows;
+        if (this.pageNum > 1 && data.length < this.pageSize) {
+          return this.loadStatus = 'nomore';
+        }
+        this.houseList = data;
+        for (let i = 0; i < this.houseList.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = this.houseList[i]
+          if (!item.faceUrl.includes(config.staticUrl)) {
+            item.image = config.staticUrl + item.faceUrl
+          } else {
+            item.image = item.faceUrl
+          }
+          if (item.type == 0) {
+            item.type = '整租'
+          } else if (item.type == 1) {
+            item.type = '合租'
+          }
+          if (item.roomType == 1) {
+            item.roomType = '主卧'
+          } else if (item.roomType == 2) {
+            item.roomType = '次卧'
+          } else {
+            item.roomType = '未知'
+          }
+          if (this.$u.test.isEmpty(item.houseNum)) {
+            item.houseNum = ''
+          }
+          if (this.$u.test.isEmpty(item.houseHall)) {
+            item.houseHall = ''
+          }
+          if (this.$u.test.isEmpty(item.toiletNum)) {
+            item.toiletNum = ''
+          }
+          this.flowList.push(item);
+        }
+        ++this.pageNum
+        this.loadStatus = 'loadmore';
+      });
+    },
+    findVillageList() {
+      let url = "/api/houseApi/findVillageList";
+      this.$u.get(url, {
+        city: uni.getStorageSync('lifeData').vuex_city,
+        orderByColumn: 'name',
+        isAsc: 'desc'
+      }).then(result => {
+        const data = result.rows
+        for (let i = 0; i < data.length; i++) {
+          // 先转成字符串再转成对象,避免数组对象引用导致数据混乱
+          let item = data[i]
+          searchData[0].submenu.push({
+            name: item.name,
+            value: item.name
+          })
+        }
+        this.filterData = searchData;
+      });
+    },
+    clickImage(houseId) {
+      this.$u.route({
+        url: '/pages/detail/detail',
+        params: {
+          houseId: houseId
+        }
+      })
+    },
+    //接收菜单结果
+    confirm(e) {
+      let type = e.value[1][0]
+      let villageName = e.value[0][0]
+      let price = e.value[2][0]
+      let combo = e.value[3]
+      let houseNum = combo[0]
+      let decoration = combo[1]
+      let feature = combo[2]
+      this.searchData = {}
+      if (type) {
+        this.searchData.type = type
+      }
+      if (villageName) {
+        this.searchData.villageName = villageName
+      }
+      if (price) {
+        this.searchData.price = price
+      }
+      if (houseNum && houseNum.length > 0) {
+        this.searchData.houseNum = houseNum.toString()
+      }
+      if (decoration && decoration.length > 0) {
+        this.searchData.decoration = decoration.toString()
+      }
+      if (feature && feature.length > 0) {
+        this.searchData.feature = feature.toString()
+      }
+      this.pageNum = 1
+      this.houseList = []
+      this.flowList = []
+      this.$refs.uWaterfall.clear();
+      this.findHouseList()
+    },
+    code() {
+      this.$mytip.toast('请咨询技术支持')
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.waterfall {
+  // padding-top: 85rpx;
+}
+
+.nomore {
+  background-color: $u-bg-color;
+}
+
+.search {
+  width: 54px;
+  height: 44px;
+
+  &:active {
+    background-color: $u-bg-color;
+  }
+}
+
+.rowClass {
+  border-radius: 8px;
+  background-color: rgb(255, 255, 255);
+  margin-top: 10 rpx;
+}
+
+.hoverClass {
+  background-color: #E4E7ED;
+}
+
+.tabName {
+  font-size: 28 rpx;
+  color: $u-main-color;
+}
+
+.demo-warter {
+  border-radius: 8px;
+  margin-top: 3px;
+  background-color: #ffffff;
+  padding: 3px;
+  position: relative;
+}
+
+.u-close {
+  position: absolute;
+  top: 20 rpx;
+  right: 20 rpx;
+}
+
+.item-cover {
+  font-size: 55 rpx;
+  color: $u-type-warning;
+}
+
+.item-title {
+  font-size: 28 rpx;
+  color: $u-main-color;
+  font-weight: bold;
+  padding-top: 5 rpx;
+  padding-left: 10 rpx;
+}
+
+.item-price {
+  font-weight: normal;
+  font-size: 32 rpx;
+  color: $u-type-warning;
+}
+
+.item-desc {
+  font-weight: normal;
+  font-size: 26 rpx;
+  color: $u-tips-color;
+  padding-bottom: 5 rpx;
+  padding-left: 10 rpx;
+}
+
+.item-tag {
+  font-size: 24 rpx;
+  color: $u-tips-color;
+  margin-top: 3px;
+}
+</style>

+ 25 - 0
AyaoJies-app/house-master/house-life/pages/webview/webview.vue

@@ -0,0 +1,25 @@
+<template>
+  <view v-if="src">
+    <web-view :fullscreen="false" :src="src" :webview-styles="wbStyles"/>
+  </view>
+</template>
+
+<script>
+export default {
+  data() {
+    return {
+      title: '',
+      src: '',
+      wbStyles: {
+        width: '100%',
+        height: '100%',
+      },
+    }
+  },
+  onLoad(option) {
+    console.log(option.title);
+    this.title = option?.title
+    this.src = option?.src
+  },
+}
+</script>

二进制
AyaoJies-app/house-master/house-life/static/center-selected.png


二进制
AyaoJies-app/house-master/house-life/static/center.png


+ 363 - 0
AyaoJies-app/house-master/house-life/static/common/js/touch-emulator.js

@@ -0,0 +1,363 @@
+(function (window, document, exportName, undefined) {
+    "use strict";
+
+    var isMultiTouch = false;
+    var multiTouchStartPos;
+    var eventTarget;
+    var touchElements = {};
+
+    // polyfills
+    if (!document.createTouch) {
+        document.createTouch = function (view, target, identifier, pageX, pageY, screenX, screenY, clientX, clientY) {
+            // auto set
+            if (clientX == undefined || clientY == undefined) {
+                clientX = pageX - window.pageXOffset;
+                clientY = pageY - window.pageYOffset;
+            }
+
+            return new Touch(target, identifier, {
+                pageX: pageX,
+                pageY: pageY,
+                screenX: screenX,
+                screenY: screenY,
+                clientX: clientX,
+                clientY: clientY
+            });
+        };
+    }
+
+    if (!document.createTouchList) {
+        document.createTouchList = function () {
+            var touchList = new TouchList();
+            for (var i = 0; i < arguments.length; i++) {
+                touchList[i] = arguments[i];
+            }
+            touchList.length = arguments.length;
+            return touchList;
+        };
+    }
+
+    /**
+     * create an touch point
+     * @constructor
+     * @param target
+     * @param identifier
+     * @param pos
+     * @param deltaX
+     * @param deltaY
+     * @returns {Object} touchPoint
+     */
+    function Touch(target, identifier, pos, deltaX, deltaY) {
+        deltaX = deltaX || 0;
+        deltaY = deltaY || 0;
+
+        this.identifier = identifier;
+        this.target = target;
+        this.clientX = pos.clientX + deltaX;
+        this.clientY = pos.clientY + deltaY;
+        this.screenX = pos.screenX + deltaX;
+        this.screenY = pos.screenY + deltaY;
+        this.pageX = pos.pageX + deltaX;
+        this.pageY = pos.pageY + deltaY;
+    }
+
+    /**
+     * create empty touchlist with the methods
+     * @constructor
+     * @returns touchList
+     */
+    function TouchList() {
+        var touchList = [];
+
+        touchList.item = function (index) {
+            return this[index] || null;
+        };
+
+        // specified by Mozilla
+        touchList.identifiedTouch = function (id) {
+            return this[id + 1] || null;
+        };
+
+        return touchList;
+    }
+
+
+    /**
+     * Simple trick to fake touch event support
+     * this is enough for most libraries like Modernizr and Hammer
+     */
+    function fakeTouchSupport() {
+        var objs = [window, document.documentElement];
+        var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend'];
+
+        for (var o = 0; o < objs.length; o++) {
+            for (var p = 0; p < props.length; p++) {
+                if (objs[o] && objs[o][props[p]] == undefined) {
+                    objs[o][props[p]] = null;
+                }
+            }
+        }
+    }
+
+    /**
+     * we don't have to emulate on a touch device
+     * @returns {boolean}
+     */
+    function hasTouchSupport() {
+        return ("ontouchstart" in window) || // touch events
+            (window.Modernizr && window.Modernizr.touch) || // modernizr
+            (navigator.msMaxTouchPoints || navigator.maxTouchPoints) > 2; // pointer events
+    }
+
+    /**
+     * disable mouseevents on the page
+     * @param ev
+     */
+    function preventMouseEvents(ev) {
+        // 注释启用默认事件
+        // ev.preventDefault();
+        // ev.stopPropagation();
+    }
+
+    /**
+     * only trigger touches when the left mousebutton has been pressed
+     * @param touchType
+     * @returns {Function}
+     */
+    function onMouse(touchType) {
+        return function (ev) {
+            // prevent mouse events
+            preventMouseEvents(ev);
+
+            if (ev.which !== 1) {
+                return;
+            }
+
+            // The EventTarget on which the touch point started when it was first placed on the surface,
+            // even if the touch point has since moved outside the interactive area of that element.
+            // also, when the target doesnt exist anymore, we update it
+            if (ev.type == 'mousedown' || !eventTarget || (eventTarget && !eventTarget.dispatchEvent)) {
+                eventTarget = ev.target;
+            }
+
+            // shiftKey has been lost, so trigger a touchend
+            if (isMultiTouch && !ev.shiftKey) {
+                triggerTouch('touchend', ev);
+                isMultiTouch = false;
+            }
+
+            triggerTouch(touchType, ev);
+
+            // we're entering the multi-touch mode!
+            if (!isMultiTouch && ev.shiftKey) {
+                isMultiTouch = true;
+                multiTouchStartPos = {
+                    pageX: ev.pageX,
+                    pageY: ev.pageY,
+                    clientX: ev.clientX,
+                    clientY: ev.clientY,
+                    screenX: ev.screenX,
+                    screenY: ev.screenY
+                };
+                triggerTouch('touchstart', ev);
+            }
+
+            // reset
+            if (ev.type == 'mouseup') {
+                multiTouchStartPos = null;
+                isMultiTouch = false;
+                eventTarget = null;
+            }
+        }
+    }
+
+    /**
+     * trigger a touch event
+     * @param eventName
+     * @param mouseEv
+     */
+    function triggerTouch(eventName, mouseEv) {
+        var touchEvent = document.createEvent('Event');
+        touchEvent.initEvent(eventName, true, true);
+
+        touchEvent.altKey = mouseEv.altKey;
+        touchEvent.ctrlKey = mouseEv.ctrlKey;
+        touchEvent.metaKey = mouseEv.metaKey;
+        touchEvent.shiftKey = mouseEv.shiftKey;
+
+        touchEvent.touches = getActiveTouches(mouseEv, eventName);
+        touchEvent.targetTouches = getActiveTouches(mouseEv, eventName);
+        touchEvent.changedTouches = getChangedTouches(mouseEv, eventName);
+
+        eventTarget.dispatchEvent(touchEvent);
+    }
+
+    /**
+     * create a touchList based on the mouse event
+     * @param mouseEv
+     * @returns {TouchList}
+     */
+    function createTouchList(mouseEv) {
+        var touchList = new TouchList();
+
+        if (isMultiTouch) {
+            var f = TouchEmulator.multiTouchOffset;
+            var deltaX = multiTouchStartPos.pageX - mouseEv.pageX;
+            var deltaY = multiTouchStartPos.pageY - mouseEv.pageY;
+
+            touchList.push(new Touch(eventTarget, 1, multiTouchStartPos, (deltaX * -1) - f, (deltaY * -1) + f));
+            touchList.push(new Touch(eventTarget, 2, multiTouchStartPos, deltaX + f, deltaY - f));
+        } else {
+            touchList.push(new Touch(eventTarget, 1, mouseEv, 0, 0));
+        }
+
+        return touchList;
+    }
+
+    /**
+     * receive all active touches
+     * @param mouseEv
+     * @returns {TouchList}
+     */
+    function getActiveTouches(mouseEv, eventName) {
+        // empty list
+        if (mouseEv.type == 'mouseup') {
+            return new TouchList();
+        }
+
+        var touchList = createTouchList(mouseEv);
+        if (isMultiTouch && mouseEv.type != 'mouseup' && eventName == 'touchend') {
+            touchList.splice(1, 1);
+        }
+        return touchList;
+    }
+
+    /**
+     * receive a filtered set of touches with only the changed pointers
+     * @param mouseEv
+     * @param eventName
+     * @returns {TouchList}
+     */
+    function getChangedTouches(mouseEv, eventName) {
+        var touchList = createTouchList(mouseEv);
+
+        // we only want to return the added/removed item on multitouch
+        // which is the second pointer, so remove the first pointer from the touchList
+        //
+        // but when the mouseEv.type is mouseup, we want to send all touches because then
+        // no new input will be possible
+        if (isMultiTouch && mouseEv.type != 'mouseup' &&
+            (eventName == 'touchstart' || eventName == 'touchend')) {
+            touchList.splice(0, 1);
+        }
+
+        return touchList;
+    }
+
+    /**
+     * show the touchpoints on the screen
+     */
+    function showTouches(ev) {
+        var touch, i, el, styles;
+
+        // first all visible touches
+        for (i = 0; i < ev.touches.length; i++) {
+            touch = ev.touches[i];
+            el = touchElements[touch.identifier];
+            if (!el) {
+                el = touchElements[touch.identifier] = document.createElement("div");
+                document.body.appendChild(el);
+            }
+
+            styles = TouchEmulator.template(touch);
+            for (var prop in styles) {
+                el.style[prop] = styles[prop];
+            }
+        }
+
+        // remove all ended touches
+        if (ev.type == 'touchend' || ev.type == 'touchcancel') {
+            for (i = 0; i < ev.changedTouches.length; i++) {
+                touch = ev.changedTouches[i];
+                el = touchElements[touch.identifier];
+                if (el) {
+                    el.parentNode.removeChild(el);
+                    delete touchElements[touch.identifier];
+                }
+            }
+        }
+    }
+
+    /**
+     * TouchEmulator initializer
+     */
+    function TouchEmulator() {
+        if (hasTouchSupport()) {
+            return;
+        }
+
+        fakeTouchSupport();
+
+        window.addEventListener("mousedown", onMouse('touchstart'), true);
+        window.addEventListener("mousemove", onMouse('touchmove'), true);
+        window.addEventListener("mouseup", onMouse('touchend'), true);
+
+        window.addEventListener("mouseenter", preventMouseEvents, true);
+        window.addEventListener("mouseleave", preventMouseEvents, true);
+        window.addEventListener("mouseout", preventMouseEvents, true);
+        window.addEventListener("mouseover", preventMouseEvents, true);
+
+        // it uses itself!
+        window.addEventListener("touchstart", showTouches, true);
+        window.addEventListener("touchmove", showTouches, true);
+        window.addEventListener("touchend", showTouches, true);
+        window.addEventListener("touchcancel", showTouches, true);
+    }
+
+    // start distance when entering the multitouch mode
+    TouchEmulator.multiTouchOffset = 75;
+
+    /**
+     * css template for the touch rendering
+     * @param touch
+     * @returns object
+     */
+    TouchEmulator.template = function (touch) {
+        var size = 0;
+        var transform = 'translate(' + (touch.clientX - (size / 2)) + 'px, ' + (touch.clientY - (size / 2)) + 'px)';
+        return {
+            position: 'fixed',
+            left: 0,
+            top: 0,
+            background: '#fff',
+            border: 'solid 1px #999',
+            opacity: .6,
+            borderRadius: '100%',
+            height: size + 'px',
+            width: size + 'px',
+            padding: 0,
+            margin: 0,
+            display: 'block',
+            overflow: 'hidden',
+            pointerEvents: 'none',
+            webkitUserSelect: 'none',
+            mozUserSelect: 'none',
+            userSelect: 'none',
+            webkitTransform: transform,
+            mozTransform: transform,
+            transform: transform,
+            zIndex: 100
+        }
+    };
+
+    // export
+    if (typeof define == "function" && define.amd) {
+        define(function () {
+            return TouchEmulator;
+        });
+    } else if (typeof module != "undefined" && module.exports) {
+        module.exports = TouchEmulator;
+    } else {
+        window[exportName] = TouchEmulator;
+    }
+})(window, document, "TouchEmulator");

二进制
AyaoJies-app/house-master/house-life/static/empty/default.png


二进制
AyaoJies-app/house-master/house-life/static/favicon.ico


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover1.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover2.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover3.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover/index_cover4.png


+ 0 - 0
AyaoJies-app/house-master/house-life/static/img/index/cover_2022/.keep


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover1.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover2.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover3.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/cover_2022/index_cover4.png


二进制
AyaoJies-app/house-master/house-life/static/img/index/swiper/swiper.jpg


二进制
AyaoJies-app/house-master/house-life/static/img/index/swiper/swiper2.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/1.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/10.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/11.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/12.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/13.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/14.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/15.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/16.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/17.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/18.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/19.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/2.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/20.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/21.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/22.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/23.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/24.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/25.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/26.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/27.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/28.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/29.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/3.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/30.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/31.png


二进制
AyaoJies-app/house-master/house-life/static/img/likeFx/32.png


部分文件因为文件数量过多而无法显示