Files
threeonecheck_web/pages/Inspectionwarning/Inspectionwarning.vue
2026-02-08 09:30:43 +08:00

470 lines
11 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="padding page">
<scroll-view scroll-x class="tab-scroll">
<view class="tab-list">
<view class="tab-item" :class="{ 'tab-active': activeIndex === index }"
v-for="(item, index) in warningList" :key="index" @click="switchTab(index)">
{{ item.name }}
</view>
</view>
</scroll-view>
<!-- 查询条件 -->
<view class="bg-white radius padding margin-top search-card">
<view class="section-header">
<image class="section-icon" src="/static/yujin/yujin_sousuo.png" mode="aspectFit"></image>
<view class="text-black text-bold">查询条件</view>
</view>
<!-- 日期选择行 -->
<view class="date-row margin-top">
<view class="date-item">
<view class="date-label">开始日期</view>
<view class="date-picker" @click="showStartDatePicker = true">
<text :class="searchForm.startDate ? 'date-value' : 'date-placeholder'">
{{ searchForm.startDate || '请选择' }}
</text>
<text class="cuIcon-unfold"></text>
</view>
<up-datetime-picker
:show="showStartDatePicker"
v-model="startDateValue"
mode="date"
@confirm="onStartDateConfirm"
@cancel="showStartDatePicker = false"
@close="showStartDatePicker = false"
></up-datetime-picker>
</view>
<view class="date-item">
<view class="date-label">结束日期</view>
<view class="date-picker" @click="showEndDatePicker = true">
<text :class="searchForm.endDate ? 'date-value' : 'date-placeholder'">
{{ searchForm.endDate || '请选择' }}
</text>
<text class="cuIcon-unfold"></text>
</view>
<up-datetime-picker
:show="showEndDatePicker"
v-model="endDateValue"
mode="date"
@confirm="onEndDateConfirm"
@cancel="showEndDatePicker = false"
@close="showEndDatePicker = false"
></up-datetime-picker>
</view>
</view>
<view class="margin-top">
<view class="date-label">公司名称</view>
<up-input v-model="searchForm.deptName" placeholder="请输入公司名称" border="surround"></up-input>
</view>
<button class="search-btn" @click="handleSearch">查询</button>
</view>
<!-- 统计概览 -->
<view class="padding bg-white radius margin-top">
<view class="section-header">
<image class="section-icon" src="/static/yujin/yujin_tongji.png" mode="aspectFit"></image>
<view class="text-bold text-black">统计概览</view>
</view>
<view class="stat-grid margin-top">
<view class="stat-item stat-total">
<view class="stat-num">{{ statistics.total }}</view>
<view class="stat-label">总计</view>
</view>
<view class="stat-item stat-overdue">
<view class="stat-num">{{ statistics.overdue }}</view>
<view class="stat-label">逾期</view>
</view>
<view class="stat-item stat-completed">
<view class="stat-num">{{ statistics.completed }}</view>
<view class="stat-label">已完成</view>
</view>
<view class="stat-item stat-pending">
<view class="stat-num">{{ statistics.pending }}</view>
<view class="stat-label">待处理</view>
</view>
</view>
</view>
<!-- 数据列表标题 -->
<view class="bg-white radius padding margin-top margin-bottom flex align-center">
<view class="list-title-bar"></view>
<view class="text-bold text-black">日常安全检查预警数据列表</view>
</view>
<!-- 数据列表 -->
<view v-for="(item, index) in dataList" :key="item.id" class="list-card">
<!-- 状态标签斜角 -->
<view class="status-tag" :class="getStatusClass(item.overdueDays)">
<text class="status-text">{{ getStatusText(item.overdueDays, item.statusName) }}</text>
</view>
<view class="card-header">
<view class="text-bold text-black">#{{ index + 1 }}</view>
</view>
<view class="card-row">
<view class="row-label">企业名称</view>
<view class="row-value">{{ item.deptName || '-' }}</view>
</view>
<view class="card-row">
<view class="row-label">计划名称</view>
<view class="row-value">{{ item.planName || '-' }}</view>
</view>
<view class="card-row">
<view class="row-label">计划周期</view>
<view class="row-value">{{ item.cycleName || '-' }}</view>
</view>
<view class="card-row">
<view class="row-label">预约检查日期</view>
<view class="row-value">{{ item.taskDate || '-' }}</view>
</view>
<view class="card-row">
<view class="row-label">实际完成时间</view>
<view class="row-value">{{ item.finishTime || '未完成' }}</view>
</view>
<view class="card-row">
<view class="row-label">负责人</view>
<view class="row-value">{{ item.executorName || '-' }}</view>
</view>
<view class="card-row">
<view class="row-label">逾期天数</view>
<view class="row-value">{{ item.overdueDays || '-' }}</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="dataList.length === 0" class="empty-tip">
<text>暂无数据</text>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { getInspectionWarningList } from '@/request/api.js'
// 搜索表单
const searchForm = reactive({
startDate: '',
endDate: '',
deptName: ''
})
// 日期选择器
const showStartDatePicker = ref(false)
const showEndDatePicker = ref(false)
const startDateValue = ref(Number(new Date()))
const endDateValue = ref(Number(new Date()))
// 统计数据
const statistics = reactive({
total: 0,
overdue: 0,
completed: 0,
pending: 0
})
// 列表数据
const dataList = ref([])
const pageNum = ref(1)
const pageSize = ref(20)
// 日期格式化
const formatDate = (timestamp) => {
const date = new Date(timestamp)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}-${month}-${day}`
}
// 日期选择确认
const onStartDateConfirm = (e) => {
searchForm.startDate = formatDate(e.value)
showStartDatePicker.value = false
}
const onEndDateConfirm = (e) => {
searchForm.endDate = formatDate(e.value)
showEndDatePicker.value = false
}
// 获取状态样式类
const getStatusClass = (overdueDays) => {
if (!overdueDays || overdueDays === '按期') {
return 'status-normal' // 按期/期限内
}
const days = parseInt(overdueDays)
if (days >= 7) {
return 'status-serious' // 严重逾期(红色)
} else if (days >= 1) {
return 'status-overdue' // 逾期(橙色)
}
return 'status-normal'
}
// 获取状态文本
const getStatusText = (overdueDays, statusName) => {
if (!overdueDays || overdueDays === '按期') {
return statusName === '已完成' ? '按期已完成' : '期限内待检'
}
const days = parseInt(overdueDays)
if (days >= 7) {
return '严重逾期'
} else if (days >= 1) {
return statusName === '已完成' ? '逾期已完成' : '逾期未检'
}
return '期限内待检'
}
// 获取数据
const fetchData = async () => {
try {
const params = {
pageNum: pageNum.value,
pageSize: pageSize.value
}
// 添加查询条件
if (searchForm.startDate) {
params.startDate = searchForm.startDate
}
if (searchForm.endDate) {
params.endDate = searchForm.endDate
}
if (searchForm.deptName && searchForm.deptName.trim()) {
params.deptName = searchForm.deptName.trim()
}
const res = await getInspectionWarningList(params)
if (res.code === 0) {
// 更新统计数据
if (res.data.statistics) {
statistics.total = res.data.statistics.total || 0
statistics.overdue = res.data.statistics.overdue || 0
statistics.completed = res.data.statistics.completed || 0
statistics.pending = res.data.statistics.pending || 0
}
// 更新列表数据
if (res.data.page && res.data.page.records) {
dataList.value = res.data.page.records
}
}
} catch (error) {
console.error('获取预警列表失败:', error)
}
}
// 搜索
const handleSearch = () => {
pageNum.value = 1
fetchData()
}
// 页面加载
onShow(() => {
fetchData()
})
</script>
<style lang="scss" scoped>
.page {
min-height: 100vh;
background: #EBF2FC;
padding-bottom: 40rpx;
}
// 区块标题
.section-header {
display: flex;
align-items: center;
.section-icon {
width: 40rpx;
height: 40rpx;
margin-right: 12rpx;
}
}
// 搜索卡片
.search-card {
.date-row {
display: flex;
gap: 20rpx;
.date-item {
flex: 1;
}
}
.date-label {
font-size: 28rpx;
color: #333;
margin-bottom: 12rpx;
}
.date-picker {
display: flex;
align-items: center;
justify-content: space-between;
height: 72rpx;
padding: 0 20rpx;
background: #f8f8f8;
border-radius: 8rpx;
border: 1rpx solid #eee;
.date-value {
color: #333;
font-size: 28rpx;
}
.date-placeholder {
color: #999;
font-size: 28rpx;
}
}
.search-btn {
margin-top: 30rpx;
background: linear-gradient(135deg, #667eea 0%, #2667E9 100%);
color: #fff;
border-radius: 40rpx;
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
}
}
// 统计卡片
.stat-grid {
display: flex;
justify-content: space-between;
gap: 16rpx;
.stat-item {
flex: 1;
height: 124rpx;
border-radius: 12rpx;
color: #fff;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.stat-num {
font-size: 40rpx;
font-weight: bold;
}
.stat-label {
font-size: 24rpx;
margin-top: 8rpx;
}
}
.stat-total {
background: linear-gradient(135deg, #628EFB 0%, #4A7CF7 100%);
}
.stat-overdue {
background: linear-gradient(135deg, #32DCC7 0%, #20C5B0 100%);
}
.stat-completed {
background: linear-gradient(135deg, #32D1E9 0%, #20B8D0 100%);
}
.stat-pending {
background: linear-gradient(135deg, #A190F5 0%, #8B78E8 100%);
}
}
// 列表标题
.list-title-bar {
width: 8rpx;
height: 32rpx;
background: #2667E9;
border-radius: 4rpx;
margin-right: 12rpx;
}
// 数据卡片
.list-card {
position: relative;
background: #FFFFFF;
box-shadow: 0rpx 2rpx 10rpx rgba(0, 0, 0, 0.08);
border-left: 8rpx solid #2667E9;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
overflow: hidden;
.card-header {
margin-bottom: 20rpx;
}
.card-row {
display: flex;
margin-top: 16rpx;
font-size: 28rpx;
line-height: 1.5;
.row-label {
color: #999;
white-space: nowrap;
flex-shrink: 0;
}
.row-value {
color: #333;
word-break: break-all;
}
}
}
// 状态标签(斜角样式)
.status-tag {
position: absolute;
top: 0;
right: 0;
width: 160rpx;
height: 50rpx;
display: flex;
align-items: center;
justify-content: center;
transform: rotate(0deg);
border-radius: 0 16rpx 0 16rpx;
.status-text {
font-size: 22rpx;
color: #fff;
font-weight: 500;
}
}
// 严重逾期 - 红色
.status-serious {
background: linear-gradient(135deg, #FF6B6B 0%, #EE5A5A 100%);
}
// 逾期 - 橙色
.status-overdue {
background: linear-gradient(135deg, #FFA726 0%, #FF9800 100%);
}
// 按期/正常 - 绿色
.status-normal {
background: linear-gradient(135deg, #66BB6A 0%, #4CAF50 100%);
}
// 逾期已完成 - 蓝色
.status-completed {
background: linear-gradient(135deg, #42A5F5 0%, #2196F3 100%);
}
// 空状态
.empty-tip {
text-align: center;
padding: 100rpx 0;
color: #999;
font-size: 28rpx;
}
</style>