Files
threeonecheck_web/pages/hiddendanger/Inspection.vue
2026-06-30 09:47:10 +08:00

341 lines
8.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class=" page padding">
<!-- 顶部状态筛选 Tab -->
<scroll-view class="status-tabs" scroll-x :show-scrollbar="false">
<view class="status-tabs-inner">
<view v-for="(tab, index) in statusTabs" :key="index" class="status-tab-item"
:class="{ 'status-tab-active': activeTab === index }" @click="activeTab = index">
<text class="status-tab-text">{{ tab.label }}</text>
<view v-if="activeTab === index" class="status-tab-bar"></view>
</view>
</view>
</scroll-view>
<view v-if="filteredList.length === 0" class="empty-tip text-gray text-center padding">暂无数据</view>
<view class="padding radius bg-white list-list margin-bottom" v-for="item in filteredList"
:key="item.hazardId">
<view class="flex justify-between margin-bottom">
<view class="text-bold text-black" style="word-break: break-all; flex: 1;">{{item.title}}</view>
<view class="text-blue" style="white-space: nowrap; flex-shrink: 0; margin-left: 16rpx;">{{item.statusName}}</view>
</view>
<view class="flex margin-bottom">
<view class="text-gray">隐患等级</view>
<view class="level-tag" :class="{
'level-minor': item.levelName === '轻微隐患',
'level-normal': item.levelName === '一般隐患',
'level-major': item.levelName === '重大隐患'
}">{{item.levelName}}</view>
</view>
<view class="flex margin-bottom">
<view class="text-gray" style="white-space: nowrap;">隐患位置</view>
<view class="text-black">{{item.address}}</view>
</view>
<view class="flex margin-bottom">
<view class="text-gray">创建时间</view>
<view class="text-black">{{item.createdAt}}</view>
</view>
<view class="flex justify-end card-actions" style="gap: 10rpx;">
<button class="round cu-btn light bg-blue" @click="details(item)">查看详情</button>
<button v-if="item.statusName === '待整改' && item.canEdit"
class="round cu-btn light bg-blue" @click="assignHazard(item)">隐患交办</button>
<button v-if="item.statusName === '待整改' && item.canEdit"
class="round cu-btn bg-blue" @click="Rectification(item)">立即整改</button>
<button v-if="item.statusName === '待验收' && item.canEdit"
class="round cu-btn light bg-blue" @click="editRectification(item)">编辑整改信息</button>
<button v-if="item.statusName === '待验收' && canAcceptance"
class="round cu-btn bg-blue" @click="acceptance(item)">立即验收</button>
<button v-if="item.statusName === '待交办'"
class="round cu-btn bg-blue" @click="assignHazard(item)">隐患交办</button>
</view>
</view>
<view class="fixed-add-btn" @click="goToAdd">
<text class="cuIcon-add"></text>
<text>新增</text>
</view>
</view>
</template>
<script setup>
import { ref, computed } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import {
enterCheckPlan,
getCheckTaskDetail,
getMyHiddenDangerList
} from '@/request/api.js'
const taskId = ref('')
const checkPointId = ref('')
const oneTableId = ref('')
const userRole = ref('')
const canAcceptance = computed(() => {
return userRole.value === 'admin' || userRole.value === 'manage'
})
const getUserRole = () => {
try {
const userInfoStr = uni.getStorageSync('userInfo')
if (userInfoStr) {
const userInfo = JSON.parse(userInfoStr)
userRole.value = userInfo.role || ''
}
} catch (error) {
console.error('获取用户信息失败:', error)
}
}
getUserRole()
const fetchTaskInfo = async (oneTableId) => {
try {
const startRes = await enterCheckPlan(oneTableId)
if (startRes.code === 0 && startRes.data) {
const tid = startRes.data.taskId
const detailRes = await getCheckTaskDetail(tid)
if (detailRes.code === 0 && detailRes.data) {
taskId.value = detailRes.data.taskId
checkPointId.value = detailRes.data.checkPointId
}
}
} catch (error) {
console.error('获取任务信息失败:', error)
}
}
onLoad((options) => {
if (options.id) {
oneTableId.value = options.id
fetchTaskInfo(options.id)
}
})
const hiddenDangerList = ref([])
const fetchHiddenDangerList = async () => {
try {
const res = await getMyHiddenDangerList()
if (res.code === 0) {
hiddenDangerList.value = res.data.records
} else {
uni.showToast({
title: res.msg || '获取隐患列表失败',
icon: 'none'
})
}
} catch (error) {
console.error(error)
uni.showToast({
title: '请求失败',
icon: 'none'
})
}
}
onShow(() => {
fetchHiddenDangerList()
})
const goToAdd = () => {
let url = '/pages/hiddendanger/add'
const params = []
if (oneTableId.value) {
params.push(`id=${oneTableId.value}`)
}
if (taskId.value) {
params.push(`taskId=${taskId.value}`)
}
if (checkPointId.value) {
params.push(`checkPointId=${checkPointId.value}`)
}
if (params.length) {
url += `?${params.join('&')}`
}
uni.navigateTo({ url })
}
const details = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/detail2?hazardId=${item.hazardId}&assignId=${item.assignId || ''}`
})
}
const Rectification = (item) => {
let url = `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}`
if (item.deadline) {
url += `&deadline=${encodeURIComponent(item.deadline)}`
}
if (item.assigneeId) {
url += `&assigneeId=${item.assigneeId}`
}
if (item.assigneeName) {
url += `&assigneeName=${encodeURIComponent(item.assigneeName)}`
}
uni.navigateTo({ url })
}
const editRectification = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/rectification?rectifyId=${item.rectifyId}&isEdit=1`
})
}
const acceptance = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/acceptance?hazardId=${item.hazardId}&assignId=${item.assignId}&rectifyId=${item.rectifyId}`
})
}
const assignHazard = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/assignment?hazardId=${item.hazardId}&assignId=${item.assignId}`
})
}
const statusTabs = ref([
{ label: '全部', value: null },
{ label: '待交办', value: 1 },
{ label: '待整改', value: 2 },
{ label: '待验收', value: 3 },
{ label: '待销号', value: 4 },
{ label: '已完成', value: 5 }
])
const activeTab = ref(0)
const filteredList = computed(() => {
const currentTab = statusTabs.value[activeTab.value]
if (!currentTab || currentTab.value === null) {
return hiddenDangerList.value
}
return hiddenDangerList.value.filter(item => item.status === currentTab.value)
})
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #EBF2FC;
padding-top: 100rpx;
padding-bottom: 120rpx;
}
.fixed-add-btn {
position: fixed;
bottom: 40rpx;
left: 30rpx;
right: 30rpx;
height: 88rpx;
background: linear-gradient(135deg, #667eea 0%, #2668EA 100%);
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 32rpx;
font-weight: 500;
box-shadow: 0 8rpx 24rpx rgba(38, 104, 234, 0.4);
z-index: 100;
.cuIcon-add {
margin-right: 10rpx;
font-size: 36rpx;
}
}
.list-list {
background: #FFFFFF;
box-shadow: 0rpx 2rpx 6rpx 2rpx rgba(0, 0, 0, 0.08);
border-left: 5px solid #2667E9;
border-radius: 20rpx;
padding: 20rpx;
}
.level-tag {
padding: 4rpx 16rpx;
border-radius: 8rpx;
white-space: nowrap;
flex-shrink: 0;
}
.level-minor {
background: #F6FFED;
border: 2rpx solid #B7EB8F;
color: #52C41A;
}
.level-normal {
background: #FFF7E6;
border: 2rpx solid #FFD591;
color: #FA8C16;
}
.level-major {
background: #FFF1F0;
border: 2rpx solid #FFA39E;
color: #F5222D;
}
.status-tabs {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 99;
white-space: nowrap;
background: #fff;
padding: 0 10rpx;
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.06);
}
.status-tabs-inner {
display: inline-flex;
align-items: center;
height: 88rpx;
}
.status-tab-item {
display: inline-flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 0 28rpx;
height: 88rpx;
position: relative;
}
.status-tab-text {
font-size: 28rpx;
color: #666;
}
.status-tab-active .status-tab-text {
color: #2667E9;
font-weight: bold;
}
.status-tab-bar {
position: absolute;
bottom: 8rpx;
width: 40rpx;
height: 6rpx;
background: #2667E9;
border-radius: 3rpx;
}
</style>
<style lang="scss">
.card-actions {
margin-top: 20rpx;
.cu-btn {
padding: 0 24rpx !important;
font-size: 28rpx !important;
height: 64rpx !important;
line-height: 64rpx !important;
white-space: nowrap !important;
flex-shrink: 0 !important;
width: auto !important;
}
}
</style>