Compare commits
No commits in common. "a5178d64f662d7764f10a65043b156121fe3ce98" and "1d16210f89422f673f6953263bafb28a1ea4017c" have entirely different histories.
a5178d64f6
...
1d16210f89
@ -397,11 +397,11 @@ export default {
|
||||
},
|
||||
|
||||
previewImage(index) {
|
||||
// if (!this.detailInfo.detailImages || !this.detailInfo.detailImages.length) return;
|
||||
if (!this.detailInfo.detailImages || !this.detailInfo.detailImages.length) return;
|
||||
|
||||
uni.previewImage({
|
||||
current: index,
|
||||
urls: this.detailInfo.imgs.map(img => img.startsWith('http') ? img : IMAGE_BASE_URL + img)
|
||||
urls: this.detailInfo.detailImages.map(img => img.startsWith('http') ? img : IMAGE_BASE_URL + img)
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
<view class="weather-main">
|
||||
<view class="current-weather">
|
||||
<image class="weather-icon"
|
||||
:src="weather.weather ? getWeatherIcon(weather.weather) : '/static/imgs/weather.png'"
|
||||
:src="weather.weather ? getWeatherIcon(weather.weather) : '/static/imgs/weather/default.png'"
|
||||
mode="aspectFit"></image>
|
||||
<text class="current-temp">{{weather.real || '--'}}°</text>
|
||||
</view>
|
||||
@ -124,7 +124,7 @@ import Copyright from '@/components/gx-copyright.vue';
|
||||
import Footer from '@/components/footer_common.vue';
|
||||
import { get, post } from '@/utils/request';
|
||||
import { IMAGE_BASE_URL, BASE_URL } from '@/utils/config';
|
||||
import {navigateTo} from '@/utils/router.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Footer,
|
||||
@ -157,15 +157,10 @@ export default {
|
||||
this.getWeather();
|
||||
},
|
||||
methods: {
|
||||
goDetail(page) {
|
||||
if(page==='neighbor'){
|
||||
navigateTo({url: `/pages/${page}/index`})
|
||||
}else{
|
||||
uni.navigateTo({
|
||||
url: `/pages/${page}/index`
|
||||
});
|
||||
}
|
||||
|
||||
goDetail(page) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/${page}/index`
|
||||
});
|
||||
},
|
||||
formatDate(date) {
|
||||
const weekdays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
|
||||
|
||||
@ -39,7 +39,6 @@
|
||||
|
||||
<!-- 预约记录列表 -->
|
||||
<view class="order-list" v-else>
|
||||
<u-loading-page :loading="dataloading"></u-loading-page>
|
||||
<view v-if="orderList.length === 0" class="empty-container">
|
||||
<noData />
|
||||
</view>
|
||||
@ -314,7 +313,6 @@
|
||||
// 获取会议室列表
|
||||
async getList() {
|
||||
try {
|
||||
wx.showLoading({title:'加载中...',mask:true})
|
||||
const res = await get('/api/v1/apps/home/metting-room', {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -331,13 +329,12 @@
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
wx.hideLoading()
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
// 获取我的预约记录
|
||||
async getOrderList() {
|
||||
try {
|
||||
wx.showLoading({title:'加载中...',mask:true})
|
||||
const res = await get('/api/v1/app_auth/metting-room/order', {
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -355,7 +352,7 @@
|
||||
icon: 'none'
|
||||
});
|
||||
} finally {
|
||||
wx.hideLoading()
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -73,7 +73,7 @@
|
||||
></u-empty>
|
||||
</view>
|
||||
|
||||
<!-- <Footer></Footer> -->
|
||||
<Footer></Footer>
|
||||
|
||||
<!-- 发布工单按钮 -->
|
||||
<view class="fab-container">
|
||||
@ -86,6 +86,7 @@
|
||||
|
||||
<script>
|
||||
import Footer from '@/components/footer_common.vue';
|
||||
import { get, post } from '@/utils/request';
|
||||
import { IMAGE_BASE_URL,BASE_URL } from '@/utils/config';
|
||||
import { formatTime, formatRelativeTime } from '@/utils/timeFormat';
|
||||
|
||||
|
||||
@ -16,58 +16,57 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 滚动区域 -->
|
||||
<scroll-view scroll-y :style="'height:' + scrollViewHeight + 'px'" @scrolltolower="loadMore"
|
||||
lower-threshold="100" :scroll-with-animation="true">
|
||||
<view class="notice-item" v-for="(item,index) in noticesList" :key="item.id"
|
||||
@click="goNoticeDetail(item.id)">
|
||||
<image :src="item.cover" class="notice-image" mode="aspectFill" lazy-load
|
||||
:show-menu-by-longpress="true" @error="handleImageError(index)"></image>
|
||||
<view class="notice-content">
|
||||
<view class="notice-title line-clamp-1">{{item.title}}</view>
|
||||
<view class="notice-description line-clamp-2" v-html="item.desc"></view>
|
||||
<view class="notice-footer">
|
||||
<text class="notice-date">{{formatTime(item.createdAt,'YYYY-MM-DD')}}</text>
|
||||
<text class="notice-more">查看详情 →</text>
|
||||
</view>
|
||||
|
||||
<!-- 实际列表 -->
|
||||
<view class="notice-item"
|
||||
v-for="(item,index) in noticesList"
|
||||
:key="item.id"
|
||||
@click="goNoticeDetail(item.id)">
|
||||
<image :src="item.cover"
|
||||
class="notice-image"
|
||||
mode="aspectFill"
|
||||
lazy-load
|
||||
:show-menu-by-longpress="true"
|
||||
@error="handleImageError(index)"></image>
|
||||
<view class="notice-content">
|
||||
<view class="notice-title line-clamp-1">{{item.title}}</view>
|
||||
<view class="notice-description line-clamp-2" v-html="item.desc"></view>
|
||||
<view class="notice-footer">
|
||||
<text class="notice-date">{{formatTime(item.createdAt,'YYYY-MM-DD')}}</text>
|
||||
<text class="notice-more">查看详情 →</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view class="load-more" v-if="noticesList.length > 0 && currentPage < totalPages">
|
||||
<text>{{isLoading ? '加载中...' : '上拉加载更多'}}</text>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view class="load-more" v-if="noticesList.length > 0 && currentPage < totalPages">
|
||||
<text>{{isLoading ? '加载中...' : '上拉加载更多'}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-if="noticesList.length === 0 && !isLoading">
|
||||
<image src="/static/imgs/noData.png" class="empty-image"></image>
|
||||
<image src="/static/images/empty-notice.png" class="empty-image"></image>
|
||||
<text class="empty-text">暂无公告</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<Copyright />
|
||||
<Copyright/>
|
||||
</view>
|
||||
|
||||
<!-- 底部导航 -->
|
||||
<Footer></Footer>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
get
|
||||
} from '@/utils/request';
|
||||
import {
|
||||
IMAGE_BASE_URL
|
||||
} from '@/utils/config';
|
||||
import {
|
||||
formatTime
|
||||
} from '@/utils/timeFormat';
|
||||
import { get } from '@/utils/request';
|
||||
import { IMAGE_BASE_URL } from '@/utils/config';
|
||||
import { formatTime } from '@/utils/timeFormat';
|
||||
import Footer from '@/components/footer_common.vue';
|
||||
import Copyright from '@/components/gx-copyright.vue';
|
||||
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Copyright
|
||||
},
|
||||
components: { Footer,Copyright },
|
||||
data() {
|
||||
return {
|
||||
formatTime,
|
||||
@ -77,33 +76,23 @@
|
||||
isLoading: false,
|
||||
currentPage: 1,
|
||||
totalPages: 1,
|
||||
lastRequestTime: 0,
|
||||
scrollViewHeight: 500 // 初始高度,mounted中会重新计算
|
||||
lastRequestTime: 0
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.calculateScrollHeight();
|
||||
this.getNotices();
|
||||
this.initScrollListener();
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.removeScrollListener();
|
||||
},
|
||||
methods: {
|
||||
// 计算滚动区域高度
|
||||
calculateScrollHeight() {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
const query = uni.createSelectorQuery().in(this);
|
||||
query.select('.container').boundingClientRect(data => {
|
||||
if (data) {
|
||||
// 减去顶部导航和其他固定元素的高度
|
||||
this.scrollViewHeight = systemInfo.windowHeight - 50;
|
||||
}
|
||||
}).exec();
|
||||
},
|
||||
|
||||
async getNotices() {
|
||||
// 防止重复请求
|
||||
const now = Date.now();
|
||||
if (this.isLoading || (now - this.lastRequestTime < 1000)) return;
|
||||
this.lastRequestTime = now;
|
||||
|
||||
|
||||
// 第一页尝试使用缓存
|
||||
if (this.currentPage === 1 && this.cachedNotices.length > 0) {
|
||||
this.noticesList = [...this.cachedNotices];
|
||||
@ -111,40 +100,29 @@
|
||||
setTimeout(() => this.fetchNotices(), 300);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
await this.fetchNotices();
|
||||
},
|
||||
|
||||
loadMore() {
|
||||
if (!this.isLoading && this.currentPage < this.totalPages) {
|
||||
console.log('触发加载更多,当前页:', this.currentPage);
|
||||
this.currentPage += 1;
|
||||
this.fetchNotices();
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
async fetchNotices() {
|
||||
this.isLoading = true;
|
||||
uni.showLoading({
|
||||
title: '加载中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
uni.showLoading({ title: '加载中...', mask: true });
|
||||
|
||||
try {
|
||||
const res = await get('/api/v1/apps/home/notices', {
|
||||
current: this.currentPage,
|
||||
pageSize: 10, // 每页10条
|
||||
pageSize: 10,
|
||||
}, {
|
||||
timeout: 5000
|
||||
timeout: 5000 // 设置超时时间
|
||||
});
|
||||
|
||||
|
||||
if (res?.success) {
|
||||
const processedData = res.data.map(item => ({
|
||||
...item,
|
||||
cover: this.processImageUrl(item.cover),
|
||||
desc: this.filterHtmlTags(item.desc)
|
||||
desc: this.filterHtmlTags(item.desc) // 过滤HTML标签防止XSS
|
||||
}));
|
||||
|
||||
|
||||
if (this.currentPage === 1) {
|
||||
this.noticesList = processedData;
|
||||
// 缓存第一页数据
|
||||
@ -156,7 +134,7 @@
|
||||
} else {
|
||||
this.noticesList = this.noticesList.concat(processedData);
|
||||
}
|
||||
|
||||
|
||||
this.totalPages = Math.ceil(res.total / 10);
|
||||
}
|
||||
} catch (err) {
|
||||
@ -172,29 +150,53 @@
|
||||
this.isLoading = false;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
processImageUrl(url) {
|
||||
if (!url) return '/static/images/default-cover.jpg';
|
||||
return url.startsWith('http') ? url : IMAGE_BASE_URL + url;
|
||||
},
|
||||
|
||||
|
||||
filterHtmlTags(str) {
|
||||
if (!str) return '';
|
||||
return str.replace(/<[^>]+>/g, '').replace(/ /g, ' ');
|
||||
},
|
||||
|
||||
|
||||
handleImageError(index) {
|
||||
this.$set(this.noticesList, index, {
|
||||
...this.noticesList[index],
|
||||
cover: '/static/images/default-cover.jpg'
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
goNoticeDetail(id) {
|
||||
uni.navigateTo({
|
||||
url: `/pages/serviceNoticeDetail/index?Id=${id}`,
|
||||
animationType: 'slide-in-right'
|
||||
});
|
||||
},
|
||||
|
||||
initScrollListener() {
|
||||
this.onScroll = () => {
|
||||
const scrollHeight = document.documentElement.scrollHeight;
|
||||
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
|
||||
const clientHeight = document.documentElement.clientHeight;
|
||||
|
||||
// 距离底部200px时加载更多
|
||||
if (scrollTop + clientHeight >= scrollHeight - 200 &&
|
||||
this.currentPage < this.totalPages &&
|
||||
!this.isLoading) {
|
||||
this.currentPage++;
|
||||
this.getNotices();
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', this.onScroll);
|
||||
},
|
||||
|
||||
removeScrollListener() {
|
||||
if (this.onScroll) {
|
||||
window.removeEventListener('scroll', this.onScroll);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -213,7 +215,7 @@
|
||||
--shadow: 0 4rpx 12rpx rgba(59, 140, 255, 0.1);
|
||||
--radius: 16rpx;
|
||||
}
|
||||
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@ -221,23 +223,24 @@
|
||||
background: linear-gradient(180deg, rgba(255, 241, 235, 0.8) 0%, rgba(192, 219, 250, 0.8) 100%);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
// border-radius: 30rpx 30rpx 0 0;
|
||||
margin-top: 30rpx;
|
||||
border-radius: 30rpx 30rpx 0 0;
|
||||
background-color: rgba(255, 255, 255, 0.85);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
|
||||
.content-wrapper {
|
||||
padding: 30rpx 0;
|
||||
|
||||
|
||||
.notice-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
padding: 0 30rpx;
|
||||
|
||||
|
||||
.notice-item {
|
||||
display: flex;
|
||||
background: var(--card-bg);
|
||||
@ -246,13 +249,12 @@
|
||||
transition: all 0.3s ease;
|
||||
box-shadow: var(--shadow);
|
||||
border: 1rpx solid var(--border-color);
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
|
||||
|
||||
.notice-image {
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
@ -261,20 +263,20 @@
|
||||
will-change: transform;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
}
|
||||
|
||||
|
||||
.notice-content {
|
||||
flex: 1;
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
|
||||
.notice-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: var(--secondary-color);
|
||||
margin-bottom: 12rpx;
|
||||
}
|
||||
|
||||
|
||||
.notice-description {
|
||||
font-size: 26rpx;
|
||||
color: var(--text-light);
|
||||
@ -282,17 +284,17 @@
|
||||
margin-bottom: 16rpx;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
|
||||
.notice-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.notice-date {
|
||||
font-size: 24rpx;
|
||||
color: var(--text-light);
|
||||
}
|
||||
|
||||
|
||||
.notice-more {
|
||||
font-size: 24rpx;
|
||||
color: var(--primary-color);
|
||||
@ -300,47 +302,47 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.load-more {
|
||||
text-align: center;
|
||||
padding: 30rpx 0;
|
||||
color: var(--text-light);
|
||||
font-size: 26rpx;
|
||||
}
|
||||
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 80rpx 0;
|
||||
|
||||
|
||||
.empty-image {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 30rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
|
||||
.empty-text {
|
||||
font-size: 28rpx;
|
||||
color: var(--text-light);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 骨架屏样式 */
|
||||
.skeleton-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 24rpx;
|
||||
|
||||
|
||||
.skeleton-item {
|
||||
display: flex;
|
||||
background: #fff;
|
||||
border-radius: var(--radius);
|
||||
overflow: hidden;
|
||||
height: 220rpx;
|
||||
|
||||
|
||||
.skeleton-image {
|
||||
width: 220rpx;
|
||||
height: 220rpx;
|
||||
@ -348,25 +350,25 @@
|
||||
background-size: 400% 100%;
|
||||
animation: loading 1.5s ease infinite;
|
||||
}
|
||||
|
||||
|
||||
.skeleton-content {
|
||||
flex: 1;
|
||||
padding: 24rpx;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
|
||||
|
||||
.skeleton-line {
|
||||
height: 32rpx;
|
||||
background: #f2f2f2;
|
||||
border-radius: 8rpx;
|
||||
margin-bottom: 16rpx;
|
||||
animation: loading 1.5s ease infinite;
|
||||
|
||||
|
||||
&.short {
|
||||
width: 60%;
|
||||
}
|
||||
|
||||
|
||||
&.shorter {
|
||||
width: 40%;
|
||||
}
|
||||
@ -374,12 +376,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
|
||||
100% {
|
||||
background-position: 0 50%;
|
||||
}
|
||||
@ -387,7 +388,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 通用工具类 */
|
||||
.line-clamp-1 {
|
||||
display: -webkit-box;
|
||||
@ -395,7 +396,7 @@
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
||||
.line-clamp-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 4.5 KiB |
Loading…
x
Reference in New Issue
Block a user