工单 告警 报事 修改

This commit is contained in:
2025-08-23 17:35:55 +08:00
parent 9a60d90592
commit ee9021b6af
10 changed files with 866 additions and 649 deletions

View File

@@ -61,6 +61,7 @@ const install = (Vue, vm) => {
getWarnDetail:(params = {}, id) => vm.$u.get(config.adminPath+`/sis/alarmEvents/${id}`,params),
getWarnEventInfo:(params = {}, alarmId) => vm.$u.get(config.adminPath+`/sis/alarmEventProcess/query/result/${alarmId}`,params),
getImageUrl:(params = {}, ossIds) => vm.$u.get(config.adminPath+`/resource/oss/listByIds/${ossIds}`,params),
//巡检任务列表
getInspection:(params = {})=>vm.$u.get(config.adminPath+'/property/item/list',params),

View File

@@ -101,7 +101,6 @@
this.realSubmit()
return
}
console.log("t1", this.selectedImages)
const images = this.selectedImages
.map(item => item?.path?.replace('file://', '') || item?.url || null)
.filter(path => path !== null);

View File

@@ -9,8 +9,15 @@
</view>
</view>
<!-- 列表区 -->
<view class="visitor-list">
<view v-for="(item, idx) in list" :key="idx" class="visitor-card" @click="showVisitorDetail(item)">
<view class="visitor-list-container">
<scroll-view
v-for="(tab, idx) in tabs"
:key="idx"
v-show="idx === activeTab"
class="visitor-list"
scroll-y
:refresher-enabled="false">
<view v-for="(item, index) in tabData[idx]" :key="index" class="visitor-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>
@@ -22,6 +29,7 @@
</view>
<view class="card-time">{{ item.createTime }}</view>
</view>
</scroll-view>
</view>
<!-- 底部按钮 -->
<button class="visitor-btn-fixed" @click="goCreateVisitor">访客邀约</button>
@@ -70,7 +78,7 @@
}
},
created() {
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
this.loadAllTabsData(); // 预加载所有标签页数据
},
methods: {
goBack() {
@@ -84,9 +92,12 @@
async changeTab(idx) {
this.activeTab = idx;
// 移除切换标签时的加载逻辑,避免重复调用接口
/*
if (!this.tabLoaded[idx]) {
await this.loadTabData(idx);
}
*/
},
async loadTabData(idx) {
this.loading = true;
@@ -109,6 +120,13 @@
this.$set(this.tabLoaded, idx, true);
this.loading = false;
},
async loadAllTabsData() {
for (let i = 0; i < this.tabs.length; i++) {
if (!this.tabLoaded[i]) {
await this.loadTabData(i);
}
}
},
showVisitorDetail(item) {
this.detailData = item;
this.showDetail = true;
@@ -134,6 +152,19 @@
3: '已完成'
};
return statusMap[status] || '';
},
// 添加预加载所有标签页数据的方法
async loadAllTabsData() {
// 并行加载所有标签页数据,提高加载速度
const loadPromises = [0, 1, 2].map((index) => {
return this.loadTabData(index);
});
await Promise.all(loadPromises);
// 标记所有标签页已加载
this.tabLoaded = [true, true, true];
}
}
}
@@ -145,6 +176,7 @@
background: #f7f7f7;
display: flex;
flex-direction: column;
overflow: hidden;
}
.visitor-tabs {
@@ -158,6 +190,15 @@
/* 防止被压缩 */
}
.visitor-list-container {
flex: 1;
position: relative;
margin: 25rpx 0 0 0;
padding: 0 35rpx;
padding-bottom: 200rpx;
/* 为底部按钮留出空间 */
}
.visitor-tab {
flex: 1;
text-align: center;
@@ -185,14 +226,17 @@
}
.visitor-list {
margin: 25rpx 0 0 0;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
padding: 0 35rpx;
flex: 1;
/* 占据所有剩余空间 */
overflow-y: auto;
/* 内容超出时,开启垂直滚动 */
padding-bottom: 200rpx;
/* 为底部按钮留出空间 */
height: calc(100vh - 80rpx - 32rpx - 80rpx); /* 减去顶部tab区域和底部按钮高度 */
box-sizing: border-box;
}
.visitor-card {

View File

@@ -16,11 +16,21 @@
</view>
</view>
<!-- 列表区 -->
<scroll-view class="warn-list" scroll-y refresher-enabled refresher-background="#f7f7f7"
:refresher-triggered="refresherTriggered" @refresherrefresh="onRefresh" @scrolltolower="loadMore"
<!-- 为每个标签页创建独立的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, idx) in list" :key="idx" class="warn-card" @click="goDetail2(item)">
<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>
@@ -39,12 +49,13 @@
<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 v-if="noMore[idx]" style="text-align:center;color:#999;font-size:26rpx;padding:20rpx;">
没有更多数据了
</view>
</scroll-view>
</view>
</view>
</template>
<script>
@@ -72,12 +83,11 @@
}
},
created() {
this.onRefresh()
this.loadAllTabsData()
},
onShow() {
uni.$once('refreshData', () => {
this.tabLoaded = [false, false]
this.onRefresh()
this.loadAllTabsData()
});
},
methods: {
@@ -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;

View File

@@ -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;
},

View File

@@ -9,14 +9,22 @@
</view>
</view>
<view class="empty-content" v-if="list.length ===0">
<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 v-else class="meet-list">
<view v-for="(item, idx) in list" :key="idx" class="meet-card" @click="showVisitorDetail(item)">
<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)">
@@ -30,6 +38,8 @@
<view class="card-time">{{ item.createTime }}</view>
</view>
</view>
</scroll-view>
</view>
</view>
</template>
@@ -53,7 +63,7 @@
}
},
created() {
this.loadTabData(this.activeTab); // 初始化加载当前tab数据
this.loadAllTabsData(); // 预加载所有标签页数据
},
methods: {
goBack() {
@@ -66,9 +76,12 @@
},
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,6 +144,7 @@
background: #f7f7f7;
display: flex;
flex-direction: column;
overflow: hidden;
}
.empty-content{
display: flex;
@@ -188,6 +214,29 @@
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;
padding: 0 35rpx;

View File

@@ -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

View File

@@ -16,8 +16,15 @@
</view>
</view>
<!-- 列表区 -->
<view class="oa-list">
<view v-for="(item, idx) in list" :key="idx" class="oa-card" @click="goToDetail(item)">
<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>
@@ -39,6 +46,7 @@
<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 {
@@ -305,6 +331,24 @@
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;
padding: 0 35rpx;

View File

@@ -58,7 +58,12 @@
</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"
@@ -68,7 +73,7 @@
@scrolltolower="onLoadMore"
@scroll="handleScroll"
>
<view v-for="(item, idx) in list" :key="idx" class="order-card" @click="goDetail(item)">
<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)">
@@ -91,11 +96,12 @@
<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 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>
@@ -137,23 +143,18 @@ export default {
},
created() {
this.loadFilterData()
this.onRefresh();
// 预加载所有标签页数据,避免切换时调用接口
this.loadAllTabsData();
this.isManager = this.vuex_user.roles[0].roleId == 1
},
onShow() {
uni.$once('refreshData', () => {
this.tabLoaded = [false, false]
this.onRefresh()
this.loadAllTabsData();
});
},
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];
@@ -264,6 +265,19 @@ export default {
{ 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>
@@ -389,13 +403,21 @@ export default {
margin-top: 8rpx;
}
.order-list {
margin: 32rpx 0 0 0;
padding: 0 24rpx;
.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);
height: calc(100vh - 80rpx - 32rpx - 88rpx); /* 减去顶部筛选区域高度 */
}
.order-card {

View File

@@ -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,6 +89,17 @@
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) {
@@ -138,7 +153,6 @@
// 关闭页面前发送事件通知前页面刷新
uni.$emit('refreshData', '');
this.detail.status = params.status
console.log("t1", params.status)
this.getStepInfo()
}
},