<template>
|
<view class="safety-facility">
|
<PageHeader title="安全设施巡检"
|
@back="goBack" />
|
<view class="tabs-section">
|
<up-tabs v-model="activeTabIndex"
|
:list="tabList"
|
itemStyle="width: 33.33%;height: 80rpx;"
|
@change="onTabChange" />
|
</view>
|
<view class="search-section">
|
<view class="search-bar">
|
<view class="search-input">
|
<up-input class="search-text"
|
v-model="keyword"
|
:placeholder="searchPlaceholder"
|
@change="handleSearch"
|
clearable />
|
</view>
|
<view class="filter-button"
|
@click="handleSearch">
|
<up-icon name="search"
|
size="24"
|
color="#999"></up-icon>
|
</view>
|
</view>
|
</view>
|
<scroll-view scroll-y
|
class="list-scroll ledger-list"
|
@scrolltolower="loadMore"
|
v-if="list.length > 0">
|
<view v-for="row in list"
|
:key="row.id"
|
class="ledger-item">
|
<view class="item-header"
|
@click="handleInspectionInfoClick(row)">
|
<view class="item-left">
|
<view class="document-icon">
|
<up-icon name="setting-fill"
|
size="16"
|
color="#ffffff"></up-icon>
|
</view>
|
<text class="item-id">{{ getCardTitle(row) }}</text>
|
</view>
|
<view class="item-right">
|
<text v-if="activeTab === 'ledger'"
|
class="item-index">{{ row.facilityCode || "-" }}</text>
|
<up-tag v-else
|
:text="row.status || '-'"
|
:type="activeTab === 'inspection' ? (row.status === '待巡检' ? 'info' : 'success') : rectStatusType(row.status)"
|
size="mini" />
|
</view>
|
</view>
|
<up-divider></up-divider>
|
<view class="item-details"
|
@click="handleInspectionInfoClick(row)">
|
<template v-if="activeTab === 'ledger'">
|
<view class="detail-row">
|
<text class="detail-label">设施类型</text>
|
<text class="detail-value">{{ row.facilityType || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">规格型号</text>
|
<text class="detail-value">{{ row.facilitySpec || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">安装位置</text>
|
<text class="detail-value">{{ row.installLocation || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">安装时间</text>
|
<text class="detail-value">{{ row.installTime || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">下次检查时间</text>
|
<text class="detail-value">{{ row.nextCheckTime || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">状态</text>
|
<up-tag :text="row.status || '-'"
|
:type="facilityStatusType(row.status)"
|
size="mini" />
|
</view>
|
</template>
|
<template v-else-if="activeTab === 'inspection'">
|
<view class="detail-row">
|
<text class="detail-label">设施名称</text>
|
<text class="detail-value">{{ row.facilityName || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">设施编号</text>
|
<text class="detail-value">{{ row.facilityCode || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">巡检类型</text>
|
<text class="detail-value">{{ row.inspectionType || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">计划巡检时间</text>
|
<text class="detail-value">{{ row.planTime || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">检查结果</text>
|
<text class="detail-value">{{ row.checkResult || '-' }}</text>
|
</view>
|
</template>
|
<template v-else>
|
<view class="detail-row">
|
<text class="detail-label">设施名称</text>
|
<text class="detail-value">{{ row.facilityName || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">问题描述</text>
|
<text class="detail-value">{{ row.problemDesc || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">问题等级</text>
|
<text class="detail-value">{{ row.problemLevel || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">整改责任人</text>
|
<text class="detail-value">{{ row.rectifyUserName || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">计划整改时间</text>
|
<text class="detail-value">{{ row.planTime || '-' }}</text>
|
</view>
|
<view class="detail-row">
|
<text class="detail-label">验收人</text>
|
<text class="detail-value">{{ row.verifyUserName || '-' }}</text>
|
</view>
|
</template>
|
</view>
|
<view class="action-buttons">
|
<template v-if="activeTab === 'ledger'">
|
<u-button size="small"
|
class="action-btn fixed-btn"
|
@click.stop="goLedgerEdit(row)">编辑</u-button>
|
<u-button size="small"
|
class="action-btn fixed-btn"
|
type="primary"
|
@click.stop="goInspectionAdd(row)">发起巡检</u-button>
|
<u-button size="small"
|
class="action-btn fixed-btn"
|
type="error"
|
@click.stop="deleteLedger(row)">删除</u-button>
|
</template>
|
<template v-else-if="activeTab === 'inspection'">
|
<u-button v-if="String(row.status) === '待巡检'"
|
size="small"
|
class="action-btn fixed-btn"
|
type="primary"
|
@click.stop="goInspectionDo(row)">巡检</u-button>
|
<u-button v-if="String(row.checkResult) === '异常'"
|
size="small"
|
class="action-btn fixed-btn"
|
type="success"
|
@click.stop="goRectificationAdd(row)">整改</u-button>
|
<u-button size="small"
|
class="action-btn fixed-btn"
|
type="error"
|
:disabled="String(row.status) !== '待巡检'"
|
@click.stop="deleteInspection(row)">删除</u-button>
|
</template>
|
<template v-else>
|
<u-button v-if="String(row.status) === '待整改' || String(row.status) === '整改中'"
|
size="small"
|
class="action-btn fixed-btn"
|
type="success"
|
@click.stop="goRectificationDo(row)">整改</u-button>
|
<u-button v-if="String(row.status) === '已整改'"
|
size="small"
|
class="action-btn fixed-btn"
|
type="primary"
|
@click.stop="goRectificationVerify(row)">验收</u-button>
|
<u-button size="small"
|
class="action-btn fixed-btn"
|
@click.stop="goRectificationView(row)">查看</u-button>
|
</template>
|
</view>
|
</view>
|
<up-loadmore :status="loadStatus" />
|
</scroll-view>
|
<view v-else
|
class="no-data">
|
<up-empty mode="data"
|
text="暂无数据"></up-empty>
|
</view>
|
<view v-if="activeTab === 'ledger'"
|
class="fab-button"
|
@click="goLedgerAdd">
|
<up-icon name="plus"
|
size="24"
|
color="#ffffff"></up-icon>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, onMounted, reactive, ref } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import {
|
deleteFacilityInspection,
|
deleteFacilityLedger,
|
getFacilityInspectionList,
|
getFacilityLedgerList,
|
getFacilityRectificationList,
|
} from "@/api/safeProduction/safetyFacility";
|
|
const tabList = reactive([
|
{ name: "设施台账", value: "ledger" },
|
{ name: "设施巡检", value: "inspection" },
|
{ name: "整改跟踪", value: "rectification" },
|
]);
|
|
const activeTabIndex = ref(0);
|
const activeTab = computed(
|
() => tabList[activeTabIndex.value]?.value || "ledger"
|
);
|
|
const keyword = ref("");
|
|
const page = reactive({ current: 1, size: 10, total: 0 });
|
const list = ref([]);
|
const loadStatus = ref("loadmore");
|
const loading = ref(false);
|
|
const searchPlaceholder = computed(() => {
|
if (activeTab.value === "ledger") return "设施编号/设施名称";
|
if (activeTab.value === "inspection") return "巡检编号";
|
return "状态(待整改/整改中/已整改/已验收)";
|
});
|
|
const facilityStatusType = status => {
|
const map = { 正常: "success", 异常: "error", 报废: "info" };
|
return map[status] || "info";
|
};
|
const rectStatusType = status => {
|
const map = {
|
待整改: "error",
|
整改中: "warning",
|
已整改: "success",
|
已验收: "info",
|
};
|
return map[status] || "info";
|
};
|
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
const getCardTitle = row => {
|
if (activeTab.value === "ledger") return row.facilityName || "-";
|
if (activeTab.value === "inspection") return row.inspectionCode || "-";
|
return row.facilityName || "-";
|
};
|
|
const handleInspectionInfoClick = row => {
|
if (activeTab.value !== "inspection") return;
|
if (String(row?.status) === "待巡检") return;
|
goInspectionView(row);
|
};
|
|
const resetAndQuery = () => {
|
page.current = 1;
|
page.total = 0;
|
list.value = [];
|
loadStatus.value = "loadmore";
|
fetchList();
|
};
|
|
const fetchList = () => {
|
if (loading.value) return;
|
loading.value = true;
|
loadStatus.value = "loading";
|
|
const reqPage = { current: page.current, size: page.size };
|
let req;
|
const kw = String(keyword.value || "").trim();
|
if (activeTab.value === "ledger") {
|
req = getFacilityLedgerList({
|
facilityCode: kw,
|
facilityName: kw,
|
...reqPage,
|
});
|
} else if (activeTab.value === "inspection") {
|
req = getFacilityInspectionList({ inspectionCode: kw, ...reqPage });
|
} else {
|
req = getFacilityRectificationList({ status: kw, ...reqPage });
|
}
|
|
req
|
.then(res => {
|
const records = res?.data?.records || [];
|
const total = Number(res?.data?.total || 0);
|
page.total = total;
|
list.value = page.current === 1 ? records : [...list.value, ...records];
|
loadStatus.value =
|
list.value.length >= page.total ? "nomore" : "loadmore";
|
})
|
.catch(() => {
|
loadStatus.value = "loadmore";
|
uni.showToast({ title: "加载失败", icon: "none" });
|
})
|
.finally(() => {
|
loading.value = false;
|
});
|
};
|
|
const handleSearch = () => {
|
resetAndQuery();
|
};
|
|
const loadMore = () => {
|
if (loadStatus.value !== "loadmore") return;
|
page.current++;
|
fetchList();
|
};
|
|
const onTabChange = val => {
|
activeTabIndex.value = val.index;
|
resetAndQuery();
|
};
|
|
const goLedgerAdd = () => {
|
uni.navigateTo({ url: "/pages/safeProduction/safetyFacility/ledgerEdit" });
|
};
|
const goLedgerEdit = row => {
|
const data = encodeURIComponent(JSON.stringify(row || {}));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/ledgerEdit?data=${data}`,
|
});
|
};
|
const goInspectionAdd = row => {
|
const data = encodeURIComponent(
|
JSON.stringify({ mode: "add", facility: row })
|
);
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
|
});
|
};
|
const goInspectionDo = row => {
|
const data = encodeURIComponent(JSON.stringify({ mode: "do", row }));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
|
});
|
};
|
const goInspectionView = row => {
|
const data = encodeURIComponent(JSON.stringify({ mode: "view", row }));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/inspectionEdit?data=${data}`,
|
});
|
};
|
const goRectificationAdd = row => {
|
const data = encodeURIComponent(
|
JSON.stringify({ mode: "add", inspection: row })
|
);
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
|
});
|
};
|
const goRectificationDo = row => {
|
const data = encodeURIComponent(JSON.stringify({ mode: "do", row }));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
|
});
|
};
|
const goRectificationVerify = row => {
|
const data = encodeURIComponent(JSON.stringify({ mode: "verify", row }));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
|
});
|
};
|
const goRectificationView = row => {
|
const data = encodeURIComponent(JSON.stringify({ mode: "view", row }));
|
uni.navigateTo({
|
url: `/pages/safeProduction/safetyFacility/rectificationEdit?data=${data}`,
|
});
|
};
|
|
const deleteLedger = row => {
|
if (!row?.id) return;
|
uni.showModal({
|
title: "删除",
|
content: "确认删除该设施吗?",
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "删除中...", mask: true });
|
deleteFacilityLedger([row.id])
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
resetAndQuery();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
const deleteInspection = row => {
|
if (!row?.id) return;
|
if (String(row.status) !== "待巡检") return;
|
uni.showModal({
|
title: "删除",
|
content: "确认删除该巡检记录吗?",
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "删除中...", mask: true });
|
deleteFacilityInspection([row.id])
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
resetAndQuery();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
onMounted(() => {
|
uni.$on("safetyFacility:refresh", resetAndQuery);
|
});
|
|
onShow(() => {
|
resetAndQuery();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "../../../styles/sales-common.scss";
|
|
.safety-facility {
|
min-height: 100vh;
|
background: #f8f9fa;
|
position: relative;
|
padding-bottom: 140rpx;
|
}
|
|
.tabs-section {
|
background: #fff;
|
}
|
|
.list-scroll {
|
flex: 1;
|
min-height: 0;
|
}
|
|
.action-buttons {
|
display: flex;
|
flex-wrap: wrap;
|
justify-content: flex-end;
|
gap: 20rpx;
|
padding-bottom: 30rpx;
|
}
|
|
.fixed-btn {
|
width: 160rpx;
|
margin: 0 !important;
|
}
|
|
.fab-button {
|
position: fixed;
|
right: 30rpx;
|
bottom: 140rpx;
|
width: 96rpx;
|
height: 96rpx;
|
background: #3c9cff;
|
border-radius: 48rpx;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
box-shadow: 0 8rpx 24rpx rgba(60, 156, 255, 0.3);
|
z-index: 1001;
|
}
|
|
.no-data {
|
padding-top: 200rpx;
|
}
|
</style>
|