<template>
|
<view class="special-equipment">
|
<PageHeader title="特种设备管理"
|
@back="goBack">
|
</PageHeader>
|
<view class="tabs-section">
|
<up-tabs v-model="activeTabIndex"
|
:list="tabList"
|
itemStyle="width: 33.33%;height: 80rpx;"
|
@change="onTabChange" />
|
</view>
|
<scroll-view scroll-y
|
class="list-scroll"
|
@scrolltolower="loadMore"
|
v-if="list.length > 0">
|
<up-checkbox-group v-if="selectMode"
|
v-model="selectedIds"
|
placement="column">
|
<view v-for="row in list"
|
:key="row.id"
|
class="card"
|
@click="toggleSelect(row)">
|
<view class="card-header">
|
<text class="title">{{ getCardTitle(row) }}</text>
|
<view class="right">
|
<up-checkbox :name="String(row.id)"
|
:label="''"
|
@click.stop></up-checkbox>
|
</view>
|
</view>
|
<up-divider></up-divider>
|
<view class="card-body">
|
<template v-if="activeTab === 'ledger'">
|
<view class="row"><text class="label">设备编号</text><text class="value">{{ row.equipmentNo || '-' }}</text></view>
|
<view class="row"><text class="label">设备类别</text><text class="value">{{ row.equipmentType || '-' }}</text></view>
|
<view class="row"><text class="label">安装位置</text><text class="value">{{ row.installLocation || '-' }}</text></view>
|
<view class="row"><text class="label">负责人</text><text class="value">{{ row.managerName || '-' }}</text></view>
|
</template>
|
<template v-else-if="activeTab === 'record'">
|
<view class="row"><text class="label">记录类型</text><text class="value">{{ recordTypeLabel(row.recordType) }}</text></view>
|
<view class="row"><text class="label">记录日期</text><text class="value">{{ row.recordDate || '-' }}</text></view>
|
<view class="row"><text class="label">执行人</text><text class="value">{{ row.executorName || '-' }}</text></view>
|
<view class="row"><text class="label">下次到期日期</text><text class="value">{{ row.nextDueDate || '-' }}</text></view>
|
</template>
|
<template v-else>
|
<view class="row"><text class="label">风险等级</text><text class="value">{{ row.riskLevel || '-' }}</text></view>
|
<view class="row"><text class="label">发现日期</text><text class="value">{{ row.discoveredDate || '-' }}</text></view>
|
<view class="row"><text class="label">责任人</text><text class="value">{{ row.responsibleUserName || '-' }}</text></view>
|
<view class="row"><text class="label">整改状态</text><text class="value">{{ rectStatusLabel(row.rectificationStatus) }}</text></view>
|
</template>
|
</view>
|
</view>
|
</up-checkbox-group>
|
<view v-else>
|
<view v-for="row in list"
|
:key="row.id"
|
class="card">
|
<view class="card-header">
|
<text class="title">{{ getCardTitle(row) }}</text>
|
<up-tag v-if="activeTab === 'record'"
|
:text="recordTypeLabel(row.recordType)"
|
type="primary"
|
size="mini" />
|
<up-tag v-else-if="activeTab === 'rectification'"
|
:text="rectStatusLabel(row.rectificationStatus)"
|
type="info"
|
size="mini" />
|
</view>
|
<up-divider></up-divider>
|
<view class="card-body">
|
<template v-if="activeTab === 'ledger'">
|
<view class="row"><text class="label">设备编号</text><text class="value">{{ row.equipmentNo || '-' }}</text></view>
|
<view class="row"><text class="label">设备类别</text><text class="value">{{ row.equipmentType || '-' }}</text></view>
|
<view class="row"><text class="label">安装位置</text><text class="value">{{ row.installLocation || '-' }}</text></view>
|
<view class="row"><text class="label">负责人</text><text class="value">{{ row.managerName || '-' }}</text></view>
|
</template>
|
<template v-else-if="activeTab === 'record'">
|
<view class="row"><text class="label">关联设备</text><text class="value">{{ row.equipmentName || '-' }}</text></view>
|
<view class="row"><text class="label">记录日期</text><text class="value">{{ row.recordDate || '-' }}</text></view>
|
<view class="row"><text class="label">执行人</text><text class="value">{{ row.executorName || '-' }}</text></view>
|
<view class="row"><text class="label">下次到期日期</text><text class="value">{{ row.nextDueDate || '-' }}</text></view>
|
</template>
|
<template v-else>
|
<view class="row"><text class="label">隐患描述</text><text class="value">{{ row.hazardDescription || '-' }}</text></view>
|
<view class="row"><text class="label">风险等级</text><text class="value">{{ row.riskLevel || '-' }}</text></view>
|
<view class="row"><text class="label">整改期限</text><text class="value">{{ row.rectificationDeadline || '-' }}</text></view>
|
<view class="row"><text class="label">责任人</text><text class="value">{{ row.responsibleUserName || '-' }}</text></view>
|
</template>
|
</view>
|
<view class="actions">
|
<u-button v-if="activeTab !== 'rectification'"
|
size="small"
|
class="action-btn"
|
@click.stop="goEdit(row)">编辑</u-button>
|
<u-button size="small"
|
class="action-btn"
|
type="error"
|
@click.stop="deleteSingle(row)">删除</u-button>
|
</view>
|
</view>
|
<up-loadmore :status="loadStatus" />
|
</view>
|
</scroll-view>
|
<view v-else
|
class="no-data">
|
<up-empty mode="data"
|
text="暂无数据"></up-empty>
|
</view>
|
<FooterButtons v-if="selectMode"
|
cancelText="取消"
|
confirmText="删除"
|
:confirmDisabled="selectedIds.length === 0"
|
@cancel="exitSelectMode"
|
@confirm="deleteSelected" />
|
<view class="fab-button"
|
@click="goAdd">
|
<up-icon name="plus"
|
size="24"
|
color="#ffffff"></up-icon>
|
</view>
|
<up-action-sheet :show="showRecordTypeSheet"
|
title="选择记录类型"
|
:actions="recordTypeActions"
|
@select="onSelectRecordType"
|
@close="showRecordTypeSheet = false" />
|
<up-action-sheet :show="showRectStatusSheet"
|
title="选择整改状态"
|
:actions="rectStatusActions"
|
@select="onSelectRectStatus"
|
@close="showRectStatusSheet = false" />
|
</view>
|
</template>
|
|
<script setup>
|
import { computed, onMounted, reactive, ref } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import FooterButtons from "@/components/FooterButtons.vue";
|
import {
|
specialEquipmentLedgerDel,
|
specialEquipmentLedgerListPage,
|
specialEquipmentRecordDel,
|
specialEquipmentRecordListPage,
|
specialEquipmentRectificationDel,
|
specialEquipmentRectificationListPage,
|
} from "@/api/safeProduction/specialEquipmentManagement";
|
|
const tabList = reactive([
|
{ name: "电子台账", value: "ledger" },
|
{ name: "检验维保", value: "record" },
|
{ name: "隐患整改", value: "rectification" },
|
]);
|
const activeTabIndex = ref(0);
|
const activeTab = computed(
|
() => tabList[activeTabIndex.value]?.value || "ledger"
|
);
|
|
const ledgerSearch = reactive({ equipmentName: "" });
|
const recordSearch = reactive({ recordType: "" });
|
const rectSearch = reactive({ rectificationStatus: "" });
|
|
const page = reactive({ current: 1, size: 10, total: 0 });
|
const list = ref([]);
|
const loadStatus = ref("loadmore");
|
const loading = ref(false);
|
|
const selectMode = ref(false);
|
const selectedIds = ref([]);
|
|
const showRecordTypeSheet = ref(false);
|
const showRectStatusSheet = ref(false);
|
|
const recordTypeActions = [
|
{ name: "检验", value: 1 },
|
{ name: "维保", value: 2 },
|
];
|
const rectStatusActions = [
|
{ name: "待整改", value: 1 },
|
{ name: "整改中", value: 2 },
|
{ name: "待复核", value: 3 },
|
{ name: "已闭环", value: 4 },
|
];
|
|
const recordTypeText = computed(() => {
|
const v = recordSearch.recordType;
|
if (!v) return "";
|
return v === 1 ? "检验" : "维保";
|
});
|
const rectStatusText = computed(() =>
|
rectStatusLabel(rectSearch.rectificationStatus)
|
);
|
|
const recordTypeLabel = v => {
|
if (String(v) === "1") return "检验";
|
if (String(v) === "2") return "维保";
|
return "-";
|
};
|
const rectStatusLabel = v => {
|
const map = { 1: "待整改", 2: "整改中", 3: "待复核", 4: "已闭环" };
|
return map[Number(v)] || "";
|
};
|
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
const getCardTitle = row => {
|
if (activeTab.value === "ledger") return row.equipmentName || "-";
|
if (activeTab.value === "record") return row.recordNo || "-";
|
return row.hazardDescription || "-";
|
};
|
|
const resetAndQuery = () => {
|
page.current = 1;
|
page.total = 0;
|
list.value = [];
|
loadStatus.value = "loadmore";
|
exitSelectMode();
|
fetchList();
|
};
|
|
const fetchList = () => {
|
if (loading.value) return;
|
loading.value = true;
|
loadStatus.value = "loading";
|
|
const reqPage = { current: page.current, size: page.size };
|
let req;
|
if (activeTab.value === "ledger") {
|
req = specialEquipmentLedgerListPage({ ...ledgerSearch, ...reqPage });
|
} else if (activeTab.value === "record") {
|
req = specialEquipmentRecordListPage({ ...recordSearch, ...reqPage });
|
} else {
|
req = specialEquipmentRectificationListPage({ ...rectSearch, ...reqPage });
|
}
|
|
req
|
.then(res => {
|
const records = res?.data?.records || res?.data?.rows || [];
|
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 ledgerQuery = () => {
|
resetAndQuery();
|
};
|
|
const enterSelectMode = () => {
|
selectMode.value = true;
|
selectedIds.value = [];
|
};
|
|
const exitSelectMode = () => {
|
selectMode.value = false;
|
selectedIds.value = [];
|
};
|
|
const toggleSelect = row => {
|
if (!row?.id) return;
|
const id = String(row.id);
|
const idx = selectedIds.value.indexOf(id);
|
if (idx >= 0) selectedIds.value.splice(idx, 1);
|
else selectedIds.value.push(id);
|
};
|
|
const deleteApi = ids => {
|
if (activeTab.value === "ledger") return specialEquipmentLedgerDel(ids);
|
if (activeTab.value === "record") return specialEquipmentRecordDel(ids);
|
return specialEquipmentRectificationDel(ids);
|
};
|
|
const deleteSelected = () => {
|
const ids = selectedIds.value.map(i => Number(i));
|
if (!ids.length) {
|
uni.showToast({ title: "请选择要删除的数据", icon: "none" });
|
return;
|
}
|
uni.showModal({
|
title: "删除确认",
|
content: "确认删除所选数据吗?",
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "删除中...", mask: true });
|
deleteApi(ids)
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
exitSelectMode();
|
resetAndQuery();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
const deleteSingle = row => {
|
if (!row?.id) return;
|
uni.showModal({
|
title: "删除确认",
|
content: "确认删除该条数据吗?",
|
success: res => {
|
if (!res.confirm) return;
|
uni.showLoading({ title: "删除中...", mask: true });
|
deleteApi([row.id])
|
.then(() => {
|
uni.showToast({ title: "删除成功", icon: "success" });
|
resetAndQuery();
|
})
|
.catch(() => {
|
uni.showToast({ title: "删除失败", icon: "none" });
|
})
|
.finally(() => {
|
uni.hideLoading();
|
});
|
},
|
});
|
};
|
|
const goAdd = () => {
|
if (activeTab.value === "ledger") {
|
uni.navigateTo({
|
url: "/pages/safeProduction/specialEquipmentManagement/ledgerEdit",
|
});
|
return;
|
}
|
if (activeTab.value === "record") {
|
uni.navigateTo({
|
url: "/pages/safeProduction/specialEquipmentManagement/recordEdit",
|
});
|
return;
|
}
|
uni.navigateTo({
|
url: "/pages/safeProduction/specialEquipmentManagement/rectificationEdit",
|
});
|
};
|
|
const goEdit = row => {
|
if (!row?.id) return;
|
const data = encodeURIComponent(JSON.stringify(row));
|
if (activeTab.value === "ledger") {
|
uni.navigateTo({
|
url: `/pages/safeProduction/specialEquipmentManagement/ledgerEdit?data=${data}`,
|
});
|
return;
|
}
|
if (activeTab.value === "record") {
|
uni.navigateTo({
|
url: `/pages/safeProduction/specialEquipmentManagement/recordEdit?data=${data}`,
|
});
|
return;
|
}
|
};
|
|
const onSelectRecordType = action => {
|
recordSearch.recordType = action.value;
|
showRecordTypeSheet.value = false;
|
resetAndQuery();
|
};
|
|
const onSelectRectStatus = action => {
|
rectSearch.rectificationStatus = action.value;
|
showRectStatusSheet.value = false;
|
resetAndQuery();
|
};
|
|
onMounted(() => {
|
resetAndQuery();
|
});
|
|
onShow(() => {
|
resetAndQuery();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "../../../styles/sales-common.scss";
|
|
.special-equipment {
|
min-height: 100vh;
|
background: #f8f9fa;
|
position: relative;
|
padding-bottom: 140rpx;
|
}
|
|
.tabs-section {
|
background: #fff;
|
padding: 0 12px 8px 12px;
|
}
|
|
.header-right {
|
display: flex;
|
align-items: center;
|
padding-right: 12rpx;
|
}
|
|
.list-scroll {
|
flex: 1;
|
min-height: 0;
|
padding: 0 0 20rpx 0;
|
}
|
|
.card {
|
background: #fff;
|
border-radius: 16rpx;
|
padding: 24rpx;
|
margin: 20rpx;
|
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
|
}
|
|
.card-header {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
gap: 12rpx;
|
}
|
|
.title {
|
font-size: 28rpx;
|
font-weight: 600;
|
color: #333;
|
flex: 1;
|
min-width: 0;
|
overflow: hidden;
|
text-overflow: ellipsis;
|
white-space: nowrap;
|
}
|
|
.card-body {
|
padding: 10rpx 0;
|
}
|
|
.row {
|
display: flex;
|
justify-content: space-between;
|
margin-bottom: 12rpx;
|
}
|
|
.label {
|
font-size: 26rpx;
|
color: #999;
|
}
|
|
.value {
|
font-size: 26rpx;
|
color: #333;
|
text-align: right;
|
max-width: 70%;
|
word-break: break-all;
|
}
|
|
.actions {
|
display: flex;
|
justify-content: flex-end;
|
align-items: center;
|
gap: 16rpx;
|
padding-top: 16rpx;
|
border-top: 1rpx solid #f0f0f0;
|
}
|
|
.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;
|
}
|
|
.card-header .right :deep(.up-checkbox__label) {
|
display: none;
|
}
|
.u-border,
|
.up-border {
|
border: none !important;
|
}
|
</style>
|