123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290 |
- <template>
- <el-container v-loading="isAppLoadings" class="hc-layout-box" :class="[!isNullES(isLayout) && isLayout === 'no' ? 'is-no-layout' : '']" element-loading-text="获取数据中...">
- <el-header class="hc-layout-header">
- <div class="hc-layout-header-logo" :style="`width: ${isCollapse ? '0px' : '200px'};`" @click="logoClick">
- <!-- <img id="logo-icon" :src="appLogoIcon" alt=""> -->
- <span v-show="!isCollapse" class="logo-name">计量系统</span>
- </div>
- <div class="header-top-collapse-bar" @click="collapseChange">
- <HcIcon v-if="isCollapse" name="menu-unfold" />
- <HcIcon v-else name="menu-fold" />
- </div>
- <div class="header-top-menu-bar">
- <HcTopMenuBar :msg-count="taskCount" @load="topMenuLoad" @change="topMenuChange" />
- </div>
- <div class="header-content-bar">
- <HcCascader @send="cascaderSend" @change="cascaderChange" />
- <hc-upload-bar />
- <HelpInfoBar />
- <ConfigBar />
- <UserInfoBar @load="userInfoLoad" />
- </div>
- </el-header>
- <el-container class="hc-layout-container">
- <el-aside v-if="isAsideMenu" class="hc-layout-aside" :class="[isCollapse ? 'is-collapse' : '']" :width="isCollapse ? '90px' : '200px'">
- <MenuBar :collapse="isCollapse" :cur="menuBarKey" :datas="menuBarData" :msg-count="taskCount" @change="menuBarChange" />
- </el-aside>
- <el-main class="hc-layout-main">
- <div class="hc-router-menu-bar">
- <RouterMenu @load="routerMenuLoad" />
- </div>
- <div id="hc-main-box" class="hc-main-page">
- <div class="hc-main-body">
- <router-view v-if="reloadRouter" v-slot="{ Component }">
- <transition name="fade-transform">
- <keep-alive :max="10">
- <component :is="Component" :msg-count="taskCount" />
- </keep-alive>
- </transition>
- </router-view>
- </div>
- </div>
- </el-main>
- </el-container>
- <hc-reminder v-model="isReminderShow" :text="isReminderText" />
- </el-container>
- </template>
- <script setup>
- import { nextTick, onMounted, onUnmounted, ref, watch } from 'vue'
- import { useRoute, useRouter } from 'vue-router'
- import { getObjValue, isNullES, useClick } from 'js-fast-way'
- import { HcSocket } from '~src/plugins/HcSocket'
- import { HcAnnouncement } from 'hc-vue3-ui'
- import { useAppStore } from '~src/store'
- import { initButtons } from '~sto/app'
- import { useProject } from '~sto/useProject'
- import { getNotification } from '~uti/tools'
- import website from '~src/config'
- //初始组合式
- const router = useRouter()
- const useRoutes = useRoute()
- const store = useAppStore()
- const reloadRouter = ref(false)
- const { isAppLoading } = useProject()
- //子组件
- import HcTopMenuBar from './modules/HcTopMenu.vue'
- import HcCascader from './modules/Cascader.vue'
- import UserInfoBar from './modules/UserInfoBar.vue'
- import HelpInfoBar from './modules/HelpInfoBar.vue'
- import ConfigBar from './modules/ConfigBar.vue'
- import RouterMenu from './modules/RouterMenu.vue'
- import MenuBar from '~src/layout/modules/MenuBar.vue'
- //菜单数据
- const menuBarKey = ref('')
- const menuBarData = ref([])
- const isLayout = ref('')
- //渲染完成
- onMounted(() => {
- const layout = useRoutes?.query?.layout, layout2 = store.isLayout
- isLayout.value = layout ?? layout2
- annRefs.value = []
- initButtons()
- })
- //监听layout
- watch(() => [useRoutes?.query?.layout, store.isLayout], ([layout, layout2]) => {
- isLayout.value = layout ?? layout2
- }, { deep: true })
- //监听项目信息变化
- const isAppLoadings = ref(true)
- watch(() => isAppLoading.value, (res) => {
- if (!website.localModel) {
- reloadRouter.value = res
- isAppLoadings.value = !res
- } else {
- if (res) {
- setTimeout(() => {
- isAppLoadings.value = false
- }, 1000)
- } else {
- isAppLoadings.value = true
- }
- }
- }, { immediate:true })
- //路由信息
- const routerMenuLoad = ({ key }) => {
- menuBarKey.value = key
- }
- // 是否折叠
- const isCollapse = ref(false)
- const collapseChange = () => {
- const bool = !isCollapse.value
- isCollapse.value = bool
- store.setCollapse(bool)
- }
- //顶部菜单导航
- const isAsideMenu = ref(true)
- const topMenuLoad = () => {
- isAsideMenu.value = false
- }
- //顶部菜单导航被点击
- const topMenuChange = (data) => {
- if (!isNullES(data)) {
- menuBarData.value = data
- isAsideMenu.value = true
- }
- }
- //菜单被点击
- const menuBarChange = ({ code }) => {
- menuBarKey.value = code
- router.push({ name: code })
- }
- //项目合同段的ID
- let socket
- const taskCount = ref(0)
- const cascaderSend = async ({ projectId, contractId }) => {
- await useClick()
- if (isNullES(contractId)) {
- //本地模式
- if (website.localModel) {
- window.$message?.error('项目信息不存在,请联系管理员')
- reloadRouter.value = false
- }
- return
- }
- //本地模式
- if (website.localModel) {
- setTimeout(() => {
- reloadRouter.value = true
- }, 1000)
- } else {
- reloadRouter.value = true
- }
- //链接webSocket
- if (!isNullES(socket)) socket.close()
- socket = new HcSocket({ projectId, contractId, userId: userId.value }, (res) => {
- socketData(res?.data)
- })
- }
- //长链接消息
- let annUpdateRef
- const annRefs = ref([])
- const isReminderShow = ref(false)
- const isReminderText = ref('')
- const socketData = async (res) => {
- console.log('socket:', res)
- const { type, data } = getObjValue(res)
- if (type === 'msgUpdateMsg') {
- closeAnnUpdate()
- //内容为空时,代表公告已经取消,由于前面已经关闭,所以不再创建
- if (isNullES(data)) return
- await nextTick()
- //系统更新公告,直接替换
- //, time: 'xxx年xx月xx日 xx:xx:xx'
- annUpdateRef = await HcAnnouncement({ type: 'update', data: data })
- } else if (type === 'msgSystemMsg') {
- //内容为空时,代表公告已经取消,由于前面已经关闭,所以不再创建
- if (isNullES(data)) {
- closeAnnFun()
- return
- }
- await nextTick()
- //普通公告,追加公告
- const ref = await HcAnnouncement({ type: 'system', data: data })
- annRefs.value.push(ref)
- } else if (type === 'msgRemind') {
- taskCount.value = data ?? 0
- } else if (type === 'msgLink') {
- if (store.isLogin) {
- socket.send('getMsg')
- store.setIsLogin(false)
- }
- } else if (type === 'msgCountDown') {
- //倒计时更新
- if (isNullES(data) || data <= 0) {
- closeReminder()
- return
- }
- isReminderText.value = `系统将在${data}秒后,进行更新`
- setReminderText(data - 1)
- isReminderShow.value = true
- }
- }
- //倒计时
- let timeRef
- let startTime
- const setReminderText = (totalTime) => {
- startTime = performance.now()
- const step = () => {
- const elapsedTime = Math.floor((performance.now() - startTime) / 1000)
- const remainingTime = totalTime - elapsedTime
- if (remainingTime < 0) {
- closeReminder()
- return
- }
- isReminderText.value = `系统将在${remainingTime}秒后,进行更新`
- requestAnimationFrame(step)
- }
- requestAnimationFrame(step)
- }
- //关闭倒计时
- const closeReminder = () => {
- isReminderShow.value = false
- if (!isNullES(timeRef)) {
- clearTimeout(timeRef)
- timeRef = null
- }
- }
- //用户信息
- const userId = ref('')
- const userInfoLoad = ({ user_id }) => {
- userId.value = user_id
- }
- // 项目切换
- const cascaderChange = () => {
- reloadRouter.value = false
- }
- //首页
- const logoClick = () => {
- router.push({ name: 'home-index' })
- }
- //关闭普通公告
- const closeAnnFun = () => {
- const refs = annRefs.value
- for (let i = 0; i < refs.length; i++) {
- if (!isNullES(refs[i])) {
- refs[i]?.close()
- }
- }
- annRefs.value = []
- }
- //关闭系统更新公告
- const closeAnnUpdate = () => {
- if (!isNullES(annUpdateRef)) {
- annUpdateRef.close()
- annUpdateRef = null
- }
- }
- //页面卸载
- onUnmounted(() => {
- if (!isNullES(socket)) socket.close()
- closeAnnFun()
- closeAnnUpdate()
- })
- </script>
- <style lang="scss">
- @import "./index.scss";
- </style>
|