| | |
| | | n |
| | | |
| | | # 页面标题 |
| | | VITE_APP_TITLE = 后台管理系统 |
| | | VITE_APP_TITLE = 后台管理系统 |
| | | |
| | | # 开发环境配置 |
| | | VITE_APP_ENV = 'development' |
| | | VITE_APP_ENV = 'development' |
| | | |
| | | # 图片地址 |
| | | VITE_APP_IMG_BASEURL='http://192.168.0.200:8036/upload' |
| | | VITE_APP_IMG_BASEURL='/api/upload' |
| | | |
| | | # 南京接口 |
| | | # VITE_APP_PUBLIC_REQUEST_API = 'http://113.250.189.120:8030' |
| | | # VITE_APP_PUBLIC_REQUEST_API = 'http://113.250.189.120:8036' |
| | | # VITE_APP_PUBLIC_REQUEST_API = 'http://113.250.189.120:8038' |
| | | #后端本地 |
| | | VITE_APP_PUBLIC_REQUEST_API = 'http://192.168.0.200:8038' |
| | | VITE_APP_PUBLIC_REQUEST_API = '/api' |
| | |
| | | |
| | | # 页面标题 |
| | | VITE_APP_TITLE = 后台管理系统 |
| | | VITE_APP_TITLE = 后台管理系统 |
| | | |
| | | # 开发环境配置 |
| | | VITE_APP_ENV = 'production' |
| | | VITE_APP_ENV = 'production' |
| | | |
| | | # 图片地址 |
| | | VITE_APP_IMG_BASEURL = 'http://113.250.189.120:8036/upload' |
| | | VITE_APP_IMG_BASEURL = '/api/upload' |
| | | |
| | | # 南京管理系统/开发环境 |
| | | VITE_APP_PUBLIC_REQUEST_API = 'http://113.250.189.120:8036' |
| | | VITE_APP_PUBLIC_REQUEST_API = '/api' |
| | | # 是否在打包时开启压缩,支持 gzip 和 brotli |
| | | VITE_BUILD_COMPRESS = gzip |
| | | VITE_BUILD_COMPRESS = gzip |
| | |
| | | node_modules |
| | | .idea/ |
| | | dist/ |
| | |
| | | <link rel="icon" href="/favicon.ico"> |
| | | <title>南京康尼地铁泵站监测服务系统</title> |
| | | <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]--> |
| | | <script type="text/javascript" src="./public/jessibuca.js"></script> |
| | | <script type="text/javascript" src="/jessibuca.js"></script> |
| | | |
| | | <style> |
| | | html, |
| | |
| | | import {publicRequest} from '@/utils/request.js' |
| | | import {requestPolling} from '@/utils/requestPolling.js' |
| | | |
| | | |
| | | /** |
| | | * 获取泵房信息 |
| | | */ |
| | | export const getPumpData = (data) => { |
| | | return publicRequest({ |
| | | return requestPolling({ |
| | | url: '/waterFacilityParameter/getData', |
| | | method: 'post', |
| | | data |
| | |
| | | * 获取泵房报警信息 |
| | | */ |
| | | export const getPumpWarning = (data) => { |
| | | return publicRequest({ |
| | | return requestPolling({ |
| | | url: '/alarmHistory/search', |
| | | method: 'post', |
| | | data |
| | |
| | | item: { |
| | | type: Object, |
| | | default: {} |
| | | }, |
| | | autoPlay: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }); |
| | | |
| | |
| | | showPause.value = false; |
| | | } |
| | | |
| | | const init = () => { |
| | | videojsb.value = new window.Jessibuca( |
| | | Object.assign({ |
| | | container: videoRef.value, |
| | | isResize: true, |
| | | // 实例化dom节点 |
| | | const initDom = async () => { |
| | | videojsb.value = new window.Jessibuca( |
| | | Object.assign({ |
| | | container: videoRef.value, |
| | | isResize: true, |
| | | isFullResize: true, |
| | | text: '', |
| | | text: '', |
| | | videoBuffer: 2, |
| | | loadingText: '加载中...', |
| | | useMSE: true, |
| | | loadingText: '加载中...', |
| | | useMSE: true, |
| | | useWCS: true, |
| | | autoWasm: true, |
| | | // debug: true, |
| | | // debug: true, |
| | | supportDblclickFullscreen: false, |
| | | operateBtns: { |
| | | fullscreen: true, |
| | | play: false, |
| | | audio: true, |
| | | recorder: false, |
| | | }, |
| | | operateBtns: { |
| | | fullscreen: true, |
| | | play: false, |
| | | audio: true, |
| | | recorder: false, |
| | | }, |
| | | controlAutoHide: true, |
| | | forceNoOffscreen: true, |
| | | isNotMute: false, |
| | | forceNoOffscreen: true, |
| | | isNotMute: false, |
| | | heartTimeoutReplay:false, |
| | | }) |
| | | ); |
| | | }) |
| | | ); |
| | | } |
| | | |
| | | // 初始化 |
| | | const init = async () => { |
| | | await initDom() |
| | | // 自动播放 |
| | | if(props.autoPlay && props.item.deviceId && props.item.channelId) { |
| | | handlePlayer() |
| | | } |
| | | }; |
| | | |
| | | onMounted(() => { |
| | |
| | | import elementIcons from '@/components/SvgIcon/svgicon' |
| | | |
| | | import './permission' // permission control |
| | | import './warning.js' |
| | | import { btnPerms } from './utils/permission' |
| | | |
| | | import { parseTime, resetForm, addDateRange, handleTree, selectDictLabel, selectDictLabels } from '@/utils/ruoyi' |
对比新文件 |
| | |
| | | import axios from 'axios' |
| | | import { ElNotification , ElMessageBox, ElMessage, ElLoading } from 'element-plus' |
| | | import {getToken, removeToken} from '@/utils/auth' |
| | | import errorCode from '@/utils/errorCode' |
| | | import { tansParams, blobValidate } from '@/utils/ruoyi' |
| | | import cache from '@/plugins/cache' |
| | | // import { saveAs } from 'file-saver' |
| | | // import useUserStore from '@/store/modules/user' |
| | | |
| | | // let downloadLoadingInstance; |
| | | // 是否显示重新登录 |
| | | export let isRelogin = { show: false }; |
| | | |
| | | axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' |
| | | |
| | | export const requestPolling = axios.create({ |
| | | // axios中请求配置有baseURL选项,表示请求URL公共部分 |
| | | //baseURL: import.meta.env.VITE_APP_BASE_API, |
| | | baseURL: import.meta.env.VITE_APP_PUBLIC_REQUEST_API, |
| | | // 超时 |
| | | timeout: 5000 |
| | | }) |
| | | |
| | | |
| | | // request拦截器 |
| | | requestPolling.interceptors.request.use((config) => { |
| | | // 是否需要设置 token |
| | | const isToken = (config.headers || {}).isToken === false |
| | | // 是否需要防止数据重复提交 |
| | | const isRepeatSubmit = (config.headers || {}).repeatSubmit === false |
| | | if (getToken() && !isToken) { |
| | | config.headers['token'] = getToken() // 让每个请求携带自定义token 请根据实际情况自行修改 |
| | | } |
| | | // if (localStorage.getItem('token')) { |
| | | // config.headers!['token'] = localStorage.getItem('token'); |
| | | // } |
| | | // get请求映射params参数 |
| | | if (config.method === 'get' && config.params) { |
| | | let url = config.url + '?' + tansParams(config.params); |
| | | url = url.slice(0, -1); |
| | | config.params = {}; |
| | | config.url = url; |
| | | } |
| | | if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) { |
| | | const requestObj = { |
| | | url: config.url, |
| | | data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, |
| | | time: new Date().getTime() |
| | | } |
| | | const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小 |
| | | const limitSize = 5 * 1024 * 1024; // 限制存放数据5M |
| | | if (requestSize >= limitSize) { |
| | | console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制,无法进行防重复提交验证。') |
| | | return config; |
| | | } |
| | | const sessionObj = cache.session.getJSON('sessionObj') |
| | | if (sessionObj === undefined || sessionObj === null || sessionObj === '') { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | } else { |
| | | const s_url = sessionObj.url; // 请求地址 |
| | | const s_data = sessionObj.data; // 请求数据 |
| | | const s_time = sessionObj.time; // 请求时间 |
| | | const interval = 2000; // 间隔时间(ms),小于此时间视为重复提交 |
| | | // if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) { |
| | | // const message = '数据正在处理,请勿重复提交'; |
| | | // console.warn(`[${s_url}]: ` + message) |
| | | // return Promise.reject(new Error(message)) |
| | | // } else { |
| | | cache.session.setJSON('sessionObj', requestObj) |
| | | // } |
| | | } |
| | | } |
| | | return config |
| | | }, error => { |
| | | console.log(error) |
| | | Promise.reject(error) |
| | | }) |
| | | |
| | | // 响应拦截器 |
| | | requestPolling.interceptors.response.use(res => { |
| | | // 未设置状态码则默认成功状态 |
| | | const code = res.data.code || 200; |
| | | // 获取错误信息 |
| | | const msg = errorCode[code] || res.data.msg || errorCode['default'] |
| | | // 二进制数据则直接返回 |
| | | if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') { |
| | | return res.data |
| | | } |
| | | if (code === 401) { |
| | | if (!isRelogin.show) { |
| | | isRelogin.show = true; |
| | | ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => { |
| | | isRelogin.show = false; |
| | | removeToken() |
| | | window.location.reload(); |
| | | }).catch(() => { |
| | | isRelogin.show = false; |
| | | }); |
| | | } |
| | | return Promise.reject('无效的会话,或者会话已过期,请重新登录。') |
| | | } else if (code === 500) { |
| | | return Promise.reject(new Error(msg)) |
| | | } else if (code === 601) { |
| | | return Promise.reject(new Error(msg)) |
| | | } else if (code !== 200) { |
| | | return Promise.reject('error') |
| | | } else { |
| | | return Promise.resolve(res.data) |
| | | } |
| | | } |
| | | ) |
| | | |
| | |
| | | <script setup lang="ts"> |
| | | import {onMounted, onUnmounted, ref} from "vue"; |
| | | import {getPumpData, getPumpWarning} from '@/api/screen/index.js' |
| | | import { ElMessageBox } from 'element-plus' |
| | | |
| | | const tucengVal = ref(0); |
| | | const warnList = ref([]) |
| | | const showMsg = ref(0) |
| | | const pointList = ref([]) |
| | | const dislogOpen = ref(false) |
| | | let timer = null; |
| | | |
| | | const warnCode = ['B001StartNumber', 'B002StartNumber', 'B003StartNumber', 'B004StartNumber'] |
| | | |
| | | const clickMsgFun = (index: number) => { |
| | | showMsg.value = showMsg.value === index ? null : index; |
| | |
| | | const getWarning = () => { |
| | | getPumpWarning({limit: 10, page:1}).then(res => { |
| | | warnList.value = res.data.list |
| | | }).catch(err => { |
| | | if(err.message.includes("timeout")){ |
| | | clearInterval(timer) |
| | | const warnDialogList = res.data.list.filter(el => warnCode.includes(el.code)) |
| | | if(!dislogOpen.value && warnDialogList.length > 0) { |
| | | dislogOpen.value=true |
| | | ElMessageBox.confirm(warnDialogList[0].facilityName, warnDialogList[0].description, { |
| | | showCancelButton: false, |
| | | confirmButtonText: '关闭', |
| | | type: 'error' |
| | | }).then(() => { |
| | | console.log('关闭') |
| | | }) |
| | | } |
| | | }) |
| | | } |
| | |
| | | // 定时获取报警信息 |
| | | timer = setInterval(() => { |
| | | getWarning() |
| | | }, 3000) |
| | | }, 5000) |
| | | }) |
| | | onUnmounted(() => { |
| | | if(timer){ |
| | |
| | | transition: all .5s; |
| | | &-t { |
| | | background-image: url('@/assets/images_lc/title_font.png'); |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | padding-left: 16%; |
| | | font-size: 1.2rem; |
| | | } |
| | |
| | | flex-direction: column; |
| | | .warnRecord-title { |
| | | background-image: url('@/assets/images_lc/title_font.png'); |
| | | background-repeat: no-repeat; |
| | | background-size: 100% 100%; |
| | | padding-left: 16%; |
| | | font-size: 1.3rem; |
| | | } |
| | |
| | | <script setup> |
| | | import {getVideoList} from '@/api/screen/video.js' |
| | | import VideoPlayer from "@/components/VideoPlayer/VideoPlayer.vue"; |
| | | import {ref} from "vue"; |
| | | import {ref, onMounted} from "vue"; |
| | | |
| | | const showList = ref([ |
| | | { id: 0, name: '监控1' }, |
| | | { id: 2, name: '监控2' }, |
| | | ]) |
| | | const showList = ref([]) |
| | | |
| | | const getList = () => { |
| | | getVideoList({pointId: '1904415927038406657'}).then(res => { |
| | | showList.value = res.data |
| | | }) |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getList() |
| | | }) |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="monitor"> |
| | | <div class="list"> |
| | | <div class="m-item" v-for="(x,i) in showList" :key="x"> |
| | | <div class="name">{{x.name}}</div> |
| | | <VideoPlayer :item="x" /> |
| | | <div class="btnlist"> |
| | | <el-button size="large">泵房水浸报警</el-button> |
| | | <el-button size="large">控制柜闪灯报警</el-button> |
| | | <div class="m-item" v-for="(x,i) in showList" :key="i"> |
| | | <div class="vbox"> |
| | | <div class="name">{{x.pointName}}</div> |
| | | <VideoPlayer :item="x" auto-play /> |
| | | <!-- <div class="btnlist">--> |
| | | <!-- <el-button size="large">泵房水浸报警</el-button>--> |
| | | <!-- <el-button size="large">控制柜闪灯报警</el-button>--> |
| | | <!-- </div>--> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | .m-item{ |
| | | width: 50%; |
| | | height: 100%; |
| | | background: rgb(158, 183, 111); |
| | | background: #000; |
| | | position: relative; |
| | | display: flex; |
| | | align-items: center; |
| | | .vbox{ |
| | | width: 100%; |
| | | height: 65%; |
| | | } |
| | | .name{ |
| | | position: absolute; |
| | | right: 0; |
| | |
| | | } |
| | | }) |
| | | list.value = newArr.splice(0,hasPump) |
| | | }).catch(err => { |
| | | if(err.message.includes("timeout")){ |
| | | clearInterval(timer) |
| | | } |
| | | }) |
| | | } |
| | | |
| | |
| | | // 定时3秒回调一次,更新数据 |
| | | timer = setInterval(() => { |
| | | getData() |
| | | }, 3000) |
| | | }, 5000) |
| | | }) |
| | | |
| | | onUnmounted(() => { |
| | |
| | | open: true, |
| | | proxy: { |
| | | // https://cn.vitejs.dev/config/#server-proxy |
| | | '/dev-api': { |
| | | target: 'http://localhost:8080', |
| | | '/api': { |
| | | target: 'http://192.168.0.200:8038', |
| | | changeOrigin: true, |
| | | rewrite: (p) => p.replace(/^\/dev-api/, '') |
| | | rewrite: (p) => p.replace(/^\/api/, '') |
| | | } |
| | | } |
| | | }, |