362 lines
13 KiB
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>
|