工单 告警 报事 修改
This commit is contained in:
@@ -1,50 +1,61 @@
|
||||
<template>
|
||||
<view class="warn-container">
|
||||
<!-- 顶部导航 -->
|
||||
<view class="warn-navbar">
|
||||
<image src="/static/ic_back.png" class="warn-back" @click="goBack" />
|
||||
<text class="warn-title">预警处理</text>
|
||||
<text class="warn-right-txt" @click="goStatistics">预警统计</text>
|
||||
</view>
|
||||
<view class="warn-container">
|
||||
<!-- 顶部导航 -->
|
||||
<view class="warn-navbar">
|
||||
<image src="/static/ic_back.png" class="warn-back" @click="goBack" />
|
||||
<text class="warn-title">预警处理</text>
|
||||
<text class="warn-right-txt" @click="goStatistics">预警统计</text>
|
||||
</view>
|
||||
|
||||
<!-- tab栏 -->
|
||||
<view class="warn-tabs">
|
||||
<view v-for="(tab, idx) in tabs" :key="idx" :class="['warn-tab', { active: idx === activeTab }]"
|
||||
@click="changeTab(idx)">
|
||||
{{ tab }}
|
||||
<view v-if="idx === activeTab" class="tab-underline"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- tab栏 -->
|
||||
<view class="warn-tabs">
|
||||
<view v-for="(tab, idx) in tabs" :key="idx" :class="['warn-tab', { active: idx === activeTab }]"
|
||||
@click="changeTab(idx)">
|
||||
{{ tab }}
|
||||
<view v-if="idx === activeTab" class="tab-underline"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 列表区 -->
|
||||
<scroll-view class="warn-list" scroll-y refresher-enabled refresher-background="#f7f7f7"
|
||||
:refresher-triggered="refresherTriggered" @refresherrefresh="onRefresh" @scrolltolower="loadMore"
|
||||
:lower-threshold="50">
|
||||
<view v-for="(item, idx) in list" :key="idx" class="warn-card" @click="goDetail2(item)">
|
||||
<view class="warn-row">
|
||||
<view class="warn-no">{{item.smallTypeName}}</view>
|
||||
<view class="warn-status">{{item.levelName}}</view>
|
||||
</view>
|
||||
<image class="warn-line-image" src="/static/ic_my_repair_03.png" />
|
||||
<view class="warn-info">预警内容:{{ item.description }}</view>
|
||||
<view class="warn-info">预警位置:{{ item.deviceGroupName }}</view>
|
||||
<view class="warn-info">预警时间:{{ item.reportTime }}</view>
|
||||
<view class="warn-info">预警设备:{{ item.deviceName }}</view>
|
||||
<view v-if="[20, 30, 31, 32].includes(item.state)" class="warn-eval-wrap" @click.stop="goDetail(item)">
|
||||
<view class="warn-eval-btn">去处理</view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- 为每个标签页创建独立的scroll-view -->
|
||||
<view class="warn-list-container">
|
||||
<scroll-view
|
||||
v-for="(tab, idx) in tabs"
|
||||
:key="idx"
|
||||
v-show="idx === activeTab"
|
||||
class="warn-list"
|
||||
scroll-y
|
||||
:refresher-enabled="true"
|
||||
refresher-background="#f7f7f7"
|
||||
:refresher-triggered="refresherTriggered"
|
||||
@refresherrefresh="onRefresh"
|
||||
@scrolltolower="loadMore"
|
||||
:lower-threshold="50">
|
||||
<view v-for="(item, index) in tabData[idx]" :key="index" class="warn-card" @click="goDetail2(item)">
|
||||
<view class="warn-row">
|
||||
<view class="warn-no">{{item.smallTypeName}}</view>
|
||||
<view class="warn-status">{{item.levelName}}</view>
|
||||
</view>
|
||||
<image class="warn-line-image" src="/static/ic_my_repair_03.png" />
|
||||
<view class="warn-info">预警内容:{{ item.description }}</view>
|
||||
<view class="warn-info">预警位置:{{ item.deviceGroupName }}</view>
|
||||
<view class="warn-info">预警时间:{{ item.reportTime }}</view>
|
||||
<view class="warn-info">预警设备:{{ item.deviceName }}</view>
|
||||
<view v-if="[20, 30, 31, 32].includes(item.state)" class="warn-eval-wrap" @click.stop="goDetail(item)">
|
||||
<view class="warn-eval-btn">去处理</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部加载提示 -->
|
||||
<view v-if="loading" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
加载中...
|
||||
</view>
|
||||
<view v-if="noMore[activeTab]" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
没有更多数据了
|
||||
</view>
|
||||
<!-- 底部加载提示 -->
|
||||
<view v-if="loading" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
加载中...
|
||||
</view>
|
||||
<view v-if="noMore[idx]" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
没有更多数据了
|
||||
</view>
|
||||
|
||||
</scroll-view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -72,13 +83,12 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.onRefresh()
|
||||
},
|
||||
onShow() {
|
||||
uni.$once('refreshData', () => {
|
||||
this.tabLoaded = [false, false]
|
||||
this.onRefresh()
|
||||
});
|
||||
this.loadAllTabsData()
|
||||
},
|
||||
onShow() {
|
||||
uni.$once('refreshData', () => {
|
||||
this.loadAllTabsData()
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
@@ -87,9 +97,12 @@
|
||||
// 切换 tab
|
||||
async changeTab(idx) {
|
||||
this.activeTab = idx;
|
||||
// 移除切换标签时的加载逻辑,避免重复调用接口
|
||||
/*
|
||||
if (!this.tabLoaded[idx]) {
|
||||
this.onRefresh()
|
||||
}
|
||||
*/
|
||||
},
|
||||
// 下拉刷新
|
||||
async onRefresh() {
|
||||
@@ -144,6 +157,19 @@
|
||||
uni.navigateTo({
|
||||
url: "/pages/sys/workbench/earlyWarning/warnStatistics"
|
||||
});
|
||||
},
|
||||
|
||||
// 添加预加载所有标签页数据的方法
|
||||
async loadAllTabsData() {
|
||||
// 并行加载所有标签页数据,提高加载速度
|
||||
const loadPromises = [0, 1].map((index) => {
|
||||
return this.loadTabData(index);
|
||||
});
|
||||
|
||||
await Promise.all(loadPromises);
|
||||
|
||||
// 标记所有标签页已加载
|
||||
this.tabLoaded = [true, true];
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -155,6 +181,7 @@
|
||||
background: #fff;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.warn-navbar {
|
||||
@@ -165,6 +192,7 @@
|
||||
justify-content: stretch;
|
||||
position: relative;
|
||||
margin-top: 50rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.warn-back {
|
||||
@@ -193,7 +221,7 @@
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
height: 80rpx;
|
||||
bwarn-bottom: 1px solid #f0f0f0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
@@ -217,23 +245,32 @@
|
||||
width: 60rpx;
|
||||
height: 6rpx;
|
||||
background: #2186ff;
|
||||
bwarn-radius: 3rpx;
|
||||
border-radius: 3rpx;
|
||||
margin: 0 auto;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.warn-list {
|
||||
padding: 0 24rpx;
|
||||
.warn-list-container {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 30rpx;
|
||||
height: calc(100vh - 80rpx - 32rpx);
|
||||
position: relative;
|
||||
background: #f7f7f7;
|
||||
}
|
||||
|
||||
.warn-list {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 24rpx;
|
||||
padding-bottom: 30rpx;
|
||||
height: calc(100vh - 80rpx - 32rpx - 100rpx - 50rpx); /* 减去顶部导航和tab区域高度 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.warn-card {
|
||||
background: #fff;
|
||||
bwarn-radius: 12rpx;
|
||||
border-radius: 12rpx;
|
||||
margin-top: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
|
||||
padding-top: 25rpx;
|
||||
|
@@ -65,7 +65,7 @@
|
||||
<image
|
||||
v-for="(img, idx) in realImages"
|
||||
:key="idx"
|
||||
:src="img.imagePath"
|
||||
:src="img"
|
||||
mode="aspectFill"
|
||||
class="preview-image"
|
||||
@click="previewImage(idx)"
|
||||
@@ -139,11 +139,19 @@ export default {
|
||||
this.loadEevetInfo();
|
||||
},
|
||||
methods: {
|
||||
|
||||
|
||||
async loadEevetInfo() {
|
||||
let res = await this.$u.api.getWarnEventInfo({}, this.warnInfo.id);
|
||||
if (res.code == "200") {
|
||||
this.handleDesc = res.data.workReply
|
||||
this.realImages = res.data.attachments
|
||||
const imgIds= res.data.attachments.map(img =>img.ossId)
|
||||
if (!imgIds) return;
|
||||
const result = await this.$u.api.getImageUrl({}, imgIds);
|
||||
if (result.code == 200 && result.data) {
|
||||
// 提取res.data数组中每个对象的url字段
|
||||
this.realImages = result.data.map(item => item.url);
|
||||
}
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
|
@@ -7,28 +7,38 @@
|
||||
{{ tab }}
|
||||
<view v-if="idx === activeTab" class="tab-underline"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="empty-content" v-if="list.length ===0">
|
||||
<image src="/static/ic_meet_01.png" class="empty-img"></image>
|
||||
<view class="empty-txt">暂无预约</view>
|
||||
<button class="empty-btn" @click="createMeet">发起预约</button>
|
||||
</view>
|
||||
<!-- 列表区 -->
|
||||
<view v-else class="meet-list">
|
||||
<view v-for="(item, idx) in list" :key="idx" class="meet-card" @click="showVisitorDetail(item)">
|
||||
<view class="card-row">
|
||||
<view class="card-type">{{ item.visitorUnit }}</view>
|
||||
<view class="card-status" :class="getStatusColor(item.serveStatus)">
|
||||
{{ getStatusLabel(item.serveStatus) }}</view>
|
||||
|
||||
<view class="meet-list-container">
|
||||
<scroll-view
|
||||
v-for="(tab, idx) in tabs"
|
||||
:key="idx"
|
||||
v-show="idx === activeTab"
|
||||
class="meet-list-scroll"
|
||||
scroll-y
|
||||
:refresher-enabled="false">
|
||||
<view class="empty-content" v-if="tabData[idx].length ===0">
|
||||
<image src="/static/ic_meet_01.png" class="empty-img"></image>
|
||||
<view class="empty-txt">暂无预约</view>
|
||||
<button class="empty-btn" @click="createMeet">发起预约</button>
|
||||
</view>
|
||||
<view class="card-info">{{ item.visitorName }}
|
||||
<text class="card-phone">{{ item.visitorPhone }}</text>
|
||||
<text class="card-divider"></text>
|
||||
<text class="card-address">{{ item.visitorUnit }}</text>
|
||||
<!-- 列表区 -->
|
||||
<view v-else class="meet-list">
|
||||
<view v-for="(item, index) in tabData[idx]" :key="index" class="meet-card" @click="showVisitorDetail(item)">
|
||||
<view class="card-row">
|
||||
<view class="card-type">{{ item.visitorUnit }}</view>
|
||||
<view class="card-status" :class="getStatusColor(item.serveStatus)">
|
||||
{{ getStatusLabel(item.serveStatus) }}</view>
|
||||
</view>
|
||||
<view class="card-info">{{ item.visitorName }}
|
||||
<text class="card-phone">{{ item.visitorPhone }}</text>
|
||||
<text class="card-divider"></text>
|
||||
<text class="card-address">{{ item.visitorUnit }}</text>
|
||||
</view>
|
||||
<view class="card-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-time">{{ item.createTime }}</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -53,22 +63,25 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
|
||||
this.loadAllTabsData(); // 预加载所有标签页数据
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
createMeet(){
|
||||
uni.navigateTo({
|
||||
url: '/pages/sys/workbench/meet/createMeet'
|
||||
});
|
||||
createMeet(){
|
||||
uni.navigateTo({
|
||||
url: '/pages/sys/workbench/meet/createMeet'
|
||||
});
|
||||
},
|
||||
async changeTab(idx) {
|
||||
this.activeTab = idx;
|
||||
// 移除切换标签时的加载逻辑,避免重复调用接口
|
||||
/*
|
||||
if (!this.tabLoaded[idx]) {
|
||||
await this.loadTabData(idx);
|
||||
}
|
||||
*/
|
||||
},
|
||||
async loadTabData(idx) {
|
||||
this.loading = true;
|
||||
@@ -90,7 +103,6 @@
|
||||
this.$set(this.tabLoaded, idx, true);
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
getStatusLabel(status) {
|
||||
const statusMap = {
|
||||
0: '待确认',
|
||||
@@ -108,6 +120,19 @@
|
||||
3: '已完成'
|
||||
};
|
||||
return statusMap[status] || '';
|
||||
},
|
||||
|
||||
// 添加预加载所有标签页数据的方法
|
||||
async loadAllTabsData() {
|
||||
// 并行加载所有标签页数据,提高加载速度
|
||||
const loadPromises = [0, 1].map((index) => {
|
||||
return this.loadTabData(index);
|
||||
});
|
||||
|
||||
await Promise.all(loadPromises);
|
||||
|
||||
// 标记所有标签页已加载
|
||||
this.tabLoaded = [true, true];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -119,36 +144,37 @@
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
.empty-content{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 168rpx;
|
||||
overflow: hidden;
|
||||
}
|
||||
.empty-img{
|
||||
width: 440rpx;
|
||||
height: 398rpx;
|
||||
}
|
||||
.empty-txt{
|
||||
color: #737373;
|
||||
font-size: 28rpx;
|
||||
margin-top: 64rpx;
|
||||
}
|
||||
|
||||
.empty-btn {
|
||||
width: 70vw;
|
||||
height: 80rpx;
|
||||
background: #0090FF;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
margin: 140rpx auto 0 auto;
|
||||
display: block;
|
||||
box-shadow: 0 18rpx 24rpx rgba(0, 0, 0, 0.18);
|
||||
font-weight: bold;
|
||||
.empty-content{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 168rpx;
|
||||
}
|
||||
.empty-img{
|
||||
width: 440rpx;
|
||||
height: 398rpx;
|
||||
}
|
||||
.empty-txt{
|
||||
color: #737373;
|
||||
font-size: 28rpx;
|
||||
margin-top: 64rpx;
|
||||
}
|
||||
|
||||
.empty-btn {
|
||||
width: 70vw;
|
||||
height: 80rpx;
|
||||
background: #0090FF;
|
||||
color: #fff;
|
||||
font-size: 32rpx;
|
||||
border: none;
|
||||
border-radius: 40rpx;
|
||||
margin: 140rpx auto 0 auto;
|
||||
display: block;
|
||||
box-shadow: 0 18rpx 24rpx rgba(0, 0, 0, 0.18);
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.meet-tabs {
|
||||
@@ -187,6 +213,29 @@
|
||||
margin: 0 auto;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.meet-list-container {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
margin: 25rpx 0 0 0;
|
||||
padding: 0 35rpx;
|
||||
padding-bottom: 200rpx;
|
||||
/* 为底部按钮留出空间 */
|
||||
}
|
||||
|
||||
.meet-list-scroll {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 35rpx;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 200rpx;
|
||||
/* 为底部按钮留出空间 */
|
||||
height: calc(100vh - 80rpx - 32rpx - 80rpx); /* 减去顶部tab区域和底部按钮高度 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.meet-list {
|
||||
margin: 25rpx 0 0 0;
|
||||
|
@@ -53,7 +53,6 @@ export default {
|
||||
pwd:this.detailItem.devicePwd,
|
||||
channelId:this.detailItem.channelNo
|
||||
}
|
||||
console.log("t1",params)
|
||||
let res = await this.$u.api.getPlay(params);
|
||||
if (res.code == 200) {
|
||||
this.videoSrc = res.data.hls
|
||||
|
@@ -16,29 +16,37 @@
|
||||
</view>
|
||||
</view>
|
||||
<!-- 列表区 -->
|
||||
<view class="oa-list">
|
||||
<view v-for="(item, idx) in list" :key="idx" class="oa-card" @click="goToDetail(item)">
|
||||
<view class="card-row">
|
||||
<view class="card-type">{{ item.type }}</view>
|
||||
<view class="card-status-tag" :class="item.statusClass">{{ item.status }}</view>
|
||||
</view>
|
||||
<view class="card-info">
|
||||
<view class="card-leave-type">请假类型:<text class="card-leave-type">{{ item.leaveType }}</text></view>
|
||||
<view class="card-leave-type">
|
||||
<text>开始时间:{{ item.startTime }}</text>
|
||||
<view class="oa-list-container">
|
||||
<scroll-view
|
||||
v-for="(tab, idx) in tabs"
|
||||
:key="idx"
|
||||
v-show="idx === activeTab"
|
||||
class="oa-list-scroll"
|
||||
scroll-y
|
||||
:refresher-enabled="false">
|
||||
<view v-for="(item, index) in tabData[idx]" :key="index" class="oa-card" @click="goToDetail(item)">
|
||||
<view class="card-row">
|
||||
<view class="card-type">{{ item.type }}</view>
|
||||
<view class="card-status-tag" :class="item.statusClass">{{ item.status }}</view>
|
||||
</view>
|
||||
<view class="card-leave-type">
|
||||
<text>结束时间:{{ item.endTime }}</text>
|
||||
<view class="card-info">
|
||||
<view class="card-leave-type">请假类型:<text class="card-leave-type">{{ item.leaveType }}</text></view>
|
||||
<view class="card-leave-type">
|
||||
<text>开始时间:{{ item.startTime }}</text>
|
||||
</view>
|
||||
<view class="card-leave-type">
|
||||
<text>结束时间:{{ item.endTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-footer">
|
||||
<view class="card-user">
|
||||
<view class="user-avatar" :style="{backgroundColor: item.avatarColor}">{{ item.avatarText }}</view>
|
||||
<text class="user-name">{{ item.userName }}</text>
|
||||
</view>
|
||||
<text class="card-datetime">{{ item.dateTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-footer">
|
||||
<view class="card-user">
|
||||
<view class="user-avatar" :style="{backgroundColor: item.avatarColor}">{{ item.avatarText }}</view>
|
||||
<text class="user-name">{{ item.userName }}</text>
|
||||
</view>
|
||||
<text class="card-datetime">{{ item.dateTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
@@ -64,7 +72,7 @@
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
|
||||
this.loadAllTabsData(); // 预加载所有标签页数据
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
@@ -78,9 +86,12 @@
|
||||
},
|
||||
async changeTab(idx) {
|
||||
this.activeTab = idx;
|
||||
// 移除切换标签时的加载逻辑,避免重复调用接口
|
||||
/*
|
||||
if (!this.tabLoaded[idx]) {
|
||||
await this.loadTabData(idx);
|
||||
}
|
||||
*/
|
||||
},
|
||||
async loadTabData(idx) {
|
||||
this.loading = true;
|
||||
@@ -221,6 +232,19 @@
|
||||
this.$set(this.tabData, idx, data);
|
||||
this.$set(this.tabLoaded, idx, true);
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
// 添加预加载所有标签页数据的方法
|
||||
async loadAllTabsData() {
|
||||
// 并行加载所有标签页数据,提高加载速度
|
||||
const loadPromises = [0, 1, 2].map((index) => {
|
||||
return this.loadTabData(index);
|
||||
});
|
||||
|
||||
await Promise.all(loadPromises);
|
||||
|
||||
// 标记所有标签页已加载
|
||||
this.tabLoaded = [true, true, true];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -232,6 +256,7 @@
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.oa-back {
|
||||
position: absolute;
|
||||
@@ -248,6 +273,7 @@
|
||||
.oa-search {
|
||||
background: #fff;
|
||||
padding: 20rpx 30rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
@@ -304,6 +330,24 @@
|
||||
margin: 0 auto;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.oa-list-container {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.oa-list-scroll {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 35rpx;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 50rpx;
|
||||
height: calc(100vh - 80rpx - 32rpx - 150rpx); /* 减去顶部区域高度 */
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.oa-list {
|
||||
margin: 25rpx 0 0 0;
|
||||
|
@@ -1,471 +1,493 @@
|
||||
<template>
|
||||
<view class="order-container" @click="handleOutsideClick">
|
||||
<!-- 筛选区 -->
|
||||
<view class="filter">
|
||||
<!-- 工单类型按钮 -->
|
||||
<view class="filter-btn" @click.stop="togglePopup('type')">
|
||||
{{ (!selectedFilters.type || selectedFilters.type.orderTypeName === '全部') ? '工单类型' : (selectedFilters.type.orderTypeName.length > 5 ? selectedFilters.type.orderTypeName.substring(0, 5) + '...' : selectedFilters.type.orderTypeName) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'type'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in typeList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('type', item)">
|
||||
{{ item.orderTypeName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 工单状态按钮 -->
|
||||
<view v-if="activeTab == 1" class="filter-btn" @click.stop="togglePopup('status')">
|
||||
{{ (!selectedFilters.status || selectedFilters.status.name === '全部') ? '工单状态' : (selectedFilters.status.name.length > 5 ? selectedFilters.status.name.substring(0, 5) + '...' : selectedFilters.status.name) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'status'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in statusList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('status', item)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 处理人按钮 -->
|
||||
<view v-if="isManager" class="filter-btn" @click.stop="togglePopup('handler')">
|
||||
{{ (!selectedFilters.handler || selectedFilters.handler.name === '全部') ? '处理人' : (selectedFilters.handler.name.length > 5 ? selectedFilters.handler.name.substring(0, 5) + '...' : selectedFilters.handler.name) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'handler'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in handlerList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('handler', item)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- tab栏 -->
|
||||
<view class="order-tabs">
|
||||
<view v-for="(tab, idx) in tabs" :key="idx" :class="['order-tab', { active: idx === activeTab }]"
|
||||
@click="changeTab(idx)">
|
||||
{{ tab }}
|
||||
<view v-if="idx === activeTab" class="tab-underline"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 列表区 -->
|
||||
<scroll-view
|
||||
scroll-y
|
||||
class="order-list"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="isRefreshing"
|
||||
refresher-background="#f7f7f7"
|
||||
@refresherrefresh="onRefresh"
|
||||
@scrolltolower="onLoadMore"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<view v-for="(item, idx) in list" :key="idx" class="order-card" @click="goDetail(item)">
|
||||
<view class="order-row">
|
||||
<view class="order-no">工单号:{{ item.orderNo }}</view>
|
||||
<view class="order-status" :class="getStatusColor(item.status)">
|
||||
{{ getStatusLabel(item.status) }}
|
||||
</view>
|
||||
</view>
|
||||
<image class="order-line-image" src="/static/ic_my_repair_03.png" />
|
||||
<view class="order-info">工单名称:{{ item.orderName }}</view>
|
||||
<view class="order-info">工单类型:{{ item.typeName }}</view>
|
||||
<view class="order-info">创建时间:{{ item.createTime }}</view>
|
||||
<view class="order-info">
|
||||
有 效 期:{{ item.createTime }}-{{ item.planCompleTime }}
|
||||
</view>
|
||||
<view v-if="item.statusText === '已结束'" class="order-eval-btn eval-btn-right">
|
||||
服务评价
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view v-if="loading" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
加载中...
|
||||
</view>
|
||||
<view v-if="!hasMore && list.length > 0" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
没有更多数据了
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
|
||||
tabs: ["待办", "全部"],
|
||||
activeTab: 0,
|
||||
// 每个 tab 分页数据
|
||||
tabData: [
|
||||
{ list: [], pageNum: 1, pageSize: 10, hasMore: true },
|
||||
{ list: [], pageNum: 1, pageSize: 10, hasMore: true },
|
||||
],
|
||||
tabLoaded: [false, false],
|
||||
isRefreshing: false, // 控制下拉刷新动画
|
||||
loading: false,
|
||||
lastScrollTop: 0,
|
||||
isAddBtnHidden: false,
|
||||
activePopup: null,
|
||||
selectedFilters: {
|
||||
type: null,
|
||||
status: null,
|
||||
handler: null,
|
||||
},
|
||||
typeList: [{ orderTypeName: '全部' }],
|
||||
statusList: [],
|
||||
handlerList: [{ name: "全部" }],
|
||||
isManager: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
list() {
|
||||
return this.tabData[this.activeTab].list;
|
||||
},
|
||||
hasMore() {
|
||||
return this.tabData[this.activeTab].hasMore;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadFilterData()
|
||||
this.onRefresh();
|
||||
<template>
|
||||
<view class="order-container" @click="handleOutsideClick">
|
||||
<!-- 筛选区 -->
|
||||
<view class="filter">
|
||||
<!-- 工单类型按钮 -->
|
||||
<view class="filter-btn" @click.stop="togglePopup('type')">
|
||||
{{ (!selectedFilters.type || selectedFilters.type.orderTypeName === '全部') ? '工单类型' : (selectedFilters.type.orderTypeName.length > 5 ? selectedFilters.type.orderTypeName.substring(0, 5) + '...' : selectedFilters.type.orderTypeName) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'type'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in typeList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('type', item)">
|
||||
{{ item.orderTypeName }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 工单状态按钮 -->
|
||||
<view v-if="activeTab == 1" class="filter-btn" @click.stop="togglePopup('status')">
|
||||
{{ (!selectedFilters.status || selectedFilters.status.name === '全部') ? '工单状态' : (selectedFilters.status.name.length > 5 ? selectedFilters.status.name.substring(0, 5) + '...' : selectedFilters.status.name) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'status'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in statusList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('status', item)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 处理人按钮 -->
|
||||
<view v-if="isManager" class="filter-btn" @click.stop="togglePopup('handler')">
|
||||
{{ (!selectedFilters.handler || selectedFilters.handler.name === '全部') ? '处理人' : (selectedFilters.handler.name.length > 5 ? selectedFilters.handler.name.substring(0, 5) + '...' : selectedFilters.handler.name) }}
|
||||
<image class="filter-img" src="/static/ic_down_arrow_g.png" />
|
||||
<view v-if="activePopup === 'handler'" class="dropdown">
|
||||
<view class="dropdown-triangle"></view>
|
||||
<view class="dropdown-list">
|
||||
<view v-for="(item, index) in handlerList" :key="index" class="dropdown-item"
|
||||
@click.stop="selectFilter('handler', item)">
|
||||
{{ item.name }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- tab栏 -->
|
||||
<view class="order-tabs">
|
||||
<view v-for="(tab, idx) in tabs" :key="idx" :class="['order-tab', { active: idx === activeTab }]"
|
||||
@click="changeTab(idx)">
|
||||
{{ tab }}
|
||||
<view v-if="idx === activeTab" class="tab-underline"></view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 列表区 -->
|
||||
<!-- 为每个标签页创建独立的scroll-view -->
|
||||
<view class="order-list-container">
|
||||
<scroll-view
|
||||
v-for="(tab, idx) in tabs"
|
||||
:key="idx"
|
||||
v-show="idx === activeTab"
|
||||
scroll-y
|
||||
class="order-list"
|
||||
:refresher-enabled="true"
|
||||
:refresher-triggered="isRefreshing"
|
||||
refresher-background="#f7f7f7"
|
||||
@refresherrefresh="onRefresh"
|
||||
@scrolltolower="onLoadMore"
|
||||
@scroll="handleScroll"
|
||||
>
|
||||
<view v-for="(item, index) in tabData[idx].list" :key="index" class="order-card" @click="goDetail(item)">
|
||||
<view class="order-row">
|
||||
<view class="order-no">工单号:{{ item.orderNo }}</view>
|
||||
<view class="order-status" :class="getStatusColor(item.status)">
|
||||
{{ getStatusLabel(item.status) }}
|
||||
</view>
|
||||
</view>
|
||||
<image class="order-line-image" src="/static/ic_my_repair_03.png" />
|
||||
<view class="order-info">工单名称:{{ item.orderName }}</view>
|
||||
<view class="order-info">工单类型:{{ item.typeName }}</view>
|
||||
<view class="order-info">创建时间:{{ item.createTime }}</view>
|
||||
<view class="order-info">
|
||||
有 效 期:{{ item.createTime }}-{{ item.planCompleTime }}
|
||||
</view>
|
||||
<view v-if="item.statusText === '已结束'" class="order-eval-btn eval-btn-right">
|
||||
服务评价
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 加载更多提示 -->
|
||||
<view v-if="loading" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
|
||||
加载中...
|
||||
</view>
|
||||
<view v-if="!tabData[idx].hasMore && 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,
|
||||
// 每个 tab 分页数据
|
||||
tabData: [
|
||||
{ list: [], pageNum: 1, pageSize: 10, hasMore: true },
|
||||
{ list: [], pageNum: 1, pageSize: 10, hasMore: true },
|
||||
],
|
||||
tabLoaded: [false, false],
|
||||
isRefreshing: false, // 控制下拉刷新动画
|
||||
loading: false,
|
||||
lastScrollTop: 0,
|
||||
isAddBtnHidden: false,
|
||||
activePopup: null,
|
||||
selectedFilters: {
|
||||
type: null,
|
||||
status: null,
|
||||
handler: null,
|
||||
},
|
||||
typeList: [{ orderTypeName: '全部' }],
|
||||
statusList: [],
|
||||
handlerList: [{ name: "全部" }],
|
||||
isManager: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
list() {
|
||||
return this.tabData[this.activeTab].list;
|
||||
},
|
||||
hasMore() {
|
||||
return this.tabData[this.activeTab].hasMore;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.loadFilterData()
|
||||
// 预加载所有标签页数据,避免切换时调用接口
|
||||
this.loadAllTabsData();
|
||||
this.isManager = this.vuex_user.roles[0].roleId == 1
|
||||
},
|
||||
onShow() {
|
||||
uni.$once('refreshData', () => {
|
||||
this.tabLoaded = [false, false]
|
||||
this.onRefresh()
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async changeTab(idx) {
|
||||
this.activeTab = idx;
|
||||
console.log('t1',"11111111")
|
||||
if (!this.tabLoaded[idx]) {
|
||||
this.isRefreshing = true;
|
||||
await this.onRefresh();
|
||||
}
|
||||
},
|
||||
async onRefresh() {
|
||||
const tab = this.tabData[this.activeTab];
|
||||
tab.pageNum = 1;
|
||||
tab.hasMore = true;
|
||||
this.isRefreshing = true;
|
||||
await this.loadTabData(this.activeTab);
|
||||
this.isRefreshing = false;
|
||||
},
|
||||
async onLoadMore() {
|
||||
const tab = this.tabData[this.activeTab];
|
||||
if (!tab.hasMore || this.loading) return;
|
||||
tab.pageNum++;
|
||||
this.loading = true;
|
||||
await this.loadTabData(this.activeTab);
|
||||
this.loading = false;
|
||||
},
|
||||
async loadTabData(idx) {
|
||||
let params = {
|
||||
pageNum: this.tabData[idx].pageNum,
|
||||
pageSize: this.tabData[idx].pageSize,
|
||||
};
|
||||
if (this.selectedFilters.type && this.selectedFilters.type.id) {
|
||||
params.type = this.selectedFilters.type.id;
|
||||
}
|
||||
if (this.selectedFilters.status && this.selectedFilters.status.id) {
|
||||
params.status = this.selectedFilters.status.id;
|
||||
}
|
||||
if (this.selectedFilters.handler && this.selectedFilters.handler.value) {
|
||||
params.handler = this.selectedFilters.handler.value;
|
||||
}
|
||||
if (idx == 0) {
|
||||
params.status = "1,2";
|
||||
}
|
||||
|
||||
let res = await this.$u.api.getOrderList2(params);
|
||||
if (res.code == "200") {
|
||||
if (this.tabData[idx].pageNum === 1) {
|
||||
this.tabData[idx].list = res.rows;
|
||||
} else {
|
||||
this.tabData[idx].list = [...this.tabData[idx].list, ...res.rows];
|
||||
}
|
||||
// 判断是否还有更多数据
|
||||
this.tabData[idx].hasMore = res.rows.length >= this.tabData[idx].pageSize;
|
||||
}
|
||||
this.$set(this.tabLoaded, idx, true);
|
||||
},
|
||||
// 其它方法保持不变
|
||||
handleScroll(e) {
|
||||
const scrollTop = e.detail.scrollTop;
|
||||
if (Math.abs(scrollTop - this.lastScrollTop) < 20) return;
|
||||
this.isAddBtnHidden = scrollTop > this.lastScrollTop && scrollTop > 50;
|
||||
this.lastScrollTop = scrollTop;
|
||||
},
|
||||
getStatusLabel(status) {
|
||||
const statusMap = {
|
||||
0: "创建工单",
|
||||
1: "已接单",
|
||||
2: "已接单",
|
||||
3: "处理中",
|
||||
4: "已完成",
|
||||
};
|
||||
return statusMap[status] || "";
|
||||
},
|
||||
getStatusColor(status) {
|
||||
const statusMap = {
|
||||
0: "orange",
|
||||
1: "doing",
|
||||
2: "doing",
|
||||
3: "doing",
|
||||
4: "done",
|
||||
};
|
||||
return statusMap[status] || "";
|
||||
},
|
||||
goDetail(item) {
|
||||
const itemStr = encodeURIComponent(JSON.stringify(item));
|
||||
uni.navigateTo({
|
||||
url: "/pages/sys/workbench/order/orderDetail?item=" + itemStr,
|
||||
});
|
||||
},
|
||||
togglePopup(name) {
|
||||
this.activePopup = this.activePopup === name ? null : name;
|
||||
},
|
||||
selectFilter(name, value) {
|
||||
this.selectedFilters[name] = value;
|
||||
this.activePopup = null;
|
||||
this.onRefresh();
|
||||
},
|
||||
handleOutsideClick() {
|
||||
if (this.activePopup !== null) {
|
||||
this.activePopup = null;
|
||||
}
|
||||
},
|
||||
async loadFilterData() {
|
||||
let resType = await this.$u.api.getOrdersType();
|
||||
if (resType.code === 200) {
|
||||
this.typeList = [...this.typeList, ...resType.rows];
|
||||
}
|
||||
let handlers = await this.$u.api.getHandler2();
|
||||
if (handlers.code === 200) {
|
||||
this.handlerList = [...this.handlerList, ...handlers.data];
|
||||
}
|
||||
this.statusList = [
|
||||
{ name: "全部" },
|
||||
{ name: "创建工单", id: "0" },
|
||||
{ name: "已接单", id: "1,2" },
|
||||
{ name: "处理中", id: "3" },
|
||||
{ name: "已完成", id: "4" },
|
||||
];
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.order-container {
|
||||
height: 100vh;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: #fff;
|
||||
padding-left: 36rpx;
|
||||
padding-top: 15rpx;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 15rpx 22rpx;
|
||||
background: #f7f7f7;
|
||||
border-radius: 25rpx;
|
||||
height: 58rpx;
|
||||
color: #9a9a9a;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 24rpx;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filter-img {
|
||||
width: 18rpx;
|
||||
height: 10rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 10rpx);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
z-index: 999;
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
/* 三角 */
|
||||
.dropdown-triangle {
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10rpx solid transparent;
|
||||
border-right: 10rpx solid transparent;
|
||||
border-bottom: 10rpx solid #fff;
|
||||
filter: drop-shadow(0 1rpx 1rpx rgba(0, 0, 0, 0.05));
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.dropdown-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.order-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
height: 80rpx;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.order-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #888;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
padding: 0 0 10rpx 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.order-tab.active {
|
||||
color: #2186ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-underline {
|
||||
width: 60rpx;
|
||||
height: 6rpx;
|
||||
background: #2186ff;
|
||||
border-radius: 3rpx;
|
||||
margin: 0 auto;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
margin: 32rpx 0 0 0;
|
||||
padding: 0 24rpx;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 30rpx;
|
||||
height: calc(100vh - 80rpx - 32rpx);
|
||||
}
|
||||
|
||||
.order-card {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
|
||||
padding-top: 25rpx;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.order-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12rpx;
|
||||
margin-top: 25rpx;
|
||||
margin-left: 19rpx;
|
||||
margin-right: 50rpx;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
font-size: 24rpx;
|
||||
color: #0b0b0b;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-line-image {
|
||||
margin-left: 29rpx;
|
||||
margin-right: 39rpx;
|
||||
height: 2rpx;
|
||||
margin-bottom: 29rpx;
|
||||
}
|
||||
|
||||
.order-status.orange {
|
||||
color: #f3ab44;
|
||||
}
|
||||
|
||||
.order-status.doing {
|
||||
color: #00c9aa;
|
||||
}
|
||||
|
||||
.order-status.done {
|
||||
color: #8a8a8a;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
font-size: 24rpx;
|
||||
color: #888;
|
||||
margin-bottom: 30rpx;
|
||||
margin-left: 47rpx;
|
||||
}
|
||||
|
||||
.order-add-btn-fixed {
|
||||
position: fixed;
|
||||
right: 40rpx;
|
||||
bottom: 80rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
z-index: 100;
|
||||
transition: transform 0.3s ease;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.order-add-btn-fixed.hide {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
},
|
||||
onShow() {
|
||||
uni.$once('refreshData', () => {
|
||||
this.loadAllTabsData();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
async changeTab(idx) {
|
||||
this.activeTab = idx;
|
||||
},
|
||||
async onRefresh() {
|
||||
const tab = this.tabData[this.activeTab];
|
||||
tab.pageNum = 1;
|
||||
tab.hasMore = true;
|
||||
this.isRefreshing = true;
|
||||
await this.loadTabData(this.activeTab);
|
||||
this.isRefreshing = false;
|
||||
},
|
||||
async onLoadMore() {
|
||||
const tab = this.tabData[this.activeTab];
|
||||
if (!tab.hasMore || this.loading) return;
|
||||
tab.pageNum++;
|
||||
this.loading = true;
|
||||
await this.loadTabData(this.activeTab);
|
||||
this.loading = false;
|
||||
},
|
||||
async loadTabData(idx) {
|
||||
let params = {
|
||||
pageNum: this.tabData[idx].pageNum,
|
||||
pageSize: this.tabData[idx].pageSize,
|
||||
};
|
||||
if (this.selectedFilters.type && this.selectedFilters.type.id) {
|
||||
params.type = this.selectedFilters.type.id;
|
||||
}
|
||||
if (this.selectedFilters.status && this.selectedFilters.status.id) {
|
||||
params.status = this.selectedFilters.status.id;
|
||||
}
|
||||
if (this.selectedFilters.handler && this.selectedFilters.handler.value) {
|
||||
params.handler = this.selectedFilters.handler.value;
|
||||
}
|
||||
if (idx == 0) {
|
||||
params.status = "1,2";
|
||||
}
|
||||
|
||||
let res = await this.$u.api.getOrderList2(params);
|
||||
if (res.code == "200") {
|
||||
if (this.tabData[idx].pageNum === 1) {
|
||||
this.tabData[idx].list = res.rows;
|
||||
} else {
|
||||
this.tabData[idx].list = [...this.tabData[idx].list, ...res.rows];
|
||||
}
|
||||
// 判断是否还有更多数据
|
||||
this.tabData[idx].hasMore = res.rows.length >= this.tabData[idx].pageSize;
|
||||
}
|
||||
this.$set(this.tabLoaded, idx, true);
|
||||
},
|
||||
// 其它方法保持不变
|
||||
handleScroll(e) {
|
||||
const scrollTop = e.detail.scrollTop;
|
||||
if (Math.abs(scrollTop - this.lastScrollTop) < 20) return;
|
||||
this.isAddBtnHidden = scrollTop > this.lastScrollTop && scrollTop > 50;
|
||||
this.lastScrollTop = scrollTop;
|
||||
},
|
||||
getStatusLabel(status) {
|
||||
const statusMap = {
|
||||
0: "创建工单",
|
||||
1: "已接单",
|
||||
2: "已接单",
|
||||
3: "处理中",
|
||||
4: "已完成",
|
||||
};
|
||||
return statusMap[status] || "";
|
||||
},
|
||||
getStatusColor(status) {
|
||||
const statusMap = {
|
||||
0: "orange",
|
||||
1: "doing",
|
||||
2: "doing",
|
||||
3: "doing",
|
||||
4: "done",
|
||||
};
|
||||
return statusMap[status] || "";
|
||||
},
|
||||
goDetail(item) {
|
||||
const itemStr = encodeURIComponent(JSON.stringify(item));
|
||||
uni.navigateTo({
|
||||
url: "/pages/sys/workbench/order/orderDetail?item=" + itemStr,
|
||||
});
|
||||
},
|
||||
togglePopup(name) {
|
||||
this.activePopup = this.activePopup === name ? null : name;
|
||||
},
|
||||
selectFilter(name, value) {
|
||||
this.selectedFilters[name] = value;
|
||||
this.activePopup = null;
|
||||
this.onRefresh();
|
||||
},
|
||||
handleOutsideClick() {
|
||||
if (this.activePopup !== null) {
|
||||
this.activePopup = null;
|
||||
}
|
||||
},
|
||||
async loadFilterData() {
|
||||
let resType = await this.$u.api.getOrdersType();
|
||||
if (resType.code === 200) {
|
||||
this.typeList = [...this.typeList, ...resType.rows];
|
||||
}
|
||||
let handlers = await this.$u.api.getHandler2();
|
||||
if (handlers.code === 200) {
|
||||
this.handlerList = [...this.handlerList, ...handlers.data];
|
||||
}
|
||||
this.statusList = [
|
||||
{ name: "全部" },
|
||||
{ name: "创建工单", id: "0" },
|
||||
{ name: "已接单", id: "1,2" },
|
||||
{ name: "处理中", id: "3" },
|
||||
{ name: "已完成", id: "4" },
|
||||
];
|
||||
},
|
||||
|
||||
// 添加预加载所有标签页数据的方法
|
||||
async loadAllTabsData() {
|
||||
// 并行加载所有标签页数据,提高加载速度
|
||||
const loadPromises = this.tabData.map((tab, index) => {
|
||||
return this.loadTabData(index);
|
||||
});
|
||||
|
||||
await Promise.all(loadPromises);
|
||||
|
||||
// 标记所有标签页已加载
|
||||
this.tabLoaded = this.tabData.map(() => true);
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.order-container {
|
||||
height: 100vh;
|
||||
background: #f7f7f7;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
background: #fff;
|
||||
padding-left: 36rpx;
|
||||
padding-top: 15rpx;
|
||||
padding-bottom: 15rpx;
|
||||
}
|
||||
|
||||
.filter-btn {
|
||||
padding: 15rpx 22rpx;
|
||||
background: #f7f7f7;
|
||||
border-radius: 25rpx;
|
||||
height: 58rpx;
|
||||
color: #9a9a9a;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
margin-right: 24rpx;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.filter-img {
|
||||
width: 18rpx;
|
||||
height: 10rpx;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 10rpx);
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 10rpx rgba(0, 0, 0, 0.1);
|
||||
z-index: 999;
|
||||
width: 200rpx;
|
||||
}
|
||||
|
||||
/* 三角 */
|
||||
.dropdown-triangle {
|
||||
position: absolute;
|
||||
top: -10rpx;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10rpx solid transparent;
|
||||
border-right: 10rpx solid transparent;
|
||||
border-bottom: 10rpx solid #fff;
|
||||
filter: drop-shadow(0 1rpx 1rpx rgba(0, 0, 0, 0.05));
|
||||
z-index: 1000;
|
||||
}
|
||||
|
||||
.dropdown-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.dropdown-item {
|
||||
padding: 20rpx;
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.dropdown-item:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.dropdown-item:hover {
|
||||
background: #f5f5f5;
|
||||
}
|
||||
|
||||
.order-tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
background: #fff;
|
||||
height: 80rpx;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.order-tab {
|
||||
flex: 1;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #888;
|
||||
position: relative;
|
||||
font-weight: 500;
|
||||
padding: 0 0 10rpx 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.order-tab.active {
|
||||
color: #2186ff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.tab-underline {
|
||||
width: 60rpx;
|
||||
height: 6rpx;
|
||||
background: #2186ff;
|
||||
border-radius: 3rpx;
|
||||
margin: 0 auto;
|
||||
margin-top: 8rpx;
|
||||
}
|
||||
|
||||
.order-list-container {
|
||||
flex: 1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.order-list {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
padding: 0 24rpx;
|
||||
overflow-y: auto;
|
||||
padding-bottom: 30rpx;
|
||||
height: calc(100vh - 80rpx - 32rpx - 88rpx); /* 减去顶部筛选区域高度 */
|
||||
}
|
||||
|
||||
.order-card {
|
||||
background: #fff;
|
||||
border-radius: 12rpx;
|
||||
margin-bottom: 24rpx;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
|
||||
padding-top: 25rpx;
|
||||
padding-bottom: 32rpx;
|
||||
}
|
||||
|
||||
.order-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 12rpx;
|
||||
margin-top: 25rpx;
|
||||
margin-left: 19rpx;
|
||||
margin-right: 50rpx;
|
||||
}
|
||||
|
||||
.order-no {
|
||||
font-size: 24rpx;
|
||||
color: #0b0b0b;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-status {
|
||||
font-size: 24rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.order-line-image {
|
||||
margin-left: 29rpx;
|
||||
margin-right: 39rpx;
|
||||
height: 2rpx;
|
||||
margin-bottom: 29rpx;
|
||||
}
|
||||
|
||||
.order-status.orange {
|
||||
color: #f3ab44;
|
||||
}
|
||||
|
||||
.order-status.doing {
|
||||
color: #00c9aa;
|
||||
}
|
||||
|
||||
.order-status.done {
|
||||
color: #8a8a8a;
|
||||
}
|
||||
|
||||
.order-info {
|
||||
font-size: 24rpx;
|
||||
color: #888;
|
||||
margin-bottom: 30rpx;
|
||||
margin-left: 47rpx;
|
||||
}
|
||||
|
||||
.order-add-btn-fixed {
|
||||
position: fixed;
|
||||
right: 40rpx;
|
||||
bottom: 80rpx;
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
z-index: 100;
|
||||
transition: transform 0.3s ease;
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.order-add-btn-fixed.hide {
|
||||
transform: translateX(200%);
|
||||
}
|
||||
</style>
|
@@ -28,10 +28,10 @@
|
||||
<view class="detail-value"><text class="detail-key">发起单位/人:</text>{{ detail.initiatorPeople }}</view>
|
||||
<view class="detail-value remark"><text>备注:</text>{{ detail.remark }}</view>
|
||||
<view class="detail-value"><text class="detail-key">工单图片:</text></view>
|
||||
<view class="image-list" v-if="detail.orderImgUrl">
|
||||
<u-image v-for="(imgUrl, index) in detail.orderImgUrl.split(',')" :key="index" :src="imgUrl"
|
||||
<view class="image-list" v-if="orderImgUrls.length > 0">
|
||||
<u-image v-for="(imgUrl, index) in orderImgUrls" :key="index" :src="imgUrl"
|
||||
width="200rpx" height="200rpx" border-radius="10rpx"
|
||||
@click="previewImage(detail.orderImgUrl.split(','), index)"
|
||||
@click="previewImage(orderImgUrls, index)"
|
||||
style="margin-right: 20rpx; margin-bottom: 20rpx;"></u-image>
|
||||
</view>
|
||||
|
||||
@@ -65,7 +65,8 @@
|
||||
detail: {},
|
||||
isManager: false,
|
||||
showSelect: false,
|
||||
users: []
|
||||
users: [],
|
||||
orderImgUrls: [] // 添加用于存储处理后的图片URL数组
|
||||
};
|
||||
},
|
||||
onLoad(options) {
|
||||
@@ -76,6 +77,9 @@
|
||||
// 现在可以使用item对象了
|
||||
// 进度映射
|
||||
this.getStepInfo()
|
||||
// 处理图片URL
|
||||
|
||||
this.getImageUrl()
|
||||
}
|
||||
if ((this.isManager && this.detailStep == 0) || (!this.isManager && this.detailStep == 1)) {
|
||||
this.getHandler()
|
||||
@@ -85,26 +89,37 @@
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
async getImageUrl() {
|
||||
if (!this.detail.orderImgUrl) return;
|
||||
|
||||
const imgIds = this.detail.orderImgUrl.split(',');
|
||||
const res = await this.$u.api.getImageUrl({}, imgIds);
|
||||
if (res.code == 200 && res.data) {
|
||||
// 提取res.data数组中每个对象的url字段
|
||||
this.orderImgUrls = res.data.map(item => item.url);
|
||||
}
|
||||
},
|
||||
|
||||
async getHandler() {
|
||||
let handlers = await this.$u.api.getHandler3({}, this.detail.type);
|
||||
if (handlers.code === 200) {
|
||||
this.users = [...this.users, ...handlers.data];
|
||||
}
|
||||
},
|
||||
getStepInfo(){
|
||||
if (this.detail.status == 0) {
|
||||
this.detailStep = 0;
|
||||
this.detailStatus = '创建工单';
|
||||
} else if (this.detail.status == 4) {
|
||||
this.detailStep = 3;
|
||||
this.detailStatus = '已结束';
|
||||
} else if (this.detail.status == 3) {
|
||||
this.detailStep = 2;
|
||||
this.detailStatus = '处理中';
|
||||
} else {
|
||||
this.detailStep = 1;
|
||||
this.detailStatus = '已接单';
|
||||
}
|
||||
},
|
||||
getStepInfo(){
|
||||
if (this.detail.status == 0) {
|
||||
this.detailStep = 0;
|
||||
this.detailStatus = '创建工单';
|
||||
} else if (this.detail.status == 4) {
|
||||
this.detailStep = 3;
|
||||
this.detailStatus = '已结束';
|
||||
} else if (this.detail.status == 3) {
|
||||
this.detailStep = 2;
|
||||
this.detailStatus = '处理中';
|
||||
} else {
|
||||
this.detailStep = 1;
|
||||
this.detailStatus = '已接单';
|
||||
}
|
||||
},
|
||||
previewImage(urls, index) {
|
||||
// 使用uView的图片预览组件
|
||||
@@ -122,23 +137,22 @@
|
||||
// 关闭页面前发送事件通知前页面刷新
|
||||
uni.$emit('refreshData', '');
|
||||
this.detail.handler = selected.value
|
||||
this.detail.status = 1
|
||||
this.detail.status = 1
|
||||
this.getStepInfo()
|
||||
}
|
||||
},
|
||||
async submit() {
|
||||
let params = this.detail
|
||||
if(this.detail.status == 1||this.detail.status == 2){
|
||||
params.status = 3
|
||||
}else {
|
||||
params.status = 4
|
||||
if(this.detail.status == 1||this.detail.status == 2){
|
||||
params.status = 3
|
||||
}else {
|
||||
params.status = 4
|
||||
}
|
||||
let res = await this.$u.api.updateOrder2(params);
|
||||
if (res.code == '200') {
|
||||
// 关闭页面前发送事件通知前页面刷新
|
||||
uni.$emit('refreshData', '');
|
||||
this.detail.status = params.status
|
||||
console.log("t1", params.status)
|
||||
this.detail.status = params.status
|
||||
this.getStepInfo()
|
||||
}
|
||||
},
|
||||
|
Reference in New Issue
Block a user