Files
property-resident-side/property-uniapp-project/pageSubPack/online-repair/onlineRepair.vue
zhouyanli 56641cbc56 修改bug
2026-08-26 18:00:43 +08:00

524 lines
12 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="repair-page">
<!-- 报修类型Tab -->
<view class="scroll-container">
<view class="repair-type-tabs">
<view
class="type-tab"
:class="{ active: activeType === 'public' }"
@click="publicClick"
style="margin-right: 20rpx;"
>
<image src="https://wuye.ckdzkj.com/images/repair/publicRepair.png" style="width: 100%;height: 100%;"></image>
<!-- <uni-icons type="staff" size="24" color="#fff"></uni-icons> -->
<!-- <text class="type-text">公共报修</text> -->
</view>
<view
class="type-tab"
:class="{ active: activeType === 'personal' }"
@click="personalClick"
>
<image src="https://wuye.ckdzkj.com/images/repair/personalRepair.png" style="width: 100%;height: 100%;"></image>
<!-- <uni-icons type="person" size="24" color="#fff"></uni-icons> -->
<!-- <text class="type-text">个人报修</text> -->
</view>
</view>
<view style="margin: 14px 0px;">
<text class="repair-title">报修记录</text>
</view>
<!-- 报修记录状态Tab -->
<view class="record-status-tabs">
<text
class="status-tab"
:class="{ active: activeStatus === 'pending' }"
@click="activeStatus = 'pending'" >
待派单
</text>
<text
class="status-tab"
:class="{ active: activeStatus === 'assigned' }"
@click="activeStatus = 'assigned'"
>
已派单
</text>
<text
class="status-tab"
:class="{ active: activeStatus === 'completed' }"
@click="activeStatus = 'completed'"
>
已完成
</text>
</view>
<!-- 报修列表 -->
<view class="repair-list">
<view class="repair-item" v-for="(item, index) in repairList" :key="index">
<!-- 标题和状态 -->
<view class="item-header">
<text class="item-title">{{ item.item || '暂无标题' }}</text>
<text class="item-status" :class="item.statusClass">{{ item.status }}</text>
</view>
<!-- 标签 -->
<view class="item-tags" v-if="item.projectTypeStr">
<text class="tag" v-if="item.projectTypeStr">{{item.projectTypeStr}}</text>
<text class="tag">{{ item.maintenanceItemName }}</text>
</view>
<!-- 内容 -->
<view class="item-content">
{{ item.problem || '' }}
</view>
<!-- 图片 -->
<view class="item-imgs" v-if="item.imageList && item.imageList.length">
<view class="img-placeholder" v-for="(img, idx) in item.imageList" :key="idx">
<image :src="typeof img === 'string' ? img : img.img" style="width: 100%;height: 100%;"></image>
</view>
</view>
<!-- 时间和详情 -->
<view class="item-footer">
<text class="item-time">{{ item.createTime || '' }}</text>
<text class="detail-btn" @click="goDetail(item)">报修详情</text>
</view>
</view>
<!-- 空状态 -->
<view v-if="repairList.length === 0" class="empty-state">
<uni-icons type="info" size="30" color="#ccc"></uni-icons>
<text class="empty-text">暂无数据</text>
</view>
</view>
<!-- 加载更多提示 -->
<view v-if="repairList.length > 0" class="load-more-tip">
<text v-if="loading">加载中...</text>
<text v-else-if="!hasMoreData">没有更多数据了</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, watch, computed } from 'vue';
import { onLoad, onShow, onUnload, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app';
import { getQueryRepair } from '../api/api.js';
// 报修类型public:公共报修personal:个人报修)
const activeType = ref('public');
// 报修状态pending:待派单assigned:已派单completed:已完成)
const activeStatus = ref('pending');
const repairList = ref([]);
const loading = ref(false);
const pageNum = ref(1);
const pageSize = ref(10);
const total = ref(0);
const hasMoreData = computed(() => repairList.value.length < total.value);
const maintenanceItemId = ref('');
const statusBarHeight = ref(uni.getSystemInfoSync().statusBarHeight || 0)
// 状态映射
const statusMap = {
pending: { text: '待派单', class: 'pending', value: '0' },
assigned: { text: '已派单', class: 'assigned', value: '1' },
completed: { text: '已完成', class: 'completed', value: '2' }
};
const getStatusInfo = (val) => {
if (val === '0' || val === 0) return statusMap.pending;
if (val === '1' || val === 1) return statusMap.assigned;
if (val === '2' || val === 2) return statusMap.completed;
return null;
};
// 获取报修列表
// reset = true 时重置到第一页;否则按当前 pageNum 追加加载
const fetchRepairList = async (reset = false) => {
const villageId = uni.getStorageSync('currentVillageId');
if (!villageId || villageId === '0') {
uni.showToast({ title: '请先选择小区', icon: 'none' });
return;
}
// 防止重复请求
if (loading.value) return;
loading.value = true;
if (reset) {
pageNum.value = 1;
repairList.value = [];
total.value = 0;
}
try {
const params = {
villageId,
// maintenanceItemId: maintenanceItemId.value,
pageSize: pageSize.value,
pageNum: pageNum.value,
problemStatus: statusMap[activeStatus.value].value
};
const res = await getQueryRepair(params);
// console.log('接口返回:', res);
if (res.code === 200) {
const list = res.rows || [];
total.value = Number(res.total) || 0;
const mapped = list.map(item => {
const statusInfo = getStatusInfo(item.problemStatus);
const images = item.problemImageUrl ? item.problemImageUrl.split(',').filter(Boolean).slice(0, 3) : [];
if (statusInfo) {
return { ...item, status: statusInfo.text, statusClass: statusInfo.class, imageList: images };
}
return { ...item, imageList: images };
});
repairList.value = pageNum.value === 1 ? mapped : [...repairList.value, ...mapped];
} else {
uni.showToast({ title: res.msg || '获取失败', icon: 'none' });
}
} catch (e) {
uni.showToast({ title: '网络异常', icon: 'none' });
} finally {
loading.value = false;
uni.stopPullDownRefresh();
}
};
// 加载更多(滚动到底部触发)
const loadMore = () => {
if (loading.value || !hasMoreData.value) return;
pageNum.value++;
fetchRepairList();
};
// 下拉刷新
onPullDownRefresh(() => {
fetchRepairList(true);
});
// 上拉加载更多
onReachBottom(() => {
loadMore();
});
// 监听状态变化自动刷新(切换 tab 时重置到第一页)
watch(activeStatus, () => {
fetchRepairList(true);
});
function publicClick(){
activeType.value = 'public'
uni.navigateTo({
url:"/pageSubPack/online-repair/publicRepair"
})
};
function personalClick(){
activeType.value = 'personal'
uni.navigateTo({
url:"/pageSubPack/online-repair/personalRepair"
})
}
// 返回上一页
const goBack = () => {
if(uni.getStorageSync('sourcePage') === "index"){
uni.switchTab({
url:"/pages/index/index"
})
}else if(uni.getStorageSync('sourcePage') === "serviceIndex"){
uni.switchTab({
url:"/pages/serviceIndex/serviceIndex"
})
}else{
uni.navigateBack()
}
uni.removeStorageSync('sourcePage')
}
// 跳转报修详情
const goDetail = (item) => {
uni.navigateTo({
url: `/pageSubPack/online-repair/repairDetail?id=${item.id}`
});
};
onLoad(() => {
// maintenanceItemId.value = option.maintenanceProjectId || '' // 接收维修项目id
fetchRepairList(true)
});
onShow(() => {
// 从其他页面返回时刷新列表
fetchRepairList(true)
});
onUnload(() =>{
})
</script>
<style scoped>
/* 页面整体样式 */
.repair-page {
background: linear-gradient(to bottom left, #E2F0FF 0%, #f9f9f9 50%);
min-height: 100vh;
padding: 0 40rpx;
}
.status_bar {
height: var(--status-bar-height);
width: 100%;
flex-shrink: 0;
}
/* 顶部导航栏 */
.nav-bar {
height: 90rpx;
display: flex;
align-items: center;
/* padding: 0 30rpx; */
color: #fff;
position: sticky;
top: 44px;
z-index: 100;
margin-bottom: 60px;
/* box-shadow: 0 4rpx 12rpx rgba(0, 122, 255, 0.2); */
}
.nav-left {
width: 60rpx;
display: flex;
align-items: center;
justify-content: center;
}
.nav-title {
flex: 1;
text-align: center;
font-size: 32rpx;
font-weight: 400;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
padding: 0 20rpx;
color: #000;
}
.nav-right {
width: 60rpx;
}
/* 滚动区域 */
.scroll-container {
width: 100%;
box-sizing: border-box;
}
/* 报修类型Tab */
.repair-type-tabs {
display: flex;
/* background-color: #fff; */
padding: 10px 0;
}
.type-tab {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 90px;
border-radius: 8px;
color: #fff;
font-size: 14px;
}
.type-tab.active {
background: linear-gradient(135deg, #1E88E5 0%, #64B5F6 100%);
}
.type-tab:not(.active) {
background: linear-gradient(135deg, #4DB6AC 0%, #80CBC4 100%);
}
.type-text {
margin-top: 5px;
}
.repair-title{
color: #222222;
font-size: 16px;
font-weight: 600;
}
/* 报修状态Tab */
.record-status-tabs {
display: flex;
/* background-color: #fff; */
/* margin-top: 10px; */
/* padding: 0 15px; */
}
.status-tab {
/* flex: 1; */
display: flex;
justify-content: flex-start;
margin-right: 40rpx;
padding: 0 20rpx;
text-align: left;
height: 40px;
line-height: 40px;
font-size: 15px;
color: #666;
position: relative;
}
.status-tab.active {
color: #2F77FD;
font-weight: bold;
}
.status-tab.active::after {
content: '';
position: absolute;
bottom: 0;
left: 50%;
transform: translateX(-50%);
width: 45px;
height: 4px;
border-radius: 4rpx;
background-color: #1E88E5;
}
/* 报修列表 */
.repair-list {
padding: 28rpx 0rpx 0;
}
.repair-item {
background-color: #fff;
border-radius: 8px;
padding: 15px;
margin-bottom: 10px;
}
.repair-item:last-child {
margin-bottom: 0;
}
/* 列表项头部 */
.item-header {
display: flex;
justify-content: flex-start;
align-items: center;
margin-bottom: 10px;
}
.item-title {
font-size: 16px;
font-weight: bold;
color: #333;
padding-right: 20rpx;
width: 77%;
word-break: break-all;
word-wrap: break-word;
white-space: normal;
line-height: 1.4;
}
.item-status {
font-size: 14px;
}
.item-status.pending {
/* 待派单-红色 */
color: #ffffff;
background-color: #E34D59;
border-radius: 20rpx;
font-size: 12px;
line-height: 22px;
padding: 0px 10px;
}
.item-status.assigned {
/* 已派单-绿色 */
color: #ffffff;
background-color: #09C2BD;
border-radius: 20rpx;
font-size: 12px;
line-height: 22px;
padding: 0px 10px;
}
.item-status.completed{
color: #ffffff;
background-color: #2F77FD;
border-radius: 20rpx;
font-size: 12px;
line-height: 22px;
padding: 0px 10px;
}
/* 标签 */
.item-tags {
display: flex;
gap: 2px;
margin-bottom: 10px;
}
.tag {
color: #999999;
font-size: 12px;
padding: 2px 8px;
border-radius: 4px;
border: 1px solid #999999;
margin-right: 8px;
}
/* 内容 */
.item-content {
font-size: 14px;
color: #666;
line-height: 1.5;
margin-bottom: 10px;
word-break: break-all;
white-space: normal;
overflow-wrap: break-word;
/* background-color: #d7e4f5; */
}
/* 图片占位 */
.item-imgs {
display: flex;
flex-wrap: wrap;
margin: -6rpx;
margin-bottom: 16px;
}
.img-placeholder {
width: 95px;
height: 80px;
background-color: #f5f5f5;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
margin: 6rpx;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 0;
}
.empty-text {
font-size: 28rpx;
color: #999;
margin-top: 20rpx;
margin-bottom: 10rpx;
}
/* 加载更多提示 */
.load-more-tip {
display: flex;
justify-content: center;
align-items: center;
padding: 30rpx 0;
color: #999;
font-size: 26rpx;
}
/* 底部时间和详情 */
.item-footer {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 28rpx;
}
.item-time {
color: #999;
}
.detail-btn {
color:#2F77FD;
}
</style>