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

502 lines
15 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="content">
<view class="flex padding-top-xl padding-bottom-xl text-white " style="background-color:#007aff ;">
<view class="cu-avatar xl round margin-left">
<image class="avatar-image" :src="getImageUrl(userInfo.avatar) || defaultAvatar" mode="aspectFill"></image>
</view>
<view class="padding-left" style="display: flex;flex-direction: column;gap: 10rpx;justify-content: center;align-items: center;">
<view class="text-bold">{{ userInfo.deptName || '未知部门' }}</view>
<view class="flex padding-top-xs">
<view>用户</view>
<view>{{ userInfo.nickName || userInfo.username || '未登录' }}</view>
</view>
<!-- <view class="flex justify-between">
<view></view>
<view class="cu-btn text-blue margin-top text-bold">切换</view>
</view> -->
</view>
</view>
<view class="padding page-content" style="background: #EBF2FC;">
<view class="bg-white padding radius">
<view class="flex margin-bottom-xl">
<view class="border-tite"></view>
<view class="margin-left-xs text-bold " >功能菜单</view>
</view>
<view class=" grid col-3 grid-square">
<view class="list " v-for="(item, index) in infoList" :key="index" @click="handleMenuClick(item)">
<image style="width: 102rpx;height: 102rpx;" :src="item.src"></image>
<view>{{ item.name}}</view>
</view>
</view>
</view>
<!-- 我的检查计划 -->
<view class="padding bg-white margin-top radius">
<view class="flex margin-bottom-xl">
<view class="border-tite"></view>
<view class="text-bold margin-left-xs">我的检查计划</view>
</view>
<!-- 无数据提示 -->
<view v-if="checkPlanData.length === 0" class="text-center text-gray padding">
暂无检查计划
</view>
<!-- 列表渲染 -->
<view class="list-list padding margin-bottom" v-for="(item, index) in checkPlanData" :key="item.id">
<view class="flex">
<image src="/static/蒙版组 273.png" style="width: 40rpx;height: 40rpx;"></image>
<view class="text-bold margin-left">{{ item.name }}</view>
</view>
<view class="flex margin-top">
<view class="border-border margin-right-xs">{{ item.runModeName }}完成</view>
<view class="border-border">{{ item.cycle }}</view>
</view>
<view class="flex text-gray margin-top">
<view>计划时间</view>
<view>{{ formatDate(item.planStartTime) }}{{ formatDate(item.planEndTime) }}</view>
</view>
<view class="flex margin-top align-center">
<view>完成进度</view>
<view class="flex align-center margin-left-sm">
<view class="cu-progress round">
<view class="bg-green" :style="{ width: item.progress + '%' }"></view>
</view>
<text class="margin-left-sm">{{ item.progress }}%</text>
</view>
</view>
<view class="grid col-4 bg-gray margin padding text-center radius">
<view>
<view class="text-orange">{{ item.totalCount }}</view>
<view>总数</view>
</view>
<view>
<view class="text-yellow">{{ item.totalCount - item.finishedCount }}</view>
<view>待完成</view>
</view>
<view>
<view class="text-olive">0</view>
<view>待验收</view>
</view>
<view>
<view class="text-blue">{{ item.finishedCount }}</view>
<view>已完成</view>
</view>
</view>
<view class="margin-top margin-bottom flex justify-end">
<button class="cu-btn round lg light bg-blue margin-right" @click.stop="ViewDetails(item)">查看详情</button>
<button v-if="item.finishedCount < item.totalCount" class="cu-btn round lg bg-blue" @click.stop="goDetails(item)">开始检查</button>
<view v-else class="cu-btn round lg bg-green">已完成</view>
</view>
</view>
</view>
<!-- 我的隐患 -->
<view class="padding bg-white margin-top radius" >
<view class="flex margin-bottom-xl ">
<view class="border-tite"></view>
<view class="text-bold margin-left-xs">我的隐患排查</view>
</view>
<view class="list-list padding margin-bottom" v-for="(item,index) in hiddenDangerData" :key="item.hazardId">
<view class="flex text-bold justify-between">
<view class="flex">
<view>隐患</view>
<view class="text-bold margin-left">#{{ index + 1 }}</view>
</view>
<view class="text-blue">{{item.statusName}}</view>
</view>
<view class="flex margin-top">
<view class="text-gray">标题</view>
<view>{{item.title}}</view>
</view>
<view class="flex margin-top">
<view class="text-gray">隐患来源</view>
<view>{{item.source}}</view>
</view>
<view class="flex margin-top">
<view class="text-gray" style="white-space: nowrap;">隐患位置</view>
<view>{{item.address}}</view>
</view>
<view class="flex margin-top">
<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-top">
<view class="text-gray">发现时间</view>
<view>{{item.createdAt}}</view>
</view>
<view class="margin-top margin-bottom flex justify-end" style="gap: 10rpx;">
<!-- 所有状态都显示查看详情 -->
<button class="cu-btn round lg light bg-blue" @click.stop="viewHazardDetail(item)">查看详情</button>
<!-- 待整改状态canEdit为true时显示隐患交办和立即整改 -->
<button v-if="item.statusName === '待整改' && item.canEdit"
class="cu-btn round lg light bg-blue" @click.stop="assignHazard(item)">隐患交办</button>
<button v-if="item.statusName === '待整改' && item.canEdit"
class="cu-btn round lg bg-blue" @click.stop="goRectification(item)">立即整改</button>
<!-- 待验收显示编辑整改信息和立即验收 -->
<button v-if="item.statusName === '待验收' && item.canEdit"
class="cu-btn round lg light bg-blue" @click.stop="editRectification(item)">编辑整改信息</button>
<button v-if="item.statusName === '待验收' && canAcceptance"
class="cu-btn round lg bg-blue" @click.stop="goAcceptance(item)">立即验收</button>
<!-- 待交办显示隐患交办 -->
<button v-if="item.statusName === '待交办'"
class="cu-btn round lg bg-blue" @click.stop="assignHazard(item)">隐患交办</button>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
// import { onLoad } from '@dcloudio/uni-app';
import {getCheckPlanList,getHiddenDangerList} from '@/request/api.js'
import { getProfileDetail } from '@/request/three_one_api/info.js';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { baseUrl } from '@/request/request.js';
const loading = ref(true);
const defaultAvatar = 'https://ossweb-img.qq.com/images/lol/web201310/skin/big99008.jpg';
// 用户信息
const userInfo = reactive({
userId: '',
username: '',
nickName: '',
deptId: '',
deptName: '',
role: '',
avatar: ''
});
// 获取用户角色判断是否有验收权限admin或manage才能验收
const canAcceptance = computed(() => {
return userInfo.role === 'admin' || userInfo.role === 'manage';
});
// 获取图片完整URL用于显示
const getImageUrl = (path) => {
if (!path) return '';
if (path.startsWith('http')) return path;
return baseUrl + path;
};
// 获取用户信息(从接口获取)
const getUserInfo = async () => {
try {
const res = await getProfileDetail();
if (res.code === 0 && res.data) {
userInfo.userId = res.data.userId || '';
userInfo.username = res.data.userName || '';
userInfo.nickName = res.data.nickName || '';
userInfo.deptId = res.data.deptId || '';
userInfo.deptName = res.data.deptName || '';
userInfo.avatar = res.data.avatar || '';
// 获取角色信息
if (res.data.roles && res.data.roles.length > 0) {
userInfo.role = res.data.roles[0].roleKey || '';
}
}
} catch (e) {
console.error('获取用户信息失败:', e);
// 如果接口失败,尝试从本地存储获取
try {
const storedUserInfo = uni.getStorageSync('userInfo');
if (storedUserInfo) {
const info = JSON.parse(storedUserInfo);
userInfo.userId = info.userId || '';
userInfo.username = info.username || '';
userInfo.nickName = info.nickName || '';
userInfo.deptId = info.deptId || '';
userInfo.deptName = info.deptName || '';
userInfo.role = info.role || '';
userInfo.avatar = info.avatar || '';
}
} catch (storageError) {
console.error('从本地存储获取用户信息失败:', storageError);
}
}
};
const infoList = ref([{
name: '成员管理',
src: '../../static/组 19378.png'
},
{
name: '企业信息填报',
src: '../../static/组 19387.png'
},
{
name: '区域设置',
src: '../../static/组 20253.png'
},
{
name: '检查表',
src: '../../static/组 20254.png'
},
{
name: '检查记录',
src: '../../static/组 20255.png'
},
{
name: '证照管理',
src: '../../static/组 20256.png'
},
{
name: '隐患排查',
src: '../../static/组 20257.png'
},
{
name: '隐患销号申请',
src: '../../static/组 20258.png'
},
{
name: '设备登记',
src: '../../static/组 20259.png'
}
]);
const ViewDetails = (item) => {
uni.navigateTo({
url: `/pages/plandetail/plandetail?id=${item.id}`
})
}
const goDetails = (item) => {
uni.navigateTo({
url: `/pages/Inspectionresult/Inspectionresult?id=${item.id}`
})
}
// 菜单点击跳转
const handleMenuClick = (item) => {
const menuRoutes = {
'成员管理': '/pages/membermanagemen/membermanagemen',
'企业信息填报': '/pages/corporateInformation/corporateInformation',
'区域设置':'/pages/area/management',
'检查表' :'/pages/checklist/checklist',
'检查记录': '/pages/Inspectionlog/Inspectionlog',
'证照管理': '/pages/Idphotomanagement/Idphotomanagement',
'隐患排查':'/pages/hiddendanger/Inspection',
'隐患销号申请':'/pages/closeout/application',
'设备登记':'/pages/equipmentregistration/equipmentregistration',
// 可以在这里添加其他菜单的跳转路径
};
const url = menuRoutes[item.name];
if (url) {
uni.navigateTo({ url });
} else {
uni.showToast({ title: '功能开发中', icon: 'none' });
}
}
//我的检查计划
const checkPlanParams = ref({
pageNum: 1,
pageSize: 10,
name: ''
});
const checkPlanData = ref([]);
const getCheckPlanLists = async () => {
try {
const res = await getCheckPlanList(checkPlanParams.value);
console.log(res);
if (res.code === 0) {
checkPlanData.value = res.data.records;
}
} catch (error) {
console.error(error);
} finally {
loading.value = false;
}
};
// 格式化日期 (2025-12-18 00:00:00 -> 2025-12-18)
const formatDate = (dateStr) => {
if (!dateStr) return '';
return dateStr.split(' ')[0];
};
// 页面加载时调用接口
// onLoad(() => {
// getUserInfo();
// getCheckPlanLists();
// });
// 页面每次显示时都会加载数据
onShow(() => {
getUserInfo();
getCheckPlanLists();
getHiddenDangerLists();
});
//我的隐患排查
const hiddenDangerParams = ref({
pageNum: 1,
pageSize: 10,
name: ''
});
const hiddenDangerData = ref([]);
const getHiddenDangerLists = async () => {
try {
const res = await getHiddenDangerList(hiddenDangerParams.value);
console.log(res);
if (res.code === 0) {
hiddenDangerData.value = res.data.records;
console.log(hiddenDangerData.value,1111);
}
} catch (error) {
console.error(error);
} finally {
loading.value = false;
}
};
// 页面加载时调用接口
onLoad(() => {
getHiddenDangerLists();
});
// ========== 隐患排查相关跳转函数 ==========
// 查看隐患详情
const viewHazardDetail = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/view?hazardId=${item.hazardId}&assignId=${item.assignId}`
})
}
// 立即整改(待整改状态)
const goRectification = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/rectification?hazardId=${item.hazardId}&assignId=${item.assignId}`
})
}
// 编辑整改信息(待验收状态)
const editRectification = (item) => {
uni.navigateTo({
url: `/pages/hiddendanger/rectification?rectifyId=${item.rectifyId}&isEdit=1`
})
}
// 立即验收
const goAcceptance = (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}`
})
}
</script>
<style lang="scss" scoped>
.page-content {
background: #EBF2FC;
border-radius: 40rpx 40rpx 0rpx 0rpx;
margin-top: -30rpx;
padding: 30rpx;
padding-bottom: 50rpx;
position: relative;
z-index: 10;
min-height: calc(100vh - 400rpx);
}
// 头像图片样式
.avatar-image {
width: 100%;
height: 100%;
border-radius: 50%;
}
.grid-list {
gap: 30rpx;
margin-top: 30rpx;
}
.list {
background: #F2F6FF;
box-shadow: 0rpx 4rpx 8rpx 2rpx #CADDFC;
border-radius: 10rpx;
text-align: center;
padding: 20rpx 0;
}
.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;
}
.border-tite {
width: 10rpx;
height: 32rpx;
background: #2667E9;
border-radius: 10rpx 10rpx 10rpx 10rpx;
}
.cu-progress {
width: 300rpx;
height: 20rpx;
background: #ebeef5;
border-radius: 100rpx;
overflow: hidden;
view {
height: 100%;
border-radius: 100rpx;
transition: width 0.3s ease;
}
}
.bg-green {
background: #2667E9;
}
.border-border {
padding: 10rpx;
background: #EEF3FF;
border-radius: 4rpx 4rpx 4rpx 4rpx;
border: 2rpx solid #AAC5FC;
text-align: center;
justify-content: center;
align-items: center;
display: flex;
font-size: 28rpx;
color: #2667E9;
}
// 隐患等级标签样式
.level-tag {
padding: 4rpx 16rpx;
border-radius: 8rpx;
}
// 轻微隐患
.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;
}
</style>