zhzf/client/src/views/dtsjygl/enterpriseInfo.vue

362 lines
13 KiB
Vue

<template>
<div class="app-container">
<el-container>
<el-aside width="250px" class="left-menu">
<el-collapse el-collapse v-model="activeLeftCollapse" class="enter-left-collapse">
<!-- 基本信息分类 -->
<el-collapse-item name="basic">
<template #title>
<el-icon class="collapse-icon"><el-icon-menu /></el-icon>
<span class="collapse-title">基本信息</span>
</template>
<div class="sub-menu">
<div class="sub-menu-item" :class="{ 'active': activeAnchor === 'basic-info' }" @click="handleMenuSelect('basic-info')">
<el-icon v-if="activeAnchor === 'basic-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>基本信息</span>
</div>
<div class="sub-menu-item" :class="{ 'active': activeAnchor === 'safety-management' }" @click="handleMenuSelect('safety-management')">
<el-icon v-if="activeAnchor === 'safety-management'" class="check-icon"><SuccessFilled /></el-icon>
<span>安全基础管理信息</span>
</div>
</div>
</el-collapse-item>
<!-- 安全监管信息 -->
<el-collapse-item name="supervision">
<template #title>
<el-icon class="collapse-icon"><el-icon-menu /></el-icon>
<span class="collapse-title">监管执法信息</span>
</template>
<div class="sub-menu">
<div class="sub-menu-item" :class="{ 'active': activeAnchor === 'license-info' }" @click="handleMenuSelect('license-info')">
<el-icon v-if="activeAnchor === 'license-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>行政许可信息</span>
</div>
<div v-if="dc.mode === 'detail'" class="sub-menu-item" :class="{ 'active': activeAnchor === 'enforcement-info' }" @click="handleMenuSelect('enforcement-info')">
<el-icon v-if="activeAnchor === 'enforcement-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>行政检查信息</span>
</div>
<div v-if="dc.mode === 'detail'" class="sub-menu-item" :class="{ 'active': activeAnchor === 'penalty-info' }" @click="handleMenuSelect('penalty-info')">
<el-icon v-if="activeAnchor === 'penalty-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>行政处罚信息</span>
</div>
<!-- <div v-if="dc.mode === 'detail'" class="sub-menu-item" :class="{ 'active': activeAnchor === 'accident-info' }" @click="handleMenuSelect('accident-info')">
<el-icon v-if="activeAnchor === 'accident-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>生产安全事故信息</span>
</div>-->
</div>
</el-collapse-item>
<el-collapse-item v-if="dc.mode === 'detail'" name="risk-info">
<template #title>
<el-icon class="collapse-icon"><el-icon-menu /></el-icon>
<span class="collapse-title">风险隐患信息</span>
</template>
<div class="sub-menu">
<!-- <div class="sub-menu-item" :class="{ 'active': activeAnchor === 'sharing-risks-info' }" @click="handleMenuSelect('sharing-risks-info')">
<el-icon v-if="activeAnchor === 'sharing-risks-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>企业风险信息</span>
</div>-->
<div class="sub-menu-item" :class="{ 'active': activeAnchor === 'danger-info' }" @click="handleMenuSelect('danger-info')">
<el-icon v-if="activeAnchor === 'danger-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>重大危险源信息</span>
</div>
<div class="sub-menu-item" :class="{ 'active': activeAnchor === 'accident-risks-info' }" @click="handleMenuSelect('accident-risks-info')">
<el-icon v-if="activeAnchor === 'accident-risks-info'" class="check-icon"><SuccessFilled /></el-icon>
<span>重大事故隐患信息</span>
</div>
</div>
</el-collapse-item>
</el-collapse>
</el-aside>
<el-main class="main-content">
<el-tabs type="border-card" class="wrapper-tabs" v-model="activeTab">
<el-tab-pane label="基本信息" name="tab1">
<el-collapse v-model="activeRightCollapse" @change="handleCollapseChange">
<el-collapse-item title="生产经营单位基本信息" name="basic-info" id="basic-info" :data-section="'basic-info'" class="content-block">
<!-- 基本信息 -->
<qyjbxx :dc="dc"/>
</el-collapse-item>
<!-- 安全基础管理信息 -->
<el-collapse-item title="生产经营单位安全基础信息表" name="safety-management" id="safety-management" :data-section="'safety-management'" class="content-block">
<aqjcglxx :dc="dc"/>
</el-collapse-item>
<!-- 行政许可信息 -->
<el-collapse-item title="行政许可信息" name="license-info" id="license-info" :data-section="'license-info'" class="content-block">
<xzxkxx :dc="dc"/>
</el-collapse-item>
<!-- 行政检查信息 -->
<el-collapse-item v-if="dc.mode === 'detail'" title="行政检查信息" name="enforcement-info" id="enforcement-info" :data-section="'enforcement-info'" class="content-block">
<zfjcjl :dc="dc"/>
</el-collapse-item>
<!-- 行政处罚信息 -->
<el-collapse-item v-if="dc.mode === 'detail'" title="行政处罚信息" name="penalty-info" id="penalty-info" :data-section="'penalty-info'" class="content-block">
<xzcfxx :dc="dc"/>
</el-collapse-item>
<!-- 生产安全事故信息 -->
<!-- <el-collapse-item v-if="dc.mode === 'detail'" title="生产安全事故信息" name="accident-info" id="accident-info" :data-section="'accident-info'" class="content-block">
<scaqsg :dc="dc"/>
</el-collapse-item>-->
<!-- 企业风险信息 -->
<!-- <el-collapse-item v-if="dc.mode === 'detail'" title="企业风险信息" name="sharing-risks-info" id="sharing-risks-info" :data-section="'sharing-risks-info'" class="content-block">
</el-collapse-item>-->
<!-- 重大危险源信息 -->
<el-collapse-item v-if="dc.mode === 'detail'" title="重大危险源信息" name="danger-info" id="danger-info" :data-section="'danger-info'" class="content-block">
<zdwxy :dc="dc"/>
</el-collapse-item>
<!-- 重大事故隐患信息 -->
<el-collapse-item v-if="dc.mode === 'detail'" title="重大事故隐患信息" name="accident-risks-info" id="accident-risks-info" :data-section="'accident-risks-info'" class="content-block">
<zdsgyh :dc="dc"/>
</el-collapse-item>
</el-collapse>
</el-tab-pane>
</el-tabs>
<div class="cvi-dialog-footer" v-if="dc.mode !== 'detail'"
style="width: 100%; position: absolute; bottom: 0; background: #FFF; z-index: 999; height: 40px; padding: 0; padding-top: 10px; box-shadow: 0 -5px 10px rgba(0, 0, 0, 0.1);">
<el-button @click="handleClose">取消</el-button>
<el-button type="primary" @click="$emit('ok')">确定</el-button>
</div>
</el-main>
</el-container>
</div>
</template>
<script setup>
import {ref, computed, onMounted, onUnmounted, watch, nextTick, reactive, toRefs} from 'vue'
import { debounce } from 'lodash-es'
import {Menu as ElIconMenu, SuccessFilled} from '@element-plus/icons-vue'
import aqjcglxx from "@pages/dtsjygl/enterprise/aqjcglxx.vue"
import qyjbxx from "@pages/dtsjygl/enterprise/qyjbxx.vue"
import xzxkxx from "@pages/dtsjygl/enterprise/xzxkxx.vue"
import {ElButton} from "element-plus"
import zfjcjl from "@pages/dtsjygl/enterprise/zfjcjl.vue"
import xzcfxx from "@pages/dtsjygl/enterprise/xzcfxx.vue"
import scaqsg from "@pages/dtsjygl/enterprise/scaqsg.vue"
import zdwxy from "@pages/dtsjygl/enterprise/zdwxy.vue"
import zdsgyh from "@pages/dtsjygl/enterprise/zdsgyh.vue"
const props = defineProps({dc: {type: Object}})
const state = reactive({})
const {} = toRefs(state)
const activeLeftCollapse = ref(['basic', 'supervision', 'risk-info'])
// 设置所有项的name值
const activeRightCollapse = ref(['basic-info', 'safety-management', 'license-info', 'enforcement-info', 'penalty-info', 'accident-info', 'sharing-risks-info', 'danger-info', 'accident-risks-info'])
const activeAnchor = ref('basic-info')
const observer = ref(null)
const activeTab = ref('tab1') // 标签页激活状态
const emit = defineEmits(['update:open', 'ok'])
// 处理菜单选择
const handleMenuSelect = (key) => {
activeAnchor.value = key
// 确保对应的右侧折叠面板是展开的
if (!activeRightCollapse.value.includes(key)) {
activeRightCollapse.value = [key]
}
// 滚动到对应位置
setTimeout(() => {
const element = document.getElementById(key)
element?.scrollIntoView({ behavior: 'smooth', block: 'start' })
}, 100)
}
// 处理右侧折叠面板变化
const handleCollapseChange = (accordion) => {
if (activeNames.length > 0) {
updateActiveState(activeNames[0])
}
}
// 新增的滚动同步逻辑
const setupIntersectionObserver = () => {
const sections = activeRightCollapse.value.map(id => document.getElementById(id)).filter(Boolean)
const options = {root: document.querySelector('.wrapper-tabs'), rootMargin: '0px', threshold: 0.5}
observer.value = new IntersectionObserver(debounce((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
updateActiveState(entry.target.id)
}
})
}, 100), options)
sections.forEach(section => observer.value.observe(section))
}
const updateActiveState = (activeId) => {
activeAnchor.value = activeId
}
// 生命周期
onMounted(() => {
window.scrollTo(0, 0)
setupIntersectionObserver()
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const sectionId = entry.target.getAttribute('data-section')
updateActiveState(sectionId)
}
})
},
{ threshold: 0.5 }
)
document.querySelectorAll('.content-block').forEach(el => {
observer.observe(el)
})
})
onUnmounted(() => {
if (observer.value) {
observer.value.disconnect()
}
})
function handleClose () {
emit('update:open', false)
}
</script>
<style>
.main-content {
padding: 0 !important;
.el-tabs--border-card > .el-tabs__content {
padding-right: 10px !important;
}
.el-tabs__content {
overflow: auto !important;
}
}
.enter-left-collapse .el-collapse-item__header {
background-color: #cee9ef;
}
</style>
<style scoped>
.wrapper-tabs {
height: 100%;
:deep(.el-tabs__content) {
padding: 0;
height: calc(100vh - 100px);
overflow: auto;
}
}
html {
scroll-behavior: smooth;
}
.app-container {
height: calc(100vh - 100px);
display: flex;
}
/* 左侧菜单样式 */
.left-menu {
background-color: #f5f7fa;
border-right: 1px solid #e6e6e6;
height: calc(100vh - 100px);
overflow-y: auto;
}
.enter-left-collapse {
border: none;
background: transparent;
}
.enter-left-collapse :deep(.el-collapse-item__header) {
height: 40px;
line-height: 40px;
font-weight: bold;
font-size: 13px;
background-color: #f5f7fa;
border-bottom: 1px solid #e6e6e6;
}
.enter-left-collapse :deep(.el-collapse-item__content) {
padding: 0;
}
.collapse-icon {
margin-right: 8px;
color: #409eff;
}
.collapse-title {
font-weight: bold;
}
.sub-menu-item {
position: relative; /* 父元素设置相对定位 */
padding: 5px 10px 5px 20px;
cursor: pointer;
display: flex;
align-items: center;
transition: all 0.3s;
}
.sub-menu-item:hover {
background-color: #ebf5ff;
}
.sub-menu-item.active {
background-color: #e1f3ff;
color: #409eff;
}
.check-icon {
position: absolute; /* 图标绝对定位 */
left: 0; /* 图标位于左侧 */
top: 50%; /* 垂直居中 */
transform: translateY(-50%); /* 垂直居中调整 */
color: #67c23a;
margin-right: 8px;
font-size: 14px;
}
/* 右侧内容区域样式 */
.main-content {
padding: 0;
display: flex;
flex-direction: column;
height: calc(100vh - 100px);
overflow: hidden;
position: relative;
}
/* 右侧折叠面板样式 */
.el-collapse {
border: none;
background: transparent;
}
.el-collapse-item {
margin-bottom: 5px;
background: #fff;
border-radius: 4px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
}
.el-collapse-item :deep(.el-collapse-item__header) {
font-weight: bold;
font-size: 16px;
padding: 0 20px;
height: 48px;
line-height: 48px;
border-bottom: 1px solid #ebeef5;
}
.el-collapse-item :deep(.el-collapse-item__content) {
padding: 20px;
}
</style>