2021.11.17需求

merge-requests/1/head
dydwang 5 years ago
parent 0e1e633929
commit 5d40a43e55

@ -15,6 +15,9 @@ module.exports = {
"no-tabs": 'off', "no-tabs": 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
"no-unused-vars":'off' //冗余变量报错 "no-unused-vars":'off', //冗余变量报错
"vue/no-use-v-if-with-v-for": "off",
"vue/no-unused-vars": "off",
"vue/no-unused-components": "off"
} }
} }

@ -1,52 +1,54 @@
{ {
"name": "duoji-frontend", "name": "duoji-frontend",
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "node antdTheme.js && vue-cli-service serve", "serve": "node antdTheme.js && vue-cli-service serve",
"build": "node antdTheme.js && vue-cli-service build", "build": "node antdTheme.js && vue-cli-service build",
"lint": "eslint --fix --ext .js,.vue src", "lint": "eslint --fix --ext .js,.vue src",
"start": "node antdTheme.js && npm run serve" "start": "node antdTheme.js && npm run serve"
}, },
"dependencies": { "dependencies": {
"ant-design-vue": "^1.6.3", "ant-design-vue": "^1.6.3",
"antd-theme-generator": "^1.2.8", "antd-theme-generator": "^1.2.8",
"axios": "^0.19.2", "axios": "^0.19.2",
"core-js": "^3.6.5", "core-js": "^3.6.5",
"element-ui": "^2.15.6", "element-ui": "^2.15.6",
"path-to-regexp": "^6.2.0", "path-to-regexp": "^6.2.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"v-viewer": "^1.5.1", "v-viewer": "^1.5.1",
"video.js": "^7.10.2", "video.js": "^7.10.2",
"vue": "^2.6.11", "videojs-contrib-hls": "^5.15.0",
"vue-json-editor": "^1.4.3", "vue": "^2.6.11",
"vue-router": "^3.2.0", "vue-json-editor": "^1.4.3",
"vuex": "^3.4.0", "vue-router": "^3.2.0",
"vuex-multi-tab-state": "^1.0.16" "vue-video-player": "^5.0.2",
}, "vuex": "^3.4.0",
"devDependencies": { "vuex-multi-tab-state": "^1.0.16"
"@vue/cli-plugin-babel": "^4.4.0", },
"@vue/cli-plugin-eslint": "^4.4.0", "devDependencies": {
"@vue/cli-service": "^4.4.0", "@vue/cli-plugin-babel": "^4.4.0",
"@vue/eslint-config-standard": "^5.1.2", "@vue/cli-plugin-eslint": "^4.4.0",
"babel-eslint": "^10.1.0", "@vue/cli-service": "^4.4.0",
"babel-plugin-import": "^1.13.0", "@vue/eslint-config-standard": "^5.1.2",
"eslint": "^6.7.2", "babel-eslint": "^10.1.0",
"eslint-plugin-import": "^2.20.2", "babel-plugin-import": "^1.13.0",
"eslint-plugin-vue": "^6.2.2", "eslint": "^6.7.2",
"less": "^2.7.3", "eslint-plugin-import": "^2.20.2",
"less-loader": "^6.2.0", "eslint-plugin-vue": "^6.2.2",
"node-sass": "^4.14.1", "less": "^2.7.3",
"sass-loader": "^8.0.2", "less-loader": "^6.2.0",
"vue-happy-scroll": "^2.1.1", "node-sass": "^4.14.1",
"vue-template-compiler": "^2.6.11" "sass-loader": "^8.0.2",
}, "vue-happy-scroll": "^2.1.1",
"rules": { "vue-template-compiler": "^2.6.11"
"generator-star-spacing": "off", },
"no-tabs": "off", "rules": {
"no-unused-vars": "off", "generator-star-spacing": "off",
"no-console": "off", "no-tabs": "off",
"no-irregular-whitespace": "off", "no-unused-vars": "off",
"no-debugger": "off" "no-console": "off",
} "no-irregular-whitespace": "off",
"no-debugger": "off"
}
} }

@ -6,6 +6,11 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<!-- 加快视频的响应速度-->
<link href="/static/video-js-cdn.min.css" rel="stylesheet">
<script src="/static/video.js"></script>
<script src="/static/videojs-contrib-hls.min.js"></script>
<title>垛机视觉系统</title> <title>垛机视觉系统</title>
</head> </head>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 234 KiB

@ -1,6 +1,6 @@
export default { export default {
updateStylesAPI: { updateStylesAPI: {
url: '/node/styles/update', url: '/node/antv-styles/update',
name: '更新标题菜单样式', name: '更新标题菜单样式',
method: 'POST' method: 'POST'
}, },
@ -8,5 +8,20 @@ export default {
url: '/node/default_css.json', url: '/node/default_css.json',
name: '获取标题菜单样式', name: '获取标题菜单样式',
method: 'GET' method: 'GET'
},
getStockRowColumnAPI: {
url: '/node/stock/getStockRowColumn',
name: '获取盘点颜色状态',
method: 'GET'
},
getStockRowColumnNesInfo: {
url: '/node/stock/getStockRowColumnNesInfo',
name: '如果是人工复合错误,那么就需要取stock_log里的关联的最新的信息',
method: 'GET'
},
viewVideoAPI: {
url: '/node/hk_video/view_video',
name: '唤醒VSplay,查看海康视频',
method: 'GET'
} }
} }

@ -1,5 +1,5 @@
<template> <template>
<a-layout-sider :class="['aside', collapsed ? 'merge' :'']" v-model="collapsed" theme="dark" :trigger="null" collapsible> <a-layout-sider :class="['aside', collapsed ? 'merge' :'']" v-model="collapsed" theme="dark" :trigger="null" collapsible :style="styles.menu.default">
<div class="logo" :style="styles.title.style"> <div class="logo" :style="styles.title.style">
<!-- <img src="@/assets/logo1.png" alt />--> <!-- <img src="@/assets/logo1.png" alt />-->
<span class="logo-title">{{ styles.title.text }}</span> <span class="logo-title">{{ styles.title.text }}</span>

@ -6,7 +6,9 @@
<slot name="title">{{ title }}</slot> <slot name="title">{{ title }}</slot>
</span> </span>
</div> </div>
<router-view class="table"></router-view> <keep-alive :include="['checkManage']">
<router-view class="table"></router-view>
</keep-alive>
<!-- footer --> <!-- footer -->
<div class="wrap-footer bg-white"> <div class="wrap-footer bg-white">
<slot name="footer"></slot> <slot name="footer"></slot>

@ -8,10 +8,6 @@ import './components/index'
import './layouts/index' import './layouts/index'
import utils from './utils/index' import utils from './utils/index'
import api from './plugins/axios/index' import api from './plugins/axios/index'
import JSMpeg from './utils/jsmpeg.min'
import vxgplayer from '../public/video_play_plugins/vxgplayer-1.8.54.min'
import '../public/video_play_plugins/vxgplayer-1.8.54.min.css'
Vue.config.productionTip = false Vue.config.productionTip = false
Vue.prototype.$utils = utils Vue.prototype.$utils = utils
Vue.prototype.$api = api Vue.prototype.$api = api
@ -26,13 +22,8 @@ import 'vue-happy-scroll/docs/happy-scroll.css'
// 图片预览插件 viewer // 图片预览插件 viewer
import 'viewerjs/dist/viewer.css' import 'viewerjs/dist/viewer.css'
import viewer from 'v-viewer' import viewer from 'v-viewer'
Vue.use(viewer) Vue.use(viewer)
import Video from 'video.js'
import 'video.js/dist/video-js.css'
Vue.prototype.$video = Video
new Vue({ new Vue({
router, router,

@ -17,7 +17,7 @@ let blobList = [
instance.interceptors.request.use((config) => { instance.interceptors.request.use((config) => {
const reqObj = config; const reqObj = config;
// 在发送请求之前做些什么 -- 路径参数拼接 // 在发送请求之前做些什么 -- 路径参数拼接
console.log(reqObj) // console.log(reqObj)
const reg = /\{(.+?)\}/g; const reg = /\{(.+?)\}/g;
if (reg.test(reqObj.url)) { if (reg.test(reqObj.url)) {
reqObj.url = reqObj.url.replace(reg, Object.values(reqObj.path)[0]); reqObj.url = reqObj.url.replace(reg, Object.values(reqObj.path)[0]);

@ -27,8 +27,8 @@ apiAll.keys().map((key) => {
const suffixIndex = toCamelCase(key.match(/.*\/.*\/(.*\..*)/)[1]).indexOf('.js'); const suffixIndex = toCamelCase(key.match(/.*\/.*\/(.*\..*)/)[1]).indexOf('.js');
const name = toCamelCase(key.match(/.*\/.*\/(.*\..*)/)[1]).substring(0, suffixIndex); const name = toCamelCase(key.match(/.*\/.*\/(.*\..*)/)[1]).substring(0, suffixIndex);
moduleApis[name] = apiAll(key).default; moduleApis[name] = apiAll(key).default;
console.log('moduleApis ', moduleApis) // console.log('moduleApis ', moduleApis)
return trans(moduleApis[name]); return trans(moduleApis[name]);
}); });
export default moduleApis; export default moduleApis;
console.log(moduleApis); // console.log(moduleApis);

@ -57,15 +57,15 @@ const routes = [{
}, },
component: () => import('@/views/historyMonitoring/index') component: () => import('@/views/historyMonitoring/index')
}, },
{ // {
path: 'alarmVideos', // path: 'alarmVideos',
name: 'alarmVideos', // name: 'alarmVideos',
meta: { // meta: {
icon: 'alert', // icon: 'alert',
name: '告警视频' // name: '告警视频'
}, // },
component: () => import('@/views/alarmVideos/index') // component: () => import('@/views/alarmVideos/index')
}, // },
{ {
path: 'alarmLog', path: 'alarmLog',
name: 'alarmLog', name: 'alarmLog',

@ -57,6 +57,4 @@ const store = {
} }
} }
} }
// 初始加载时默认更新一次主题
// changeTheme(store.state.data.theme['primary-color']);
export default store; export default store;

@ -65,16 +65,16 @@
{{ text.status == null ? ' ' : text.status == 0 ? '正常' : '告警' }} {{ text.status == null ? ' ' : text.status == 0 ? '正常' : '告警' }}
</span> </span>
</span> </span>
<span slot="videoPath1" slot-scope="text"> <span slot="videoPath1" slot-scope="row">
<a-button type="link" v-if="text.videoPath1" @click="showModel(text.videoPath1)"> <a-button type="link" v-if="row.videoPath1" @click="showModel(row.videoPath1, row.cmd1)">
查看视频 查看视频
</a-button> </a-button>
<span v-else> <span v-else>
-- --
</span> </span>
</span> </span>
<span slot="videoPath2" slot-scope="text"> <span slot="videoPath2" slot-scope="row">
<a-button type="link" v-if="text.videoPath2" @click="showModel(text.videoPath2)"> <a-button type="link" v-if="row.videoPath2" @click="showModel(row.videoPath2, row.cmd2)">
查看视频 查看视频
</a-button> </a-button>
<span v-else> <span v-else>
@ -145,6 +145,21 @@ export default {
{ {
title: "涉及货位", title: "涉及货位",
dataIndex: "location", dataIndex: "location",
},
// TODO 日志合并
{
title: "视频时长",
dataIndex: "timeLength",
},
{
title: "球机1",
// dataIndex: "videoPath1",
scopedSlots: {customRender: 'videoPath1'}
},
{
title: "球机2",
// dataIndex: "videoPath2",
scopedSlots: {customRender: 'videoPath2'}
} }
], ],
visible: false, visible: false,
@ -234,9 +249,19 @@ export default {
this.time = [] this.time = []
this.handleGetalarmLog() this.handleGetalarmLog()
}, },
showModel(data) { showModel(path, cmd) {
this.visible = true // 使用第三方软件打开海康视频
this.vid = videoUrl + data if(cmd) {
let params = {
openCmd: cmd
};
this.$api.httpNodeApi.viewVideoAPI({params}).then(res=> {
console.log(res);
})
}else {
this.visible = true
this.vid = videoUrl + path;
}
}, },
closeModel(visible, data) { closeModel(visible, data) {
this.visible = visible this.visible = visible

@ -0,0 +1,255 @@
<template>
<div class="subsection">
<a-layout style="width: 900px">
<a-layout style="width: 100%;height: 310px">
<a-layout-sider width="110px">
<a-tabs default-active-key="1" tab-position="left" @change="value => select.column = value" v-if="total.column > nums.column">
<a-tab-pane
v-for="index in latticeColumn"
:key="index"
>
<span slot="tab">
{{ getRandom(index, latticeColumn, nums.column, total.column) }}
<a-icon type="close-circle" v-if="status.column[index] === 1" style="color: #d81e06" />
<a-icon type="check-circle" v-else-if="status.column[index] === 2" style="color: #1afa29" />
<a-icon type="exclamation-circle" v-else style="color: #909399" />
</span>
</a-tab-pane>
</a-tabs>
</a-layout-sider>
<a-layout-content>
<slot :data="{select, nums, random}"></slot>
</a-layout-content>
</a-layout>
<a-layout-footer>
<a-tabs default-active-key="1" tab-position="bottom" @change="value => select.row = value" v-if="total.row > nums.row">
<a-tab-pane
v-for="index in latticeRow"
:key="index"
>
<span slot="tab">
{{ getRandom(index, latticeRow, nums.row, total.row) }}
<a-icon type="close-circle" v-if="status.row[index] === 1" style="color: #d81e06" />
<a-icon type="check-circle" v-else-if="status.row[index] === 2" style="color: #1afa29" />
<a-icon type="exclamation-circle" v-else style="color: #909399" />
</span>
</a-tab-pane>
</a-tabs>
</a-layout-footer>
</a-layout>
</div>
</template>
<script>
export default {
name: "Subsection",
components: {},
props: {
// 默认行第一个 列第一个
select: {
type: Object,
default: () => {
return {
row: 1,
column: 1
}
}
},
// 总共数据
total: {
row: 1,
column: 1
},
nums: {
// 行20个 列10个
type: Object,
default: () => {
return {
row: 15,
column: 10
}
}
},
stockInfo: {
type: Object,
default: () => {
return {}
}
}
},
computed: {
// 应有的格子数
latticeRow() {
return parseInt(this.total.row / this.nums.row) + (this.total.row % this.nums.row > 0 ? 1 : 0);
},
latticeColumn() {
return parseInt(this.total.column / this.nums.column) + (this.total.column % this.nums.column > 0 ? 1 : 0);
},
random() {
return {
row: this.getRandomRow(this.select.row),
column: this.getRandomColumn(this.select.column),
}
},
watchStockInfo() {
return JSON.stringify(this.stockInfo);
}
},
watch: {
watchStockInfo() {
this.getStatus();
}
},
data() {
return {
status: {
row: {},
column: {}
}
}
},
mounted() {
},
created() {
this.getStatus();
},
destroyed() {
},
methods: {
// 获取行或列的范围字符串
getRandom(index, lattice, num, total) {
if(index !== lattice) {
return `${(index - 1) * num + 1} - ${index * num}`;
}else {
return `${(index - 1) * num + 1} - ${total}`;
}
},
// 获取行和列的范围数组
getRandomRow(val) {
return this.getRandom(val, this.latticeRow, this.nums.row, this.total.row).split(' - ').map(item => Number(item));
},
getRandomColumn(val) {
return this.getRandom(val, this.latticeColumn, this.nums.column, this.total.column).split(' - ').map(item => Number(item));
},
// 获取某段的状态
fragmentStatus(type, val) {
let status0 = false;// 未盘点
let status1 = false;// 盘点错误
let rowStart = 1, rowEnd = this.total.row;
let columnStart = 1, columnEnd = this.total.column;
if(type === 'row') {
[rowStart, rowEnd] = this.getRandomRow(val);
}else {
[columnStart, columnEnd] = this.getRandomColumn(val);
}
console.log(rowStart, rowEnd, columnStart, columnEnd);
// 判断盘点错误与未盘点
// for(let row = rowStart; row++; row <= rowEnd) {
// for(let column = columnStart; column++; column <= columnEnd) {
// let rowColStatus = (this.stockInfo[`${row}-${column}`] || {}).status;
// if(!rowColStatus) {
// // 未盘点
// status0 = true;
// }else if(rowColStatus === 1) {
// // 盘点错误
// status1 = true;
// }
// }
// }
// if(status1) {
// return 1; // 盘点错误
// }else if(status0) {
// return 0; // 未盘点
// }else {
// return 2; // 盘点成功
// }
},
async getStatus() {
// for(let i = 1 ; i++; i < this.latticeRow) {
// let rowColumn = this.getRandomRow(i);
// this.status.row[i] = this.fragmentStatus('row', i);
// }
//
// for(let i = 1 ; i++; i < this.latticeColumn) {
// let rowColumn = this.getRandomColumn(i);
// this.status.column[i] = this.fragmentStatus('column', i);
// }
for(let row = 1; row <= this.total.row; row++) {
for(let column = 1; column <= this.total.column; column++) {
let status = (this.stockInfo[`${row}-${column}`] || {}).status || 0;
if(status < 2) {
// 当前是在第几段
let latticeRow = parseInt(row / this.nums.row) + (row % this.nums.row > 0 ? 1 : 0);
let latticeColumn = parseInt(column / this.nums.column) + (column % this.nums.column > 0 ? 1 : 0);
if(status === 1) {
console.log('第几段', latticeRow, latticeColumn);
console.log(row, column,status);
this.$set(this.status.row, latticeRow, status);
this.$set(this.status.column, latticeColumn, status);
}else {
if(!this.status.row[latticeRow]) this.$set(this.status.row, latticeRow, status);
if(!this.status.column[latticeColumn]) this.$set(this.status.column, latticeColumn, status);
}
}
}
}
console.log(this.status);
},
}
}
</script>
<style scoped lang="scss">
.subsection /deep/{
width: 100%;
height: 360px;
overflow: hidden;
.ant-tabs-nav .ant-tabs-tab {
// padding: 0;
margin-right: 0;
}
.ant-radio-button-wrapper-checked:not(.ant-radio-button-wrapper-disabled) {
&:hover{
background: #40a9ff;
border-color: #40a9ff;
}
background: #40a9ff;
border-color: #40a9ff;
box-shadow: -1px 0 0 0 #40a9ff;
}
.ant-radio-button-wrapper-checked {
box-shadow: -1px 0 0 0 #40a9ff;
}
.radio-button-cell {
width: 100px;
text-align: center;
}
.ant-layout-sider {
height: 100%;
.ant-tabs {
height: 300px;
}
.ant-tabs-tab {
padding: 8px;
margin-bottom: 5px;
width: 104px;
}
}
.ant-layout-footer {
// width: 500px;
padding: 0 0 0 110px;
.ant-tabs {
// width: 735px;
}
.ant-tabs-bottom-bar {
margin-top: 0;
}
}
.ant-layout, .ant-layout-sider, .ant-layout-footer {
background-color: #ffffff;
}
}
</style>

@ -36,7 +36,6 @@
</a-select-option> </a-select-option>
</a-select> </a-select>
</div> </div>
<div v-if="checkObj.id"> <div v-if="checkObj.id">
<div v-for="(key,value) in checkList" :key="value"> <div v-for="(key,value) in checkList" :key="value">
<div v-if="checkObj.shelveId == value"> <div v-if="checkObj.shelveId == value">
@ -45,13 +44,25 @@
style="width:100%;display:flex;align-items:center;justify-content:space-between;flex-direction: column"> style="width:100%;display:flex;align-items:center;justify-content:space-between;flex-direction: column">
<div class="carousel-page" <div class="carousel-page"
v-if="columnItem.row == checkObj.row && columnItem.column == checkObj.column"> v-if="columnItem.row == checkObj.row && columnItem.column == checkObj.column">
<p class="carousel-page-title" @click="goHistory(checkObj.orderNum)" v-if="checkObj.orderNum">工单号:{{checkObj.orderNum}}</p> <p class="carousel-page-title" >
<p class="carousel-page-title" @click="goHistory()" v-else>工单号:暂无</p> <span>
货架号 : {{ $route.query.shelveId }}
</span>
<span @click="goHistory(checkObj.orderNum)" style="width: 400px;display: inline-block;cursor: pointer">
工单号:{{checkObj.orderNum}}
</span>
<span @click="goHistory()" style="width: 400px;display: inline-block;cursor: pointer">
工单号:暂无
</span>
</p>
<!-- <p class="carousel-page-title" @click="goHistory(checkObj.orderNum)" v-if="checkObj.orderNum">工单号:{{checkObj.orderNum}}</p>-->
<!-- <p class="carousel-page-title" @click="goHistory()" v-else>工单号:暂无</p>-->
<div class="carousel-page-content"> <div class="carousel-page-content">
<div class="img-box"> <div class="img-box">
<img <img
v-if="checkObj.preoperationPic" v-if="checkObj.preoperationPic"
:src="imgUrl+checkObj.preoperationPic" :src="imgUrl+checkObj.preoperationPic"
style="width: 100%;height: 358px"
alt=""/> alt=""/>
<div <div
v-else v-else
@ -64,6 +75,7 @@
<img <img
v-if="checkObj.overoperationPic" v-if="checkObj.overoperationPic"
:src="imgUrl+checkObj.overoperationPic" :src="imgUrl+checkObj.overoperationPic"
style="width: 100%;height: 358px"
alt=""/> alt=""/>
<div <div
v-else v-else
@ -72,6 +84,18 @@
</div> </div>
<p>操作后照片</p> <p>操作后照片</p>
</div> </div>
<div class="img-box">
<ul>
<li v-for="item in params" :key="item.label">
<span class="img-box-title">
{{ item.label }}:
</span>
<span class="img-box-value">
{{ scanAndCheck[item.key] }}
</span>
</li>
</ul>
</div>
</div> </div>
<div class="carousel-page-footer"> <div class="carousel-page-footer">
<div class="info-box"> <div class="info-box">
@ -133,37 +157,54 @@
style="width:100%;display:flex;align-items:center;justify-content:space-between;flex-direction: column"> style="width:100%;display:flex;align-items:center;justify-content:space-between;flex-direction: column">
<div class="carousel-page" <div class="carousel-page"
v-if="listrow == row && listcolumn == column"> v-if="listrow == row && listcolumn == column">
<p class="carousel-page-title" @click="goHistory()">工单号:暂无</p> <p class="carousel-page-title" >
<span>
货架号 : {{ $route.query.shelveId }}
</span>
<span @click="goHistory()" style="width: 400px;display: inline-block;cursor: pointer">
工单号:暂无
</span>
</p>
<div class="carousel-page-content"> <div class="carousel-page-content">
<div class="img-box"> <div class="img-box">
<div <div
style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea"> style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea">
<img src="/test1.jpg" style="width: 100%;height: 358px" alt=""> <!-- <img v-if="row==4 && column==18" src="/red-test1.jpg" style="width: 100%;height: 358px" alt="">-->
<!-- 暂无图片--> <!-- <img v-else src="/test1.jpg" style="width: 100%;height: 358px" alt="">-->
<img
v-if="checkObj.preoperationPic"
:src="imgUrl+checkObj.preoperationPic"
style="width: 100%;height: 358px"
alt=""/>
<span v-else>暂无图片</span>
</div> </div>
<p>操作前照片</p> <p>操作前照片</p>
</div> </div>
<div class="img-box"> <div class="img-box">
<div <div
style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea"> style="display: flex;align-items: center;justify-content: center;width:500px;height:400px;background:#eaeaea">
<img src="/test2.jpg" style="width: 100%;height: 358px" alt=""> <!-- <img v-if="row==4 && column==18" src="/red-test2.jpg" style="width: 100%;height: 358px" alt="">-->
<!-- 暂无图片--> <!-- <img v-else src="/test2.jpg" style="width: 100%;height: 358px" alt="">-->
<img
v-if="checkObj.overoperationPic"
:src="imgUrl+checkObj.overoperationPic"
style="width: 100%;height: 358px"
alt=""/>
<span v-else>暂无图片</span>
</div> </div>
<p>操作后照片</p> <p>操作后照片</p>
</div> </div>
<div class="img-box"> <div class="img-box">
<a-spin tip="加载中..." :spinning="!Object.keys(scanAndCheck).length"> <ul>
<ul> <li v-for="item in params" :key="item.label">
<li v-for="item in params" :key="item.label">
<span class="img-box-title"> <span class="img-box-title">
{{ item.label }}: {{ item.label }}:
</span> </span>
<span class="img-box-value"> <span class="img-box-value">
{{ scanAndCheck[item.key] }} {{ scanAndCheck[item.key] }}
</span> </span>
</li> </li>
</ul> </ul>
</a-spin>
</div> </div>
</div> </div>
<div class="carousel-page-footer"> <div class="carousel-page-footer">
@ -253,6 +294,11 @@ export default {
] ]
} }
}, },
beforeRouteLeave(to ,form, next) {
// 修复第二次进入界面不执行created
this.$destroy();
next();
},
created() { created() {
this.imgUrl = imgUrl this.imgUrl = imgUrl
console.log(this.$route.query.id) console.log(this.$route.query.id)
@ -267,17 +313,17 @@ export default {
console.log(this.shelveId) console.log(this.shelveId)
console.log(this.row) console.log(this.row)
console.log(this.column) console.log(this.column)
this.getStockInfo(this.row, this.column, this.shelveId) this.getStockInfo(this.row, this.column, this.shelveId);
} else if (this.$route.query.checkObj && this.$route.query.item && this.$route.query.item.id && this.$route.query.item.name) { } else if (this.$route.query.checkObj && this.$route.query.item && this.$route.query.item.id && this.$route.query.item.name) {
this.checkObj = this.$route.query.checkObj this.checkObj = this.$route.query.checkObj
this.streetDetail = this.$route.query.item this.streetDetail = this.$route.query.item
this.id = this.$route.query.item.id this.id = this.$route.query.item.id
this.selectName = this.$route.query.item.name this.selectName = this.$route.query.item.name
this.getScanAndCheck();
} }
}, },
mounted() { mounted() {
this.getStreetList(); this.getStreetList();
this.getScanAndCheck();
if (JSON.stringify(this.checkObj) !== '{}') { if (JSON.stringify(this.checkObj) !== '{}') {
if (this.checkObj.shelveId == this.streetDetail.leftShelveId) { if (this.checkObj.shelveId == this.streetDetail.leftShelveId) {
this.selectType = 'left' this.selectType = 'left'
@ -292,24 +338,41 @@ export default {
}, },
methods: { methods: {
getScanAndCheck() { getScanAndCheck() {
this.scanAndCheck = { this.$set(this, 'scanAndCheck', {
SystemCode: 'D1H0000147', SystemCode: this.checkObj.category,
ScanCode: 'D1H0000147', ScanCode: null,
SystemNumber: 10, SystemNumber: this.checkObj.count,
CheckNumber: 10 CheckNumber: null
}
this.$api.httpApi.scanAndCheck({
name: 'getData'
}).then(res=>{
// 如果还未执行完成 2秒后再次请求
if(res.status === '0') {
setTimeout(()=>{
this.getScanAndCheck();
}, 2000);
}else{
this.scanAndCheck = res.data[0];
}
}) })
if(this.checkObj.status == 2) {
this.scanAndCheck.ScanCode = this.scanAndCheck.SystemCode;
this.scanAndCheck.CheckNumber = this.scanAndCheck.SystemNumber;
}else {
this.$api.httpNodeApi.getStockRowColumnNesInfo({
params:{
row: Number(this.row),
column: Number(this.column),
shelveId: this.shelveId + ''
}
}).then(res=>{
if(res.code === 200) {
this.scanAndCheck.ScanCode = res.data.new_category;
this.scanAndCheck.CheckNumber = res.data.new_count;
}
})
}
// this.$api.httpApi.scanAndCheck({
// name: 'getData'
// }).then(res=>{
// // 如果还未执行完成 2秒后再次请求
// if(res.status === '0') {
// setTimeout(()=>{
// this.getScanAndCheck();
// }, 2000);
// }else{
// this.scanAndCheck = res.data[0];
// }
// })
}, },
//获取巷道列表 //获取巷道列表
getStreetList() { getStreetList() {
@ -320,12 +383,11 @@ export default {
} }
}).then(res => { }).then(res => {
this.listData = res.data.list; this.listData = res.data.list;
console.log(this.listData)
this.select = this.id this.select = this.id
this.getStreetDetail(this.id) this.getStreetDetail(this.id)
this.getStockList(this.id) this.getStockList(this.id)
}).catch(err => { }).catch(err => {
console.error(err);
}); });
}, },
//获取巷道详情 //获取巷道详情
@ -363,8 +425,9 @@ export default {
} }
}).then(res => { }).then(res => {
if (res.data) { if (res.data) {
this.checkObj = res.data this.checkObj = res.data;
this.shelveId = res.data.shelveId this.shelveId = res.data.shelveId;
this.getScanAndCheck();
} }
}).catch(err => { }).catch(err => {
@ -514,7 +577,8 @@ export default {
} }
}).then(res => { }).then(res => {
if (res.code == 200) { if (res.code == 200) {
this.next(index) // this.next(index)
this.checkObj.status = 2;
this.$message.success('操作成功'); this.$message.success('操作成功');
} }
@ -525,12 +589,13 @@ export default {
showModel(checkObj, index) { showModel(checkObj, index) {
this.visible = true this.visible = true
this.modelData = checkObj this.modelData = checkObj
this.index = index this.index = index;
}, },
submit(visible, index) { submit(visible, index) {
this.visible = visible this.visible = visible
console.log(index) console.log(index)
this.next(index) // this.next(index);
this.checkObj.status = 1;
}, },
closeModel(visible, data) { closeModel(visible, data) {
this.visible = visible this.visible = visible

@ -1,10 +1,8 @@
<template> <template>
<div class="check-page"> <div class="check-page">
<div style="width:100%;text-align:right;margin-bottom:5px"> <a-button type="primary" @click="exportStock" class="export-all">
<a-button type="primary" @click="exportStock" style="text-align:right"> 导出全部巷道
导出全部巷道 </a-button>
</a-button>
</div>
<div class="title-info"> <div class="title-info">
<span class="explain">颜色说明:</span> <span class="explain">颜色说明:</span>
<span class="info-text"> <span class="info-text">
@ -21,137 +19,105 @@
</span> </span>
</div> </div>
<div style="margin-top: 10px">
<a-select v-if="data[0]" :default-value="data[0].name"
@change="handleChange" class="select-roadway">
<a-select-option v-for="i in data" :key="i.name" :value="i.id">
{{i.name}}
</a-select-option>
</a-select>
</div>
<!--左货架DOM--> <!--左货架DOM-->
<div class="center-box">
<span class="shelf-number">
左货架号: {{leftShelveId.shelveId}}
</span>
<a-radio-group v-model="size" style="margin:10px 0" @change="getStockRowColumn"
v-if="streetDetail.leftInsideShelveId && streetDetail.leftOutsideShelveId">
<a-radio-button value="leftOutsideShelveId">
外
</a-radio-button>
<a-radio-button value="leftInsideShelveId">
内
</a-radio-button>
</a-radio-group>
</div>
<div class="check-content" v-for="item in data" :key="item.id"> <div class="check-content" v-for="item in data" :key="item.id">
<div class="roadway-top" v-if="item.id == select"> <subsection v-if="item.id == select" :total="{row: item.leftRow, column: item.leftColumn}" :stockInfo="stockInfo.left">
<happy-scroll color="rgba(100,100,100,0.5)" size="8" class="scroll-box"> <template v-slot="scope">
<div class="roadway-box"> <div class="roadway-top">
<div class="line" v-for="(column,index) in item.leftColumn" :key="index"> <div class="roadway-box">
<div v-for="(row,i) in item.leftRow" :key="i" class="el"> <div class="line" v-for="(column,index) in item.leftColumn" :key="index" v-if="column >= scope.data.random.column[0] && column <= scope.data.random.column[1]">
<!--渲染默认巷道框架规格 定位浮在 已有巷道上做对应--> <div v-for="(row,i) in item.leftRow" :key="i" class="el" v-if="row >= scope.data.random.row[0] && row <= scope.data.random.row[1]">
<span <!--渲染默认巷道框架规格 定位浮在 已有巷道上做对应-->
v-if="item.leftShelveId" <span
class="default" class="default"
style="background:#bfbfbf;border-radius:4px" :style="{background:getStatusBg(stockInfo.left, `${row}-${column}`)}"
@click="tocheck(row,column,item.leftShelveId,item.id,item.name,'left','none')" @click="tocheck(row,column,leftShelveId.shelveId,item.id,item.name,'left',leftShelveId.shelveType)"
> >
{{row}}-{{column}}
</span>
<span
v-if="item.leftInsideShelveId && size =='leftInsideShelveId'"
class="default"
style="background:#bfbfbf;border-radius:4px"
@click="tocheck(row,column,item.leftInsideShelveId,item.id,item.name,'left','inside')"
>
{{row}}-{{column}}
</span>
<span
v-if="item.leftOutsideShelveId && size== 'leftOutsideShelveId'"
class="default"
style="background:#bfbfbf;border-radius:4px"
@click="tocheck(row,column,item.leftOutsideShelveId,item.id,item.name,'left','out')"
>
{{row}}-{{column}} {{row}}-{{column}}
</span> </span>
<div v-for="(key,value) in checkList" :key="value">
<div v-for="(columnItem,val) in key" :key="val">
<div
v-if="columnItem.row== row && columnItem.column ==column && value == streetDetail.leftShelveId"
@click="tocheckOperation(columnItem,item)"
class="el"
:style="{background:columnItem.status ==0?'#bfbfbf':columnItem.status == 2?'#1afa29':'#d81e06'}"
>
{{columnItem.row}}-{{columnItem.column}}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</happy-scroll> </template>
<a-radio-group v-model="size" style="margin:10px 0" </subsection>
v-if="streetDetail.leftInsideShelveId && streetDetail.leftOutsideShelveId">
<a-radio-button value="leftOutsideShelveId">
外
</a-radio-button>
<a-radio-button value="leftInsideShelveId">
内
</a-radio-button>
</a-radio-group>
</div>
</div> </div>
<!--单伸类型右货架DOM--> <!--单伸类型右货架DOM-->
<div class="center-box"> <div class="center-box">
<a-select v-if="data[0]" :default-value="data[0].name" style="width: 180px" <span class="shelf-number">
@change="handleChange" class="select-roadway"> 右货架号: {{rightShelveId.shelveId}}
<a-select-option v-for="i in data" :key="i.name" :value="i.id"> </span>
{{i.name}}
</a-select-option> <a-radio-group v-model="size2" style="margin:10px 0" @change="getStockRowColumn"
</a-select> v-if="streetDetail.rightInsideShelveId && streetDetail.rightOutsideShelveId">
<a-radio-button value="rightOutsideShelveId">
外
</a-radio-button>
<a-radio-button value="rightInsideShelveId">
内
</a-radio-button>
</a-radio-group>
</div> </div>
<div class="check-content" v-for="item in data" :key="item.name"> <div class="check-content" v-for="item in data" :key="item.name">
<div class="roadway-buttom" v-if="item.id == select"> <subsection v-if="item.id == select" :total="{row:item.leftRow, column: item.leftColumn}" :stockInfo="stockInfo.right">
<happy-scroll color="rgba(100,100,100,0.5)" size="8" class="scroll-box"> <template v-slot="scope">
<div class="roadway-box"> <div class="roadway-buttom">
<div class="line" v-for="(column,index) in item.rightColumn" :key="index"> <div class="roadway-box">
<div v-for="(row,index) in item.rightRow" :key="index" class="el"> <div class="line" v-for="(column,index) in item.rightColumn" :key="index" v-if="column >= scope.data.random.column[0] && column <= scope.data.random.column[1]">
<div v-for="(row,index) in item.rightRow" :key="index" class="el" v-if="row >= scope.data.random.row[0] && row <= scope.data.random.row[1]">
<!--渲染默认巷道框架规格 定位浮在 已有巷道上做对应--> <!--渲染默认巷道框架规格 定位浮在 已有巷道上做对应-->
<span <span
v-if="item.rightShelveId" class="default"
class="default" :style="{background:getStatusBg(stockInfo.right, `${row}-${column}`)}"
style="background:#bfbfbf;border-radius:4px" @click="tocheck(row,column,rightShelveId.shelveId,item.id,item.name,'right',rightShelveId.shelveType)">
@click="tocheck(row,column,item.rightShelveId,item.id,item.name,'right','none')">
{{row}}-{{column}}
</span>
<span
v-if="item.rightInsideShelveId&& size2 == 'rightInsideShelveId'"
class="default"
style="background:#bfbfbf;border-radius:4px"
@click="tocheck(row,column,item.rightShelveId,item.id,item.name,'right','inside')">
{{row}}-{{column}} {{row}}-{{column}}
</span> </span>
<span
v-if="item.rightOutsideShelveId && size2 == 'rightOutsideShelveId'"
class="default"
style="background:#bfbfbf;border-radius:4px"
@click="tocheck(row,column,item.rightOutsideShelveId,item.id,item.name,'right','out')">
{{row}}-{{column}}
</span>
<div v-for="(key,value) in checkList" :key="value">
<div v-for="(columnItem,val) in key" :key="val">
<div
v-if="columnItem.row== row && columnItem.column ==column && value == streetDetail.rightShelveId"
@click="tocheckOperation(columnItem,item)"
class="el"
:style="{background:columnItem.status ==0?'#bfbfbf':columnItem.status == 2?'#1afa29':'#d81e06'}"
>
{{columnItem.row}}-{{columnItem.column}}
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</happy-scroll> </template>
<a-radio-group v-model="size2" style="margin:10px 0" </subsection>
v-if="streetDetail.rightInsideShelveId && streetDetail.rightOutsideShelveId">
<a-radio-button value="rightOutsideShelveId">
外
</a-radio-button>
<a-radio-button value="rightInsideShelveId">
内
</a-radio-button>
</a-radio-group>
</div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Subsection from "./Subsection";
export default { export default {
name:'checkManage',
data() { data() {
return { return {
size: 'leftOutsideShelveId', size: 'leftOutsideShelveId',
@ -160,11 +126,61 @@ export default {
select: '', select: '',
streetId: 0, streetId: 0,
streetDetail: {}, streetDetail: {},
checkList: {} checkList: [],
}; stockInfo: {
left: {},
right: {}
},
timer: null
}
},
computed: {
// 获取左侧货架号
leftShelveId() {
let shelveId;
let shelveType = 'none';
if(this.streetDetail.leftShelveId) {
shelveId = this.streetDetail.leftShelveId;
}else if(this.streetDetail.leftInsideShelveId && this.size =='leftInsideShelveId'){
shelveId = this.streetDetail.leftInsideShelveId;
shelveType = 'inside';
}else if(this.streetDetail.leftOutsideShelveId && this.size== 'leftOutsideShelveId'){
shelveId = this.streetDetail.leftOutsideShelveId;
shelveType = 'out';
};
return {
shelveId,
shelveType
};
},
// 获取右侧货架号
rightShelveId() {
let shelveId;
let shelveType = 'none';
if(this.streetDetail.rightShelveId) {
shelveId = this.streetDetail.rightShelveId;
}else if(this.streetDetail.rightInsideShelveId && this.size2 =='rightInsideShelveId'){
shelveId = this.streetDetail.rightInsideShelveId;
shelveType = 'inside';
}else if(this.streetDetail.rightOutsideShelveId && this.size2 == 'rightOutsideShelveId'){
shelveId = this.streetDetail.rightOutsideShelveId;
shelveType = 'out';
};
return {
shelveId,
shelveType
};
}
}, },
mounted() { mounted() {
this.request() this.request();
},
activated() {
this.request();
},
beforeRouteLeave(to, form, next) {
this.timer && clearInterval(this.timer);
next();
}, },
methods: { methods: {
//获取巷道列表 //获取巷道列表
@ -178,11 +194,54 @@ export default {
this.data = res.data.list; this.data = res.data.list;
this.select = res.data.list[0].id this.select = res.data.list[0].id
this.getStockList(res.data.list[0].id) this.getStockList(res.data.list[0].id)
this.getStreetDetail(res.data.list[0].id) this.getStreetDetail(res.data.list[0].id);
this.getStockRowColumn();
}).catch(err => { }).catch(err => {
}); });
}, },
// 获取盘点状态
async getStockRowColumn() {
const init = () => {
let row = this.data.filter(item => item.id === this.select)[0];
let leftShelveId = null, rightShelveId = null;
if(row.leftInsideShelveId && this.size == 'leftInsideShelveId') {
leftShelveId = row.leftInsideShelveId;
}else if(row.leftOutsideShelveId && this.size == 'leftOutsideShelveId'){
leftShelveId = row.leftOutsideShelveId;
}else if(row.leftShelveId) {
leftShelveId = row.leftShelveId;
}
if(row.rightInsideShelveId && this.size2 == 'rightInsideShelveId') {
rightShelveId = row.rightInsideShelveId;
}else if(row.rightOutsideShelveId && this.size2 == 'rightOutsideShelveId'){
rightShelveId = row.rightOutsideShelveId;
}else if(row.rightShelveId) {
rightShelveId = row.rightShelveId;
}
let params = {
leftShelveId,
rightShelveId
};
this.$api.httpNodeApi.getStockRowColumnAPI({params}).then(({data})=>{
this.$set(this, 'stockInfo', data);
// this.stockInfo = data;
});
}
this.timer && clearInterval(this.timer);
init();
this.timer = setInterval(init, 5000);
},
getStatus(data, rowCol) {
return (data[rowCol] || {}).status;
},
// 获取状态对应的颜色
getStatusBg(data, rowCol) {
let status = this.getStatus(data, rowCol);
return status == 1 ?'#d81e06': status == 2 ? '#1afa29': '#bfbfbf';
},
//获取巷道详情 //获取巷道详情
getStreetDetail(id) { getStreetDetail(id) {
this.$axios.get('/street/' + id, { this.$axios.get('/street/' + id, {
@ -207,10 +266,12 @@ export default {
}); });
}, },
handleChange(value) { handleChange(value) {
console.error('handleChange');
console.log(value) console.log(value)
this.select = value this.select = value
this.getStreetDetail(value) this.getStreetDetail(value)
this.getStockList(value) this.getStockList(value);
this.getStockRowColumn()
}, },
tocheckOperation(checkObj, item) { tocheckOperation(checkObj, item) {
console.log(checkObj) console.log(checkObj)
@ -236,87 +297,85 @@ export default {
}).catch(err => { }).catch(err => {
}); });
} },
}, },
components: {} components: {Subsection}
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.check-page { .check-page {
position: relative; position: relative;
.title-info {
display: flex;
align-items: center;
justify-content: start;
.explain {
font-weight: 600;
}
.info-text { .title-info {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: start;
margin-right: 15px;
}
}
.ant-tag { .explain {
margin-right: 0; font-weight: 600;
display: block;
line-height: 25px;
text-align: center;
cursor: pointer;
} }
.roadway-top { .info-text {
padding: 20px 0; display: flex;
width: 90%; align-items: center;
} justify-content: center;
margin-right: 15px;
.roadway-buttom {
padding: 20px 0 20px 0;
width: 90%;
} }
}
.scroll-box { .ant-tag {
height: 270px; margin-right: 0;
.roadway-box { display: block;
transform: rotateX(180deg); line-height: 25px;
padding: 10px 10px 0 0; text-align: center;
cursor: pointer;
}
.line { .roadway-top, roadway-buttom {
display: flex; padding: 5px 0;
transform: rotateX(180deg); //两次垂直镜像翻转让原本由上到下排列的div 更改为由下到上 width: 100%;
}
.el { .roadway-box {
width: 46px; transform: rotateX(180deg);
height: 25px; padding: 10px 10px 0 0;
margin: 1px 2px; .line {
text-align: center; display: flex;
border-radius: 4px; transform: rotateX(180deg); //两次垂直镜像翻转让原本由上到下排列的div 更改为由下到上
cursor: pointer;
font-size: 14px;
position: relative;
.default { .el {
position: absolute; width: 46px;
top: 0; height: 25px;
left: 0; line-height: 25px;
right: 0; margin: 2px;
bottom: 0; font-size: 12px;
} text-align: center;
} border-radius: 4px;
cursor: pointer;
position: relative;
.default {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
} }
} }
} }
}
.center-box { .center-box {
width: 500px; width: 500px;
display: flex; height: 52px;
align-items: center; line-height: 52px;
justify-content: space-between; .shelf-number {
display: inline-block;
width: 200px;
} }
} }
.export-all {
position: absolute;
right: 20px;
}
}
</style> </style>

@ -63,7 +63,7 @@
</span> </span>
</span> </span>
<span slot="videoPath1" slot-scope="text"> <span slot="videoPath1" slot-scope="text">
<a-button type="link" v-if="text.videoPath1" @click="showModel(text.videoPath1)"> <a-button type="link" v-if="text.videoPath1" @click="showModel(text.videoPath1, text.cmd1)">
查看视频 查看视频
</a-button> </a-button>
<span v-else> <span v-else>
@ -71,7 +71,7 @@
</span> </span>
</span> </span>
<span slot="videoPath2" slot-scope="text"> <span slot="videoPath2" slot-scope="text">
<a-button type="link" v-if="text.videoPath2" @click="showModel(text.videoPath2)"> <a-button type="link" v-if="text.videoPath2" @click="showModel(text.videoPath2, text.cmd2)">
查看视频 查看视频
</a-button> </a-button>
<span v-else> <span v-else>
@ -226,9 +226,19 @@ export default {
this.queryParam.startTimestamp = "" this.queryParam.startTimestamp = ""
this.queryParam.endTimestamp = "" this.queryParam.endTimestamp = ""
}, },
showModel(data) { showModel(path, cmd) {
this.visible = true // 使用第三方软件打开海康视频
this.vid = videoUrl + data if(cmd) {
let params = {
openCmd: cmd
};
this.$api.httpNodeApi.viewVideoAPI({params}).then(res=> {
console.log(res);
})
}else {
this.visible = true
this.vid = videoUrl + path;
}
}, },
closeModel(visible, data) { closeModel(visible, data) {
this.visible = visible this.visible = visible

@ -0,0 +1,94 @@
<template>
<video-player
ref="video-player"
class="vjs-custom-skin"
:options="playerOptions"
@pause="onPlayerPause"
@playing="onPlayerPlaying"
@ended="onPlayerEnded"
/>
</template>
<script>
import 'vue-video-player/src/custom-theme.css'
import { videoPlayer } from 'vue-video-player'
export default {
name: 'VideoPlayer',
props: {
src: {
type: String,
// default: 'http://cctvalih5ca.v.myalicdn.com/live/cctv6_1/index.m3u8',
required: true
}
},
components: {
videoPlayer
},
data() {
return {
isPlay: false, // 是否正在播放
playerOptions: {
sources: [{
type: 'application/x-mpegURL',
withCredentials: false,
src: this.src
}],
height: '100%',
language: 'zh-CN',
preload: 'auto', // 建议浏览器在<video>加载元素后是否应该开始下载视频数据。auto浏览器选择最佳行为,立即开始加载视频(如果浏览器支持)
techOrder: ['html5'],
flash: { hls: { withCredentials: false }},
html5: { hls: { withCredentials: false }},
autoplay: true, // 自动播放
muted: true, // 默认情况下将会消除任何音频。
controls: true,
notSupportedMessage: '不支持的视频格式',
controlBar: {
timeDivider: false, // 当前时间和持续时间的分隔符
durationDisplay: false, // 显示持续时间
remainingTimeDisplay: false, // 是否显示剩余时间功能
fullscreenToggle: true // 是否显示全屏按钮
}
}
}
},
mounted() {
this.$nextTick(()=> {
const videoRef = this.$refs['video-player'];
// videoRef.player.play();
console.log(videoRef);
})
},
methods: {
// 暂停回调
onPlayerPause() {
this.isPlay && this.$emit('showModel');
// this.isPlay = false;
},
// 已开始播放回调
onPlayerPlaying(...args) {
this.isPlay = true;
},
// 视频播完回调
onPlayerEnded($event) {
this.isPlay = false;
},
}
}
</script>
<style lang="scss" scoped>
.vjs-custom-skin /deep/{
width: 100%;
height: 100%;
cursor: pointer;
.video-player, .video-js {
height: 100% !important;
}
// 屏蔽视频操作栏
.vjs-control-bar {
display: none !important;
}
}
</style>

@ -1,55 +1,37 @@
<template> <template>
<div class="realTime bg-white"> <div class="realTime bg-white">
<a-tabs default-active-key="1" slot="headerContent" v-model="tabKey" @change="tabsChange"> <a-tabs default-active-key="1" slot="headerContent" v-model="tabKey" @change="tabsChange">
<a-tab-pane key="0" tab="全部"> <a-tab-pane :key="item.streetId.toString()" :tab="item.streetName" v-for="item in realTimeListData"></a-tab-pane>
</a-tab-pane>
<a-tab-pane :key="(index+1).toString()" :tab="item.streetName" v-for="(item,index) in realTimeListData">
</a-tab-pane>
</a-tabs> </a-tabs>
<div class="flex-layouts"> <!-- {{cameras.length}} {{ selectTab.videoStyleRow }} * {{ selectTab.videoStyleColumn }}-->
<div class="video-list" v-for="(item,index) in realTimeListData" :key="(index+1).toString()"> <a-row :gutter="20">
<div class="video-item" v-for="i in item.cameras" :key="i.id"> <a-col
<template v-if="tabKey==0? tabKey==0 : tabKey==(index+1).toString()"> v-for="(item, index) in cameras.slice(0, selectTab.videoStyleRow * selectTab.videoStyleColumn)"
<object style="width:390px;height:219px" class="video-obj" :id="'video'+i.id" :span="24 / selectTab.videoStyleColumn"
type='application/x-vlc-plugin' events='True' width="100%" height="100%" :key="index"
ref="vlc" :style="{
pluginspage="http://www.videolan.org" height: videoHeight,
codebase="http://downloads.videolan.org/pub/videolan/vlc-webplugins/2.0.6/npapi-vlc-2.0.6.tar.xz"> marginBottom: ((selectTab.videoStyleRow * selectTab.videoStyleColumn - index - 1) >= selectTab.videoStyleColumn) ? '20px': 0
<param name='controls' value='false'/> }"
<param name='text' value='正在加载视频中...'/> >
<param name='branding' value='false'/> <video-player
<param name="windowless" value="true"> v-if="showVideo"
<param name='fullscreen' value='false'/> @showModel="showModel(item)"
<param name='mrl' :value='i.rtsp'/> :src="item.m3u8">
<param name='autoplay' value='yes'/> </video-player>
<embed type="application/x-google-vlc-plugin"/> </a-col>
</object> </a-row>
<div class="video-name">
<iframe class="vlcIframe"
style=" position:absolute;visibility:inherit; top:0px;left:0px;height:100%;width:100%; z-Index:-1; ">
</iframe>
{{item.streetName}} {{i.name}}
</div>
<div class="video-model">
<iframe class="vlcIframe"
style=" position:absolute;visibility:inherit; top:0px;left:0px;height:100%;width:100%; z-Index:-1; ">
</iframe>
<div style="width: 100%;height: 100%" @click="showModel(i)">
</div>
</div>
</template>
</div>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import VideoPlayer from "./VideoPlayer";
export default { export default {
name: "historyMonitoring", name: "historyMonitoring",
components: {
VideoPlayer
},
data() { data() {
return { return {
realTimeListData: [], realTimeListData: [],
@ -58,65 +40,50 @@ export default {
path: [], path: [],
player: "", player: "",
visible: false, visible: false,
modelData: [] modelData: [],
clientHeight: 0,
showVideo: false,
}; };
}, },
computed: {
selectTab() {
return (this.realTimeListData.filter(item=> item.streetId == this.tabKey)[0] || {})
},
cameras() {
return this.selectTab.cameras || [];
},
videoHeight() {
return (( this.clientHeight - this.selectTab.videoStyleRow * 20 )/ this.selectTab.videoStyleRow ) + 'px'
},
},
inject: ['reload'], inject: ['reload'],
mounted() { mounted() {
console.log('index mounted执行了')
this.getRealTimeList() this.getRealTimeList()
if (sessionStorage.getItem('tabKey') == null) { if (sessionStorage.getItem('tabKey') == null) {
sessionStorage.setItem('tabKey', 0) sessionStorage.setItem('tabKey', 0)
} }
this.tabKey = sessionStorage.getItem('tabKey') this.tabKey = sessionStorage.getItem('tabKey');
}, this.getClientHeight();
destroyed(){ // 监听界面尺寸变化
if (this.$refs.vlc) { // window.onresize = () => {
for (var i = 0; i < this.$refs.vlc.length; i++) { // this.getClientHeight();
try{ // }
this.$refs.vlc[i].playlist.stop();
}catch (e) {
console.log(e);
}
}
}
}, },
beforeRouteLeave(to,form,next) { destroyed() {
// console.log(11111111111111) // window.onresize = null;
console.log(this.$refs.vlc)
this.$nextTick(() => {
if (this.$refs.vlc) {
for (var i = 0; i < this.$refs.vlc.length; i++) {
try{
this.$refs.vlc[i].playlist.stop();
}catch (e) {
console.log(e);
}
}
next(true)
} else {
next(true)
}
})
console.log('beforeRouteLeave')
}, },
methods: { methods: {
getClientHeight() {
this.clientHeight = this.$el.clientHeight - 80;
},
getRealTimeList(){ getRealTimeList(){
var that=this this.showVideo = false;
this.$api.httpApi.getRealTimeList({ this.$api.httpApi.getRealTimeList({
data: {} data: {}
}).then(res => { }).then(res => {
console.log(res.data)
if(res.code == 200) { if(res.code == 200) {
this.realTimeListData = res.data this.realTimeListData = res.data.reverse();
res.data.forEach(function (item) { this.showVideo = true;
// console.log(item.cameras)
var $that = that
item.cameras.forEach(function (item) {
// console.log(item.rtsp)
$that.playVideo('video' + item.id, item.rtsp)
})
})
} }
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
@ -125,25 +92,16 @@ export default {
playVideo(id, rtsp) { playVideo(id, rtsp) {
// 设置url 播放 ---添加到事件队列在下一个tick执行,避免 TypeError: t.module.postMessage is not a function // 设置url 播放 ---添加到事件队列在下一个tick执行,避免 TypeError: t.module.postMessage is not a function
this.$nextTick(() => { this.$nextTick(() => {
setTimeout(function () { this.$refs.video.forEach(video=> {
var vlc = document.getElementById(`${id}`); video.play();
var options = new Array(":network-caching=100");//减少延迟 })
var vlcItem = vlc.playlist.add(`${rtsp}`, `${id}`, options);
// vlc.playlist.play()
vlc.playlist.playItem(vlcItem);
console.log(22222222222222)
console.log(vlc)
}, 500)
}) })
}, },
tabsChange(key) { tabsChange(key) {
console.log(key)
sessionStorage.setItem('tabKey', key) sessionStorage.setItem('tabKey', key)
this.reload() this.reload()
}, },
showModel(item) { showModel(item) {
console.log(item)
this.$nextTick(() => { this.$nextTick(() => {
this.$router.push({name: "realTimeMonitoringModel", query: {modelData: item}}); this.$router.push({name: "realTimeMonitoringModel", query: {modelData: item}});
}) })
@ -152,88 +110,8 @@ export default {
}; };
</script> </script>
<style lang='scss'> <style lang='scss' scoped>
.vxgplayer{
margin:0!important;
}
.realTime { .realTime {
padding: 24px; padding: 24px;
&-position {
display: flex;
justify-content: space-between;
&-box {
flex: 1;
display: flex;
justify-content: space-between;
&-btns {
flex: 1;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
}
&-control {
text-align: right;
cursor: pointer;
color: #55a4ff;
.anticon {
transform: rotate(0deg);
transform-origin: center;
transition: all 0.2s linear;
}
.anticon-rotate {
transform: rotate(180deg);
}
}
}
}
/*#video-cav{*/
/* position: fixed;*/
/* z-index: 999;*/
/* border: solid 1px skyblue;*/
/* width: 390px;*/
/* height: 219px;*/
/*}*/
.flex-layouts {
display: flex;
width: 1630px;
flex-wrap: wrap;
}
.video-list {
display: flex;
.video-item {
display: flex;
width: 100%;
height: 219px;
position: relative;
margin: 3px;
cursor: pointer;
z-index: 10;
/*.video-obj{*/
/*}*/
.video-name {
position: absolute;
top: 15px;
left: 15px;
color: #ffda62;
font-weight: 600;
font-size: 16px;
z-index: 10;
}
.video-model {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 20;
}
}
}
} }
</style> </style>

@ -243,14 +243,14 @@ export default {
plcIp: newVal.plcIp, plcIp: newVal.plcIp,
plcPort: newVal.plcPort, plcPort: newVal.plcPort,
leftType: newVal.leftType === null ? '' : newVal.leftType === 0 ? '单伸' : '双伸', leftType: newVal.leftType === null ? '' : newVal.leftType === 0 ? '单伸' : '双伸',
leftRow: newVal.leftRow, leftRow: 7 || newVal.leftRow,
leftColumn: newVal.leftColumn, leftColumn: 18 || newVal.leftColumn,
leftShelveId: newVal.leftShelveId, leftShelveId: newVal.leftShelveId,
leftInsideShelveId: newVal.leftInsideShelveId, leftInsideShelveId: newVal.leftInsideShelveId,
leftOutsideShelveId: newVal.leftOutsideShelveId, leftOutsideShelveId: newVal.leftOutsideShelveId,
rightType: newVal.rightType === null ? '' : newVal.rightType === 0 ? '单伸' : '双伸', rightType: newVal.rightType === null ? '' : newVal.rightType === 0 ? '单伸' : '双伸',
rightRow: newVal.rightRow, rightRow: 7 || newVal.rightRow,
rightColumn: newVal.rightColumn, rightColumn: 18 || newVal.rightColumn,
rightShelveId: newVal.rightShelveId, rightShelveId: newVal.rightShelveId,
rightInsideShelveId:newVal.rightInsideShelveId, rightInsideShelveId:newVal.rightInsideShelveId,
rightOutsideShelveId:newVal.rightOutsideShelveId, rightOutsideShelveId:newVal.rightOutsideShelveId,

@ -32,7 +32,8 @@ module.exports = {
} }
}, },
'/api': { '/api': {
target: 'http://192.168.0.108:8099', // target: 'http://192.168.0.133:8099',
target: 'http://115.236.65.98:13001/monitor',
logLevel:'debug', //控制台终端打印代理前的真实地址 logLevel:'debug', //控制台终端打印代理前的真实地址
}, },
}, },

Loading…
Cancel
Save