Files
SmartParks_uniapp/pages/sys/workbench/inspection/inspection.vue
liyuanchao c7ff9a5234
Some checks failed
Uniapp 自动化打包 CI/CD / 打包 Uniapp 项目 (push) Has been cancelled
1.
2025-09-05 16:54:53 +08:00

305 lines
7.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="ins-container">
<!-- tab栏 -->
<view class="ins-tabs">
<view v-for="(tab, idx) in tabs" :key="idx" :class="['ins-tab', {active: idx === activeTab}]"
@click="changeTab(idx)">
{{ tab }}
<view v-if="idx === activeTab" class="tab-underline"></view>
</view>
</view>
<!-- 为每个标签页创建独立的scroll-view -->
<view class="ins-list-container">
<scroll-view
v-for="(tab, idx) in tabs"
:key="idx"
v-show="idx === activeTab"
class="ins-list"
scroll-y
refresher-enabled
:refresher-triggered="refresherTriggered[idx]"
refresher-background="#f7f7f7"
@refresherrefresh="onRefresh"
@scrolltolower="loadMore"
:scroll-with-animation="true"
>
<view v-for="(item, index) in tabData[idx].list" :key="index" class="ins-card" @click="goProcess(item)">
<view class="ins-row">
<view class="ins-no">{{item.planName || ''}} {{ item.createTime ? item.createTime.substring(0,11) : '' }}</view>
<view class="ins-status" :class="getStatusColor(item.status)">
{{ getStatusLabel(item.status) }}
</view>
</view>
<image class="ins-line-image" src="/static/ic_my_repair_03.png" />
<view class="ins-info">巡检人{{ item.actUserName || '' }}</view>
<view class="ins-info">计划完成时间{{ item.planInsTime || '' }}</view>
<view class="ins-info">实际完成时间{{ item.location || '' }}</view>
<view class="ins-info">巡检进度{{ item.inspectionProgress || '' }}</view>
</view>
<!-- 加载更多提示 -->
<view v-if="loading[idx]" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
加载中...
</view>
<view v-if="noMore[idx] && tabData[idx].list.length > 0" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
没有更多数据了
</view>
</scroll-view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
tabs: ['待进行', '处理中', '已完成', '已超时'],
activeTab: 0,
tabData: [
{ list: [], pageNum: 1, pageSize: 10 },
{ list: [], pageNum: 1, pageSize: 10 },
{ list: [], pageNum: 1, pageSize: 10 },
{ list: [], pageNum: 1, pageSize: 10 }
],
pageNum: [1, 1, 1, 1], // 每个 tab 当前页码
pageSize: 10,
noMore: [false, false, false, false], // 每个 tab 是否没有更多数据
tabLoaded: [false, false, false, false], // tab 是否加载过
loading: [false, false, false, false], // 每个 tab 的加载状态
refresherTriggered: [false, false, false, false] // 每个 tab 的下拉刷新状态
}
},
computed: {
list() {
return this.tabData[this.activeTab].list;
},
hasMore() {
return !this.noMore[this.activeTab];
}
},
created() {
this.loadAllTabsData();
},
methods: {
goBack() {
uni.navigateBack();
},
// 加载所有tab数据
async loadAllTabsData() {
for (let idx = 0; idx < this.tabs.length; idx++) {
if (!this.tabLoaded[idx]) {
await this.loadTabData(idx);
}
}
},
// 切换 tab
async changeTab(idx) {
this.activeTab = idx;
if (!this.tabLoaded[idx]) {
await this.onRefresh();
}
},
// 下拉刷新
async onRefresh() {
this.refresherTriggered[this.activeTab] = true;
this.pageNum[this.activeTab] = 1;
this.noMore[this.activeTab] = false;
this.tabData[this.activeTab].list = [];
await this.loadTabData(this.activeTab);
this.refresherTriggered[this.activeTab] = false;
},
// 滚动加载更多
async loadMore() {
if (this.loading[this.activeTab] || this.noMore[this.activeTab]) return;
this.pageNum[this.activeTab]++;
this.loading[this.activeTab] = true;
await this.loadTabData(this.activeTab);
this.loading[this.activeTab] = false;
},
async loadTabData(idx) {
this.loading[idx] = true;
let params = {
pageNum: this.pageNum[idx],
pageSize: this.pageSize
};
// 根据tab索引设置不同的状态参数
switch(idx) {
case 0: // 待进行
params.status = '0';
break;
case 1: // 处理中
params.status = '1';
break;
case 2: // 已完成
params.status = '2';
break;
case 3: // 已超时
params.status = '3';
break;
}
let res = await this.$u.api.getInspection(params);
if (res.code == '200') {
let rows = res.rows || [];
if (rows.length < this.pageSize) {
this.noMore[idx] = true;
}
if (this.pageNum[idx] === 1) {
// 刷新时重置数据
this.tabData[idx].list = rows;
} else {
// 加载更多时追加数据
this.tabData[idx].list = [...this.tabData[idx].list, ...rows];
}
}
this.$set(this.tabLoaded, idx, true);
this.loading[idx] = false;
},
goProcess(item) {
const detailItemStr = encodeURIComponent(JSON.stringify(item));
uni.navigateTo({
url: `/pages/sys/workbench/inspection/inspectionProcess?item=${detailItemStr}`
});
},
getStatusLabel(status) {
const statusMap = {
0: '待进行',
1: '处理中',
2: '已完成',
3: '已超时'
};
return statusMap[status] || '';
},
getStatusColor(status){
const statusMap = {
0: '待确认',
1: 'orange',
2: '已取消',
3: 'done',
4: 'done'
};
return statusMap[status] || '';
}
}
}
</script>
<style scoped>
.ins-container {
height: 100vh;
background: #f7f7f7;
display: flex;
flex-direction: column;
}
.ins-tabs {
display: flex;
align-items: center;
justify-content: space-around;
background: #fff;
height: 80rpx;
border-bottom: 1px solid #f0f0f0;
flex-shrink: 0;
/* 防止被压缩 */
}
.ins-tab {
flex: 1;
text-align: center;
font-size: 30rpx;
color: #888;
position: relative;
font-weight: 500;
padding: 0 0 10rpx 0;
/* tab点击事件 */
cursor: pointer;
}
.ins-tab.active {
color: #2186FF;
font-weight: bold;
}
.tab-underline {
width: 60rpx;
height: 6rpx;
background: #2186FF;
border-radius: 3rpx;
margin: 0 auto;
margin-top: 8rpx;
}
.ins-list-container {
flex: 1;
overflow: hidden;
}
.ins-list {
height: 100%;
padding: 25rpx 35rpx 0;
box-sizing: border-box;
}
.ins-card {
background: #fff;
border-radius: 16rpx;
margin-bottom: 24rpx;
padding: 20rpx 40rpx 70rpx 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
}
.ins-row {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12rpx;
margin-top: 25rpx;
margin-left: 19rpx;
margin-right: 50rpx;
}
.ins-no {
font-size: 24rpx;
color: #0B0B0B;
font-weight: 500;
}
.ins-status {
font-size: 24rpx;
font-weight: 500;
}
.ins-line-image {
margin: left 29rpx;
margin-right: 39rpx;
height: 2rpx;
margin-bottom: 29rpx;
}
.ins-status.orange {
color: #F3AB44;
}
.ins-status.doing {
color: #00C9AA;
}
.ins-status.done {
color: #8A8A8A;
}
.ins-status.overdue {
color: #FF4D4D;
}
.ins-info {
font-size: 24rpx;
color: #888;
margin-bottom: 30rpx;
margin-left: 47rpx;
}
</style>