<template> <a-layout :class="['layout', device]"> <!-- SideMenu --> <a-drawer v-if="isMobile()" placement="left" :wrapClassName="`drawer-sider ${navTheme}`" :closable="false" :visible="collapsed" @close="drawerClose" > <side-menu mode="inline" :menus="menus" :theme="navTheme" :collapsed="false" :collapsible="true" @menuSelect="menuSelect" ></side-menu> </a-drawer> <side-menu v-else-if="isSideMenu()" mode="inline" :menus="menus" :theme="navTheme" :collapsed="collapsed" :collapsible="true" ></side-menu> <a-layout :class="[layoutMode, `content-width-${contentWidth}`]" :style="{ paddingLeft: contentPaddingLeft, minHeight: '100vh' }"> <!-- layout header --> <global-header :mode="layoutMode" :menus="menus" :theme="navTheme" :collapsed="collapsed" :device="device" @toggle="toggle" /> <!-- layout content --> <a-layout-content :class="navTheme" :style="{ height: '100%', margin: '30px 20px 0', paddingTop: multiTab&&fixedHeader ? '66px' : (!multiTab&&fixedHeader?'45px':'0') }"> <transition name="page-transition"> <!-- <route-view v-if="isRouterAlive"/> --> <router-view ></router-view> </transition> </a-layout-content> <!-- 消息通知 --> <div class="notes-box" v-if="notesList.length && nowRoute.indexOf('notice')<0"> <div v-for="item in notesList" :key="item.id"> <a-alert v-if="item.notice.bizType=='TEMP_ORDER'" type="warning" showIcon closable @close="setRead(item)"> <div slot="description"> 【急送提醒】{{ item.notice.plainContent }} <a-button @click="toAction(item)" size="small" type="link" class="button-info">点击查看</a-button> </div> </a-alert> <a-alert v-if="item.notice.bizType=='SHELF_REPLENISH'" type="info" showIcon closable @close="setRead(item)"> <div slot="description"> 【补货提醒】{{ item.notice.plainContent }} <a-button @click="toAction(item)" size="small" type="link" class="button-info">立即处理</a-button> </div> </a-alert> <a-alert v-if="item.notice.bizType=='SHELF_ORDER'" type="info" showIcon closable @close="setRead(item)"> <div slot="description"> 【订单提醒】{{ item.notice.plainContent }} <a-button @click="toAction(item)" size="small" type="link" class="button-info">点击查看</a-button> </div> </a-alert> <a-alert v-if="item.notice.bizType=='SHELF_WARN'" type="warning" showIcon closable @close="setRead(item)"> <div slot="description"> 【货架异常提醒】{{ item.notice.plainContent }} <a-button @click="toAction(item)" size="small" type="link" class="button-info">点击查看</a-button> </div> </a-alert> </div> <div class="notes-footer"> <div class="notes-more" @click="noDoNotes">暂不处理</div> <div class="notes-more" @click="toNotes">更多消息>></div> </div> </div> <audio controls="controls" hidden :src="mp3" ref="audio"></audio> <!-- 视频播放弹窗 --> <div v-if="isShowVideoVal"> <a-modal v-model="isShowVideoVal" wrapClassName="vidio_cont" :footer="null" centered :maskClosable="false" :destroyOnClose="true" :width="1000" @cancel="closeVido"> <video-player class="video-player vjs-custom-skin" ref="videoPlayer" :playsinline="true" :options="playerOptions" ></video-player> </a-modal> </div> <!-- pdf 预览 --> <pdfViewModal ref="pdfview" :openModal="showPdfView" @cancel="showPdfView=false"></pdfViewModal> <!-- 选择打印机 --> <selectPrint ref="selectPrint" :openModal="showSelectPrint" @cancel="showSelectPrint=false"></selectPrint> <!-- layout footer --> <a-layout-footer> <!-- <global-footer /> --> </a-layout-footer> <!-- Setting Drawer (show in development mode) --> <!-- <setting-drawer></setting-drawer> --> </a-layout> </a-layout> </template> <script> import moment from 'moment' import { triggerWindowResizeEvent } from '@/utils/util' import { mapState, mapActions, mapGetters } from 'vuex' import { mixin, mixinDevice, commonMixin } from '@/utils/mixin' import config from '@/config/defaultSettings' import pdfViewModal from '@/views/common/pdfViewModal.vue' import selectPrint from '@/views/common/selectPrint.vue' import RouteView from './RouteView' import SideMenu from '@/components/Menu/SideMenu' import GlobalHeader from '@/components/GlobalHeader' import GlobalFooter from '@/components/GlobalFooter' import SettingDrawer from '@/components/SettingDrawer' import { asyncRouterMap } from '@/config/router.config' import mp3 from '@/assets/notes.mp3' import store from '@/store' export default { name: 'BasicLayout', mixins: [mixin, mixinDevice, commonMixin], provide () { return { setIsHomeNav: this.setIsHomeNav, reloadView: this.reloadView } }, components: { RouteView, SideMenu, GlobalHeader, GlobalFooter, SettingDrawer, pdfViewModal, selectPrint }, data () { return { production: config.production, collapsed: false, menus: [], isRouterAlive: true, showPdfView: false, showSelectPrint: false, notesList: [], mp3: mp3 } }, computed: { ...mapState({ // 动态主路由 mainMenu: state => state.permission.routers, multiTab: state => state.app.multiTab, fixedHeader: state => state.app.fixedHeader }), ...mapGetters(['nowRoute', 'isShowVideo']), isShowVideoVal () { return this.$store.state.app.isShowVideo }, // 接受到ws消息 wsMessage () { return this.$store.getters.wsMessageData() }, contentPaddingLeft () { if (!this.fixSidebar || this.isMobile()) { return '0' } if (this.sidebarOpened) { return '180px' } return '80px' }, playerOptions () { const playerOptions = { playbackRates: [0.7, 1.0, 1.5, 2.0], // 播放速度 autoplay: true, // 如果true,浏览器准备好时开始回放。 muted: false, // 默认情况下将会消除任何音频。 loop: false, // 导致视频一结束就重新开始。 preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持) language: 'zh-CN', aspectRatio: '16:9', // 将播放器置于流畅模式,并在计算播放器的动态大小时使用该值。值应该代表一个比例 - 用冒号分隔的两个数字(例如"16:9"或"4:3") fluid: true, // 当true时,Video.js player将拥有流体大小。换句话说,它将按比例缩放以适应其容器。 sources: [{ type: '', // 这里的种类支持很多种:基本视频格式、直播、流媒体等,具体可以参看git网址项目 src: '' // url地址 }], poster: '../assets/bg_movie@2x.png', // 你的封面地址 // width: document.documentElement.clientWidth, //播放器宽度 notSupportedMessage: '此视频暂无法播放,请稍后再试', // 允许覆盖Video.js无法播放媒体源时显示的默认信息。 controlBar: { timeDivider: true, durationDisplay: true, remainingTimeDisplay: false, fullscreenToggle: true // 全屏按钮 } } // 当前展示是否为销售单模块 if (this.nowRoute.indexOf('salesQuery') > -1) { playerOptions.sources[0].src = 'https://jianguan-images.oss-cn-beijing.aliyuncs.com/helpvideo/1xiaoshou.mp4' } // 当前展示是否为销售退货模块 if (this.nowRoute.indexOf('salesReturn') > -1) { playerOptions.sources[0].src = 'https://jianguan-images.oss-cn-beijing.aliyuncs.com/helpvideo/2xiaoshoutuihuo.mp4' } // 当前展示是否为采购单管理模块 if (this.nowRoute.indexOf('purchaseOrder') > -1) { playerOptions.sources[0].src = 'https://jianguan-images.oss-cn-beijing.aliyuncs.com/helpvideo/3caigou.mp4' } // 当前展示是否为采购退货模块 if (this.nowRoute.indexOf('purchaseReturn') > -1) { playerOptions.sources[0].src = 'https://jianguan-images.oss-cn-beijing.aliyuncs.com/helpvideo/4caigoutuihuo.mp4' } return playerOptions } }, watch: { sidebarOpened (val) { this.collapsed = !val }, // 监听ws消息通知 wsMessage (a, b) { if (a !== b && a) { // 新未读消息 if (a.type == 'new_remind') { if (this.nowRoute.indexOf('notice') < 0) { this.getNotes() } // 播放音效 this.playAudio() } } }, // 打印预览 '$store.state.app.showPdfPrintView' (newValue, oldValue) { if (newValue) { this.showPdfView = newValue this.$nextTick(() => { this.$refs.pdfview.setData(this.$store.state.app.pdfPrintList) }) } }, // 选择打印机 '$store.state.app.showSelectPrint' (newValue, oldValue) { if (newValue) { this.showSelectPrint = newValue } } }, created () { if (this.mainMenu) { this.menus = this.mainMenu.find((item) => item.path === '/').children } else { // 没有权限时只显示首页 const noqx = asyncRouterMap.find((item) => item.path === '/').children this.menus = [noqx.find(item => item.path === '/home')] } // 重置主题,字体,布局 this.collapsed = !this.sidebarOpened this.$store.dispatch('ToggleMultiTab', true) this.$store.dispatch('ToggleColor', '#2A86F4') this.$store.dispatch('ToggleTheme', localStorage.getItem('DEFAULT_THEME') || 'dark') this.$store.dispatch('ToggleFontSize', localStorage.getItem('DEFAULT_FONT_SIZE') || 'small') // 判断是否是当月25日后 this.$store.state.app.isLastDayForMonth = moment().date() >= 25 if (this.$store.state.app.isLastDayForMonth && this.$hasPermissions('M_mothEndTips')) { this.$notification.warning({ message: '提示', description: `临到月底了,请尽快处理系统中没有完结的单据!` }) } // 打印设置 this.$store.commit('SET_pdfPrintList', []) this.$store.commit('SET_showPdfPrint', false) this.$store.commit('SET_showSelectPrint', false) this.$store.commit('SET_printLoading', false) this.$store.commit('SET_printDefNeedle', localStorage.getItem('DEFAULT_PRINT_NEEDLE') || undefined) this.$store.commit('SET_printDefInk', localStorage.getItem('DEFAULT_PRINT_INK') || undefined) // 消息通知 this.getNotes() }, mounted () { const userAgent = navigator.userAgent if (userAgent.indexOf('Edge') > -1) { this.$nextTick(() => { this.collapsed = !this.collapsed setTimeout(() => { this.collapsed = !this.collapsed }, 16) }) } }, methods: { ...mapActions([ 'setSidebar', 'getMessageList', // 查询列表 'hasRead' // 设置已读 ]), reloadView () {}, // 关闭视频弹窗 closeVido () { store.commit('IS_ShOW_VIDEO', false) }, toggle () { this.collapsed = !this.collapsed this.setSidebar(!this.collapsed) triggerWindowResizeEvent() }, paddingCalc () { let left = '' if (this.sidebarOpened) { left = this.isDesktop() ? '160px' : '80px' } else { left = (this.isMobile() && '0') || ((this.fixSidebar && '80px') || '0') } return left }, menuSelect () { }, drawerClose () { this.collapsed = false }, playAudio () { this.$refs.audio.currentTime = 0// 从头开始播放 this.$refs.audio.play() // 播放 }, // 获取最新消息 getNotes () { this.getMessageList({ pageNo: 1, pageSize: 5, notice: { type: 'tx' }, readFlag: 0 }).then((res) => { if (res.status == 200) { const data = res.data for (var i = 0; i < data.list.length; i++) { if (data.list[i].notice.extInfo) { data.list[i].notice.extInfo = JSON.parse(data.list[i].notice.extInfo) } } this.notesList = res.data.list } else { this.notesList = [] } }) }, toAction (data) { console.log(this.nowRoute) // 急送订单 if (data.notice.extInfo.bizType == 'TEMP_ORDER') { if (this.nowRoute.indexOf('salesManagement/salesQuery/detail') >= 0) { this.$router.go(-1) } setTimeout(() => { this.$router.push({ name: 'salesDetail', params: { sn: data.notice.extInfo.bizSn } }) }, 500) } // 补货订单 if (data.notice.extInfo.bizType == 'SHELF_REPLENISH') { this.$router.push({ name: 'replenishmentManagement', query: { bizType: 'ALL' } }) } // 货架订单 if (data.notice.extInfo.bizType == 'SHELF_ORDER') { if (this.nowRoute.indexOf('numsGoodsShelves/shelfOrder/shelfOrderDetail') >= 0) { this.$router.go(-1) } setTimeout(() => { this.$router.push({ name: 'shelfOrderDetail', params: { sn: data.notice.extInfo.bizSn } }) }, 500) } // 货架异常 if (data.notice.extInfo.bizType == 'SHELF_WARN') { if (this.nowRoute.indexOf('numsGoodsShelves/shelfOrder/list') >= 0) { this.$router.go(-1) } setTimeout(() => { this.$router.push({ name: 'shelfOrderList', query: { bizType: 'SHELF_WARN', shelfSn: data.notice.extInfo.bizSn } }) }, 500) } // 设置已读 this.setRead(data) }, // 设置已读 setRead (row) { this.hasRead({ msg_id: row.id }).then(res => { // 刷新列表 if (res.status == 200) { this.getNotes() } }) }, toNotes () { this.$router.push({ path: '/notice' }) }, noDoNotes () { this.notesList = [] } } } </script> <style lang="less"> @import url('../components/global.less'); .notes-box{ position:fixed; right:0; bottom:0; min-width:400px; z-index: 10000; box-shadow: -8px 7px 11px 2px #d7d7d7; .ant-alert-with-description .ant-alert-close-icon{ top: 13px; } .ant-alert, .ant-alert-info{ padding: 10px 30px!important; } .ant-alert .ant-alert-icon, .ant-alert-info .ant-alert-icon{ top: 16px !important; left: 10px !important; font-size: 18px; } .ant-alert-with-description .ant-alert-description{ font-size: 14px; } .notes-footer{ display:flex; background: #fff; border: 1px solid #eee; border-radius: 5px 5px 0 0; > div{ width: 50%; &:first-child{ border-right:1px solid #eee; } } .notes-more{ padding: 10px; text-align:center; color:#00aaff; font-size: 14px; cursor:pointer; } } } </style>