mirror of
http://36.133.248.69:3088/admin/RentWeAppFront.git
synced 2026-06-07 14:32:27 +08:00
优化,完善代码
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// 全局配置文件
|
||||
// let baseUrl = 'http://219.138.32.164:8089';
|
||||
// let baseUrl = 'http://localhost:3000/api';
|
||||
// let staticUrl = 'http://localhost:3000';
|
||||
// let baseUrl = 'http://localhost:8089';
|
||||
// let staticUrl = 'http://localhost:3080';
|
||||
let baseUrl = 'https://www.wujiaguotou.com/api';
|
||||
let staticUrl = 'https://www.wujiaguotou.com';
|
||||
// 版本号 用于更新
|
||||
|
||||
@@ -5,21 +5,18 @@ const install = (Vue, vm) => {
|
||||
Vue.prototype.$u.http.setConfig({
|
||||
// baseUrl打包app时放开,h5模式下会和vue.config.js代理冲突,导致失效
|
||||
baseUrl: config.baseUrl,
|
||||
originalData:true,
|
||||
originalData: true,
|
||||
timeout: 10000,
|
||||
});
|
||||
// 请求拦截,配置Token等参数
|
||||
Vue.prototype.$u.http.interceptor.request = (config) => {
|
||||
// config.header.Token = '5d33018e653d897fc259b42cf022c1b3';
|
||||
// 方式一,存放在vuex的token,假设使用了uView封装的vuex方式,见:https://uviewui.com/components/globalVariable.html
|
||||
// 自定义token头
|
||||
// 1️⃣ 获取本地 userInfo
|
||||
const userInfo = uni.getStorageSync('userInfo') || {};
|
||||
|
||||
// 2️⃣ 提取 userType
|
||||
const userType = userInfo.userType;
|
||||
config.header = {
|
||||
...config.header, // ⭐ 保留你外部传入的 header
|
||||
...config.header, // ⭐ 保留外部传入的 header
|
||||
'content-type': 'application/json',
|
||||
...(userType ? { 'USERTYPE': userType } : {}) // 有 userType 才加
|
||||
}
|
||||
@@ -34,17 +31,19 @@ const install = (Vue, vm) => {
|
||||
} else if(res.statusCode == 301) {
|
||||
vm.$u.toast('警告:' + res.msg);
|
||||
return false;
|
||||
} else if(res.statusCode == 401) {
|
||||
} else if(res.statusCode == 401 || res.statusCode == 403) {
|
||||
const currentPage = vm.$route.path;
|
||||
// 判断当前页面是否为登录页
|
||||
// 登录成功修改token与用户信息
|
||||
vm.$u.vuex('vuex_token', '');
|
||||
vm.$u.vuex('vuex_user', {});
|
||||
uni.removeStorageSync('userInfo');
|
||||
if (currentPage !== '/pages-biz/login/login') {
|
||||
uni.navigateTo({
|
||||
url:'/pages-biz/login/login'
|
||||
})
|
||||
vm.$u.toast('认证失败,请重新登录')
|
||||
return false;
|
||||
} else if(res.statusCode == 403) {
|
||||
uni.navigateTo({
|
||||
url:'/pages-biz/login/login'
|
||||
})
|
||||
vm.$u.toast('认证失败,请重新登录')
|
||||
url: '/pages-biz/login/login'
|
||||
});
|
||||
vm.$u.toast('认证失败,请重新登录');
|
||||
}
|
||||
return false;
|
||||
} else if(res.statusCode == 500) {
|
||||
vm.$u.toast('请求错误:' + res.msg);
|
||||
@@ -56,17 +55,15 @@ const install = (Vue, vm) => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 请求错误拦截(超时/网络异常)
|
||||
Vue.prototype.$u.http.interceptor.responseError = (err) => {
|
||||
// err 是 uni.request 的 fail 对象
|
||||
// 超时一般是 err.errMsg 包含 timeout
|
||||
|
||||
if (err.errMsg && err.errMsg.includes('timeout')) {
|
||||
vm.$u.toast('请求超时,请稍后重试');
|
||||
} else {
|
||||
vm.$u.toast('网络异常,请检查网络');
|
||||
}
|
||||
|
||||
return Promise.reject(err);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -46,40 +46,40 @@ export default [
|
||||
// },
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
"name": '租金',
|
||||
"type": 'hierarchy',
|
||||
"submenu": [
|
||||
{
|
||||
"name": "不限",
|
||||
"value": ""
|
||||
},
|
||||
{
|
||||
"name": "<1000元",
|
||||
"value": "0-1000"
|
||||
},
|
||||
{
|
||||
"name": "1000-1500元",
|
||||
"value": "1000-1500"
|
||||
},
|
||||
{
|
||||
"name": "1500-2000元",
|
||||
"value": "1500-2000"
|
||||
},
|
||||
{
|
||||
"name": "2000-3000元",
|
||||
"value": "2000-3000"
|
||||
},
|
||||
{
|
||||
"name": "3000-4500元",
|
||||
"value": "3000-4500"
|
||||
},
|
||||
{
|
||||
"name": ">4500元",
|
||||
"value": "4500"
|
||||
}
|
||||
]
|
||||
},
|
||||
// {
|
||||
// "name": '租金',
|
||||
// "type": 'hierarchy',
|
||||
// "submenu": [
|
||||
// {
|
||||
// "name": "不限",
|
||||
// "value": ""
|
||||
// },
|
||||
// {
|
||||
// "name": "<1000元",
|
||||
// "value": "0-1000"
|
||||
// },
|
||||
// {
|
||||
// "name": "1000-1500元",
|
||||
// "value": "1000-1500"
|
||||
// },
|
||||
// {
|
||||
// "name": "1500-2000元",
|
||||
// "value": "1500-2000"
|
||||
// },
|
||||
// {
|
||||
// "name": "2000-3000元",
|
||||
// "value": "2000-3000"
|
||||
// },
|
||||
// {
|
||||
// "name": "3000-4500元",
|
||||
// "value": "3000-4500"
|
||||
// },
|
||||
// {
|
||||
// "name": ">4500元",
|
||||
// "value": "4500"
|
||||
// }
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
"name": '筛选',
|
||||
"type": 'radio',
|
||||
@@ -110,11 +110,11 @@ export default [
|
||||
"submenu": [
|
||||
{
|
||||
"name": "简装",
|
||||
"value": "简装",
|
||||
"value": "简装"
|
||||
},
|
||||
{
|
||||
"name": "中装",
|
||||
"value": "中装",
|
||||
"value": "中装"
|
||||
},
|
||||
{
|
||||
"name": "精修",
|
||||
|
||||
@@ -1,51 +1,55 @@
|
||||
<template>
|
||||
<view class="carousel" :style="{width:boxWidth,height:boxHeight}" @touchstart="touchStart" @touchmove="touchMove"
|
||||
@touchend="touchEnd">
|
||||
<!-- 轮播轨道 -->
|
||||
<view class="track" :style="trackStyle">
|
||||
<view class="slide" v-for="(item, index) in normalizedList" :key="index">
|
||||
<view class="carousel" :style="{width: boxWidth, height: boxHeight}">
|
||||
<!-- Swiper 轮播 -->
|
||||
<swiper :current="current" :autoplay="autoplay ? interval : 0" :interval="interval" :circular="true"
|
||||
:indicator-dots="false" :display-multiple-items="1" @change="onSwiperChange" class="swiper-container">
|
||||
<swiper-item v-for="(item, index) in normalizedList" :key="index" class="slide">
|
||||
<!-- 图片 -->
|
||||
<image v-if="item.mediaType === 'image'" :src="item.src" mode="aspectFill" />
|
||||
<image v-if="item.mediaType==='image'" :src="item.src"
|
||||
:class="['img', imageModeMap[index]==='contain'?'vertical':'']" @load="onImageLoad($event,index)"
|
||||
@tap="onImageTap(index)" />
|
||||
|
||||
<!-- 视频 -->
|
||||
<view v-else-if="item.mediaType === 'video'" class="video-wrapper" @click.stop="playVideo(index)">
|
||||
<video :id="'video-' + index" :src="item.src" :poster="item.poster"
|
||||
:controls="playingIndex === index" :show-center-play-btn="false" object-fit="cover"
|
||||
@play="onVideoPlay" @pause="onVideoPause" />
|
||||
<view v-if="playingIndex !== index" class="play-btn">▶</view>
|
||||
<view v-else-if="item.mediaType==='video'" class="video-wrapper" @click.stop="playVideo(index)">
|
||||
<video :id="'video-'+index" :src="item.src" :poster="item.poster" :controls="playingIndex===index"
|
||||
:show-center-play-btn="false" object-fit="cover" @play="onVideoPlay" @pause="onVideoPause"
|
||||
class="video" />
|
||||
<view v-if="playingIndex!==index" class="play-btn">▶</view>
|
||||
</view>
|
||||
|
||||
<!-- VR -->
|
||||
<view v-else-if="item.mediaType === 'vr'" class="vr-wrapper">
|
||||
<image class="vr-cover" :src="item.src" mode="aspectFill" />
|
||||
<image class="vr-icon" mode="aspectFit" :src="vrIcon" @tap.stop="enterVR()" />
|
||||
</view>
|
||||
<view v-else-if="item.mediaType==='vr'" class="vr-wrapper">
|
||||
<image class="vr-cover" :src="item.src" mode="aspectFit" />
|
||||
<image class="vr-icon" :src="vrIcon" mode="aspectFit" @tap.stop="enterVR()" />
|
||||
</view>
|
||||
</swiper-item>
|
||||
</swiper>
|
||||
|
||||
<!-- 自定义点指示器 -->
|
||||
<view v-if="indicator==='dot'" class="dots">
|
||||
<view v-for="(item,index) in normalizedList" :key="index" class="dot" :class="{active:index===current}" />
|
||||
</view>
|
||||
|
||||
<!-- 点指示器 -->
|
||||
<view v-if="indicator === 'dot'" class="dots">
|
||||
<view v-for="(item, index) in normalizedList" :key="index" class="dot"
|
||||
:class="{ active: index === current }" />
|
||||
</view>
|
||||
<!-- 自定义箭头 -->
|
||||
<view v-if="indicator==='arrow'" class="arrow left" @click.stop="prev">‹</view>
|
||||
<view v-if="indicator==='arrow'" class="arrow right" @click.stop="next">›</view>
|
||||
|
||||
<!-- 箭头指示器 -->
|
||||
<view v-if="indicator === 'arrow'" class="arrow left" @click.stop="prev">‹</view>
|
||||
<view v-if="indicator === 'arrow'" class="arrow right" @click.stop="next">›</view>
|
||||
|
||||
<!-- 底部分区长条指示器(固定分区长度,跳动游标) -->
|
||||
<!-- 底部分区指示器 -->
|
||||
<view v-if="autoTypeIndicateList.length" class="type-bar">
|
||||
<view v-for="(item, index) in autoTypeIndicateList" :key="index" class="type-segment"
|
||||
:class="{ active: current >= item.startIndex && current <= item.endIndex }"
|
||||
:style="{ width: getSegmentWidth + '%' }" @click.stop="jumpToType(item)">
|
||||
{{ item.name }}
|
||||
<view v-for="(item,index) in autoTypeIndicateList" :key="index" class="type-segment"
|
||||
:class="{active:current>=item.startIndex && current<=item.endIndex}"
|
||||
:style="{width:getSegmentWidth+'%'}" @click.stop="jumpToType(item)">
|
||||
{{item.name}}
|
||||
</view>
|
||||
</view>
|
||||
<!-- 右下角索引 -->
|
||||
<view class="index-display">
|
||||
{{ current + 1 }} / {{ normalizedList.length }}
|
||||
</view>
|
||||
|
||||
<!-- 右下角索引 -->
|
||||
<view class="index-display">{{current+1}} / {{normalizedList.length}}</view>
|
||||
|
||||
<!-- 双击放大 -->
|
||||
<view v-if="zoomed" class="zoom-overlay" @tap="zoomed=false">
|
||||
<image :src="zoomSrc" mode="widthFix" class="zoom-img" />
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -56,7 +60,7 @@
|
||||
list: {
|
||||
type: Array,
|
||||
required: true
|
||||
}, // [{src:'',type:''}]
|
||||
},
|
||||
indicator: {
|
||||
type: String,
|
||||
default: 'dot'
|
||||
@@ -93,38 +97,26 @@
|
||||
data() {
|
||||
return {
|
||||
current: 0,
|
||||
containerWidth: 0,
|
||||
startX: 0,
|
||||
offsetX: 0,
|
||||
timer: null,
|
||||
playingIndex: null
|
||||
playingIndex: null,
|
||||
imageModeMap: {},
|
||||
zoomed: false,
|
||||
zoomSrc: '',
|
||||
lastTap: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
/* VR 永远在最前 */
|
||||
normalizedList() {
|
||||
const vr = []
|
||||
const other = []
|
||||
this.list.forEach(item => {
|
||||
item.mediaType === 'vr' ? vr.push(item) : other.push(item)
|
||||
})
|
||||
const vr = [],
|
||||
other = []
|
||||
this.list.forEach(item => item.mediaType === 'vr' ? vr.push(item) : other.push(item))
|
||||
return [...vr, ...other]
|
||||
},
|
||||
|
||||
trackStyle() {
|
||||
return `width:${this.normalizedList.length * this.containerWidth}px;
|
||||
transform: translate3d(${-this.current * this.containerWidth + this.offsetX}px,0,0);
|
||||
transition:${this.offsetX === 0 ? 'transform .3s' : 'none'};`
|
||||
},
|
||||
|
||||
/* 自动生成分区指示 */
|
||||
autoTypeIndicateList() {
|
||||
const list = this.normalizedList
|
||||
if (!list.length) return []
|
||||
|
||||
const result = []
|
||||
let startIndex = 0
|
||||
let bizType = list[0].bizType
|
||||
let startIndex = 0,
|
||||
bizType = list[0].bizType
|
||||
for (let i = 1; i <= list.length; i++) {
|
||||
if (i === list.length || list[i].bizType !== bizType) {
|
||||
result.push({
|
||||
@@ -140,77 +132,38 @@
|
||||
return result
|
||||
},
|
||||
getSegmentWidth() {
|
||||
if (!this.autoTypeIndicateList.length) return 100
|
||||
return 100 / this.autoTypeIndicateList.length
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(this.calcWidth)
|
||||
this.start()
|
||||
},
|
||||
beforeUnmount() {
|
||||
this.stop()
|
||||
},
|
||||
onLoad() {},
|
||||
watch: {
|
||||
normalizedList(list) {
|
||||
if (this.current >= list.length) this.current = 0
|
||||
},
|
||||
current() {
|
||||
this.stopVideo()
|
||||
return this.autoTypeIndicateList.length ? 100 / this.autoTypeIndicateList.length : 100
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
calcWidth() {
|
||||
uni.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.carousel')
|
||||
.boundingClientRect(rect => {
|
||||
if (rect) this.containerWidth = rect.width
|
||||
})
|
||||
.exec()
|
||||
onSwiperChange(e) {
|
||||
this.current = e.detail.current
|
||||
this.stopVideo()
|
||||
},
|
||||
|
||||
start() {
|
||||
if (!this.autoplay) return
|
||||
this.stop()
|
||||
this.timer = setInterval(this.next, this.interval)
|
||||
// 图片模式判断
|
||||
onImageLoad(e, index) {
|
||||
const {
|
||||
width,
|
||||
height
|
||||
} = e.detail
|
||||
if (!width || !height) return
|
||||
this.$set(this.imageModeMap, index, width >= height ? 'cover' : 'contain')
|
||||
},
|
||||
stop() {
|
||||
this.timer && clearInterval(this.timer)
|
||||
this.timer = null
|
||||
},
|
||||
next() {
|
||||
this.current = (this.current + 1) % this.normalizedList.length
|
||||
},
|
||||
prev() {
|
||||
this.current = (this.current - 1 + this.normalizedList.length) % this.normalizedList.length
|
||||
},
|
||||
|
||||
touchStart(e) {
|
||||
this.stop()
|
||||
this.startX = e.touches[0].clientX
|
||||
},
|
||||
touchMove(e) {
|
||||
this.offsetX = e.touches[0].clientX - this.startX
|
||||
},
|
||||
touchEnd() {
|
||||
if (Math.abs(this.offsetX) > this.containerWidth / 4) {
|
||||
this.offsetX > 0 ? this.prev() : this.next()
|
||||
// 双击放大
|
||||
onImageTap(index) {
|
||||
const now = new Date().getTime()
|
||||
if (now - this.lastTap < 300) {
|
||||
this.zoomed = true
|
||||
this.zoomSrc = this.normalizedList[index].src
|
||||
}
|
||||
this.offsetX = 0
|
||||
this.start()
|
||||
this.lastTap = now
|
||||
},
|
||||
|
||||
/* 视频 */
|
||||
// 视频
|
||||
playVideo(index) {
|
||||
if (this.playingIndex === index) return
|
||||
this.stopVideo()
|
||||
this.playingIndex = index
|
||||
this.stop()
|
||||
this.$nextTick(() => {
|
||||
uni.createVideoContext('video-' + index, this).play()
|
||||
})
|
||||
},
|
||||
stopVideo() {
|
||||
if (this.playingIndex !== null) {
|
||||
@@ -218,31 +171,30 @@
|
||||
this.playingIndex = null
|
||||
}
|
||||
},
|
||||
onVideoPlay() {
|
||||
this.stop()
|
||||
},
|
||||
onVideoPause() {
|
||||
this.start()
|
||||
},
|
||||
|
||||
/* VR */
|
||||
onVideoPlay() {},
|
||||
onVideoPause() {},
|
||||
// VR
|
||||
enterVR() {
|
||||
this.stop()
|
||||
this.stopVideo()
|
||||
this.$u.route({
|
||||
url: this.vrViewPage,
|
||||
params: {
|
||||
title: "vr看资产",
|
||||
title: 'vr看资产',
|
||||
id: this.assetsId
|
||||
}
|
||||
})
|
||||
},
|
||||
/* 分区跳转 */
|
||||
// 分区跳转
|
||||
jumpToType(item) {
|
||||
this.stop()
|
||||
this.stopVideo()
|
||||
this.current = item.startIndex
|
||||
this.$nextTick(this.start)
|
||||
},
|
||||
prev() {
|
||||
const len = this.normalizedList.length
|
||||
this.current = (this.current - 1 + len) % len
|
||||
},
|
||||
next() {
|
||||
const len = this.normalizedList.length
|
||||
this.current = (this.current + 1) % len
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,28 +202,77 @@
|
||||
|
||||
<style scoped>
|
||||
.carousel {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.track {
|
||||
display: flex;
|
||||
.swiper-container,
|
||||
swiper-item {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.slide {
|
||||
width: 100%;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.slide image,
|
||||
.video-wrapper,
|
||||
.vr-wrapper,
|
||||
video {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.img.vertical {
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.video-wrapper {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
.vr-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.vr-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 12%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
background: rgba(80, 80, 80, 0.45);
|
||||
border-radius: 50%;
|
||||
padding: 12rpx;
|
||||
}
|
||||
|
||||
/* dots */
|
||||
.dots {
|
||||
position: absolute;
|
||||
@@ -285,7 +286,7 @@
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
border-radius: 50%;
|
||||
background: rgba(255, 255, 255, .5);
|
||||
background: rgba(255, 255, 255, 0.5);
|
||||
margin: 0 6rpx;
|
||||
}
|
||||
|
||||
@@ -302,7 +303,7 @@
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
text-align: center;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
border-radius: 50%;
|
||||
@@ -316,62 +317,25 @@
|
||||
right: 20rpx;
|
||||
}
|
||||
|
||||
/* video */
|
||||
.video-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.play-btn {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
text-align: center;
|
||||
border-radius: 50%;
|
||||
background: rgba(0, 0, 0, .5);
|
||||
color: #fff;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
|
||||
/* vr */
|
||||
.vr-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.vr-icon {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 12%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 100rpx !important;
|
||||
height: 100rpx !important;
|
||||
background: rgba(80, 80, 80, 0.45);
|
||||
border-radius: 50%;
|
||||
padding: 12rpx;
|
||||
}
|
||||
|
||||
/* type bar */
|
||||
.type-bar {
|
||||
position: absolute;
|
||||
bottom: 80rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
height: 40rpx;
|
||||
display: flex;
|
||||
height: 40rpx;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
overflow: hidden;
|
||||
min-width: 300rpx;
|
||||
overflow: hidden;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
|
||||
.type-segment {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
/* 保持文字白色 */
|
||||
font-size: 20rpx;
|
||||
cursor: pointer;
|
||||
padding: 0 10rpx;
|
||||
@@ -380,7 +344,6 @@
|
||||
|
||||
.type-segment.active {
|
||||
background: rgba(255, 47, 49, 0.6);
|
||||
/* 仅背景高亮,不覆盖文字 */
|
||||
}
|
||||
|
||||
.index-display {
|
||||
@@ -393,4 +356,23 @@
|
||||
font-size: 24rpx;
|
||||
border-radius: 12rpx;
|
||||
}
|
||||
|
||||
/* zoom */
|
||||
.zoom-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.zoom-img {
|
||||
max-width: 100%;
|
||||
max-height: 100%;
|
||||
}
|
||||
</style>
|
||||
@@ -85,7 +85,7 @@ export default {
|
||||
open(val) {
|
||||
this.visible = true;
|
||||
const currentYear = new Date().getFullYear();
|
||||
this.years = Array.from({ length: currentYear - 1980 + 1 }, (_, i) => 1980 + i);
|
||||
this.years = Array.from({ length: currentYear - 1980 + 11 }, (_, i) => 1980 + i);
|
||||
const date = val ? new Date(val) : new Date();
|
||||
const y = date.getFullYear();
|
||||
const m = date.getMonth() + 1;
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
<view class="container">
|
||||
<view class="basic-info">
|
||||
<view class="info-header">
|
||||
<view class="category-tag">{{ asset.type || '未知' }}</view>
|
||||
<view class="asset-name">{{ asset.name || '未知'}}</view>
|
||||
<view class="category-tag">{{ asset.type || '待维护' }}</view>
|
||||
<view class="asset-name">{{ asset.name || '待维护'}}</view>
|
||||
</view>
|
||||
<view class=" featureArea feature-list">
|
||||
<view class="feature-tag" v-for="(item, index) in asset.features" :key="index"
|
||||
@@ -26,15 +26,15 @@
|
||||
</view>
|
||||
<view class="stress-info">
|
||||
<view class="stress-item">
|
||||
<view class="stress-value">{{ asset.rent || '未知'}}/月</view>
|
||||
<view class="stress-value">{{ asset.rent ? asset.rent + '/月' : '面议'}}</view>
|
||||
<view class="stress-label">租金</view>
|
||||
</view>
|
||||
<view class="stress-item">
|
||||
<view class="stress-value">{{ asset.layout || '未知'}}</view>
|
||||
<view class="stress-value">{{ asset.layout || '待维护'}}</view>
|
||||
<view class="stress-label">户型</view>
|
||||
</view>
|
||||
<view class="stress-item">
|
||||
<view class="stress-value">{{ asset.area || '未知'}}㎡</view>
|
||||
<view class="stress-value">{{ asset.area || '待维护'}}㎡</view>
|
||||
<view class="stress-label">面积</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -49,17 +49,17 @@
|
||||
<view class="table-row">
|
||||
<view class="row-item">
|
||||
<view class="item-label">朝向</view>
|
||||
<view class="item-value">{{ asset.orientation || '未知'}}</view>
|
||||
<view class="item-value">{{ asset.orientation || '待维护'}}</view>
|
||||
</view>
|
||||
<view class="row-item">
|
||||
<view class="item-label">电梯</view>
|
||||
<view class="item-value">{{ asset.hasLift|| '未知' }}</view>
|
||||
<view class="item-value">{{ asset.hasLift|| '待维护' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-row">
|
||||
<view class="row-item">
|
||||
<view class="item-label">单元</view>
|
||||
<view class="item-value">{{ asset.unitNo || '未知'}}</view>
|
||||
<view class="item-value">{{ asset.unitNo || '待维护'}}</view>
|
||||
</view>
|
||||
<view class="row-item">
|
||||
<view class="item-label">楼层</view>
|
||||
@@ -69,19 +69,19 @@
|
||||
<view class="table-row">
|
||||
<view class="row-item full-width">
|
||||
<view class="item-label">门牌号</view>
|
||||
<view class="item-value">{{ asset.roomNo || '未知'}}</view>
|
||||
<view class="item-value">{{ asset.roomNo || '待维护'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-row">
|
||||
<view class="row-item full-width">
|
||||
<view class="item-label">资产描述</view>
|
||||
<view class="item-value">{{asset.remark || '未知'}}</view>
|
||||
<view class="item-value">{{asset.remark || '待维护'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-row">
|
||||
<view class="row-item full-width">
|
||||
<view class="item-label">商圈:</view>
|
||||
<view class="item-value">{{ asset.bizZone || '暂无'}}</view>
|
||||
<view class="item-value">{{ asset.bizZone || '待维护'}}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="table-row">
|
||||
@@ -166,7 +166,6 @@
|
||||
this.assetId = options.assetsNo;
|
||||
// 静态数据初始化
|
||||
this.loadAssetDetail();
|
||||
this.recordView();
|
||||
},
|
||||
mounted() {
|
||||
const navbar = this.$refs.navbar;
|
||||
@@ -234,7 +233,6 @@
|
||||
let url = `/assets/detail?id=${this.assetId}`
|
||||
this.$u.get(url).then(result => {
|
||||
const data = result.data
|
||||
console.log(data)
|
||||
this.asset = {
|
||||
name: data.assetsName,
|
||||
bizZone: data.bizZone,
|
||||
@@ -256,7 +254,7 @@
|
||||
vrImgs: data.vrImgs,
|
||||
remark: data.assetsDesc,
|
||||
status: data.assetsStatus,
|
||||
features: ['家电齐全']
|
||||
features: data.features
|
||||
};
|
||||
this.managerPhone = data.managerPhone
|
||||
this.markers = [{
|
||||
@@ -265,9 +263,11 @@
|
||||
longitude: this.asset.lng,
|
||||
title: this.asset.name,
|
||||
}, ];
|
||||
this.recordView(this.assetId);
|
||||
}).catch(err => {
|
||||
console.log("获取资产信息失败:", err)
|
||||
})
|
||||
|
||||
},
|
||||
formatMoney(num) {
|
||||
return Number(num).toLocaleString();
|
||||
@@ -313,10 +313,15 @@
|
||||
},
|
||||
recordView(assetId) {
|
||||
let token = this.$getToken()
|
||||
let userInfo = uni.getStorageSync('userInfo')
|
||||
if (token) {
|
||||
console.log(this.asset)
|
||||
let url = "/potential/add";
|
||||
this.$u.get(url, {
|
||||
assetId: this.assetId
|
||||
assetId: this.assetId,
|
||||
assetsName: this.asset.name,
|
||||
userType: userInfo.userType
|
||||
|
||||
}, {
|
||||
'WT': this.$getToken()
|
||||
}).then(obj => {
|
||||
|
||||
@@ -42,10 +42,9 @@
|
||||
<u-empty mode="list" text="暂无退租申请记录" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
<!-- 底部新增留言按钮 -->
|
||||
<!-- <view class="add-btn-container">
|
||||
<view class="add-btn-container">
|
||||
<button class="add-btn" @click="toApply()">新增退租申请</button>
|
||||
</view> -->
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -56,11 +55,19 @@
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
flowList: [],
|
||||
loadStatus: 'loadmore',
|
||||
isRefreshing: false
|
||||
loadStatus: 'more', // ✅ 只改这里
|
||||
isRefreshing: false,
|
||||
// 导航栏样式(你原来缺失,我补上)
|
||||
navbarStyle: {
|
||||
isTransparent: false,
|
||||
bgColor: '#ffffff',
|
||||
textColor: '#2D2B2C',
|
||||
opacity: 1
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 👇 你的方法 1 行没改
|
||||
statusText(status) {
|
||||
switch (status) {
|
||||
case '申请中':
|
||||
@@ -74,8 +81,8 @@
|
||||
return 'unknown';
|
||||
}
|
||||
},
|
||||
// 👇 你的方法 1 行没改
|
||||
formatDate(dateStr) {
|
||||
// 格式化日期,例如:2025-11-10 周五 09:00
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||
const year = date.getFullYear();
|
||||
@@ -84,11 +91,11 @@
|
||||
const weekday = weekdays[date.getDay()];
|
||||
const hours = String(date.getHours()).padStart(2, '0');
|
||||
const minutes = String(date.getMinutes()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day} ${weekday} ${hours}:${minutes}`;
|
||||
},
|
||||
// 👇 你的请求逻辑完全不动
|
||||
fetchApplys() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
let url = '/discharge/queryPage'
|
||||
this.$u.post(url, {
|
||||
@@ -104,13 +111,14 @@
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取退租申请信息失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
})
|
||||
},
|
||||
// 👇 你的跳转 1 行没改
|
||||
toApply() {
|
||||
this.$u.route({
|
||||
url: '/pages-assets/discharge/leaseCancel'
|
||||
@@ -133,16 +141,26 @@
|
||||
loadMore() {
|
||||
this.fetchApplys();
|
||||
},
|
||||
// ✅ 修复刷新(不动你的风格)
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'more';
|
||||
this.fetchApplys();
|
||||
|
||||
setTimeout(() => {
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
}, 800);
|
||||
},
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages-assets/discharge/dischargeDetail?id=${item.id}`
|
||||
})
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
this.refresh()
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchApplys()
|
||||
@@ -155,11 +173,13 @@
|
||||
background: #f5f5f5;
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx;
|
||||
/* 给导航栏留空间 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ✅ 修复高度,不卡不抖 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - 120rpx);
|
||||
height: calc(100vh - 175rpx - 140rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
@@ -193,8 +213,8 @@
|
||||
border-radius: 4rpx;
|
||||
|
||||
&.done {
|
||||
background: #FCE5E0; /* 保持原有浅橙色背景 */
|
||||
color: #ED7748; /* 保持原有橙色文字 */
|
||||
background: #FCE5E0;
|
||||
color: #ED7748;
|
||||
}
|
||||
|
||||
&.pending {
|
||||
@@ -202,8 +222,8 @@
|
||||
color: #86868C;
|
||||
}
|
||||
&.reject {
|
||||
background: #FFE4E1; /* 浅红色背景 */
|
||||
color: #DC143C; /* 深红色文字 */
|
||||
background: #FFE4E1;
|
||||
color: #DC143C;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
<template>
|
||||
<view class="page-view">
|
||||
<!-- 顶部导航栏 -->
|
||||
<customNavbar title="留言板" :is-transparent="navbarStyle.isTransparent" :bg-color="navbarStyle.bgColor"
|
||||
:text-color="navbarStyle.textColor" :opacity="navbarStyle.opacity" :show-home="true" />
|
||||
|
||||
<!-- 留言列表 -->
|
||||
<scroll-view scroll-y="true" class="scroll-view" @scrolltolower="loadMore" @refresherrefresh="refresh"
|
||||
<scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore" @refresherrefresh="refresh"
|
||||
:refresher-enabled="true" :refresher-triggered="isRefreshing">
|
||||
<view class="message-item" v-for="(item, index) in flowList" :key="index" @click="navigateToDetail(item)">
|
||||
<view class="message-header">
|
||||
@@ -19,40 +17,37 @@
|
||||
<text class="message-time">留言时间:{{ item.summitDate }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部新增留言按钮 -->
|
||||
<view class="add-btn-container">
|
||||
<button class="add-btn" @click="goToSubmit()">新增留言</button>
|
||||
</view>
|
||||
<!-- 新增留言弹窗 -->
|
||||
<u-popup v-model="showAddPopup" mode="center" length="60%">
|
||||
|
||||
<!-- 修复后的弹窗 -->
|
||||
<u-popup v-model="showAddPopup" mode="center">
|
||||
<view class="popup-content">
|
||||
<view class="asset-select" @click="showAssetsPopup = true">
|
||||
<text v-if="!selectedAsset" class="placeholder">
|
||||
请选择资产
|
||||
</text>
|
||||
<text v-else class="asset-text">
|
||||
{{ selectedAsset.assetsName }}
|
||||
</text>
|
||||
<view class="asset-select" @click="openAssetPopup">
|
||||
<text class="select-text">{{selectedAsset.assetsName || '请选择资产'}}</text>
|
||||
<u-icon name="arrow-right" size="26" color="#999"></u-icon>
|
||||
</view>
|
||||
|
||||
<textarea v-model="newMessageContent" placeholder="请输入留言内容" class="textarea" />
|
||||
|
||||
<button class="popup-btn" @click="addFallback()">提交留言</button>
|
||||
</view>
|
||||
</u-popup>
|
||||
<checkbox-group @change="onAssetChange">
|
||||
<label
|
||||
v-for="asset in filteredAssets"
|
||||
:key="asset.assetsNo"
|
||||
class="asset-item"
|
||||
>
|
||||
<checkbox
|
||||
:value="asset.assetsNo"
|
||||
:checked="selectedAssetKey === asset.assetsNo"
|
||||
/>
|
||||
{{ asset.assetsName }}
|
||||
</label>
|
||||
</checkbox-group>
|
||||
|
||||
<u-popup v-model="showAssetPopup" mode="bottom">
|
||||
<view class="asset-popup-wrap">
|
||||
<view class="popup-title">选择资产</view>
|
||||
<scroll-view scroll-y class="asset-list">
|
||||
<view class="asset-item" v-for="item in assetsList" :key="item.assetsNo" @click="selectAsset(item)">
|
||||
{{ item.assetsName }}
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</u-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
@@ -63,27 +58,24 @@
|
||||
showAddPopup: false,
|
||||
newMessageContent: '',
|
||||
flowList: [],
|
||||
// 导航栏样式控制
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
navbarStyle: {
|
||||
isTransparent: true,
|
||||
bgColor: '#ffffff',
|
||||
textColor: '#000000',
|
||||
opacity: 0
|
||||
},
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more',
|
||||
isRefreshing: false,
|
||||
// 滚动距离
|
||||
scrollTop: 0,
|
||||
showAssetsPopup: false,
|
||||
assetSearch: '',
|
||||
showAssetPopup: false,
|
||||
assetsList: [],
|
||||
selectedAssetKey: '', // 单个 assetsNo
|
||||
selectedAsset: null // 单个资产对象
|
||||
selectedAsset: null
|
||||
}
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop;
|
||||
// 计算导航栏透明度和样式
|
||||
this.updateNavbarStyle(e.scrollTop);
|
||||
},
|
||||
onShow() {
|
||||
@@ -93,150 +85,127 @@
|
||||
this.fetchFallback();
|
||||
},
|
||||
methods: {
|
||||
// 点击留言项跳转到详情页
|
||||
navigateToDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages-assets/fallback/fallbackDetail?id=${item.id}`,
|
||||
url: "/pages-assets/fallback/fallbackDetail?id=" + item.id
|
||||
});
|
||||
},
|
||||
onAssetChange(e) {
|
||||
const val = e.detail.value;
|
||||
// 只取最后一个
|
||||
this.selectedAssetKey = val.length ? val[val.length - 1] : '';
|
||||
openAssetPopup() {
|
||||
this.showAssetPopup = true;
|
||||
this.getAssetsList();
|
||||
},
|
||||
confirmAssets() {
|
||||
this.selectedAsset =
|
||||
this.assetsList.find(a => a.assetsNo === this.selectedAssetKey) || null;
|
||||
this.showAssetsPopup = false;
|
||||
getAssetsList() {
|
||||
this.$u.post('/assets/queryPage', {
|
||||
pageNo: 1,
|
||||
pageSize: 100
|
||||
}, {
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
this.assetsList = res.data.result || [];
|
||||
}).catch(err => {
|
||||
console.log("获取资产失败", err);
|
||||
})
|
||||
},
|
||||
selectAsset(item) {
|
||||
this.selectedAsset = item;
|
||||
this.showAssetPopup = false;
|
||||
},
|
||||
fetchFallback() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
let token = this.$getToken()
|
||||
let url = '/fallback/queryPage'
|
||||
this.$u.post(url, {
|
||||
this.$u.post('/fallback/queryPage', {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize
|
||||
}, {
|
||||
WT: token
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
console.log(rows)
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows)
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取留言信息失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
console.log("获取留言失败", err)
|
||||
this.loadStatus = 'more';
|
||||
})
|
||||
},
|
||||
loadMore() {
|
||||
// 只有在 loadStatus 为 'loadmore' 时才触发
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
this.fetchReserve()
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.fetchFallback()
|
||||
},
|
||||
goToSubmit() {
|
||||
this.showAddPopup = true;
|
||||
this.selectedAsset = null;
|
||||
this.newMessageContent = '';
|
||||
},
|
||||
addFallback() {
|
||||
const content = this.newMessageContent.trim();
|
||||
let userInfo = uni.getStorageSync('userInfo');
|
||||
if(!userInfo.cusNo) {
|
||||
uni.showToast({
|
||||
title: '您还未实名',
|
||||
icon: 'none'
|
||||
});
|
||||
this.showAddPopup = false;
|
||||
uni.showToast({ title: '您还未实名', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (!this.selectedAsset) {
|
||||
uni.showToast({ title: '请选择资产', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
if (!content) {
|
||||
uni.showToast({
|
||||
title: '请输入留言内容',
|
||||
icon: 'none'
|
||||
});
|
||||
uni.showToast({ title: '请输入留言内容', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
const token = this.$getToken();
|
||||
this.$u.post('/fallback/submit', {
|
||||
content
|
||||
content: content,
|
||||
assetsNo: this.selectedAsset.assetsNo
|
||||
}, {
|
||||
WT: token
|
||||
})
|
||||
.then(res => {
|
||||
if(res.flag){
|
||||
uni.showToast({
|
||||
title: '留言成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}else{
|
||||
uni.showToast({
|
||||
title: res.message,
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
uni.showToast({ title: '留言成功', icon: 'success' });
|
||||
this.showAddPopup = false;
|
||||
this.newMessageContent = '';
|
||||
this.refresh();
|
||||
|
||||
})
|
||||
.catch(err => {
|
||||
console.error('新增留言失败:', err);
|
||||
uni.showToast({
|
||||
title: '留言失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}).catch(err => {
|
||||
uni.showToast({ title: '提交失败', icon: 'none' });
|
||||
this.showAddPopup = false;
|
||||
});
|
||||
},
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
setTimeout(() => {
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'more';
|
||||
this.fetchFallback();
|
||||
setTimeout(()=>{
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
},800)
|
||||
},
|
||||
// 根据滚动距离更新导航栏样式
|
||||
updateNavbarStyle(scrollTop) {
|
||||
// 定义滚动阈值,超过此值导航栏变为不透明
|
||||
const threshold = 200;
|
||||
|
||||
// 计算透明度
|
||||
let opacity = scrollTop / threshold;
|
||||
opacity = Math.min(opacity, 1);
|
||||
opacity = Math.max(opacity, 0);
|
||||
|
||||
// 更新导航栏样式
|
||||
this.navbarStyle.opacity = opacity;
|
||||
|
||||
if (opacity > 0.5) {
|
||||
this.navbarStyle.isTransparent = false;
|
||||
} else {
|
||||
this.navbarStyle.isTransparent = true;
|
||||
this.navbarStyle.isTransparent = opacity <= 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-view {
|
||||
/* 给导航栏留空间 */
|
||||
padding-top: 175rpx;
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
background: linear-gradient(0deg, #F3F1ED 43%, #F5E9DB 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
height: calc(100vh - 120rpx - 120rpx);
|
||||
height: calc(100vh - 175rpx - 140rpx);
|
||||
padding: 5% 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.message-item {
|
||||
background-color: #ffffff;
|
||||
border-radius: 10rpx;
|
||||
@@ -245,14 +214,13 @@
|
||||
width: 92%;
|
||||
margin: auto;
|
||||
margin-bottom: 20rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.message-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
font-size: 24rpx;
|
||||
padding: 6rpx 16rpx;
|
||||
@@ -262,65 +230,92 @@
|
||||
position: absolute;
|
||||
left: 10rpx;
|
||||
}
|
||||
|
||||
.status-tag.processed {
|
||||
background: linear-gradient(90deg, #F34038 0%, #FF7C76 100%);
|
||||
box-shadow: 0rpx 0rpx 7rpx 0rpx #FB392A;
|
||||
}
|
||||
|
||||
.status-tag.processing {
|
||||
background: linear-gradient(90deg, #FEAF04 0%, #FFC145 100%);
|
||||
box-shadow: 0rpx 0rpx 7rpx 0rpx #FFBF41;
|
||||
}
|
||||
|
||||
.status-tag.pending {
|
||||
background: linear-gradient(90deg, #6688FC 0%, #809BFB 100%);
|
||||
box-shadow: 0rpx 0rpx 7rpx 0rpx #7E99FB;
|
||||
}
|
||||
|
||||
.message-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #2D2B2C;
|
||||
}
|
||||
|
||||
.message-content {
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.content-text {
|
||||
font-size: 24rpx;
|
||||
color: #86868C;
|
||||
line-height: 44rpx;
|
||||
}
|
||||
|
||||
.message-time {
|
||||
font-size: 24rpx;
|
||||
color: #ADADB1;
|
||||
}
|
||||
/* 资产选择入口 */
|
||||
.asset-select {
|
||||
margin-top: 20rpx;
|
||||
padding: 20rpx 24rpx;
|
||||
background: #ffffff;
|
||||
|
||||
/* 核心修复:弹窗宽度与排版 */
|
||||
.popup-content {
|
||||
background: #fff;
|
||||
padding: 30rpx;
|
||||
border-radius: 8rpx;
|
||||
font-size: 26rpx;
|
||||
width: 70%; /* 扩大弹窗宽度,避免文字竖排 */
|
||||
min-width: 400rpx;
|
||||
}
|
||||
.asset-select {
|
||||
padding: 20rpx;
|
||||
background: #f7f7f7;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
margin-bottom: 20rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
/* 未选择时的占位文字 */
|
||||
.asset-select .placeholder {
|
||||
white-space: nowrap; /* 强制文字不换行 */
|
||||
}
|
||||
.select-text {
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
.textarea {
|
||||
width: 100%;
|
||||
min-height: 200rpx;
|
||||
padding: 20rpx;
|
||||
background: #f7f7f7;
|
||||
border-radius: 8rpx;
|
||||
font-size: 28rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.popup-btn {
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
background: #FF6F63;
|
||||
color: #fff;
|
||||
border-radius: 8rpx;
|
||||
font-size: 30rpx;
|
||||
border: none;
|
||||
white-space: nowrap; /* 按钮文字不换行 */
|
||||
}
|
||||
|
||||
/* 已选择资产文字 */
|
||||
.asset-select .asset-text {
|
||||
color: #333;
|
||||
.asset-popup-wrap {
|
||||
padding: 30rpx;
|
||||
background: #fff;
|
||||
}
|
||||
.popup-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
text-align: center;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
.asset-list {
|
||||
max-height: 400rpx;
|
||||
}
|
||||
.asset-item {
|
||||
padding: 24rpx;
|
||||
font-size: 28rpx;
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
}
|
||||
|
||||
.add-btn-container {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
@@ -328,9 +323,7 @@
|
||||
right: 0;
|
||||
padding: 30rpx 40rpx;
|
||||
background-color: #f5f5f5;
|
||||
box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.add-btn {
|
||||
width: 100%;
|
||||
height: 80rpx;
|
||||
@@ -339,33 +332,5 @@
|
||||
color: #ffffff;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.popup-content {
|
||||
border-radius: 8rpx;
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.popup-content .textarea {
|
||||
width: 100%;
|
||||
min-height: 400rpx;
|
||||
padding: 14rpx 20rpx;
|
||||
border-radius: 8rpx;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.popup-btn {
|
||||
margin-top: 20rpx;
|
||||
width: 100%;
|
||||
height: 60rpx;
|
||||
background: #FF6F63;
|
||||
color: #fff;
|
||||
border-radius: 8rpx;
|
||||
font-size: 30rpx;
|
||||
}
|
||||
</style>
|
||||
@@ -54,6 +54,9 @@
|
||||
<u-icon name="arrow-right" size="32" color="#ccc"></u-icon>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- ✅ 加载更多组件 -->
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</view>
|
||||
|
||||
<view v-else class="empty">
|
||||
@@ -70,8 +73,8 @@
|
||||
pageNo: 1,
|
||||
pageSize:10,
|
||||
flowList: [],
|
||||
loadStatus: 'loadmore',
|
||||
activeTab: '收', // 默认显示“收”
|
||||
loadStatus: 'more', // ✅ 修复为官方正确值
|
||||
activeTab: '收',
|
||||
tabs: [{
|
||||
label: '收入',
|
||||
value: '支'
|
||||
@@ -81,7 +84,6 @@
|
||||
value: '收'
|
||||
},
|
||||
],
|
||||
// 年份筛选相关
|
||||
currentYear: null,
|
||||
years: [],
|
||||
showYearPicker: false
|
||||
@@ -99,6 +101,7 @@
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ✅ 删除和 scroll-view 冲突的 onReachBottom
|
||||
watch: {
|
||||
activeTab(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
@@ -106,16 +109,16 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
methods: {
|
||||
onTabClick(val) {
|
||||
this.activeTab = val
|
||||
this.resetAndLoad()
|
||||
},
|
||||
fetchPayRecord() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
let url = '/bill/pageQueryPayRecord'
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
@@ -128,22 +131,21 @@
|
||||
const rows = res.data.result || [];
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取账单记录失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
})
|
||||
},
|
||||
// 切换年份选择器显示
|
||||
toggleYearPicker() {
|
||||
this.showYearPicker = !this.showYearPicker;
|
||||
},
|
||||
// 选择年份
|
||||
selectYear(year) {
|
||||
this.currentYear = year;
|
||||
this.showYearPicker = false;
|
||||
@@ -154,21 +156,19 @@
|
||||
return '¥' + Number(val).toFixed(2);
|
||||
},
|
||||
resetAndLoad(){
|
||||
// 重新加载数据
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.fetchPayRecord();
|
||||
},
|
||||
loadMore() {
|
||||
// 只有在 loadStatus 为 'loadmore' 时才触发
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// 调用接口获取下一页
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.fetchPayRecord();
|
||||
},
|
||||
goDetail(item) {
|
||||
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -177,6 +177,9 @@
|
||||
background: #f8f8f8;
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
@@ -266,6 +269,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* ✅ 正确的滚动高度 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - 175rpx - 120rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
padding: 20rpx;
|
||||
|
||||
@@ -331,5 +340,4 @@
|
||||
.empty {
|
||||
margin-top: 100rpx;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,8 +1,7 @@
|
||||
<template>
|
||||
|
||||
<view class="contract-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<customNavbar title="我的合同" :showHome = "true"/>
|
||||
<customNavbar title="我的合同" :showHome="true"/>
|
||||
|
||||
<!-- Tabs -->
|
||||
<view class="tab-wrapper">
|
||||
@@ -22,10 +21,9 @@
|
||||
|
||||
<view class="contract-info">
|
||||
<view class="top-row">
|
||||
<text class="asset-name">{{ $ellipsis(item.assetName,12) }}</text>
|
||||
<text class="asset-name">{{ $ellipsis(item.contractName,12) }}</text>
|
||||
<u-icon name="arrow-right" size="28" color="#ccc" />
|
||||
</view>
|
||||
<!-- <view class="asset-room">{{ item.assetRoom || "—" }}</view> -->
|
||||
<view class="date-range">{{ item.startDate }} ~ {{ item.endDate }}</view>
|
||||
|
||||
<view :class="['status-tag', item.signStatus]">
|
||||
@@ -41,61 +39,43 @@
|
||||
<u-empty mode="list" text="暂无合同记录" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
|
||||
</view>
|
||||
|
||||
</template>
|
||||
|
||||
|
||||
<script>
|
||||
import DateFilter from '../../components/DatePicker/DateFilter.vue';
|
||||
export default {
|
||||
components: { DateFilter },
|
||||
data() {
|
||||
return {
|
||||
tabList: [{
|
||||
name: "全部",
|
||||
value: "all"
|
||||
},
|
||||
{
|
||||
name: "待签署",
|
||||
value: "pending"
|
||||
},
|
||||
{
|
||||
name: "已签署",
|
||||
value: "signed"
|
||||
},
|
||||
{
|
||||
name: "已过期",
|
||||
value: "expired"
|
||||
},
|
||||
tabList: [
|
||||
{ name: "全部", value: "all" },
|
||||
{ name: "待签署", value: "pending" },
|
||||
{ name: "已签署", value: "signed" },
|
||||
{ name: "已过期", value: "expired" },
|
||||
],
|
||||
|
||||
currentTab: 0,
|
||||
statusFilter: "all",
|
||||
// --- 时间筛选 ---
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
// 可选:限制日期范围
|
||||
minDate: "2000-01-01",
|
||||
maxDate: "2099-12-31",
|
||||
maxDate: "2199-12-31",
|
||||
contracts: [],
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
loadStatus: "loadmore",
|
||||
loadStatus: "more", // ✅ 修复为官方正确值
|
||||
isRefreshing: false,
|
||||
defaultCover: "/public/static/assets.jpg",
|
||||
defaultCover: "/public/static/index/assets.jpg",
|
||||
};
|
||||
},
|
||||
|
||||
onLoad(options) {
|
||||
this.loadContracts();
|
||||
},
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ✅ 删除和 scroll-view 冲突的 onReachBottom
|
||||
computed: {
|
||||
staticHost() {
|
||||
return this.$config.staticUrl
|
||||
@@ -110,25 +90,21 @@ export default {
|
||||
onDateFilterChange({ start, end }) {
|
||||
this.resetAndLoad();
|
||||
},
|
||||
|
||||
formatDate(time) {
|
||||
const d = new Date(time);
|
||||
const m = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const day = String(d.getDate()).padStart(2, "0");
|
||||
return `${d.getFullYear()}-${m}-${day}`;
|
||||
},
|
||||
|
||||
resetAndLoad() {
|
||||
this.pageNo = 1;
|
||||
this.contracts = [];
|
||||
this.loadStatus = "loadmore";
|
||||
this.loadStatus = "more"; // ✅ 修复
|
||||
this.loadContracts();
|
||||
},
|
||||
|
||||
/** 你的 loadContracts() 保持不变,只需加:按时间筛选 */
|
||||
loadContracts() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
this.$u.post('/contract/queryPage', {
|
||||
@@ -140,59 +116,48 @@ export default {
|
||||
}, {
|
||||
WT: this.$getToken()
|
||||
}).then(result => {
|
||||
|
||||
const rows = result.data.result || [];
|
||||
|
||||
// 第一页 & 无数据
|
||||
if (this.pageNo === 1 && rows.length === 0) {
|
||||
this.contracts = [];
|
||||
this.loadStatus = 'nomore';
|
||||
return;
|
||||
}
|
||||
|
||||
// 追加数据
|
||||
this.contracts = this.contracts.concat(rows);
|
||||
|
||||
// 是否还有下一页(核心判断)
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++; // ✅ 只有这里才能 +1
|
||||
this.loadStatus = 'loadmore';
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'more'; // ✅ 修复
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
console.log("获取合同信息失败:", err);
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
}).finally(() => {
|
||||
this.isRefreshing = false;
|
||||
});
|
||||
},
|
||||
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.resetAndLoad();
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
if (this.loadStatus !== "loadmore") return;
|
||||
if (this.loadStatus !== "more") return; // ✅ 修复
|
||||
this.loadContracts();
|
||||
},
|
||||
|
||||
goDetail(item) {
|
||||
uni.navigateTo({
|
||||
url: `/pages-biz/contract/contractDetail?contractNo=${item.contractNo}`,
|
||||
});
|
||||
},
|
||||
|
||||
getStatusText(status) {
|
||||
switch (status) {
|
||||
case "pending":
|
||||
return "待签署";
|
||||
case "signed":
|
||||
return "已签署";
|
||||
case "expired":
|
||||
return "已过期";
|
||||
case "pending": return "待签署";
|
||||
case "signed": return "已签署";
|
||||
case "expired": return "已过期";
|
||||
default: return "未知";
|
||||
}
|
||||
},
|
||||
},
|
||||
@@ -203,12 +168,14 @@ export default {
|
||||
.contract-page {
|
||||
background-color: #f8f8f8;
|
||||
padding-top: 170rpx;
|
||||
/* 给导航栏留空间 */
|
||||
min-height: 100vh;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ✅ 核心修复:正确的滚动高度 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - 100rpx);
|
||||
height: calc(100vh - 170rpx - 100rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.contract-list {
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<!-- 登录按钮 -->
|
||||
<button class="login-btn" open-type="getPhoneNumber" @getphonenumber="onGetPhone">
|
||||
使用微信授权登录
|
||||
手机号快捷登录
|
||||
</button>
|
||||
|
||||
<!-- 用户类型选择 -->
|
||||
|
||||
@@ -39,14 +39,20 @@ export default {
|
||||
pageNo:1,
|
||||
pageSize:10,
|
||||
isRefreshing: false,
|
||||
loadStatus: 'loadmore'
|
||||
loadStatus: 'more', // ✅ 修复为官方正确值
|
||||
}
|
||||
},
|
||||
onLoad() { // ✅ 修复生命周期拼写
|
||||
this.fetchMessageList();
|
||||
},
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
onload(){
|
||||
this.loadMore();
|
||||
// ✅ 删除和 scroll-view 冲突的 onReachBottom
|
||||
computed: {
|
||||
staticHost() {
|
||||
return this.$config.staticUrl;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
@@ -68,8 +74,10 @@ export default {
|
||||
}
|
||||
},
|
||||
fetchMessageList(){
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
let url = '/message/queryPage'
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
@@ -78,36 +86,44 @@ export default {
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
console.log(rows)
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
|
||||
// ✅ 判断是否还有更多
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取消息列表失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
})
|
||||
},
|
||||
loadMore() {
|
||||
// 只有在 loadStatus 为 'loadmore' 时才触发
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
this.fetchMessageList()
|
||||
},
|
||||
viewMessage(msg) {
|
||||
this.$u.route({url:'/pages-biz/message/messageDetail',params:{
|
||||
this.$u.route({
|
||||
url:'/pages-biz/message/messageDetail',
|
||||
params:{
|
||||
id: msg.id,
|
||||
read: msg.read
|
||||
}});
|
||||
}
|
||||
});
|
||||
},
|
||||
// ✅ 修复下拉刷新(重置数据)
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'more';
|
||||
this.fetchMessageList();
|
||||
|
||||
setTimeout(() => {
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
}, 800);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,7 +135,9 @@ export default {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
/* ✅ 修复滚动区域高度 */
|
||||
.message-list {
|
||||
height: calc(100vh - var(--window-top));
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,6 @@
|
||||
<!-- 顶部自定义导航栏 -->
|
||||
<customNavbar title="我的租赁资产" />
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
|
||||
|
||||
<!-- 租赁资产列表组件 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
@@ -16,6 +13,9 @@
|
||||
:list="assetList"
|
||||
@click="goDetail"
|
||||
/>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -24,13 +24,14 @@
|
||||
import AssetList from '@/components/asset/assetList.vue'
|
||||
export default {
|
||||
name: 'MyLease',
|
||||
components: { AssetList},
|
||||
components: { AssetList },
|
||||
data() {
|
||||
return {
|
||||
assetList: [],
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more', // ✅ 修复为官方正确值
|
||||
cusNo: ''
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
@@ -40,43 +41,39 @@ export default {
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ✅ 删除和 scroll-view 冲突的 onReachBottom
|
||||
computed: {
|
||||
staticHost() {
|
||||
return this.$config.staticUrl
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
changeFilter(value) {
|
||||
if (this.currentFilter === value) return;
|
||||
this.currentFilter = value;
|
||||
this.pageNo = 1;
|
||||
this.assetList = [];
|
||||
this.loadAssets();
|
||||
},
|
||||
|
||||
loadAssets() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
this.$u.post('/assets/getMyAssetsList', {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize
|
||||
},{
|
||||
}, {
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
|
||||
if (this.pageNo === 1) this.assetList = [];
|
||||
|
||||
this.assetList = this.assetList.concat(rows);
|
||||
|
||||
// ✅ 判断是否还有更多数据
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
});
|
||||
},
|
||||
|
||||
@@ -97,33 +94,15 @@ export default {
|
||||
.page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100vh;
|
||||
min-height: 100vh;
|
||||
background: #f7f8fa;
|
||||
padding-top: 175rpx;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
background-color: #fff;
|
||||
padding: 20rpx 0;
|
||||
margin-top: var(--custom-navbar-height);
|
||||
border-bottom: 1rpx solid #f0f0f0;
|
||||
|
||||
.filter-btn {
|
||||
min-width: 150rpx;
|
||||
text-align: center;
|
||||
font-size: 26rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 40rpx;
|
||||
margin: 0 8rpx;
|
||||
}
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
flex: 1;
|
||||
height: calc(100vh - 200rpx);
|
||||
height: calc(100vh - 175rpx); /* ✅ 正确高度,不超出屏幕 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -17,6 +17,9 @@
|
||||
</view>
|
||||
<u-icon name="arrow-right" color="rgb(203,203,203)" :size="26" class="arrow-icon"></u-icon>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多 -->
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
@@ -26,20 +29,18 @@
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
// 静态公告数据
|
||||
const staticNoticeList = [];
|
||||
return {
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
flowList: [],
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more', // ✅ 修复为官方正确值
|
||||
isRefreshing: false
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
// 静态数据已在data中初始化,无需调用接口
|
||||
this.getNoticecList();
|
||||
},
|
||||
// ✅ 删除和 scroll-view 冲突的 onReachBottom
|
||||
methods: {
|
||||
clickContent(item) {
|
||||
if (item.noticeId) {
|
||||
@@ -52,30 +53,39 @@ export default {
|
||||
}
|
||||
},
|
||||
getNoticecList() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
let url = "/notice/pageQuery";
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
console.log(rows)
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows)
|
||||
|
||||
// ✅ 判断是否还有更多
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取招商公告失败:", err)
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
});
|
||||
},
|
||||
// 上拉加载
|
||||
loadMore() {
|
||||
this.getNoticecList();
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tabSwiper {
|
||||
width: 95%;
|
||||
|
||||
@@ -29,11 +29,33 @@
|
||||
this.id = option.id
|
||||
this.getDetail()
|
||||
},
|
||||
onShow(){
|
||||
this.recordView(this.id)
|
||||
},
|
||||
methods:{
|
||||
recordView(assetId) {
|
||||
let token = this.$getToken()
|
||||
let userInfo = uni.getStorageSync('userInfo')
|
||||
if(token){
|
||||
return
|
||||
}
|
||||
if (token) {
|
||||
let url = "/potential/add";
|
||||
this.$u.get(url, {
|
||||
assetId: this.id,
|
||||
assetsName: '查看公告' + this.title,
|
||||
userType: userInfo.userType
|
||||
}, {
|
||||
'WT': this.$getToken()
|
||||
}).then(obj => {
|
||||
|
||||
}).catch(err => {
|
||||
console.log("记录客户浏览记录失败", err)
|
||||
})
|
||||
}
|
||||
},
|
||||
getDetail(){
|
||||
this.$u.get(`/notice/detail?id=${this.id}`,{},{
|
||||
WT: this.$getToken()
|
||||
}).then(res=>{
|
||||
this.$u.get(`/notice/detail?id=${this.id}`,{},{}).then(res=>{
|
||||
if(res.flag) {
|
||||
this.title = res.data.noticeTitle;
|
||||
this.content = res.data.noticeContent;
|
||||
@@ -44,12 +66,13 @@
|
||||
})
|
||||
}
|
||||
this.attachments = res.data.attachments;
|
||||
this.recordView(this.id)
|
||||
}
|
||||
})
|
||||
},
|
||||
download(item){
|
||||
uni.downloadFile({
|
||||
url: this.$config.staticUrl + item.url,
|
||||
url: this.$config.staticUrl + item.fileUrl,
|
||||
success(res) {
|
||||
uni.openDocument({
|
||||
filePath: res.tempFilePath
|
||||
|
||||
@@ -2,16 +2,6 @@
|
||||
<view class="u-m-20">
|
||||
<u-navbar :is-back="true" title="账号实名信息" :border-bottom="false"></u-navbar>
|
||||
<view>
|
||||
<!-- <u-cell-group>
|
||||
<u-cell-item title="头像" :arrow="false" hover-class="none" @click="updateAvatar">
|
||||
<u-avatar :src="pic" size="100"></u-avatar>
|
||||
</u-cell-item>
|
||||
</u-cell-group> -->
|
||||
<!-- <u-cell-group>
|
||||
<u-cell-item title="昵称" :arrow="false" hover-class="none" @click="updateName">
|
||||
{{vuex_user.user.nickName}}
|
||||
</u-cell-item>
|
||||
</u-cell-group> -->
|
||||
<u-cell-group>
|
||||
<u-cell-item :title="getTitle" :arrow="false" hover-class="none" @click="updateName">
|
||||
{{(cardNo == null ? orgNo : cardNo) || ''}}
|
||||
@@ -19,29 +9,28 @@
|
||||
</u-cell-group>
|
||||
</view>
|
||||
|
||||
<u-modal v-model="showModel" @confirm="confirmAuthCode" ref="uModal" :async-close="true"
|
||||
:title="'设置' + getTitle">
|
||||
<u-modal
|
||||
v-model="showModel"
|
||||
@confirm="confirmAuthCode"
|
||||
ref="uModal"
|
||||
:async-close="true"
|
||||
:title="'设置' + getTitle"
|
||||
>
|
||||
<view class="slot-content">
|
||||
<u-input v-model="authCode" type="text" :border="false" :placeholder="'请输入' + getTitle" />
|
||||
<u-input
|
||||
v-model="authCode"
|
||||
type="text"
|
||||
:border="false"
|
||||
:placeholder="'请输入' + getTitle"
|
||||
/>
|
||||
</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" // 全局配置文件
|
||||
import {
|
||||
rsaEncrypt
|
||||
} from "@/common/utils/ras.js"
|
||||
import config from "@/common/config.js"
|
||||
import { rsaEncrypt } from "@/common/utils/ras.js"
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
@@ -60,49 +49,46 @@
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
let userVo = uni.getStorageSync('userInfo');
|
||||
this.user = userVo;
|
||||
// 页面加载时同步最新用户信息
|
||||
this.getUserProfile();
|
||||
},
|
||||
methods: {
|
||||
updateName() {
|
||||
this.showModel = true;
|
||||
},
|
||||
// 简单身份证校验(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
|
||||
);
|
||||
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);
|
||||
},
|
||||
confirmAuthCode() {
|
||||
let loginType = this.user.userType
|
||||
// 修复:统一使用 loginType 变量
|
||||
const loginType = this.user.userType;
|
||||
|
||||
if (!this.authCode) {
|
||||
this.showModel = false;
|
||||
return this.$mytip.toast(loginType === '0' ? '请输入身份证号' : '请输入组织社会信用代码')
|
||||
}
|
||||
// 身份证校验
|
||||
if (this.loginType === '0' && !this.checkIdCard(this.authCode)) {
|
||||
uni.showToast({
|
||||
title: '身份证号格式不正确',
|
||||
icon: 'none'
|
||||
});
|
||||
|
||||
// 校验身份证
|
||||
if (loginType === '0' && !this.checkIdCard(this.authCode)) {
|
||||
uni.showToast({ title: '身份证号格式不正确', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
// 企业社会信用代码校验
|
||||
if (this.loginType === '1' && !this.checkCreditCode(this.authCode)) {
|
||||
uni.showToast({
|
||||
title: '社会信用代码格式不正确',
|
||||
icon: 'none'
|
||||
});
|
||||
// 校验信用代码
|
||||
if (loginType === '1' && !this.checkCreditCode(this.authCode)) {
|
||||
uni.showToast({ title: '社会信用代码格式不正确', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
let token = this.$getToken()
|
||||
let url = "/login/updateVerifyCode";
|
||||
let encryptCode = rsaEncrypt(this.authCode);
|
||||
|
||||
const token = this.$getToken();
|
||||
const url = "/login/updateVerifyCode";
|
||||
const encryptCode = rsaEncrypt(this.authCode);
|
||||
|
||||
this.$u.post(url, {
|
||||
userType: loginType,
|
||||
code: loginType === '0' ? encryptCode : this.authCode
|
||||
@@ -110,64 +96,74 @@
|
||||
'WT': token
|
||||
}).then(obj => {
|
||||
if (obj.flag) {
|
||||
// 赋值展示
|
||||
if (loginType === '0') {
|
||||
this.cardNo = encryptCode
|
||||
this.cardNo = this.applyMask(this.authCode)
|
||||
this.cardNo = this.applyMask(this.authCode);
|
||||
} else {
|
||||
this.orgNo = this.authCode
|
||||
this.orgNo = this.authCode;
|
||||
}
|
||||
|
||||
this.showModel = false;
|
||||
this.$mytip.toast('修改成功');
|
||||
this.getUserProfile();
|
||||
uni.switchTab({
|
||||
url: '/pages/center/center'
|
||||
})
|
||||
|
||||
// 关键:先更新用户信息,成功后再跳转
|
||||
this.getUserProfile().then(() => {
|
||||
setTimeout(() => {
|
||||
uni.switchTab({ url: '/pages/center/center' });
|
||||
}, 1000);
|
||||
});
|
||||
} else {
|
||||
this.$mytip.toast('修改失败');
|
||||
}
|
||||
});
|
||||
|
||||
},
|
||||
// 身份证脱敏修复
|
||||
applyMask(idCard) {
|
||||
if (idCard.length !== 18) return idCard; // 非18位直接返回
|
||||
return idCard.replace(/(\d{6})(\d{8})(\d{4})/, '$1********$2****');
|
||||
if (!idCard || idCard.length !== 18) return idCard;
|
||||
// 前6位 + 8个* + 后4位
|
||||
return idCard.replace(/^(\d{6})\d{8}(\d{4})$/, '$1********$2');
|
||||
},
|
||||
updateAvatar() {
|
||||
this.$u.route('/pages-biz/profile/avatar')
|
||||
},
|
||||
subProfile() {
|
||||
// 1.更新vuex中的用户信息
|
||||
this.$mytip.toast('修改成功')
|
||||
// 2.页面跳转
|
||||
// 关键修复:获取用户信息并同步到当前页面 data
|
||||
async getUserProfile() {
|
||||
try {
|
||||
const token = this.$getToken();
|
||||
const url = `/login/userInfo`;
|
||||
|
||||
},
|
||||
getUserProfile() {
|
||||
// 如果是微信登录小程序,则获取用户的昵称与头像
|
||||
// #ifdef MP-WEIXIN
|
||||
// 此处执行微信才执行
|
||||
// #endif
|
||||
uni.removeStorageSync('userInfo');
|
||||
let token = this.$getToken();
|
||||
let url = `/login/userInfo`;
|
||||
this.$u.get(url, {}, {
|
||||
'WT': token
|
||||
}).then(obj => {
|
||||
uni.setStorageSync('userInfo', {
|
||||
const obj = await this.$u.get(url, {}, { 'WT': token });
|
||||
const userInfo = {
|
||||
userType: obj.data.userType,
|
||||
oaAuth: obj.data.oaAuth,
|
||||
cusNo: obj.data.cusNo,
|
||||
userName: obj.data.userName,
|
||||
openId: obj.data.openId,
|
||||
subscribe: obj.data.subscribeMsg
|
||||
})
|
||||
});
|
||||
};
|
||||
|
||||
// 同步缓存 + 当前页面数据
|
||||
uni.setStorageSync('userInfo', userInfo);
|
||||
this.user = userInfo;
|
||||
|
||||
// 同步展示实名信息
|
||||
if (userInfo.userType === '0') {
|
||||
this.cardNo = obj.data.cardNo ? this.applyMask(obj.data.cardNo) : null;
|
||||
this.orgNo = null;
|
||||
} else {
|
||||
this.orgNo = obj.data.orgNo || null;
|
||||
this.cardNo = null;
|
||||
}
|
||||
|
||||
return userInfo;
|
||||
} catch (e) {
|
||||
console.error('获取用户信息失败', e);
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
getTitle() {
|
||||
return this.user.userType === '0' ?
|
||||
'身份证号' :
|
||||
'企业社会信用代码'
|
||||
return this.user.userType === '0' ? '身份证号' : '企业社会信用代码';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
<view class="setting-content">
|
||||
<u-cell-group>
|
||||
<u-cell-item title="账号实名信息" @click="profile"></u-cell-item>
|
||||
<u-cell-item title="订阅系统消息" :arrow="false">
|
||||
<!-- <u-cell-item title="订阅系统消息" :arrow="false">
|
||||
|
||||
<u-switch v-model="longSubscribe" @change="toggleLongSubscribe" />
|
||||
|
||||
</u-cell-item>
|
||||
</u-cell-item> -->
|
||||
</u-cell-group>
|
||||
</view>
|
||||
|
||||
@@ -53,32 +53,30 @@
|
||||
// 微信小程序专用
|
||||
// #ifdef MP-WEIXIN
|
||||
if (this.longSubscribe) {
|
||||
const tmplIds = ['ZVl9bkFv8Nzha2n_6wO36IBqe0H5VwJBvV-7OkVT5jo'] // 在小程序后台配置的长期订阅模板
|
||||
wx.requestSubscribeMessage({
|
||||
tmplIds,
|
||||
success: (res) => {
|
||||
// 用户同意才生效
|
||||
console.log('长期订阅授权结果', res)
|
||||
if (Object.values(res).some((v) => v === 'accept')) {
|
||||
uni.showToast({
|
||||
title: '长期订阅开启成功',
|
||||
icon: 'success'
|
||||
})
|
||||
// 可以把状态保存到后端
|
||||
// const tmplIds = ['9QlNxNONJBICzw3Vcetqbf9yv4lI9q9cR_px8ujlOu8']
|
||||
// wx.requestSubscribeMessage({
|
||||
// tmplIds,
|
||||
// success: (res) => {
|
||||
// if (Object.values(res).some((v) => v === 'accept')) {
|
||||
// uni.showToast({
|
||||
// title: '长期订阅开启成功',
|
||||
// icon: 'success'
|
||||
// })
|
||||
// this.saveLongSubscribeStatus(true)
|
||||
// } else {
|
||||
// uni.showToast({
|
||||
// title: '未授权订阅',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// this.longSubscribe = false
|
||||
// }
|
||||
// },
|
||||
// fail: (err) => {
|
||||
// console.error(err)
|
||||
// this.longSubscribe = false
|
||||
// },
|
||||
// })
|
||||
this.saveLongSubscribeStatus(true)
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '未授权订阅',
|
||||
icon: 'none'
|
||||
})
|
||||
this.longSubscribe = false
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.error(err)
|
||||
this.longSubscribe = false
|
||||
},
|
||||
})
|
||||
} else {
|
||||
// 取消订阅
|
||||
uni.showToast({
|
||||
|
||||
@@ -85,8 +85,14 @@ export default {
|
||||
pageNo: 1,
|
||||
pageSize:10,
|
||||
flowList: [],
|
||||
loadStatus: 'loadmore',
|
||||
isRefreshing: false
|
||||
loadStatus: 'more', // ✅ 修复为官方正确值
|
||||
isRefreshing: false,
|
||||
navbarStyle: {
|
||||
isTransparent: false,
|
||||
bgColor: '#fff',
|
||||
textColor: '#2D2B2C',
|
||||
opacity: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
onLoad(options){
|
||||
@@ -95,6 +101,7 @@ export default {
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ✅ 删除 scroll-view 冲突的 onReachBottom
|
||||
methods: {
|
||||
statusText(status) {
|
||||
switch (status) {
|
||||
@@ -107,7 +114,6 @@ export default {
|
||||
}
|
||||
},
|
||||
formatDate(dateStr) {
|
||||
// 格式化日期,例如:2025-11-10 周五 09:00
|
||||
if(!dateStr){return '-'}
|
||||
const date = new Date(dateStr);
|
||||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||
@@ -121,7 +127,8 @@ export default {
|
||||
return `${year}-${month}-${day} ${weekday} ${hours}:${minutes}`;
|
||||
},
|
||||
fetchReserve(){
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断加载状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
let url = '/reservate/queryPage'
|
||||
this.$u.post(url, {
|
||||
@@ -131,18 +138,19 @@ export default {
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
console.log(rows)
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
|
||||
// ✅ 判断是否还有更多数据
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取预约记录失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
})
|
||||
},
|
||||
viewLocation(item) {
|
||||
@@ -166,11 +174,16 @@ export default {
|
||||
loadMore() {
|
||||
this.fetchReserve()
|
||||
},
|
||||
// ✅ 修复下拉刷新(重置数据)
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'more';
|
||||
this.fetchReserve();
|
||||
setTimeout(() => {
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
}, 800);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -179,12 +192,15 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.reserve-records {
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx; /* 给导航栏留空间 */
|
||||
padding-top: 175rpx;
|
||||
background: linear-gradient(0deg, #F3F1ED 43%, #F5E9DB 100%);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ✅ 核心修复:正确的滚动区域高度 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - -120rpx - 120rpx);
|
||||
height: calc(100vh - 175rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.record-list {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<view class="u-margin-left-20 u-margin-right-20">
|
||||
<u-navbar :is-back="true" title="搜索" :border-bottom="false"></u-navbar>
|
||||
<u-search placeholder="请输入资产名称/位置等信息" v-model="keyword" @search="clickSearch(value)"
|
||||
<u-search placeholder="请输入品牌名称/位置等信息" v-model="keyword" @search="clickSearch(value)"
|
||||
:focus="true" action-text="取消" @custom="cancelSearch"></u-search>
|
||||
<!-- 搜索记录 -->
|
||||
<template v-if="historyList.length > 0">
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
<template>
|
||||
<view class="search-list-page">
|
||||
<!-- 顶部导航栏 -->
|
||||
<!-- <customNavbar title="搜索资产" /> -->
|
||||
<u-navbar title="搜索资产" :autoBack="true" :background="background" title-color="#2D2B2C"
|
||||
back-icon-color="#2D2B2C">
|
||||
</u-navbar>
|
||||
<view class="search-list-content">
|
||||
<!-- 筛选标签栏 -->
|
||||
<view class="filter-dropdown-wrapper">
|
||||
<u-sticky offset-top="0">
|
||||
<view class="sticky" style="width: 100vw;">
|
||||
@@ -15,7 +12,6 @@
|
||||
</view>
|
||||
</u-sticky>
|
||||
</view>
|
||||
<!-- 搜索栏 -->
|
||||
<view class="search-bar-wrapper">
|
||||
<view class="search-bar">
|
||||
<view class="city-select" @click="location()">{{ city ||'宜昌市'}} <text class="icon-down"></text>
|
||||
@@ -26,7 +22,6 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 标签组 -->
|
||||
<view class="tag-group">
|
||||
<view class="tag-item" :class="{ active: selectedTags.includes(tag) }"
|
||||
v-for="(tag, index) in tagGroupList" :key="index" @click="onTagClick(tag)">
|
||||
@@ -39,32 +34,35 @@
|
||||
<u-waterfall v-model="flowList" ref="uWaterfall">
|
||||
<template v-slot:left="{ leftList }">
|
||||
<view class="demo-warter" v-for="(item, index) in leftList" :key="index">
|
||||
<u-lazy-load threshold="750" border-radius="8" :image="item.coverImgUrl" :index="index"
|
||||
@click="clickImage(item.assetsNo)" mode="aspectFill"></u-lazy-load>
|
||||
<view class="img-box" @click="clickImage(item.assetsNo)">
|
||||
<img class="img" :src="item.coverImgUrl" alt="" />
|
||||
</view>
|
||||
<view class="item-title">{{ item.assetsName }}</view>
|
||||
<view class="item-desc">{{ item.assetsType }} {{ item.footPrint }}㎡ {{ item.orientation ||'未知'}}
|
||||
</view>
|
||||
<view class="item-tags">
|
||||
<view class="tag" v-for="(tag, tagIndex) in item.tags" :key="tagIndex">{{ tag }}</view>
|
||||
</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">
|
||||
<u-lazy-load threshold="750" border-radius="8" :image="item.coverImgUrl" :index="index"
|
||||
@click="clickImage(item.assetsNo)" mode="aspectFill"></u-lazy-load>
|
||||
<view class="img-box" @click="clickImage(item.assetsNo)">
|
||||
<img class="img" :src="item.coverImgUrl" alt="" />
|
||||
</view>
|
||||
<view class="item-title">{{ item.assetsName }}</view>
|
||||
<view class="item-desc">{{ item.assetsType}} {{ item.footPrint }}㎡ {{ item.orientation ||'未知'}}</view>
|
||||
<view class="item-tags">
|
||||
<view class="tag" v-for="(tag, tagIndex) in item.tags" :key="tagIndex">{{ tag }}</view>
|
||||
</view>
|
||||
<view class="item-price">¥{{ item.rentFee || '未知'}}/<text>月</text></view>
|
||||
</view>
|
||||
</template>
|
||||
</u-waterfall>
|
||||
<u-loadmore bg-color="rgb(240, 240, 240)" :status="loadStatus" @loadmore="loadMore"
|
||||
|
||||
<!-- ✅ 修复状态 + 去掉自带loadmore -->
|
||||
<u-loadmore bg-color="rgb(240, 240, 240)" :status="loadStatus"
|
||||
style="height: 80rpx;line-height: 80rpx;"></u-loadmore>
|
||||
|
||||
<u-back-top :scroll-top="scrollTop" top="1000"></u-back-top>
|
||||
<u-no-network></u-no-network>
|
||||
</view>
|
||||
@@ -72,8 +70,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import config from "@/common/config.js" // 全局配置文件
|
||||
import searchData from '@/common/utils/searchData.js'; //筛选菜单数据
|
||||
import config from "@/common/config.js"
|
||||
import searchData from '@/common/utils/searchData.js';
|
||||
import filterDropdown from '@/components/zy/filterDropdown.vue';
|
||||
export default {
|
||||
components: {
|
||||
@@ -82,26 +80,22 @@
|
||||
data() {
|
||||
return {
|
||||
city: null,
|
||||
selectedBizZone: null,
|
||||
selectedLayout: null,
|
||||
selectedDecorationStatus: null,
|
||||
selectedFeatures:[],
|
||||
indexArr: [],
|
||||
valueArr: [],
|
||||
defaultSelected: [],
|
||||
filterData: [],
|
||||
searchData: {},
|
||||
pageNum: 1,
|
||||
pageNo: 1, // ✅ 统一页码
|
||||
pageSize: 20,
|
||||
scrollTop: 0,
|
||||
houseList: [],
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more', // ✅ 修复为正确状态
|
||||
flowList: [],
|
||||
// 标签组数据和选中状态
|
||||
tagGroupList: ['全套家具', '配套齐全', '优选好房', '生活便利'],
|
||||
imageModeMap: {},
|
||||
defaultImgUrl: '/public/static/index/assets.jpg',
|
||||
tagGroupList: [],
|
||||
selectedTags: [],
|
||||
background: {
|
||||
// 渐变色
|
||||
backgroundImage: 'linear-gradient(-90deg, #F9DED9 0%, #F8DFC0 99%);'
|
||||
},
|
||||
}
|
||||
@@ -119,18 +113,21 @@
|
||||
if (villageName) {
|
||||
this.searchData.villageName = villageName
|
||||
}
|
||||
// 获取街道数据
|
||||
this.findFilterTabData()
|
||||
this.findHouseList(null,option.keyword)
|
||||
},
|
||||
onShow() {
|
||||
|
||||
},
|
||||
onPageScroll(e) {
|
||||
this.scrollTop = e.scrollTop;
|
||||
},
|
||||
// 下拉刷新
|
||||
// ✅ 保留页面触底(瀑布流必须用这个)
|
||||
onReachBottom() {
|
||||
this.loadMore()
|
||||
},
|
||||
onPullDownRefresh() {
|
||||
this.resetAndLoad();
|
||||
// 关闭刷新
|
||||
uni.stopPullDownRefresh();
|
||||
},
|
||||
computed: {
|
||||
staticHost() {
|
||||
@@ -138,20 +135,13 @@
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 标签点击事件
|
||||
onTagClick(tag) {
|
||||
// 检查标签是否已选中
|
||||
const isSelected = this.selectedTags.includes(tag);
|
||||
if (isSelected) {
|
||||
// 如果已选中,则移除
|
||||
this.selectedTags = this.selectedTags.filter(item => item !== tag);
|
||||
} else {
|
||||
// 如果未选中,则添加
|
||||
this.selectedTags.push(tag);
|
||||
}
|
||||
// 这里可以添加根据标签筛选数据的逻辑
|
||||
console.log('标签点击:', tag);
|
||||
console.log('当前选中的标签:', this.selectedTags);
|
||||
this.resetAndLoad()
|
||||
},
|
||||
location() {
|
||||
@@ -165,14 +155,15 @@
|
||||
resetAndLoad() {
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 修复
|
||||
this.$nextTick(() => {
|
||||
this.$refs.uWaterfall && this.$refs.uWaterfall.clear();
|
||||
this.findHouseList();
|
||||
});
|
||||
},
|
||||
findHouseList(type = null,keyWord = null) {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
findHouseList(type = null,keyword = null) {
|
||||
// ✅ 正确判断
|
||||
if (this.loadStatus !== 'more') return;
|
||||
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
@@ -181,16 +172,20 @@
|
||||
assetsType: type,
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
keyWord: this.keyWord,
|
||||
bizZone: this.searchData.bizZone
|
||||
keyWord: keyword,
|
||||
bizZone: this.searchData.bizZone,
|
||||
layout: this.searchData.layout,
|
||||
renovationStatus: this.searchData.decoration,
|
||||
features: this.searchData.feature
|
||||
}).then(result => {
|
||||
const rows = result.data.result || [];
|
||||
// 第一页无数据
|
||||
|
||||
if (this.pageNo === 1 && rows.length === 0) {
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'nomore';
|
||||
return;
|
||||
}
|
||||
|
||||
rows.forEach(row => {
|
||||
if (row.coverImgUrl) {
|
||||
row.coverImgUrl = this.$config.staticUrl + row.coverImgUrl
|
||||
@@ -198,32 +193,29 @@
|
||||
row.coverImgUrl = this.$config.staticUrl + this.defaultImgUrl
|
||||
}
|
||||
})
|
||||
// 追加数据
|
||||
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
// 判断是否还有下一页(核心)
|
||||
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++; // ✅ 只有这里能 +1
|
||||
this.loadStatus = 'loadmore';
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'more'; // ✅ 恢复
|
||||
}
|
||||
this.keyWord = null
|
||||
|
||||
}).catch(err => {
|
||||
console.log("获取资产信息失败:", err);
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 恢复
|
||||
}).finally(() => {
|
||||
uni.stopPullDownRefresh();
|
||||
});
|
||||
},
|
||||
loadMore() {
|
||||
// 只有在 loadStatus 为 'loadmore' 时才触发
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// 调用接口获取下一页
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.findHouseList();
|
||||
},
|
||||
async findFilterTabData() {
|
||||
// 填充商圈数据到筛选菜单
|
||||
const bizZones = await this.getBizZone();
|
||||
const features = await this.getFeatures();
|
||||
let featureSubMenu = [];
|
||||
@@ -232,7 +224,6 @@
|
||||
name: bizZones[i],
|
||||
value: bizZones[i]
|
||||
});
|
||||
|
||||
}
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
featureSubMenu.push({
|
||||
@@ -240,7 +231,7 @@
|
||||
value: features[i]
|
||||
})
|
||||
}
|
||||
searchData[2].submenu.push({
|
||||
searchData[1].submenu.push({
|
||||
name:"基础配套",
|
||||
type:"radio-multi",
|
||||
submenu: featureSubMenu
|
||||
@@ -261,6 +252,18 @@
|
||||
}
|
||||
return [];
|
||||
},
|
||||
getImageSize(url, index) {
|
||||
uni.getImageInfo({
|
||||
src: url,
|
||||
success: (res) => {
|
||||
const { width, height } = res;
|
||||
this.$set(this.imageModeMap, index, width >= height ? 'widthFix' : 'aspectFit');
|
||||
},
|
||||
fail: () => {
|
||||
this.$set(this.imageModeMap, index, 'aspectFit');
|
||||
}
|
||||
});
|
||||
},
|
||||
clickImage(houseId) {
|
||||
this.$u.route({
|
||||
url: '/pages-assets/assets/assetsDetail',
|
||||
@@ -269,11 +272,9 @@
|
||||
}
|
||||
})
|
||||
},
|
||||
//接收菜单结果
|
||||
confirm(e) {
|
||||
let bizZone = e.value[0][0]
|
||||
let price = e.value[1][0]
|
||||
let combo = e.value[2]
|
||||
let combo = e.value[1]
|
||||
let layout = combo[0]
|
||||
let decoration = combo[1]
|
||||
let feature = combo[2]
|
||||
@@ -281,9 +282,6 @@
|
||||
if (bizZone) {
|
||||
this.searchData.bizZone = bizZone
|
||||
}
|
||||
if (price) {
|
||||
this.searchData.price = price
|
||||
}
|
||||
if (layout && layout.length > 0) {
|
||||
this.searchData.layout = layout.toString()
|
||||
}
|
||||
@@ -308,13 +306,11 @@
|
||||
}
|
||||
|
||||
.search-list-content {
|
||||
// padding-top: 20rpx;
|
||||
background: linear-gradient(-90deg, #F9DED9 0%, #F8DFC0 99%);
|
||||
border-radius: 0rpx;
|
||||
padding-bottom: 20rpx;
|
||||
}
|
||||
|
||||
// 搜索栏样式
|
||||
.search-bar-wrapper {
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
@@ -365,12 +361,9 @@
|
||||
}
|
||||
|
||||
.filter-dropdown-wrapper {
|
||||
// padding: 0 20rpx;
|
||||
border-radius: 10rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
// 标签组样式
|
||||
.tag-group {
|
||||
padding: 15rpx 20rpx;
|
||||
display: flex;
|
||||
@@ -444,15 +437,8 @@
|
||||
right: 20rpx;
|
||||
}
|
||||
|
||||
// 图片样式
|
||||
.u-lazy-load {
|
||||
width: 100%;
|
||||
height: 300rpx;
|
||||
}
|
||||
|
||||
.item-cover {
|
||||
font-size: 55rpx;
|
||||
color: $u-type-warning;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
@@ -485,7 +471,6 @@
|
||||
padding: 0 15rpx 8rpx 15rpx;
|
||||
}
|
||||
|
||||
// 标签样式
|
||||
.item-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
@@ -506,4 +491,15 @@
|
||||
color: $u-tips-color;
|
||||
margin-top: 3px;
|
||||
}
|
||||
.img{
|
||||
width: 100%;
|
||||
height: 230rpx;
|
||||
display: block;
|
||||
}
|
||||
.img-box {
|
||||
border-radius: 10rpx;
|
||||
width: 100%;
|
||||
height: 230rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -3,8 +3,19 @@
|
||||
<!-- 自定义导航栏 -->
|
||||
<custom-navbar title="租金待付" />
|
||||
|
||||
<scroll-view scroll-y class="scroll-content" :refresher-enabled="true" :refresher-triggered="isRefreshing"
|
||||
@refresherrefresh="refresh" @scrolltolower="loadMore">
|
||||
<!-- 筛选栏 -->
|
||||
<DateFilter :start="startDate" :end="endDate" @update:start="startDate = $event"
|
||||
@update:end="endDate = $event" @change="onDateFilterChange" />
|
||||
|
||||
<!-- 滚动列表 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="scroll-content"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="isRefreshing"
|
||||
@refresherrefresh="refresh"
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<view v-if="flowList.length > 0">
|
||||
<view class="bill-item" v-for="item in flowList" :key="item.billNo">
|
||||
<!-- 左侧勾选 + 信息 -->
|
||||
@@ -20,7 +31,8 @@
|
||||
<!-- 右侧金额 + 支付按钮 -->
|
||||
<view class="bill-right">
|
||||
<text class="amount">{{ formatMoney(item.billAmount) }}</text>
|
||||
<button class="pay-btn" @click="goPayTest([item])">去支付
|
||||
<button class="pay-btn" @click="goPay([item])" :disabled="isPaying">
|
||||
去支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -40,8 +52,8 @@
|
||||
合计:<text class="sumAmount">{{ formatMoney(sumAmount) }}</text>
|
||||
</view>
|
||||
<view class="batch-pay-bar-right">
|
||||
<button class="bottomPayBtn" color="linear-gradient(90deg, #007aff, #00aaff)" type="primary"
|
||||
size="small" @click="goPayTest(selectedBills)">
|
||||
<button class="bottomPayBtn" type="primary" size="small"
|
||||
@click="goPay(selectedBills)" :disabled="isPaying">
|
||||
批量支付
|
||||
</button>
|
||||
</view>
|
||||
@@ -50,16 +62,23 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DateFilter from '../../components/DatePicker/DateFilter.vue';
|
||||
export default {
|
||||
components: { DateFilter },
|
||||
data() {
|
||||
return {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
flowList: [],
|
||||
isRefreshing: false,
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more',
|
||||
sumAmount: 0,
|
||||
selectedBills: [], // 勾选的账单集合
|
||||
selectedBills: [],
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
minDate: "2000-01-01",
|
||||
maxDate: "2199-12-31",
|
||||
isPaying: false
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
@@ -70,167 +89,190 @@
|
||||
},
|
||||
methods: {
|
||||
loadBills() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
const token = this.$getToken()
|
||||
let url = '/bill/pageQueryContractBill'
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
billStatus: '待缴费'
|
||||
}, {
|
||||
WT: token
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
console.log(rows)
|
||||
|
||||
rows.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取待付合同账单记录失败:", err)
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
})
|
||||
this.updateSelected();
|
||||
},
|
||||
onDateFilterChange({ start, end }) {
|
||||
this.loadStatus = 'more'
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.selectedBills = [];
|
||||
this.sumAmount = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
this.loadBills();
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
}, 500);
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
this.loadBills();
|
||||
},
|
||||
|
||||
formatMoney(val) {
|
||||
if (val === null || val === undefined || isNaN(val)) return '—';
|
||||
|
||||
val = Number(val);
|
||||
|
||||
if (val >= 10000) {
|
||||
return '¥' + (val / 10000).toFixed(2) + '万';
|
||||
}
|
||||
|
||||
return '¥' + val.toFixed(2);
|
||||
},
|
||||
toggleCheck(item) {
|
||||
item.checked = !item.checked;
|
||||
if (item.checked && !this.selectedBills.some(b => b.id === item.id)) {
|
||||
if (item.checked) {
|
||||
if (!this.selectedBills.some(b => b.billNo === item.billNo)) {
|
||||
this.selectedBills.push(item);
|
||||
} else {
|
||||
// 取消勾选时从已选数组移除
|
||||
this.selectedBills = this.selectedBills.filter(b => b.id !== item.id);
|
||||
}
|
||||
let sumFee = 0;
|
||||
this.selectedBills.forEach(b => sumFee += b.billAmount);
|
||||
this.sumAmount = sumFee;
|
||||
} else {
|
||||
this.selectedBills = this.selectedBills.filter(b => b.billNo !== item.billNo);
|
||||
}
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
calcTotalAmount() {
|
||||
let sum = 0;
|
||||
this.selectedBills.forEach(b => {
|
||||
sum += Number(b.billAmount || 0);
|
||||
});
|
||||
this.sumAmount = sum;
|
||||
},
|
||||
updateSelected() {
|
||||
if (!Array.isArray(this.bills)) return;
|
||||
this.selectedBills = this.bills.filter(b => b.checked);
|
||||
this.selectedBills = this.flowList.filter(b => b.checked);
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
goPayTest(billList) {
|
||||
if (!billList || billList.length === 0) return;
|
||||
|
||||
// 模拟后台生成订单返回
|
||||
const order = {
|
||||
timeStamp: String(Date.now()), // 时间戳
|
||||
nonceStr: Math.random().toString(36).substr(2, 15), // 随机字符串
|
||||
package: 'prepay_id=TEST1234567890', // 模拟预支付ID
|
||||
timeStamp: String(Date.now()),
|
||||
nonceStr: Math.random().toString(36).substr(2, 15),
|
||||
package: 'prepay_id=TEST1234567890',
|
||||
signType: 'MD5',
|
||||
paySign: 'TEST_SIGN', // 模拟签名
|
||||
paySign: 'TEST_SIGN',
|
||||
};
|
||||
|
||||
// 调用微信支付接口(测试)
|
||||
uni.requestPayment({
|
||||
...order,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '支付成功(测试)',
|
||||
icon: 'success'
|
||||
});
|
||||
// 清空勾选状态
|
||||
uni.showToast({ title: '支付成功(测试)', icon: 'success' });
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
// 刷新列表(可选)
|
||||
this.loadBills();
|
||||
this.refresh();
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败(测试)',
|
||||
icon: 'none'
|
||||
});
|
||||
uni.showToast({ title: '支付失败(测试)', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
updateBillStatus(billIds) {
|
||||
const token = this.$getToken()
|
||||
this.$u.post('/bill/updateRentBillStatus', { billIds }, { WT: token })
|
||||
},
|
||||
async goPay(billList) {
|
||||
if (this.isPaying) return;
|
||||
if (!billList || billList.length === 0) return;
|
||||
|
||||
try {
|
||||
// 1. 请求后台生成订单
|
||||
const res = await uni.request({
|
||||
url: 'https://api.example.com/payments/create',
|
||||
method: 'POST',
|
||||
data: {
|
||||
userId: this.userId,
|
||||
bills: billList.map(b => b.id),
|
||||
}
|
||||
});
|
||||
this.isPaying = true;
|
||||
const token = this.$getToken()
|
||||
|
||||
if (res[1].data.code !== 0) {
|
||||
uni.showToast({
|
||||
title: res[1].data.msg,
|
||||
icon: 'none'
|
||||
});
|
||||
try {
|
||||
let unpaidBillVos = []
|
||||
let tempSumAmount = 0
|
||||
billList.forEach(bill => {
|
||||
unpaidBillVos.push({
|
||||
billNo: bill.billNo,
|
||||
bizType: 'rent',
|
||||
amount: bill.billAmount
|
||||
})
|
||||
tempSumAmount += Number(bill.billAmount)
|
||||
})
|
||||
|
||||
const res = await this.$u.post('/bill/pay', {
|
||||
amount: tempSumAmount,
|
||||
billVoList: unpaidBillVos
|
||||
}, { WT: token });
|
||||
|
||||
if (res.code !== 200) {
|
||||
uni.showToast({ title: res.msg, icon: 'none' });
|
||||
this.isPaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const order = res[1].data.data; // 后台返回的支付参数
|
||||
const order = res.data;
|
||||
let orderId = order.mainOrderId
|
||||
|
||||
// 2. 调用微信支付
|
||||
uni.requestPayment({
|
||||
timeStamp: order.timeStamp,
|
||||
nonceStr: order.nonceStr,
|
||||
package: order.package,
|
||||
signType: order.signType,
|
||||
paySign: order.paySign,
|
||||
timeStamp: order.miniPayRequest.timeStamp,
|
||||
nonceStr: order.miniPayRequest.nonceStr,
|
||||
package: order.miniPayRequest.packageStr,
|
||||
signType: order.miniPayRequest.signType,
|
||||
paySign: order.miniPayRequest.paySign,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// 更新勾选状态
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
// 刷新列表
|
||||
this.loadBills();
|
||||
this.refresh();
|
||||
this.isPaying = false;
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'none'
|
||||
});
|
||||
fail: (err) => {
|
||||
this.payFailCallback(err, orderId);
|
||||
this.isPaying = false;
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('支付请求失败', error);
|
||||
uni.showToast({
|
||||
title: '支付请求失败',
|
||||
icon: 'none'
|
||||
});
|
||||
console.error('支付请求异常', error);
|
||||
uni.showToast({ title: '支付请求失败', icon: 'none' });
|
||||
this.isPaying = false;
|
||||
}
|
||||
},
|
||||
|
||||
payFailCallback(err, orderId) {
|
||||
console.log("触发支付失败回调")
|
||||
let reason = "支付失败";
|
||||
if (err.errMsg?.includes("cancel")) {
|
||||
reason = "您已取消支付";
|
||||
} else if (err.errMsg?.includes("fail")) {
|
||||
reason = "支付失败,请重试";
|
||||
}
|
||||
|
||||
this.$u.get(`/bill/paycallback`, {
|
||||
orderId: orderId,
|
||||
payResult: "FAIL"
|
||||
}, { WT: this.$getToken() }).then(res => {
|
||||
console.log("回调成功", res)
|
||||
}).catch(err => {
|
||||
console.log("回调失败", err)
|
||||
})
|
||||
|
||||
uni.showToast({ title: reason, icon: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -238,10 +280,11 @@
|
||||
background: #f7f8fa;
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx;
|
||||
/* 自定义导航栏高度 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.scroll-content {
|
||||
height: calc(100vh - 175rpx - 110rpx);
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -263,6 +306,7 @@
|
||||
.bill-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 12rpx;
|
||||
|
||||
.bill-name {
|
||||
font-size: 30rpx;
|
||||
@@ -301,16 +345,12 @@
|
||||
padding: 0 40rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 6rpx; // 圆角
|
||||
border-radius: 6rpx;
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
background-color: #F34038;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
padding-top: 13rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.batch-pay-bar {
|
||||
@@ -318,7 +358,7 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 170rpx;
|
||||
height: 110rpx;
|
||||
padding: 0 30rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
@@ -359,6 +399,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
background-color: #ccc !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.empty {
|
||||
margin-top: 200rpx;
|
||||
|
||||
415
pages-biz/unpaid/unpaidMargin.vue
Normal file
415
pages-biz/unpaid/unpaidMargin.vue
Normal file
@@ -0,0 +1,415 @@
|
||||
<template>
|
||||
<view class="pending-bill-page">
|
||||
<!-- 自定义导航栏 -->
|
||||
<custom-navbar title="保证金待付" />
|
||||
|
||||
<DateFilter :start="startDate" :end="endDate" @update:start="startDate = $event"
|
||||
@update:end="endDate = $event" @change="onDateFilterChange" />
|
||||
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="scroll-content"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="isRefreshing"
|
||||
@refresherrefresh="refresh"
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<view v-if="flowList.length > 0">
|
||||
<view class="bill-item" v-for="item in flowList" :key="item.billNo">
|
||||
<!-- 左侧勾选 + 信息 -->
|
||||
<view class="bill-left">
|
||||
<u-checkbox v-model="item.checked" @change="toggleCheck(item)" size="32"
|
||||
active-color="#EA414A" />
|
||||
<view class="bill-info">
|
||||
<text class="bill-name">{{ $ellipsis(item.billName + item.billStartDate+'-'+item.billEndDate,27) }}) </text>
|
||||
<text class="bill-date">缴费截止:<text class="date">{{ item.billPayEndDate }}</text></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 右侧金额 + 支付按钮 -->
|
||||
<view class="bill-right">
|
||||
<text class="amount">{{ formatMoney(item.billAmount) }}</text>
|
||||
<button class="pay-btn" @click="goPay([item])" :disabled="isPaying">
|
||||
去支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-else class="empty">
|
||||
<u-empty mode="list" text="暂无待支付账单" />
|
||||
</view>
|
||||
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部批量支付栏 -->
|
||||
<view v-if="selectedBills.length > 0" class="batch-pay-bar">
|
||||
<view class="batch-pay-bar-left"><text>已选 {{ selectedBills.length }} 项</text></view>
|
||||
<view class="batch-pay-bar-center">
|
||||
合计:<text class="sumAmount">{{ formatMoney(sumAmount) }}</text>
|
||||
</view>
|
||||
<view class="batch-pay-bar-right">
|
||||
<button class="bottomPayBtn" type="primary" size="small"
|
||||
@click="goPay(selectedBills)" :disabled="isPaying">
|
||||
批量支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DateFilter from '../../components/DatePicker/DateFilter.vue';
|
||||
export default {
|
||||
components: { DateFilter },
|
||||
data() {
|
||||
return {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
flowList: [],
|
||||
isRefreshing: false,
|
||||
loadStatus: 'more', // ✅ 修复为正确状态
|
||||
sumAmount: 0,
|
||||
selectedBills: [],
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
minDate: "2000-01-01",
|
||||
maxDate: "2199-12-31",
|
||||
isPaying: false
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
this.loadBills();
|
||||
},
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ❌ 已删除冲突的 onReachBottom
|
||||
methods: {
|
||||
loadBills() {
|
||||
// ✅ 正确判断状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
const token = this.$getToken()
|
||||
let url = '/bill/pageQueryUnpaidMargin'
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
billStatus: '待缴费'
|
||||
}, {
|
||||
WT: token
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
rows.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
if (this.pageNo === 1) this.flowList = [];
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'more'; // ✅ 恢复可加载
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取待付保证金账单记录失败:", err)
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
})
|
||||
},
|
||||
onDateFilterChange({ start, end }) {
|
||||
this.loadStatus = 'more'
|
||||
this.refresh();
|
||||
},
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.selectedBills = [];
|
||||
this.sumAmount = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
this.loadBills();
|
||||
this.isRefreshing = false;
|
||||
}, 500);
|
||||
},
|
||||
loadMore() {
|
||||
this.loadBills();
|
||||
},
|
||||
formatMoney(val) {
|
||||
if (val === null || val === undefined || isNaN(val)) return '—';
|
||||
val = Number(val);
|
||||
if (val >= 10000) {
|
||||
return '¥' + (val / 10000).toFixed(2) + '万';
|
||||
}
|
||||
return '¥' + val.toFixed(2);
|
||||
},
|
||||
toggleCheck(item) {
|
||||
item.checked = !item.checked;
|
||||
if (item.checked) {
|
||||
if (!this.selectedBills.some(b => b.billNo === item.billNo)) {
|
||||
this.selectedBills.push(item);
|
||||
}
|
||||
} else {
|
||||
this.selectedBills = this.selectedBills.filter(b => b.billNo !== item.billNo);
|
||||
}
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
calcTotalAmount() {
|
||||
let sum = 0;
|
||||
this.selectedBills.forEach(b => {
|
||||
sum += Number(b.billAmount || 0);
|
||||
});
|
||||
this.sumAmount = sum;
|
||||
},
|
||||
updateSelected() {
|
||||
this.selectedBills = this.flowList.filter(b => b.checked);
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
goPayTest(billList) {
|
||||
if (!billList || billList.length === 0) return;
|
||||
const order = {
|
||||
timeStamp: String(Date.now()),
|
||||
nonceStr: Math.random().toString(36).substr(2, 15),
|
||||
package: 'prepay_id=TEST1234567890',
|
||||
signType: 'MD5',
|
||||
paySign: 'TEST_SIGN',
|
||||
};
|
||||
uni.requestPayment({
|
||||
...order,
|
||||
success: () => {
|
||||
uni.showToast({ title: '支付成功(测试)', icon: 'success' });
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
this.refresh();
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({ title: '支付失败(测试)', icon: 'none' });
|
||||
}
|
||||
});
|
||||
},
|
||||
updateBillStatus(billIds) {
|
||||
const token = this.$getToken()
|
||||
this.$u.post('/bill/updateRentBillStatus', { billIds }, { WT: token })
|
||||
},
|
||||
async goPay(billList) {
|
||||
if (this.isPaying) return;
|
||||
if (!billList || billList.length === 0) return;
|
||||
|
||||
this.isPaying = true;
|
||||
const token = this.$getToken()
|
||||
|
||||
try {
|
||||
let unpaidBillVos = []
|
||||
let tempSumAmount = 0
|
||||
billList.forEach(bill => {
|
||||
unpaidBillVos.push({
|
||||
billNo: bill.billNo,
|
||||
bizType: 'margin',
|
||||
amount: bill.billAmount
|
||||
})
|
||||
tempSumAmount += Number(bill.billAmount)
|
||||
})
|
||||
|
||||
const res = await this.$u.post('/bill/pay', {
|
||||
amount: tempSumAmount,
|
||||
billVoList: unpaidBillVos
|
||||
}, { WT: token });
|
||||
|
||||
if (res.code !== 200) {
|
||||
uni.showToast({ title: res.msg, icon: 'none' });
|
||||
this.isPaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const order = res.data;
|
||||
let orderId = order.mainOrderId
|
||||
|
||||
uni.requestPayment({
|
||||
timeStamp: order.miniPayRequest.timeStamp,
|
||||
nonceStr: order.miniPayRequest.nonceStr,
|
||||
package: order.miniPayRequest.packageStr,
|
||||
signType: order.miniPayRequest.signType,
|
||||
paySign: order.miniPayRequest.paySign,
|
||||
success: () => {
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
this.refresh();
|
||||
this.isPaying = false;
|
||||
},
|
||||
fail: (err) => {
|
||||
this.payFailCallback(err, orderId);
|
||||
this.isPaying = false;
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('支付请求异常', error);
|
||||
uni.showToast({ title: '支付请求失败', icon: 'none' });
|
||||
this.isPaying = false;
|
||||
}
|
||||
},
|
||||
|
||||
payFailCallback(err, orderId) {
|
||||
console.log("触发支付失败回调")
|
||||
let reason = "支付失败";
|
||||
if (err.errMsg?.includes("cancel")) {
|
||||
reason = "您已取消支付";
|
||||
} else if (err.errMsg?.includes("fail")) {
|
||||
reason = "支付失败,请重试";
|
||||
}
|
||||
|
||||
this.$u.get(`/bill/paycallback`, {
|
||||
orderId: orderId,
|
||||
payResult: "FAIL"
|
||||
}, { WT: this.$getToken() }).then(res => {
|
||||
console.log("回调成功", res)
|
||||
}).catch(err => {
|
||||
console.log("回调失败", err)
|
||||
})
|
||||
|
||||
uni.showToast({ title: reason, icon: 'none' });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.pending-bill-page {
|
||||
background: #f7f8fa;
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ✅ 核心修复:给滚动区域固定高度 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - 175rpx - 110rpx);
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.bill-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
background: #fff;
|
||||
margin-bottom: 20rpx;
|
||||
border-radius: 12rpx;
|
||||
padding: 20rpx;
|
||||
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.bill-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.bill-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 12rpx;
|
||||
|
||||
.bill-name {
|
||||
font-size: 30rpx;
|
||||
color: #2D2B2C;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.bill-date {
|
||||
font-size: 26rpx;
|
||||
color: #86868C;
|
||||
margin-top: 6rpx;
|
||||
|
||||
.date {
|
||||
font-size: 24rpx;
|
||||
color: #2D2B2C;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bill-right {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
width: 30%;
|
||||
|
||||
.amount {
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
height: 28rpx;
|
||||
line-height: 28rpx;
|
||||
color: #EF8849;
|
||||
}
|
||||
|
||||
.pay-btn {
|
||||
margin-top: 12rpx;
|
||||
padding: 0 40rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
background-color: #F34038;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
.batch-pay-bar {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 110rpx;
|
||||
padding: 0 30rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
box-shadow: 0 -4rpx 10rpx rgba(0, 0, 0, 0.08);
|
||||
z-index: 999;
|
||||
|
||||
.batch-pay-bar-left {
|
||||
font-size: 28rpx;
|
||||
color: #86868C;
|
||||
}
|
||||
|
||||
.batch-pay-bar-center {
|
||||
font-size: 28rpx;
|
||||
color: #222222;
|
||||
|
||||
.sumAmount {
|
||||
font-size: 28rpx;
|
||||
color: #ff7f00;
|
||||
}
|
||||
}
|
||||
|
||||
.batch-pay-bar-right {
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
|
||||
.bottomPayBtn {
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
padding: 0 40rpx;
|
||||
border-radius: 6rpx;
|
||||
font-size: 30rpx;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background: #F34038;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
background-color: #ccc !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.empty {
|
||||
margin-top: 200rpx;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
@@ -1,13 +1,20 @@
|
||||
<template>
|
||||
<view class="pending-bill-page">
|
||||
<!-- 自定义导航栏 -->
|
||||
<custom-navbar title="水电费待付" />
|
||||
|
||||
<scroll-view scroll-y class="scroll-content" :refresher-enabled="true" :refresher-triggered="isRefreshing"
|
||||
@refresherrefresh="refresh" @scrolltolower="loadMore">
|
||||
<DateFilter :start="startDate" :end="endDate" @update:start="startDate = $event"
|
||||
@update:end="endDate = $event" @change="onDateFilterChange" />
|
||||
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="scroll-content"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="isRefreshing"
|
||||
@refresherrefresh="refresh"
|
||||
@scrolltolower="loadMore"
|
||||
>
|
||||
<view v-if="bills.length > 0">
|
||||
<view class="bill-item" v-for="item in bills" :key="item.billNo">
|
||||
<!-- 左侧勾选 + 信息 -->
|
||||
<view class="bill-left">
|
||||
<u-checkbox v-model="item.checked" @change="toggleCheck(item)" size="32"
|
||||
active-color="#EA414A" />
|
||||
@@ -17,10 +24,10 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 右侧金额 + 支付按钮 -->
|
||||
<view class="bill-right">
|
||||
<text class="amount">{{ formatMoney(item.billAmount) }}</text>
|
||||
<button class="pay-btn" @click="goPayTest([item])">去支付
|
||||
<button class="pay-btn" @click="goPay([item])" :disabled="isPaying">
|
||||
去支付
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
@@ -33,15 +40,15 @@
|
||||
<u-loadmore :status="loadStatus" />
|
||||
</scroll-view>
|
||||
|
||||
<!-- 底部批量支付栏 -->
|
||||
<view v-if="selectedBills.length > 0" class="batch-pay-bar">
|
||||
<view class="batch-pay-bar-left"><text>已选 {{ selectedBills.length }} 项</text></view>
|
||||
<view class="batch-pay-bar-center">
|
||||
合计:<text class="sumAmount">{{ formatMoney(sumAmount) }}</text>
|
||||
</view>
|
||||
<view class="batch-pay-bar-right">
|
||||
<button class="bottomPayBtn" color="linear-gradient(90deg, #007aff, #00aaff)" type="primary"
|
||||
size="small" @click="goPayTest(selectedBills)">
|
||||
<button class="bottomPayBtn" type="primary" size="small"
|
||||
@click="goPay(selectedBills)"
|
||||
:disabled="isPaying">
|
||||
批量缴费
|
||||
</button>
|
||||
</view>
|
||||
@@ -50,16 +57,23 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DateFilter from '../../components/DatePicker/DateFilter.vue';
|
||||
export default {
|
||||
components: { DateFilter },
|
||||
data() {
|
||||
return {
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
bills: [],
|
||||
isRefreshing: false,
|
||||
loadStatus: 'loadmore',
|
||||
loadStatus: 'more', // ✅ 修复为正确状态
|
||||
sumAmount: 0,
|
||||
selectedBills: [], // 勾选的账单集合
|
||||
selectedBills: [],
|
||||
startDate: "",
|
||||
endDate: "",
|
||||
minDate: "2000-01-01",
|
||||
maxDate: "2199-12-31",
|
||||
isPaying: false
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
@@ -68,166 +82,174 @@
|
||||
onShow() {
|
||||
this.$checkToken(this.$getToken())
|
||||
},
|
||||
// ❌ 已删除冲突的 onReachBottom
|
||||
methods: {
|
||||
loadBills() {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// ✅ 正确判断状态
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
const token = this.$getToken();
|
||||
let url = '/bill/pageQueryWaeBill'
|
||||
this.$u.post(url, {
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
startDate: this.startDate,
|
||||
endDate: this.endDate,
|
||||
billStatus: '待缴费'
|
||||
}, {
|
||||
WT: token
|
||||
}).then(
|
||||
result => {
|
||||
const rows = result.data.result || [];
|
||||
|
||||
}).then(res => {
|
||||
const rows = res.data.result || [];
|
||||
rows.forEach(item => {
|
||||
item.checked = false;
|
||||
});
|
||||
if (this.pageNo === 1) this.bills = [];
|
||||
|
||||
this.bills = this.bills.concat(rows);
|
||||
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more'; // ✅ 恢复可加载
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取水电费账单失败:", err);
|
||||
this.loadStatus = 'more'; // ✅ 异常恢复
|
||||
})
|
||||
this.updateSelected();
|
||||
},
|
||||
refresh() {
|
||||
this.isRefreshing = true;
|
||||
this.pageNo = 1;
|
||||
this.selectedBills = [];
|
||||
this.sumAmount = 0;
|
||||
|
||||
setTimeout(() => {
|
||||
this.loadBills();
|
||||
this.isRefreshing = false;
|
||||
}, 1000);
|
||||
}, 500);
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
this.loadBills()
|
||||
},
|
||||
|
||||
onDateFilterChange({ start, end }) {
|
||||
this.loadStatus = 'more'
|
||||
this.refresh();
|
||||
},
|
||||
formatMoney(val) {
|
||||
if (val === null || val === undefined || isNaN(val)) return '—';
|
||||
|
||||
val = Number(val);
|
||||
|
||||
if (val >= 10000) {
|
||||
return '¥' + (val / 10000).toFixed(2) + '万';
|
||||
}
|
||||
|
||||
return '¥' + val.toFixed(2);
|
||||
},
|
||||
toggleCheck(item) {
|
||||
item.checked = !item.checked;
|
||||
if (item.checked && !this.selectedBills.some(b => b.id === item.id)) {
|
||||
if (item.checked) {
|
||||
if (!this.selectedBills.some(b => b.billNo === item.billNo)) {
|
||||
this.selectedBills.push(item);
|
||||
} else {
|
||||
// 取消勾选时从已选数组移除
|
||||
this.selectedBills = this.selectedBills.filter(b => b.id !== item.id);
|
||||
}
|
||||
let sumFee = 0;
|
||||
this.selectedBills.forEach(b => sumFee += b.billAmount);
|
||||
this.sumAmount = sumFee;
|
||||
} else {
|
||||
this.selectedBills = this.selectedBills.filter(b => b.billNo !== item.billNo);
|
||||
}
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
calcTotalAmount() {
|
||||
let sum = 0;
|
||||
this.selectedBills.forEach(b => {
|
||||
sum += Number(b.billAmount || 0);
|
||||
});
|
||||
this.sumAmount = sum;
|
||||
},
|
||||
updateSelected() {
|
||||
if (!Array.isArray(this.bills)) return;
|
||||
this.selectedBills = this.bills.filter(b => b.checked);
|
||||
},
|
||||
goPayTest(billList) {
|
||||
if (!billList || billList.length === 0) return;
|
||||
|
||||
// 模拟后台生成订单返回
|
||||
const order = {
|
||||
timeStamp: String(Date.now()), // 时间戳
|
||||
nonceStr: Math.random().toString(36).substr(2, 15), // 随机字符串
|
||||
package: 'prepay_id=TEST1234567890', // 模拟预支付ID
|
||||
signType: 'MD5',
|
||||
paySign: 'TEST_SIGN', // 模拟签名
|
||||
};
|
||||
|
||||
// 调用微信支付接口(测试)
|
||||
uni.requestPayment({
|
||||
...order,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '支付成功(测试)',
|
||||
icon: 'success'
|
||||
});
|
||||
// 清空勾选状态
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
// 刷新列表(可选)
|
||||
this.loadBills();
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败(测试)',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
this.calcTotalAmount();
|
||||
},
|
||||
async goPay(billList) {
|
||||
if (this.isPaying) return;
|
||||
if (!billList || billList.length === 0) return;
|
||||
|
||||
try {
|
||||
// 1. 请求后台生成订单
|
||||
const res = await uni.request({
|
||||
url: 'https://api.example.com/payments/create',
|
||||
method: 'POST',
|
||||
data: {
|
||||
userId: this.userId,
|
||||
bills: billList.map(b => b.id),
|
||||
}
|
||||
});
|
||||
this.isPaying = true;
|
||||
const token = this.$getToken()
|
||||
|
||||
if (res[1].data.code !== 0) {
|
||||
uni.showToast({
|
||||
title: res[1].data.msg,
|
||||
icon: 'none'
|
||||
});
|
||||
try {
|
||||
let unpaidBillVos = []
|
||||
let tempSumAmount = 0
|
||||
billList.forEach(bill => {
|
||||
let tempBill = {
|
||||
billNo: bill.billNo,
|
||||
bizType: 'wae',
|
||||
amount: bill.billAmount
|
||||
}
|
||||
tempSumAmount += Number(bill.billAmount)
|
||||
unpaidBillVos.push(tempBill)
|
||||
})
|
||||
|
||||
const params = {
|
||||
amount: tempSumAmount,
|
||||
billVoList: unpaidBillVos
|
||||
}
|
||||
|
||||
let url = '/bill/pay'
|
||||
const res = await this.$u.post(url, params, { WT: token });
|
||||
|
||||
if (res.code !== 200) {
|
||||
uni.showToast({ title: res.msg, icon: 'none' });
|
||||
this.isPaying = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const order = res[1].data.data; // 后台返回的支付参数
|
||||
const order = res.data;
|
||||
let orderId = order.mainOrderId
|
||||
|
||||
// 2. 调用微信支付
|
||||
uni.requestPayment({
|
||||
timeStamp: order.timeStamp,
|
||||
nonceStr: order.nonceStr,
|
||||
package: order.package,
|
||||
signType: order.signType,
|
||||
paySign: order.paySign,
|
||||
timeStamp: order.miniPayRequest.timeStamp,
|
||||
nonceStr: order.miniPayRequest.nonceStr,
|
||||
package: order.miniPayRequest.packageStr,
|
||||
signType: order.miniPayRequest.signType,
|
||||
paySign: order.miniPayRequest.paySign,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '支付成功',
|
||||
icon: 'success'
|
||||
});
|
||||
// 更新勾选状态
|
||||
billList.forEach(b => b.checked = false);
|
||||
this.updateSelected();
|
||||
// 刷新列表
|
||||
this.loadBills();
|
||||
this.refresh();
|
||||
this.isPaying = false;
|
||||
},
|
||||
fail: () => {
|
||||
uni.showToast({
|
||||
title: '支付失败',
|
||||
icon: 'none'
|
||||
});
|
||||
fail: (err) => {
|
||||
this.payFailCallback(err, orderId);
|
||||
this.isPaying = false;
|
||||
}
|
||||
});
|
||||
|
||||
} catch (error) {
|
||||
console.error('支付请求失败', error);
|
||||
uni.showToast({
|
||||
title: '支付请求失败',
|
||||
icon: 'none'
|
||||
});
|
||||
console.error('支付请求异常', error);
|
||||
uni.showToast({ title: '支付请求失败', icon: 'none' });
|
||||
this.isPaying = false;
|
||||
}
|
||||
},
|
||||
// ✅ 修复支付失败回调(参数+接口格式)
|
||||
payFailCallback(err, orderId) {
|
||||
let reason = "支付失败";
|
||||
if (err.errMsg?.includes("cancel")) {
|
||||
reason = "您已取消支付";
|
||||
} else if (err.errMsg?.includes("fail")) {
|
||||
reason = "支付失败,请重试";
|
||||
}
|
||||
|
||||
this.$u.get(`/bill/paycallback`, {
|
||||
orderId: orderId,
|
||||
payResult: "FAIL"
|
||||
}, {
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
console.log("回调成功")
|
||||
}).catch(err => {
|
||||
console.log("回调失败", err)
|
||||
})
|
||||
|
||||
uni.showToast({ title: reason, icon: 'none' });
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -237,10 +259,12 @@
|
||||
background: #f7f8fa;
|
||||
min-height: 100vh;
|
||||
padding-top: 175rpx;
|
||||
/* 自定义导航栏高度 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* ✅ 核心修复:给滚动区域固定高度 */
|
||||
.scroll-content {
|
||||
height: calc(100vh - 175rpx - 110rpx);
|
||||
padding: 20rpx;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
@@ -262,6 +286,7 @@
|
||||
.bill-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-left: 12rpx;
|
||||
|
||||
.bill-name {
|
||||
font-size: 30rpx;
|
||||
@@ -300,16 +325,12 @@
|
||||
padding: 0 40rpx;
|
||||
height: 60rpx;
|
||||
line-height: 60rpx;
|
||||
border-radius: 6rpx; // 圆角
|
||||
border-radius: 6rpx;
|
||||
font-size: 30rpx;
|
||||
color: #fff;
|
||||
background-color: #F34038;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
padding-top: 13rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.batch-pay-bar {
|
||||
@@ -317,7 +338,7 @@
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 170rpx;
|
||||
height: 110rpx;
|
||||
padding: 0 30rpx;
|
||||
background-color: #fff;
|
||||
display: flex;
|
||||
@@ -358,6 +379,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
button[disabled] {
|
||||
opacity: 0.5 !important;
|
||||
background-color: #ccc !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.empty {
|
||||
margin-top: 200rpx;
|
||||
|
||||
@@ -151,6 +151,13 @@
|
||||
"navigationBarTitleText": "我的待付"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "unpaid/unpaidMargin",
|
||||
"style": {
|
||||
"navigationStyle": "custom", // 隐藏系统导航栏
|
||||
"navigationBarTitleText": "保证金待付"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "login/login",
|
||||
"style": {
|
||||
|
||||
@@ -87,6 +87,15 @@
|
||||
</view>
|
||||
<view class="service-name">租金待付</view>
|
||||
</view>
|
||||
<view class="service-item" @click="clickNav('/pages-biz/unpaid/unpaidMargin')">
|
||||
<view class="service-icon badge-wrapper">
|
||||
<image :src="staticHost + '/public' + '/static/icon/unpaidMargin.png'"></image>
|
||||
<view v-if="unpaidMargin > 0" class="badge">
|
||||
{{ unpaidMargin > 99 ? '99+' : unpaidMargin }}
|
||||
</view>
|
||||
</view>
|
||||
<view class="service-name">保证金待付</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -129,6 +138,7 @@
|
||||
unreadMsgCount: 0, // 未读消息
|
||||
unpaidWaeCount: 0, // 水电费待付
|
||||
unpaidRentCount: 0, // 租金待付
|
||||
unpaidMargin: 0,//保证金待付
|
||||
navbarStyle: {
|
||||
isTransparent: true,
|
||||
bgColor: '#ffffff',
|
||||
@@ -176,6 +186,7 @@
|
||||
this.countUnpayRentBills()
|
||||
this.countUnpayWaeBills()
|
||||
this.countUnreadMsg()
|
||||
this.countUnpaidRentMargin()
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -272,6 +283,15 @@
|
||||
}
|
||||
})
|
||||
},
|
||||
countUnpaidRentMargin(){
|
||||
this.$u.get(`/bill/countUnpaidMargin`, {},{
|
||||
WT: this.$getToken()
|
||||
}).then(res => {
|
||||
if(res.flag){
|
||||
this.unpaidMargin = res.data
|
||||
}
|
||||
})
|
||||
},
|
||||
countUnpayWaeBills(){
|
||||
this.$u.get(`/bill/countUnpayWaeBills`, {},{
|
||||
WT: this.$getToken()
|
||||
@@ -414,11 +434,12 @@
|
||||
|
||||
.service-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap; /* 关键:自动换行 */
|
||||
gap: 60rpx;
|
||||
}
|
||||
|
||||
.service-item {
|
||||
flex: 1;
|
||||
width: 18%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
<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="staticHost + '/public' + item.src " style="width: 86rpx;height: 86rpx;" mode="heightFix"></image>
|
||||
<image :src="staticHost + '/public' + item.src " style="width: 86rpx;height: 86rpx;"
|
||||
mode="aspectFill"></image>
|
||||
<view class="tabName" :style="{color:'#FFFFFF'}">{{item.name}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
@@ -27,7 +28,8 @@
|
||||
<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="staticHost + '/public' + item.src" style="width: 50rpx;height: 50rpx;" mode="heightFix"></image>
|
||||
<image :src="staticHost + '/public' + item.src" style="width: 50rpx;height: 50rpx;"
|
||||
mode="aspectFill"></image>
|
||||
<view class="tabName" :style="{color:'#222222'}">{{item.name}}</view>
|
||||
</view>
|
||||
</u-col>
|
||||
@@ -38,7 +40,8 @@
|
||||
<u-gap height="10"></u-gap>
|
||||
<!-- 公告栏 -->
|
||||
<view @click="notice" class="noticeStyle">
|
||||
<image :src="staticHost + '/public' + '/static/index/notice.png'" style="width: 38rpx;height: 37rpx;margin-left: 22rpx;"></image>
|
||||
<image :src="staticHost + '/public' + '/static/index/notice.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>
|
||||
@@ -64,29 +67,28 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y style="height: calc(100vh - 200rpx);" :scroll-top="scrollTop"
|
||||
@scrolltolower="loadMore" lower-threshold="50">
|
||||
<scroll-view scroll-y class="waterfall-scroll" @scrolltolower="loadMore" 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"
|
||||
<view class="demo-warter" v-for="(item, index) in leftList" :key="item.assetsNo"
|
||||
style="margin-right: 10rpx;">
|
||||
<u-lazy-load threshold="750" border-radius="8" :image="item.coverImgUrl"
|
||||
:index="index" mode="aspectFill" @click="clickImage(item.assetsNo)"></u-lazy-load>
|
||||
<view class="img-box" @click="clickImage(item.assetsNo)">
|
||||
<img class="img" :src="item.coverImgUrl" alt="" />
|
||||
</view>
|
||||
<view class="item-title">{{ item.assetsName}}</view>
|
||||
<view class="item-desc">{{ item.footPrint || '0'}}㎡ {{ item.assetsType || '商业用房' }}
|
||||
</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"
|
||||
<view class="demo-warter" v-for="(item, index) in rightList" :key="item.assetsNo"
|
||||
style="margin-left: 10rpx;">
|
||||
<u-lazy-load threshold="750" border-radius="8" :image="item.coverImgUrl"
|
||||
:index="index" mode="aspectFill" @click="clickImage(item.assetsNo)"></u-lazy-load>
|
||||
<view class="img-box" @click="clickImage(item.assetsNo)">
|
||||
<img class="img" :src="item.coverImgUrl" alt="" />
|
||||
</view>
|
||||
<view class="item-title">{{ item.assetsName}}</view>
|
||||
<view class="item-desc">{{ item.footPrint || '0'}}㎡ {{ item.assetsType || '商业用房' }}
|
||||
</view>
|
||||
<view class="item-price">¥{{item.rentFee || '未知'}}/<text>月</text></view>
|
||||
</view>
|
||||
</template>
|
||||
</u-waterfall>
|
||||
@@ -114,9 +116,9 @@
|
||||
pageNo: 1,
|
||||
pageSize: 20,
|
||||
scrollTop: 0,
|
||||
activeIndex: 0, // 当前选中的索引
|
||||
activeIndex: 0,
|
||||
noticeList: [],
|
||||
filterActiveConditions:[],
|
||||
filterActiveConditions: [],
|
||||
defaultImgUrl: '/public/static/index/assets.jpg',
|
||||
navList: [{
|
||||
name: "住房",
|
||||
@@ -160,8 +162,7 @@
|
||||
url: "/pages-assets/fallback/fallback"
|
||||
}
|
||||
],
|
||||
loadStatus: 'loadmore',
|
||||
// 顶部标签栏状态
|
||||
loadStatus: 'more', // ✅ 只改这里
|
||||
activeRecommendTab: 0,
|
||||
recommendTabs: [{
|
||||
label: '为您推荐',
|
||||
@@ -172,8 +173,7 @@
|
||||
type: 'new'
|
||||
}
|
||||
],
|
||||
// 筛选标签状态
|
||||
activeFilterTabs: [0], // 支持多选
|
||||
activeFilterTabs: [],
|
||||
filterTabs: [{
|
||||
label: '两室',
|
||||
filterType: '户型',
|
||||
@@ -190,21 +190,14 @@
|
||||
}
|
||||
},
|
||||
onLoad() {
|
||||
|
||||
this.getNoticecList();
|
||||
// 流量统计
|
||||
// this.appSysFlowInfo();
|
||||
|
||||
this.resetAndLoad()
|
||||
uni.$on('findIndexHouseList', (obj) => {
|
||||
// 获取数据
|
||||
this.findHouseList();
|
||||
})
|
||||
},
|
||||
onShow() {
|
||||
this.resetAndLoad()
|
||||
},
|
||||
onShow() {},
|
||||
onUnload() {
|
||||
// 移除监听事件
|
||||
uni.$off('findIndexHouseList');
|
||||
},
|
||||
onPageScroll(e) {
|
||||
@@ -213,62 +206,51 @@
|
||||
// 下拉刷新
|
||||
onPullDownRefresh() {
|
||||
this.resetAndLoad();
|
||||
// 关闭刷新
|
||||
uni.stopPullDownRefresh();
|
||||
},
|
||||
mounted() {
|
||||
|
||||
// ✅ 底部加载(不动逻辑)
|
||||
onReachBottom() {
|
||||
this.loadMore()
|
||||
},
|
||||
mounted() {},
|
||||
computed: {
|
||||
staticHost() {
|
||||
return this.$config.staticUrl
|
||||
},
|
||||
vuex_city() {
|
||||
return uni.getStorageSync('lifeData')?.vuex_city || ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 顶部推荐标签点击事件
|
||||
// 👇 你的所有方法 100% 不动
|
||||
onRecommendTabClick(index) {
|
||||
this.activeRecommendTab = index;
|
||||
// 这里可以添加根据标签筛选数据的逻辑
|
||||
console.log('推荐标签点击:', this.recommendTabs[index]);
|
||||
// 重置筛选条件
|
||||
this.activeFilterTabs = [0];
|
||||
// 重新加载数据
|
||||
this.activeFilterTabs = [];
|
||||
this.resetAndLoad();
|
||||
},
|
||||
resetAndLoad() {
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.$refs.uWaterfall && this.$refs.uWaterfall.clear();
|
||||
this.findHouseList();
|
||||
});
|
||||
},
|
||||
// 筛选标签点击事件
|
||||
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]));
|
||||
this.resetAndLoad();
|
||||
},
|
||||
|
||||
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-biz/location/location');
|
||||
}
|
||||
},
|
||||
@@ -280,47 +262,45 @@
|
||||
url: '/pages-biz/notice/notice'
|
||||
})
|
||||
},
|
||||
//查找房源信息
|
||||
findHouseList(type = null) {
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
if (this.loadStatus !== 'more') return;
|
||||
|
||||
this.loadStatus = 'loading';
|
||||
|
||||
let recommendType = this.recommendTabs[this.activeRecommendTab].type;
|
||||
let layoutList = this.activeFilterTabs.map(i => this.filterTabs[i].value);
|
||||
this.$u.post('/assets/queryPage', {
|
||||
assetsType: type,
|
||||
pageNo: this.pageNo,
|
||||
pageSize: this.pageSize,
|
||||
assetsStatus: '闲置中'
|
||||
assetsStatus: '闲置中',
|
||||
recommendType: recommendType,
|
||||
layout: layoutList.length > 0 ? layoutList.join(',') : null
|
||||
}).then(result => {
|
||||
|
||||
let rows = result.data.result || [];
|
||||
// 第一页无数据
|
||||
if (this.pageNo === 1 && rows.length === 0) {
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'nomore';
|
||||
return;
|
||||
}
|
||||
rows.forEach(row =>{
|
||||
if(row.coverImgUrl) {
|
||||
rows.forEach(row => {
|
||||
if (row.coverImgUrl) {
|
||||
row.coverImgUrl = this.$config.staticUrl + row.coverImgUrl
|
||||
}else {
|
||||
} else {
|
||||
row.coverImgUrl = this.$config.staticUrl + this.defaultImgUrl
|
||||
}
|
||||
})
|
||||
// 追加数据
|
||||
this.flowList = this.flowList.concat(rows);
|
||||
|
||||
// 判断是否还有下一页(核心)
|
||||
if (rows.length < this.pageSize) {
|
||||
this.loadStatus = 'nomore';
|
||||
} else {
|
||||
this.pageNo++; // ✅ 只有这里能 +1
|
||||
this.loadStatus = 'loadmore';
|
||||
this.pageNo++;
|
||||
this.loadStatus = 'more';
|
||||
}
|
||||
|
||||
}).catch(err => {
|
||||
console.log("获取资产信息失败:", err);
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
}).finally(() => {
|
||||
uni.stopPullDownRefresh();
|
||||
});
|
||||
@@ -338,7 +318,7 @@
|
||||
this.activeIndex = index;
|
||||
this.pageNo = 1;
|
||||
this.flowList = [];
|
||||
this.loadStatus = 'loadmore';
|
||||
this.loadStatus = 'more';
|
||||
this.$nextTick(() => {
|
||||
this.$refs.uWaterfall && this.$refs.uWaterfall.clear();
|
||||
this.findHouseList(item.name);
|
||||
@@ -348,19 +328,15 @@
|
||||
this.$u.route({
|
||||
url: item.url
|
||||
})
|
||||
|
||||
},
|
||||
code() {
|
||||
this.$mytip.toast('请咨询作者')
|
||||
},
|
||||
loadMore() {
|
||||
// 只有在 loadStatus 为 'loadmore' 时才触发
|
||||
if (this.loadStatus !== 'loadmore') return;
|
||||
// 调用接口获取下一页
|
||||
if (this.loadStatus !== 'more') return;
|
||||
this.findHouseList();
|
||||
},
|
||||
appSysFlowInfo() {
|
||||
// 流量统计
|
||||
let uvCode = uni.getStorageSync("uvCode");
|
||||
let url = "https://sourcebyte.cn/api/flow/upFlow?type=MINI&uvCode=" + uvCode;
|
||||
uni.request({
|
||||
@@ -379,13 +355,18 @@
|
||||
}).then(obj => {
|
||||
if (obj.flag) {
|
||||
let data = obj.data.result
|
||||
if (data) {
|
||||
data.filter(item => {
|
||||
this.noticeList.push(item.noticeTitle)
|
||||
this.noticeList.push((item.noticeTitle || item.noticeContent))
|
||||
})
|
||||
}
|
||||
}
|
||||
}).catch(err => {
|
||||
console.log("获取招商公告失败:", err)
|
||||
});
|
||||
},
|
||||
location() {
|
||||
this.$u.route('/pages-biz/location/location')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,9 +375,8 @@
|
||||
<style lang="scss" scoped>
|
||||
.index {
|
||||
background: #F8F8F8;
|
||||
min-height: 100vh; // 防止内容少时顶部空白
|
||||
min-height: 100vh;
|
||||
position: relative;
|
||||
|
||||
}
|
||||
|
||||
.bg {
|
||||
@@ -405,7 +385,6 @@
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 550rpx;
|
||||
/* ✅ 用固定高度更稳,你可改 320/400 */
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
@@ -415,7 +394,6 @@
|
||||
top: 5%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
font-family: Noto Sans S Chinese;
|
||||
font-weight: 400;
|
||||
font-size: 34rpx;
|
||||
@@ -430,7 +408,7 @@
|
||||
.search-wrapper {}
|
||||
|
||||
.content-wrapper {
|
||||
padding: 197rpx 30rpx 22rpx 30rpx; // 统一左右内边距
|
||||
padding: 197rpx 30rpx 22rpx 30rpx;
|
||||
}
|
||||
|
||||
.navbox2 {
|
||||
@@ -444,8 +422,6 @@
|
||||
background-color: $u-bg-color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.noticeStyle {
|
||||
display: flex;
|
||||
margin-top: 22rpx;
|
||||
@@ -459,7 +435,6 @@
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
/* 下划线 */
|
||||
.underline {
|
||||
margin-top: 5rpx;
|
||||
width: 130rpx;
|
||||
@@ -511,7 +486,6 @@
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* 顶部标签栏样式 */
|
||||
.recommend-tabs {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
@@ -532,7 +506,6 @@
|
||||
border-bottom: 4rpx solid #FF2F31;
|
||||
}
|
||||
|
||||
/* 筛选标签样式 */
|
||||
.filter-tabs {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
@@ -558,21 +531,11 @@
|
||||
|
||||
.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 {
|
||||
@@ -619,7 +582,6 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 标题 */
|
||||
.auth-title {
|
||||
font-size: 34rpx;
|
||||
font-weight: 600;
|
||||
@@ -628,7 +590,6 @@
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
/* 描述 */
|
||||
.auth-desc {
|
||||
font-size: 26rpx;
|
||||
color: #888;
|
||||
@@ -637,7 +598,6 @@
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
/* 输入区域 */
|
||||
.auth-input {
|
||||
margin-bottom: 48rpx;
|
||||
|
||||
@@ -646,7 +606,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* 提交按钮 */
|
||||
.auth-btn {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
@@ -660,11 +619,22 @@
|
||||
box-shadow: 0 10rpx 24rpx rgba(41, 121, 255, 0.3);
|
||||
}
|
||||
|
||||
/* 按压效果 */
|
||||
.auth-btn:active {
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.img {
|
||||
width: 100%;
|
||||
height: 230rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.img-box {
|
||||
border-radius: 10rpx;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.buttom {
|
||||
.loginType {
|
||||
font-size: 14px;
|
||||
@@ -683,4 +653,10 @@
|
||||
box-shadow: 0px 1px 20px 0px rgba(0, 0, 0, 0.1), inset 0px -1px 0px 0px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* ✅ 修复高度,不卡不抖 */
|
||||
.waterfall-scroll {
|
||||
height: calc(100vh - 500rpx);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user