Files
RentWeAppFront/pages/index/index.vue

819 lines
21 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view class="index">
<image src="/static/index/index_bg.png" mode="aspectFill" class="bg"></image>
<!-- 搜索栏 -->
<view class="index-title">
启辰资产
</view>
<view class="content-wrapper">
<view class="search-wrapper">
<search-bar :city="vuex_city==''?'选择':vuex_city" placeholder="你想住在哪儿" @chooseCity="location"
@search="search" />
</view>
<!-- 房源信息导航栏 -->
<view class="nav-area">
<view class="rowClass">
<u-row>
<u-col span="3" text-align="center" v-for="(item,index) in navList" :key="index">
<view class="u-padding-20" @tap="clickNav(item, index)" hover-class="hoverClass">
<image :src="item.src" style="width: 86rpx;height: 86rpx;" mode="heightFix"></image>
<view class="tabName" :style="{color:'#FFFFFF'}">{{item.name}}</view>
</view>
</u-col>
</u-row>
</view>
<view class="rowClass navbox2">
<u-row>
<u-col span="3" text-align="center" v-for="(item,index) in gridList" :key="index">
<view class="u-padding-20" @tap="clickGrid(item)" hover-class="hoverClass">
<image :src="item.src" style="width: 50rpx;height: 50rpx;" mode="heightFix"></image>
<view class="tabName" :style="{color:'#222222'}">{{item.name}}</view>
</view>
</u-col>
</u-row>
</view>
</view>
<u-gap height="10"></u-gap>
<!-- 公告栏 -->
<view @click="notice" class="noticeStyle">
<image src="/static/index/公告.png" style="width: 38rpx;height: 37rpx;margin-left: 22rpx;"></image>
<view class="notice-content">
<u-notice-bar mode="vertical" :list="noticeList" type="primary" more-icon bg-color="none"
:duration="5000" :fontSize="30" color="#2D2B2C" :volumeIcon="false"></u-notice-bar>
</view>
</view>
<u-gap height="5"></u-gap>
<view class="tab-content">
<!-- 顶部标签栏 -->
<view class="recommend-tabs">
<view
class="tab-item"
:class="{ active: activeRecommendTab === index }"
v-for="(tab, index) in recommendTabs"
:key="index"
@click="onRecommendTabClick(index)"
>
{{ tab }}
</view>
</view>
<!-- 筛选标签 -->
<view class="filter-tabs">
<view
class="filter-item"
:class="{ active: activeFilterTabs.includes(index) }"
v-for="(tab, index) in filterTabs"
:key="index"
@click="onFilterTabClick(index)"
>
{{ tab }}
</view>
</view>
<scroll-view scroll-y style="height: calc(100vh - 200rpx);" :scroll-top="scrollTop" @scrolltolower="findHouseList"
lower-threshold="50">
<u-waterfall v-model="flowList" ref="uWaterfall">
<template v-slot:left="{leftList}">
<view class="demo-warter" v-for="(item, index) in leftList" :key="index"
style="margin-right: 10rpx;">
<u-lazy-load threshold="750" border-radius="8" :image="item.image"
:index="index" mode="aspectFill" @click="clickImage(item.id)"></u-lazy-load>
<view class="item-title">{{ item.assetsName}}</view>
<view class="item-desc">{{ item.footPrint}} {{ item.propertyType || '商业用房' }}</view>
<view class="item-price">¥{{item.rentFee}}/<text></text></view>
</view>
</template>
<template v-slot:right="{rightList}">
<view class="demo-warter" v-for="(item, index) in rightList" :key="index"
style="margin-left: 10rpx;">
<u-lazy-load threshold="750" border-radius="8" :image="item.image"
:index="index" mode="aspectFill" @click="clickImage(item.id)"></u-lazy-load>
<view class="item-title">{{ item.assetsName}}</view>
<view class="item-desc">{{ item.footPrint}} {{ item.propertyType || '商业用房' }}</view>
<view class="item-price">¥{{item.rentFee}}/<text></text></view>
</view>
</template>
</u-waterfall>
</scroll-view>
</view>
<u-back-top :scroll-top="scrollTop" top="1000"></u-back-top>
<u-no-network></u-no-network>
</view>
<u-popup v-model="showFillAuthInfo" mode="center" :mask-close-able="false" border-radius="24">
<view class="auth-popup">
<!-- 标题 -->
<view class="auth-title">
请完善{{authLabel}}信息
</view>
<!-- 描述 -->
<view class="auth-desc">
您当前尚未完善相关信息为避免影响后续功能使用请尽快补充
</view>
<!-- 输入区域 -->
<view class="auth-input">
<u-input v-model="authCode" :placeholder="authPlaceholder" clearable border="bottom" font-size="30"
placeholder-style="color:#bbb" />
</view>
<!-- 按钮 -->
<button class="auth-btn" @click="recordAuthInfo">
提交
</button>
</view>
</u-popup>
</view>
</template>
<script>
import SearchBar from '../../components/searchBar/SearchBar.vue';
import indexNavbarVue from '../../components/navbar/indexNavbar.vue';
export default {
components: {
SearchBar,
indexNavbarVue
},
data() {
return {
loginType: null,
authCode: '', // 身份证号 / 社会信用代码
showFillAuthInfo: false,
keyword: '',
pageNum: 1,
pageSize: 20,
scrollTop: 0,
houseList: [],
activeIndex: 0, // 当前选中的索引
swiperList: [{
image: '/static/img/index/swiper/swiper3.jpg',
title: '身无彩凤双飞翼,心有灵犀一点通'
},
{
image: '/static/img/index/swiper/swiper.jpg',
title: '身无彩凤双飞翼,心有灵犀一点通'
},
],
noticeList: [
'景秀天成新上优质房源,欢迎咨询',
'限时优惠活动租房立减500元',
'新用户注册即送200元租房券',
'寒雨连江夜入吴'
],
navList: [{
name: "住房",
src: "/static/index/住房.png",
type: "0",
underline_color: "linear-gradient(to right, #ff8c00, #ffcc33)"
},
{
name: "商铺",
src: "/static/index/商铺.png",
type: "1",
underline_color: "linear-gradient(to right, #89CFF0, #5AA4D1)"
},
{
name: "厂房",
src: "/static/index/厂房.png",
url: "/pages/center/tips",
underline_color: "linear-gradient(to right, #0000FF, #800080)"
},
{
name: "停车场",
src: "/static/index/停车场.png",
type: "2",
underline_color: "linear-gradient(to bottom, #000080, #00008080)"
}
],
gridList: [{
name: "看房预约",
src: "/static/index/看房预约.png",
url: "pages/reserve/reserveRecords"
},
{
name: "合同签约",
src: "/static/index/合同签约.png",
url: "pages/center/contract"
},
{
name: "退租申请",
src: "/static/index/退租申请.png",
url: "pages/form/leaseCancel"
},
{
name: "留言板",
src: "/static/index/留言板.png",
url: "pages/form/leaseCancel"
}
],
loadStatus: 'loadmore',
// 顶部标签栏状态
activeRecommendTab: 0,
recommendTabs: ['为您推荐', '附近', '上新'],
// 筛选标签状态
activeFilterTabs: [0], // 支持多选
filterTabs: ['上新', '整租', '一室一厅'],
flowList: [
{ id: 1, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 2, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 3, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 4, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 5, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 6, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 7, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 8, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 9, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' },
{ id: 10, assetsName: '景秀天成保租房景秀天成保租房', footPrint: 105, rentFee: 1500, image: '/static/img/index/swiper/swiper3.jpg', propertyType: '商业用房' }
],
uvCode: uni.getStorageSync('uvCode')
}
},
onLoad() {
// 自动定位到所在的城市
// this.checkCity();
// 获取数据
// this.findHouseList();
// this.getNoticecList();
// 流量统计
// this.appSysFlowInfo();
// uni.$on('findIndexHouseList', (obj) => {
// // 获取数据
// this.findHouseList(1);
// })
},
onShow() {
this.needFillAuthInfo();
},
onUnload() {
// 移除监听事件
uni.$off('findIndexHouseList');
},
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
onReachBottom() {
this.loadStatus = 'loading';
// 获取数据
this.findHouseList()
},
// 下拉刷新
onPullDownRefresh() {
// 获取数据
this.findHouseList(1);
// 关闭刷新
uni.stopPullDownRefresh();
},
mounted() {
},
computed: {
authLabel() {
return this.loginType === 'person' ?
'身份证号' :
'企业社会信用代码'
},
authPlaceholder() {
return this.loginType === 'person' ?
'请输入身份证号' :
'请输入企业社会信用代码'
}
},
methods: {
// 顶部推荐标签点击事件
onRecommendTabClick(index) {
this.activeRecommendTab = index;
// 这里可以添加根据标签筛选数据的逻辑
console.log('推荐标签点击:', this.recommendTabs[index]);
// 重置筛选条件
this.activeFilterTabs = [0];
// 重新加载数据
this.pageNum = 1;
this.flowList = [];
this.findHouseList(1);
},
// 筛选标签点击事件
onFilterTabClick(index) {
// 检查是否已选中
const isActive = this.activeFilterTabs.includes(index);
if (isActive) {
// 如果已选中,则移除
this.activeFilterTabs = this.activeFilterTabs.filter(item => item !== index);
} else {
// 如果未选中,则添加
this.activeFilterTabs.push(index);
}
// 这里可以添加根据筛选标签筛选数据的逻辑
console.log('筛选标签点击:', this.filterTabs[index]);
console.log('当前选中的筛选标签:', this.activeFilterTabs.map(i => this.filterTabs[i]));
},
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');
}
},
// 简单身份证校验18 位)
checkIdCard(code) {
return /^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$/.test(
code
);
},
// 统一社会信用代码校验18 位)
checkCreditCode(code) {
return /^[0-9A-Z]{18}$/.test(code);
},
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 = "/assets/findAssetList";
this.$u.post(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.data.result;
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
// }
this.flowList.push(item);
}
++this.pageNum
this.loadStatus = 'loadmore';
}).catch(err => {
console.log("失败:", err)
})
},
clickSearch() {
this.$u.route('/pages/search/search');
},
clickImage(houseId) {
this.$u.route({
url: '/pages/detail/assetsDetail'
})
// this.$u.route({
// url: '/pages/detail/detail',
// params: {
// houseId: houseId
// }
// })
},
clickNav(item, index) {
this.activeIndex = index;
this.findHouseList(item.type);
},
clickGrid(item) {
console.log('跳转我的预约,url:' + item.url)
this.$u.route({
url: item.url
})
},
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 = "/notice/findNoticeList";
this.$u.get(url, {
pageNum: 1,
pageSize: 50,
orderByColumn: 'create_time',
isAsc: 'desc'
}).then(obj => {
let data = obj.data.result
data.filter(item => {
this.noticeList.push(item.noticeTitle)
})
});
},
needFillAuthInfo() {
let lifeData = uni.getStorageSync('lifeData');
let token = lifeData.vuex_token
if (!token || token === null || token === undefined ||
(typeof token === 'object' && Object.keys(token).length === 0)) {
return;
}
let url = "/login/needFillAuthInfo";
this.$u.get(url, {}, {
'WT': token
}).then(obj => {
console.log(obj.data)
if (obj.data) {
this.showFillAuthInfo = obj.data
const indexParam = uni.getStorageSync('indexParam') || {}
this.loginType = indexParam.loginType || 'person'
}
});
},
moreInfo() {
uni.navigateToMiniProgram({
appId: 'wxbca64173e772915e', // 此为开源字节appid
path: '/pages/index/index', // 此为开源字节首页路径
envVersion: "release",
success: res => {
// 打开成功
console.log("打开成功", res);
},
fail: err => {
console.log(err);
}
})
},
recordAuthInfo() {
// 身份证校验
if (this.loginType === 'person' && !this.checkIdCard(this.authCode)) {
uni.showToast({
title: '身份证号格式不正确',
icon: 'none'
});
return;
}
// 企业社会信用代码校验
if (this.loginType === 'company' && !this.checkCreditCode(this.authCode)) {
uni.showToast({
title: '社会信用代码格式不正确',
icon: 'none'
});
return;
}
let lifeData = uni.getStorageSync('lifeData');
let token = lifeData.vuex_token
if (!token || token === null || token === undefined ||
(typeof token === 'object' && Object.keys(token).length === 0)) {
return;
}
let url = "/login/recordAuthInfo";
this.$u.post(url, {
code: this.authCode,
userType: this.loginType,
}, {
'WT': token
}).then(obj => {
if (obj.flag) {
this.showFillAuthInfo = false;
this.authCode = '';
}
})
}
}
}
</script>
<style lang="scss" scoped>
.index {
background: #F8F8F8;
min-height: 100vh; // 防止内容少时顶部空白
position: relative;
}
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 550rpx;
/* ✅ 用固定高度更稳,你可改 320/400 */
z-index: 0;
}
.index-title {
position: absolute;
z-index: 1;
top: 5%;
left: 50%;
transform: translateX(-50%);
transform: translateX(-50%);
font-family: Noto Sans S Chinese;
font-weight: 400;
font-size: 34rpx;
color: #FFFFFF;
}
.content-wrapper {
position: relative;
z-index: 1;
}
.search-wrapper {}
.content-wrapper {
padding: 197rpx 30rpx 22rpx 30rpx; // 统一左右内边距
}
.navbox2 {
height: 170rpx;
padding-top: 2%;
background: #FFFFFF;
border-radius: 10rpx;
}
.nomore {
background-color: $u-bg-color;
}
.noticeStyle {
display: flex;
margin-top: 22rpx;
height: 86rpx;
background-color: #FFFFFF;
border-radius: 10rpx;
align-items: center;
}
.notice-content {
flex: 1;
}
/* 下划线 */
.underline {
margin-top: 5rpx;
width: 130rpx;
height: 6rpx;
border-radius: 5rpx;
transition: all 0.25s ease;
}
.rowClass {
margin-top: 20rpx;
}
.rowBgColor {
background-color: rgb(248, 248, 248);
}
.leftOffSetRow {
margin-left: 20%;
}
.hoverClass {
background-color: #E4E7ED;
}
.tabName {
font-size: 28rpx;
}
.u-close {
position: absolute;
top: 20rpx;
right: 20rpx;
}
.item-cover {
font-size: 55rpx;
color: $u-type-warning;
}
.item-tag {
font-size: 24rpx;
color: $u-tips-color;
margin-top: 3px;
}
.tab-content {
padding: 0 20rpx;
margin-top: 22rpx;
background: #fff;
}
/* 顶部标签栏样式 */
.recommend-tabs {
display: flex;
justify-content: flex-start;
padding: 20rpx 0;
background: #fff;
font-size: 32rpx;
font-weight: 600;
}
.tab-item {
margin-right: 40rpx;
padding: 10rpx 0;
color: #333;
}
.tab-item.active {
color: #FF2F31;
border-bottom: 4rpx solid #FF2F31;
}
/* 筛选标签样式 */
.filter-tabs {
display: flex;
justify-content: flex-start;
padding: 0 0 20rpx 0;
background: #fff;
flex-wrap: wrap;
}
.filter-item {
margin-right: 20rpx;
margin-bottom: 10rpx;
padding: 12rpx 24rpx;
background: #f5f5f5;
border-radius: 20rpx;
font-size: 26rpx;
color: #666;
}
.filter-item.active {
background: #FFECEC;
color: #FF2F31;
}
.demo-warter {
margin-bottom: 20rpx;
// background: #fff;
// border-radius: 8rpx;
overflow: hidden;
// box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
}
.u-waterfall {
padding: 0 20rpx;
/* 左右留白一致 */
}
/* 图片样式 */
.u-lazy-load {
width: 100%;
height: 300rpx;
}
.item-title {
font-size: 28rpx;
font-weight: 600;
margin-top: 14rpx;
padding: 0 10rpx;
color: #333;
line-height: 40rpx;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.item-price {
font-size: 32rpx;
color: #FF2F31;
margin-bottom: 10rpx;
}
.item-price text {
font-size: 24rpx;
}
.item-desc {
font-weight: normal;
font-size: 24rpx;
color: #999;
}
.item-desc,
.item-price {
padding: 0 10rpx;
margin-top: 8rpx;
}
.auth-popup {
width: 600rpx;
padding: 48rpx 40rpx 40rpx;
background-color: #fff;
border-radius: 24rpx;
box-sizing: border-box;
}
/* 标题 */
.auth-title {
font-size: 34rpx;
font-weight: 600;
color: #1a1a1a;
text-align: center;
margin-bottom: 20rpx;
}
/* 描述 */
.auth-desc {
font-size: 26rpx;
color: #888;
text-align: center;
line-height: 1.6;
margin-bottom: 40rpx;
}
/* 输入区域 */
.auth-input {
margin-bottom: 48rpx;
::v-deep .u-input {
padding-bottom: 12rpx;
}
}
/* 提交按钮 */
.auth-btn {
width: 100%;
height: 88rpx;
line-height: 88rpx;
background: linear-gradient(135deg, #FF2F31, #FF9379);
color: #fff;
font-size: 30rpx;
font-weight: 500;
border-radius: 44rpx;
border: none;
box-shadow: 0 10rpx 24rpx rgba(41, 121, 255, 0.3);
}
/* 按压效果 */
.auth-btn:active {
opacity: 0.85;
}
.buttom {
.loginType {
font-size: 14px;
position: fixed;
right: 30rpx;
bottom: 300rpx;
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>