feat:添加现场大屏整体框架,完成现场大屏承包商项目信息、AI报警情况以及特殊作业情况的静态页面绘画
This commit is contained in:
parent
809e3a1f34
commit
c908c79e55
31
package-lock.json
generated
31
package-lock.json
generated
@ -56,6 +56,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.0.1",
|
"@commitlint/cli": "^17.0.1",
|
||||||
"@commitlint/config-conventional": "^17.0.0",
|
"@commitlint/config-conventional": "^17.0.0",
|
||||||
|
"@types/echarts": "^4.9.22",
|
||||||
"@types/node": "^17.0.31",
|
"@types/node": "^17.0.31",
|
||||||
"@types/sortablejs": "^1.15.0",
|
"@types/sortablejs": "^1.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||||
@ -3186,6 +3187,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
|
||||||
"integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
|
"integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/echarts": {
|
||||||
|
"version": "4.9.22",
|
||||||
|
"resolved": "https://mirrors.huaweicloud.com/repository/npm/@types/echarts/-/echarts-4.9.22.tgz",
|
||||||
|
"integrity": "sha512-7Fo6XdWpoi8jxkwP7BARUOM7riq8bMhmsCtSG8gzUcJmFhLo387tihoBYS/y5j7jl3PENT5RxeWZdN9RiwO7HQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/zrender": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@types/eslint": {
|
"node_modules/@types/eslint": {
|
||||||
"version": "8.40.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz",
|
||||||
@ -3287,6 +3297,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/zrender": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://mirrors.huaweicloud.com/repository/npm/@types/zrender/-/zrender-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-1jZ9bJn2BsfmYFPBHtl5o3uV+ILejAtGrDcYSpT4qaVKEI/0YY+arw3XHU04Ebd8Nca3SQ7uNcLaqiL+tTFVMg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.59.7",
|
"version": "5.59.7",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
|
||||||
@ -18822,6 +18838,15 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-18.6.4.tgz",
|
||||||
"integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
|
"integrity": "sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ=="
|
||||||
},
|
},
|
||||||
|
"@types/echarts": {
|
||||||
|
"version": "4.9.22",
|
||||||
|
"resolved": "https://mirrors.huaweicloud.com/repository/npm/@types/echarts/-/echarts-4.9.22.tgz",
|
||||||
|
"integrity": "sha512-7Fo6XdWpoi8jxkwP7BARUOM7riq8bMhmsCtSG8gzUcJmFhLo387tihoBYS/y5j7jl3PENT5RxeWZdN9RiwO7HQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/zrender": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@types/eslint": {
|
"@types/eslint": {
|
||||||
"version": "8.40.0",
|
"version": "8.40.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.40.0.tgz",
|
||||||
@ -18923,6 +18948,12 @@
|
|||||||
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.16.tgz",
|
||||||
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
"integrity": "sha512-oh8q2Zc32S6gd/j50GowEjKLoOVOwHP/bWVjKJInBwQqdOYMdPrf1oVlelTlyfFK3CKxL1uahMDAr+vy8T7yMQ=="
|
||||||
},
|
},
|
||||||
|
"@types/zrender": {
|
||||||
|
"version": "4.0.6",
|
||||||
|
"resolved": "https://mirrors.huaweicloud.com/repository/npm/@types/zrender/-/zrender-4.0.6.tgz",
|
||||||
|
"integrity": "sha512-1jZ9bJn2BsfmYFPBHtl5o3uV+ILejAtGrDcYSpT4qaVKEI/0YY+arw3XHU04Ebd8Nca3SQ7uNcLaqiL+tTFVMg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"@typescript-eslint/eslint-plugin": {
|
"@typescript-eslint/eslint-plugin": {
|
||||||
"version": "5.59.7",
|
"version": "5.59.7",
|
||||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
|
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.7.tgz",
|
||||||
|
|||||||
@ -68,6 +68,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.0.1",
|
"@commitlint/cli": "^17.0.1",
|
||||||
"@commitlint/config-conventional": "^17.0.0",
|
"@commitlint/config-conventional": "^17.0.0",
|
||||||
|
"@types/echarts": "^4.9.22",
|
||||||
"@types/node": "^17.0.31",
|
"@types/node": "^17.0.31",
|
||||||
"@types/sortablejs": "^1.15.0",
|
"@types/sortablejs": "^1.15.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
"@typescript-eslint/eslint-plugin": "^5.22.0",
|
||||||
|
|||||||
@ -28,6 +28,7 @@ export const BASE_IMAGE_URL = import.meta.env.VITE_BASE_IMAGE_URL;
|
|||||||
// export const COMPANY: string = "zsbf"; //中水北方
|
// export const COMPANY: string = "zsbf"; //中水北方
|
||||||
// export const COMPANY: string = "as"; //鞍山项目
|
// export const COMPANY: string = "as"; //鞍山项目
|
||||||
// export const COMPANY: string = "agjt"; //鞍钢集团
|
// export const COMPANY: string = "agjt"; //鞍钢集团
|
||||||
|
export const COMPANY: string = "agjtLive"; //鞍钢集团现场大屏
|
||||||
// export const COMPANY: string = "agjtCommand"; //鞍钢集团指挥部大屏
|
// export const COMPANY: string = "agjtCommand"; //鞍钢集团指挥部大屏
|
||||||
// export const COMPANY: string = "slx"; //苏立信项目
|
// export const COMPANY: string = "slx"; //苏立信项目
|
||||||
// export const COMPANY: string = "hfqc"; //合肥启程项目
|
// export const COMPANY: string = "hfqc"; //合肥启程项目
|
||||||
@ -37,4 +38,4 @@ export const BASE_IMAGE_URL = import.meta.env.VITE_BASE_IMAGE_URL;
|
|||||||
// export const COMPANY: string = "phmw"; //鄱湖美湾医疗、医美产业集群项目 (需要去src\routers\modules\staticRouter.ts更换首页)
|
// export const COMPANY: string = "phmw"; //鄱湖美湾医疗、医美产业集群项目 (需要去src\routers\modules\staticRouter.ts更换首页)
|
||||||
// export const COMPANY: string = "xjnb"; // 新建宁波项目
|
// export const COMPANY: string = "xjnb"; // 新建宁波项目
|
||||||
// export const COMPANY: string = "ahsa"; // 安徽水安项目
|
// export const COMPANY: string = "ahsa"; // 安徽水安项目
|
||||||
export const COMPANY: string = "zkax"; // 中科安信项目
|
// export const COMPANY: string = "zkax"; // 中科安信项目
|
||||||
|
|||||||
@ -1321,7 +1321,7 @@ export const ZHZRFMenu: Array<any> = [
|
|||||||
},
|
},
|
||||||
|
|
||||||
]; //中海·臻如府
|
]; //中海·臻如府
|
||||||
// 中科安信大屏
|
|
||||||
export const ZKAXMenu: Array<any> = [
|
export const ZKAXMenu: Array<any> = [
|
||||||
{
|
{
|
||||||
moduleName: "首页概览",
|
moduleName: "首页概览",
|
||||||
@ -1343,4 +1343,4 @@ export const ZKAXMenu: Array<any> = [
|
|||||||
moduleName: "进度计划",
|
moduleName: "进度计划",
|
||||||
modulePath: "/schedulePlan"
|
modulePath: "/schedulePlan"
|
||||||
}
|
}
|
||||||
];
|
]; //中科安信大屏
|
||||||
@ -24,8 +24,8 @@ export const staticRouter: RouteRecordRaw[] = [
|
|||||||
{
|
{
|
||||||
path: "/large",
|
path: "/large",
|
||||||
name: "大屏",
|
name: "大屏",
|
||||||
component: () => import("@/views/sevenLargeScreen/indexL.vue"), //七参数标准版
|
// component: () => import("@/views/sevenLargeScreen/indexL.vue"), //七参数标准版
|
||||||
// component: () => import("@/views/commandScreen/indexCommand.vue"), //指挥部大屏
|
component: () => import("@/views/commandScreen/indexCommand.vue"), //指挥部大屏
|
||||||
// component: () => import("@/views/sevenLargeScreen/indexL_syhy.vue"), // 只有一级路由(盘锦、嘉兴、鄱湖美湾医疗项目需切换至该首页)
|
// component: () => import("@/views/sevenLargeScreen/indexL_syhy.vue"), // 只有一级路由(盘锦、嘉兴、鄱湖美湾医疗项目需切换至该首页)
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
@ -269,6 +269,11 @@ export const staticRouter: RouteRecordRaw[] = [
|
|||||||
path: "/commandScreen",
|
path: "/commandScreen",
|
||||||
name: "指挥部大屏",
|
name: "指挥部大屏",
|
||||||
component: () => import("@/views/commandScreen/commandCenter/index.vue")
|
component: () => import("@/views/commandScreen/commandCenter/index.vue")
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/liveScreen",
|
||||||
|
name: "现场大屏",
|
||||||
|
component: () => import("@/views/commandScreen/liveScreen/index.vue")
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
meta: {
|
meta: {
|
||||||
|
|||||||
@ -5,6 +5,7 @@
|
|||||||
<div class="header">
|
<div class="header">
|
||||||
<span class="projectTitle">
|
<span class="projectTitle">
|
||||||
<p v-if="COMPANY === 'agjtCommand'">指挥部大屏</p>
|
<p v-if="COMPANY === 'agjtCommand'">指挥部大屏</p>
|
||||||
|
<p v-if="COMPANY === 'agjtLive'">现场大屏</p>
|
||||||
</span>
|
</span>
|
||||||
<div class="leftIcon">
|
<div class="leftIcon">
|
||||||
<div class="info">数字化项目监管平台</div>
|
<div class="info">数字化项目监管平台</div>
|
||||||
@ -69,6 +70,13 @@ let agjtCommandList = ref([
|
|||||||
modulePath: "/commandScreen"
|
modulePath: "/commandScreen"
|
||||||
}
|
}
|
||||||
]);
|
]);
|
||||||
|
// 鞍山现场大屏
|
||||||
|
let agjtLiveList = ref([
|
||||||
|
{
|
||||||
|
moduleName: "现场大屏",
|
||||||
|
modulePath: "/liveScreen"
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
const itemList = ref([]);
|
const itemList = ref([]);
|
||||||
const activeTab = ref(0);
|
const activeTab = ref(0);
|
||||||
@ -100,6 +108,10 @@ onMounted(async () => {
|
|||||||
// menuList.value = AGJTCommandMenu;
|
// menuList.value = AGJTCommandMenu;
|
||||||
menuList.value = agjtCommandList.value;
|
menuList.value = agjtCommandList.value;
|
||||||
}
|
}
|
||||||
|
if (COMPANY === "agjtLive") {
|
||||||
|
// menuList.value = AGJTCommandMenu;
|
||||||
|
menuList.value = agjtLiveList.value;
|
||||||
|
}
|
||||||
//这里是跳转过来后免登录的操作,接收token 登录 懂了
|
//这里是跳转过来后免登录的操作,接收token 登录 懂了
|
||||||
//数据看板跳转免登录
|
//数据看板跳转免登录
|
||||||
if (window.location.href.indexOf("token") != -1) {
|
if (window.location.href.indexOf("token") != -1) {
|
||||||
@ -194,6 +206,9 @@ function jumpBgd() {
|
|||||||
if(COMPANY === "agjtCommand"){
|
if(COMPANY === "agjtCommand"){
|
||||||
window.location.replace("http://47.93.215.234:9809" + "/#/login?token=" + store.token);
|
window.location.replace("http://47.93.215.234:9809" + "/#/login?token=" + store.token);
|
||||||
}
|
}
|
||||||
|
if(COMPANY === "agjtLive"){
|
||||||
|
window.location.replace("http://47.93.215.234:9809" + "/#/login?token=" + store.token);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
40
src/views/commandScreen/liveScreen/centerBottomLeft.vue
Normal file
40
src/views/commandScreen/liveScreen/centerBottomLeft.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<div class="centerBottomLeft">
|
||||||
|
<Card title="劳务实名制">
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { ref, watch, onMounted } from "vue";
|
||||||
|
import { getStageOption } from "@/api/modules/projectOverview";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.centerBottomLeft {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
margin-top: 4%;
|
||||||
|
}
|
||||||
|
.notoDta {
|
||||||
|
bottom: 10%;
|
||||||
|
width: 20%;
|
||||||
|
left: 35%;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
img {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
40
src/views/commandScreen/liveScreen/centerBottomRight.vue
Normal file
40
src/views/commandScreen/liveScreen/centerBottomRight.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<div class="centerBottomRight">
|
||||||
|
<Card title="质量待办">
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { ref, watch, onMounted } from "vue";
|
||||||
|
import { getStageOption } from "@/api/modules/projectOverview";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.centerBottomRight {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
margin-top: 4%;
|
||||||
|
}
|
||||||
|
.notoDta {
|
||||||
|
bottom: 10%;
|
||||||
|
width: 20%;
|
||||||
|
left: 35%;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
img {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
374
src/views/commandScreen/liveScreen/centerTop.vue
Normal file
374
src/views/commandScreen/liveScreen/centerTop.vue
Normal file
@ -0,0 +1,374 @@
|
|||||||
|
<template>
|
||||||
|
<div class="centerTop">
|
||||||
|
<Card title="安全教育">
|
||||||
|
<div class="top-tab" v-if="COMPANY === 'agjt'">
|
||||||
|
<div
|
||||||
|
class="tab-box"
|
||||||
|
:style="boxStyle(item)"
|
||||||
|
v-for="(item, index) in topText2"
|
||||||
|
:key="item.id"
|
||||||
|
@click="activeBtn(item, index)"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="top-tab" v-else>
|
||||||
|
<div
|
||||||
|
class="tab-box"
|
||||||
|
:style="boxStyle(item)"
|
||||||
|
v-for="(item, index) in topText"
|
||||||
|
:key="item.id"
|
||||||
|
@click="activeBtn(item, index)"
|
||||||
|
>
|
||||||
|
{{ item.title }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="href-content" v-if="showVideo == 1">
|
||||||
|
<el-carousel indicator-position="none" height="450px" style="width: 76%;">
|
||||||
|
<el-carousel-item v-for="(item, index) in videoList" :key="item.id">
|
||||||
|
<ckplayerComp
|
||||||
|
:name="index"
|
||||||
|
:poster="''"
|
||||||
|
:deviceIp="`http://${item.account}:${item.password}`"
|
||||||
|
:videoUrls="item.serialNumber"
|
||||||
|
:autoPlay="true"
|
||||||
|
></ckplayerComp>
|
||||||
|
</el-carousel-item>
|
||||||
|
</el-carousel>
|
||||||
|
</div>
|
||||||
|
<div class="videoBox" v-if="showVideo == 2" @mouseenter="showChangeVideo = true" @mouseleave="showChangeVideo = false">
|
||||||
|
<el-upload
|
||||||
|
:action="BASEURL + '/upload/image'"
|
||||||
|
:on-success="file => handleSuccessTwo(file, 1)"
|
||||||
|
:on-error="file => handleError(file, 1)"
|
||||||
|
:beforeUpload="file => handleBeforeUploadVideo(file, 1)"
|
||||||
|
name="files"
|
||||||
|
:show-file-list="false"
|
||||||
|
>
|
||||||
|
<!-- 更换视频 -->
|
||||||
|
<span class="change-video" v-if="showChangeVideo">更换视频</span>
|
||||||
|
</el-upload>
|
||||||
|
<video :src="BASEURL + '/image/' + projectData.videoUrl" class="videos" autoplay controls loop></video>
|
||||||
|
</div>
|
||||||
|
<div class="imgBox" v-if="showVideo == 3">
|
||||||
|
<div class="imgs" @mouseenter="showChangeImg = true" @mouseleave="showChangeImg = false">
|
||||||
|
<el-upload
|
||||||
|
:action="BASEURL + '/upload/image'"
|
||||||
|
:on-success="file => handleSuccess(file, 1)"
|
||||||
|
:on-error="file => handleError(file, 1)"
|
||||||
|
:beforeUpload="file => handleBeforeUploadPic(file, 1)"
|
||||||
|
name="files"
|
||||||
|
:show-file-list="false"
|
||||||
|
>
|
||||||
|
<!-- 更换图片 -->
|
||||||
|
<span class="change-video" v-if="showChangeImg">更换图片</span>
|
||||||
|
</el-upload>
|
||||||
|
<img :src="BASEURL + '/image/' + picUrl" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
|
||||||
|
import { editProjectInfo, eidtProjectShowConfig, queryBySnData } from "@/api/modules/projectOverview";
|
||||||
|
import { selectLiveVideoListApi } from "@/api/modules/video";
|
||||||
|
import ckplayerComp from "./ckplayerComp.vue";
|
||||||
|
import { COMPANY } from "@/config/config";
|
||||||
|
|
||||||
|
const store = GlobalStore();
|
||||||
|
const videoList = ref([] as any);
|
||||||
|
// ts
|
||||||
|
type Props = {
|
||||||
|
projectData?: any; // 传入项目信息
|
||||||
|
};
|
||||||
|
// withDefaults 定义默认值(传入的数据类型同默认值)
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
projectData: {}
|
||||||
|
});
|
||||||
|
// 项目信息
|
||||||
|
const projectData = ref({} as any);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.projectData,
|
||||||
|
newVal => {
|
||||||
|
if (newVal) {
|
||||||
|
// props.xData = newVal;
|
||||||
|
projectData.value = newVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
//效果图
|
||||||
|
const picUrl = ref("" as any);
|
||||||
|
|
||||||
|
const BASEURL = import.meta.env.VITE_API_URL;
|
||||||
|
// 显示视频
|
||||||
|
const showVideo = ref(1 as any);
|
||||||
|
|
||||||
|
// 显示更换图片
|
||||||
|
const showChangeImg = ref(false as any);
|
||||||
|
|
||||||
|
// 显示更换视频
|
||||||
|
const showChangeVideo = ref(false as any);
|
||||||
|
|
||||||
|
let topText2 = ref([
|
||||||
|
{ id: 1, title: "现场视频", isActive: true },
|
||||||
|
{ id: 2, title: "宣传视频", isActive: false },
|
||||||
|
{ id: 3, title: "效果图", isActive: false }
|
||||||
|
]);
|
||||||
|
let topText = ref([
|
||||||
|
// { id: 1, title: "现场视频", isActive: true },
|
||||||
|
{ id: 2, title: "宣传视频", isActive: true },
|
||||||
|
{ id: 3, title: "效果图", isActive: false }
|
||||||
|
]);
|
||||||
|
const getVideoList = async (showLoading: boolean) => {
|
||||||
|
let res: any = await selectLiveVideoListApi({
|
||||||
|
projectSn: store.sn
|
||||||
|
},showLoading);
|
||||||
|
if(res.result && res.result.extend1){
|
||||||
|
videoList.value = JSON.parse(res.result.extend1).result.videoList;
|
||||||
|
// 为了解决视频播放器渲染,第二个总是会默认显示一半,我动态设置样式让视图刷新,只要设置百分百就有问题,所以只能使用此方法
|
||||||
|
setTimeout(() => {
|
||||||
|
// 获取所有的 video 元素
|
||||||
|
var videos = document.querySelectorAll(".href-content video")
|
||||||
|
// var videos = document.getElementsByTagName("video");
|
||||||
|
// 遍历所有的 video 元素
|
||||||
|
for (var i = 0; i < videos.length; i++) {
|
||||||
|
// 修改视频元素的样式
|
||||||
|
videos[i].style.width = "99.9%";
|
||||||
|
videos[i].style.height = "99.9%";
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function boxStyle(item: any) {
|
||||||
|
if (item.isActive) {
|
||||||
|
let choiseStyle = {
|
||||||
|
color: "#fff"
|
||||||
|
};
|
||||||
|
return choiseStyle;
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
let tabIndex = ref(1 as any);
|
||||||
|
function activeBtn(item: any) {
|
||||||
|
let currentState = item.isActive;
|
||||||
|
if (!currentState) {
|
||||||
|
topText.value.forEach(el => {
|
||||||
|
el.isActive = false;
|
||||||
|
});
|
||||||
|
item.isActive = !currentState;
|
||||||
|
tabIndex.value = item.id;
|
||||||
|
}
|
||||||
|
showVideo.value = item.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadFail = () => {
|
||||||
|
ElMessage({
|
||||||
|
showClose: true,
|
||||||
|
message: "上传失败,请重试",
|
||||||
|
type: "warning"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const fileTypeFail = (text: any) => {
|
||||||
|
ElMessage({
|
||||||
|
showClose: true,
|
||||||
|
message: text,
|
||||||
|
type: "warning"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploadSuccess = () => {
|
||||||
|
ElMessage({
|
||||||
|
showClose: true,
|
||||||
|
message: "上传成功",
|
||||||
|
type: "success"
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 视频文件上传 之前
|
||||||
|
function handleBeforeUploadVideo(file: any) {
|
||||||
|
let fileType = file.type.split("/")[0];
|
||||||
|
if (fileType == "video") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
fileTypeFail("请选择正确的视频文件"); //"请选择正确的文件"
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 图片文件上传 之前
|
||||||
|
function handleBeforeUploadPic(file: any) {
|
||||||
|
let fileType = file.type.split("/")[0];
|
||||||
|
if (fileType == "image") {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
fileTypeFail("请选择正确的图片文件"); //"请选择正确的文件"
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传失败
|
||||||
|
function handleError(file: any) {
|
||||||
|
uploadFail(); //"上传失败,请重试"
|
||||||
|
}
|
||||||
|
// 效果图上传成功
|
||||||
|
function handleSuccess(file: any) {
|
||||||
|
if (file.code == 200 || file.status == "SUCCESS") {
|
||||||
|
let url = file.data[0].imageUrl;
|
||||||
|
saveEffectData(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 视频上传成功
|
||||||
|
function handleSuccessTwo(file: any) {
|
||||||
|
if (file.code == 200 || file.status == "SUCCESS") {
|
||||||
|
let url = file.data[0].imageUrl;
|
||||||
|
// this.imgUrl = url;
|
||||||
|
saveOrDeleteVideo(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//效果图 保存
|
||||||
|
function saveEffectData(url: any) {
|
||||||
|
// let configValue = JSON.stringify(url);
|
||||||
|
let data = {
|
||||||
|
projectSn: store.sn,
|
||||||
|
showType: 3,
|
||||||
|
showTitle: "效果图", //'效果图'
|
||||||
|
configValue: url
|
||||||
|
};
|
||||||
|
eidtProjectShowConfig(data).then((res: any) => {
|
||||||
|
if (res.code == 200) {
|
||||||
|
getQueryBySnData();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询效果图
|
||||||
|
function getQueryBySnData() {
|
||||||
|
queryBySnData({
|
||||||
|
projectSn: store.sn,
|
||||||
|
showType: 3
|
||||||
|
}).then((res: any) => {
|
||||||
|
if (res.result) {
|
||||||
|
picUrl.value = res.result.configValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// //保存或删除宣传视频
|
||||||
|
function saveOrDeleteVideo(url) {
|
||||||
|
editProjectInfo({
|
||||||
|
projectSn: store.sn,
|
||||||
|
videoUrl: url
|
||||||
|
}).then(res => {
|
||||||
|
uploadSuccess(); //"上传成功"
|
||||||
|
projectData.value.videoUrl = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//将方法暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
getQueryBySnData
|
||||||
|
})
|
||||||
|
onMounted(async () => {
|
||||||
|
if(COMPANY !== 'agjt') showVideo.value = 2
|
||||||
|
await getVideoList();
|
||||||
|
getQueryBySnData();
|
||||||
|
if(COMPANY != 'agjt'){
|
||||||
|
showVideo.value = 2;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.centerTop {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
.videoBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 92%;
|
||||||
|
margin-top: 8%;
|
||||||
|
background: url("@/assets/images/comprehensiveManage/project10.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
.videos {
|
||||||
|
width: 78%;
|
||||||
|
height: 90%;
|
||||||
|
margin-left: 11%;
|
||||||
|
margin-top: 1%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.imgBox {
|
||||||
|
width: 100%;
|
||||||
|
height: 92%;
|
||||||
|
margin-top: 8%;
|
||||||
|
background: url("@/assets/images/comprehensiveManage/project10.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
.imgs {
|
||||||
|
width: 78%;
|
||||||
|
height: 82%;
|
||||||
|
margin: 3% 11%;
|
||||||
|
img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
margin-top: 5%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.href-content {
|
||||||
|
width: 100%;
|
||||||
|
height: 92%;
|
||||||
|
margin-top: 8%;
|
||||||
|
background: url("@/assets/images/comprehensiveManage/project10.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// .href-content {
|
||||||
|
// width: 95%;
|
||||||
|
// height: 92%;
|
||||||
|
// margin: 0 auto;
|
||||||
|
// margin-top: 8%;
|
||||||
|
// }
|
||||||
|
|
||||||
|
.change-video {
|
||||||
|
position: absolute;
|
||||||
|
background: url("@/assets/images/cardImg.png") no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
color: #fff;
|
||||||
|
padding: 1% 2%;
|
||||||
|
font-size: 16px;
|
||||||
|
left: 45%;
|
||||||
|
top: 55%;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-tab {
|
||||||
|
position: absolute;
|
||||||
|
top: 12%;
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 0 30%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
.tab-box {
|
||||||
|
font-size: 16px;
|
||||||
|
color: rgba(255, 255, 255, 0.3);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
41
src/views/commandScreen/liveScreen/ckplayerComp.vue
Normal file
41
src/views/commandScreen/liveScreen/ckplayerComp.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<!--ckplayer 视频播放-->
|
||||||
|
<template>
|
||||||
|
<div style="width: 100%;height: 100%">
|
||||||
|
<video :id="'videoItem' + name" muted controls autoplay style="width: 100%;height: 100%;object-fit: fill;" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Srs from "@/assets/js/srs.sdk";
|
||||||
|
export default {
|
||||||
|
props: ["videoUrls", "autoPlay", "poster", "deviceIp", "name"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
player: "",
|
||||||
|
rtcPlayer: null
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted: function () {
|
||||||
|
this.player = document.getElementById("videoItem" + this.name);
|
||||||
|
//方法一:使用srs.sdk.js
|
||||||
|
this.rtcPlayer = new Srs.SrsRtcWhipWhepAsync();
|
||||||
|
this.rtcPlayer.play(this.videoUrls);
|
||||||
|
// video标签
|
||||||
|
this.player.srcObject = this.rtcPlayer.stream;
|
||||||
|
// 方法二:使用jswebrtc.min.js
|
||||||
|
// new JSWebrtc.Player(this.url, { video: player, autoplay: true, });
|
||||||
|
},
|
||||||
|
beforeDestroy: function () {
|
||||||
|
this.rtcPlayer.close();
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// watch第一次绑定值的时候不会执行监听,修改数据才会触发函数
|
||||||
|
videoUrls(newVal,oldVal) {
|
||||||
|
this.rtcPlayer = new Srs.SrsRtcWhipWhepAsync();
|
||||||
|
this.rtcPlayer.play(newVal);
|
||||||
|
this.player.srcObject = this.rtcPlayer.stream;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
146
src/views/commandScreen/liveScreen/index.vue
Normal file
146
src/views/commandScreen/liveScreen/index.vue
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<template>
|
||||||
|
<div class="projectContent">
|
||||||
|
<div class="left">
|
||||||
|
<leftTop :projectData="projectData" class="leftTop" ref="leftTopRef"></leftTop>
|
||||||
|
<leftCenter :statisticsCount="statisticsCount" class="leftCenter"></leftCenter>
|
||||||
|
<leftBottom :statisticsCount="statisticsCount" class="leftBottom"></leftBottom>
|
||||||
|
</div>
|
||||||
|
<div class="center">
|
||||||
|
<centerTop :projectData="projectData" class="centerTop" ref="centerTopRef"></centerTop>
|
||||||
|
<div class="centerBottom">
|
||||||
|
<centerBottomLeft :projectData="projectData" class="centerBottomLeft" ref="centerBottomLeftRef"></centerBottomLeft>
|
||||||
|
<centerBottomRight :projectData="projectData" class="centerBottomRight" ref="centerBottomRightRef"></centerBottomRight>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="right">
|
||||||
|
<rightTop class="rightTop" ref="rightTopRef"></rightTop>
|
||||||
|
<rightBottom class="rightBottom" ref="rightBottomRef"></rightBottom>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import leftTop from "@/views/commandScreen/liveScreen/leftTop.vue";
|
||||||
|
import leftCenter from "@/views/commandScreen/liveScreen/leftCenter.vue";
|
||||||
|
import leftBottom from "@/views/commandScreen/liveScreen/leftBottom.vue";
|
||||||
|
import centerTop from "@/views/commandScreen/liveScreen/centerTop.vue";
|
||||||
|
import centerBottomLeft from "@/views/commandScreen/liveScreen/centerBottomLeft.vue";
|
||||||
|
import centerBottomRight from "@/views/commandScreen/liveScreen/centerBottomRight.vue";
|
||||||
|
import rightTop from "@/views/commandScreen/liveScreen/rightTop.vue";
|
||||||
|
import rightBottom from "@/views/commandScreen/liveScreen/rightBottom.vue";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
const store = GlobalStore();
|
||||||
|
import { getWorkerStatisticsCountApi, getProjectDetail } from "@/api/modules/projectOverview";
|
||||||
|
import { ref, onMounted, onBeforeUnmount,nextTick } from "vue";
|
||||||
|
const statisticsCount = ref(null as any);
|
||||||
|
|
||||||
|
const projectData = ref(null as any);
|
||||||
|
//获取项目信息
|
||||||
|
const getProjectInfo = async (showLoading: boolean) => {
|
||||||
|
const res = await getProjectDetail({ projectSn: store.sn },showLoading);
|
||||||
|
projectData.value = res.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
//获取人员概览
|
||||||
|
const getPersonDetail = async () => {
|
||||||
|
const res = await getWorkerStatisticsCountApi({ sn: store.sn });
|
||||||
|
statisticsCount.value = res.result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const leftTopRef = ref();
|
||||||
|
const centerTopRef = ref();
|
||||||
|
const centerBottomLeftRef = ref();
|
||||||
|
const rightTopRef = ref();
|
||||||
|
const rightBottomRef = ref();
|
||||||
|
const callChildFn = async () => {
|
||||||
|
nextTick( async ()=>{
|
||||||
|
leftTopRef.value.projectTypeEnum()
|
||||||
|
centerTopRef.value.getQueryBySnData()
|
||||||
|
centerBottomLeftRef.value.getProgressOption()
|
||||||
|
rightTopRef.value.getSafeInfo()
|
||||||
|
rightBottomRef.value.getList()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//定时器
|
||||||
|
const interval = ref(null as any);
|
||||||
|
//定时调用
|
||||||
|
const startInterval = async () => {
|
||||||
|
interval.value= setInterval(() => {
|
||||||
|
getPersonDetail();
|
||||||
|
getProjectInfo();
|
||||||
|
callChildFn();
|
||||||
|
}, 30 * 1000);
|
||||||
|
}
|
||||||
|
// 在组件销毁时清除 interval
|
||||||
|
const destroyInterval = () => {
|
||||||
|
if (interval.value) {
|
||||||
|
clearInterval(interval.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 在组件销毁时调用 destroyInterval 方法清除 interval
|
||||||
|
onBeforeUnmount(() => {
|
||||||
|
destroyInterval();
|
||||||
|
})
|
||||||
|
window.onbeforeunload = (e) => {
|
||||||
|
destroyInterval();
|
||||||
|
}
|
||||||
|
onMounted( async () => {
|
||||||
|
getPersonDetail();
|
||||||
|
getProjectInfo();
|
||||||
|
startInterval();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.projectContent {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
.left {
|
||||||
|
width: 26%;
|
||||||
|
.leftTop {
|
||||||
|
height: 32%;
|
||||||
|
}
|
||||||
|
.leftCenter {
|
||||||
|
height: 33%;
|
||||||
|
margin: 3% 0 3% 0;
|
||||||
|
}
|
||||||
|
.leftBottom {
|
||||||
|
height: 35.25%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.center {
|
||||||
|
width: 46%;
|
||||||
|
margin: 0 1%;
|
||||||
|
|
||||||
|
.centerTop {
|
||||||
|
height: 66%;
|
||||||
|
margin-bottom: 2.1%;
|
||||||
|
}
|
||||||
|
.centerBottom{
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.centerBottomLeft {
|
||||||
|
width: 49%;
|
||||||
|
height: 35.23%;
|
||||||
|
}
|
||||||
|
.centerBottomRight {
|
||||||
|
width: 49%;
|
||||||
|
height: 35.23%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
width: 26%;
|
||||||
|
|
||||||
|
.rightTop {
|
||||||
|
height: 32%;
|
||||||
|
}
|
||||||
|
.rightBottom {
|
||||||
|
height: 78.636%;
|
||||||
|
margin: 3% 0 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
136
src/views/commandScreen/liveScreen/leftBottom.vue
Normal file
136
src/views/commandScreen/liveScreen/leftBottom.vue
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
<template>
|
||||||
|
<div class="leftBottom">
|
||||||
|
<Card title="特殊作业情况">
|
||||||
|
<div class="mainContainer">
|
||||||
|
<div id="pieEchart" style="width:100%;height:100%"></div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
|
||||||
|
function drawPie(){
|
||||||
|
type EChartsOption = echarts.EChartsOption;
|
||||||
|
|
||||||
|
var chartDom = document.getElementById('pieEchart')!;
|
||||||
|
var myChart = echarts.init(chartDom);
|
||||||
|
var option: EChartsOption;
|
||||||
|
|
||||||
|
option = {
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item',
|
||||||
|
formatter: '{a} <br/>{b}: {c} ({d}%)'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: [ 'Direct', 'Marketing', 'Search Engine', 'Email', 'Union Ads', 'Video Ads', 'Baidu', 'Google', 'Bing', 'Others' ]
|
||||||
|
},
|
||||||
|
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
grid:{
|
||||||
|
left: '5%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '5%',
|
||||||
|
containLabel:true
|
||||||
|
},
|
||||||
|
name: 'Access From',
|
||||||
|
type: 'pie',
|
||||||
|
selectedMode: 'single',
|
||||||
|
radius: [0, '30%'],
|
||||||
|
label: {
|
||||||
|
position: 'inner',
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{ value: 1548, name: 'Search Engine' },
|
||||||
|
{ value: 775, name: 'Direct' },
|
||||||
|
{ value: 679, name: 'Marketing', selected: true }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Access From',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['45%', '60%'],
|
||||||
|
labelLine: {
|
||||||
|
length: 1
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
formatter: '{a|{a}}{abg|}\n{hr|}\n {b|{b}:}{c} {per|{d}%} ',
|
||||||
|
backgroundColor: '#F6F8FC',
|
||||||
|
borderColor: '#8C8D8E',
|
||||||
|
borderWidth: 1,
|
||||||
|
borderRadius: 3,
|
||||||
|
|
||||||
|
rich: {
|
||||||
|
a: {
|
||||||
|
color: '#6E7079',
|
||||||
|
lineHeight: 10,
|
||||||
|
align: 'center'
|
||||||
|
},
|
||||||
|
hr: {
|
||||||
|
borderColor: '#8C8D8E',
|
||||||
|
width: '100%',
|
||||||
|
borderWidth: 1,
|
||||||
|
height: 0
|
||||||
|
},
|
||||||
|
b: {
|
||||||
|
color: '#4C5058',
|
||||||
|
fontSize: 10,
|
||||||
|
fontWeight: 'bold',
|
||||||
|
lineHeight: 12
|
||||||
|
},
|
||||||
|
per: {
|
||||||
|
color: '#fff',
|
||||||
|
backgroundColor: '#4C5058',
|
||||||
|
padding: [1, 1],
|
||||||
|
borderRadius: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{ value: 1048, name: 'Baidu' },
|
||||||
|
{ value: 335, name: 'Direct' },
|
||||||
|
{ value: 310, name: 'Email' },
|
||||||
|
{ value: 251, name: 'Google' },
|
||||||
|
{ value: 234, name: 'Union Ads' },
|
||||||
|
{ value: 147, name: 'Bing' },
|
||||||
|
{ value: 135, name: 'Video Ads' },
|
||||||
|
{ value: 102, name: 'Others' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
option && myChart.setOption(option);
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted( async () => {
|
||||||
|
drawPie()
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.leftBottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.mainContainer{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
58
src/views/commandScreen/liveScreen/leftCenter.vue
Normal file
58
src/views/commandScreen/liveScreen/leftCenter.vue
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<template>
|
||||||
|
<div class="leftCenter">
|
||||||
|
<Card title="AI报警情况">
|
||||||
|
<div class="mainContainer">
|
||||||
|
<div class="imgBox"><img src="@\assets\images\vehicleManagement\goCar.png"/></div>
|
||||||
|
<div class="textBox">
|
||||||
|
<div>报警位置:东南口</div>
|
||||||
|
<div>报警事件:2024-03-01 12:00:00</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
import { COMPANY } from "@/config/config";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import { getPersonTypeAndEduStatisticsApi } from "@/api/modules/labor";
|
||||||
|
const store = GlobalStore();
|
||||||
|
// ts
|
||||||
|
|
||||||
|
onMounted( async () => {
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.leftCenter {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.mainContainer{
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
height: calc(100% - 20px);
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
.imgBox{
|
||||||
|
width: 100%;
|
||||||
|
height: 85%;
|
||||||
|
img{
|
||||||
|
width: 100%;
|
||||||
|
height:100%;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.textBox{
|
||||||
|
height: 15%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
140
src/views/commandScreen/liveScreen/leftTop.vue
Normal file
140
src/views/commandScreen/liveScreen/leftTop.vue
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
<template>
|
||||||
|
<div class="leftTop">
|
||||||
|
<Card title="承包商项目信息">
|
||||||
|
<!-- <div class="projectInfo">
|
||||||
|
<div><span>项目名称:</span> {{ projectData.projectName || "" }}</div>
|
||||||
|
<div :title="projectLocal"><span>项目地址:</span> {{ projectLocal }}</div>
|
||||||
|
<div><span>项目经理:</span> {{ projectData.projectManage || "" }}</div>
|
||||||
|
<div><span>联系电话:</span> {{ projectData.projectTel || "" }}</div>
|
||||||
|
<div><span>建筑面积:</span> {{ projectData.projectAcreage || "" }} ㎡</div>
|
||||||
|
<div><span>开工日期:</span> {{ projectData.startWorkDate || "" }}</div>
|
||||||
|
<div><span>项目编号:</span> {{ projectData.projectNumber || "" }}</div>
|
||||||
|
<div><span>工程类别:</span> {{ projectData.projectType && projectTypeEnumList.length > 0 ? projectTypeEnumList[projectData.projectType - 1].name : "" }}</div>
|
||||||
|
</div> -->
|
||||||
|
<div class="mainContainer">
|
||||||
|
<div>承包商名称:辽宁五瞏</div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">施工区域:东北角一区</div> <div class="boxInner2">项目编号:002</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">项目经理:王海龙</div> <div class="boxInner2">项目类型:epc总承包</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">联系电话:13312545623</div> <div class="boxInner2">竣工日期:2024-03-01</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">建筑面积:12457㎡</div> <div class="boxInner2">合同总额:230万元</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">投资总额:12457万元</div> <div class="boxInner2">工程类别:矿山</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">开工日期:2024-03-01</div> <div class="boxInner2">结构类型:混合结构</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">项目编号:鞍高开项备[2021]23号)</div> <div class="boxInner2">施工阶段:主体施工</div></div>
|
||||||
|
<div class="lineBox"><div class="boxInner1">工程类别:矿山</div> <div class="boxInner2">工程状态</div></div>
|
||||||
|
</div>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
import { ref, onMounted, watch } from "vue";
|
||||||
|
import { getStageOption } from "@/api/modules/projectOverview";
|
||||||
|
|
||||||
|
// ts
|
||||||
|
type Props = {
|
||||||
|
projectData?: any; // 传入项目信息
|
||||||
|
};
|
||||||
|
// withDefaults 定义默认值(传入的数据类型同默认值)
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
projectData: {}
|
||||||
|
});
|
||||||
|
// 项目信息
|
||||||
|
const projectData = ref({} as any);
|
||||||
|
|
||||||
|
const projectLocal = ref("" as any);
|
||||||
|
const store = GlobalStore();
|
||||||
|
const projectTypeEnumList:any = ref([]); //工程类别
|
||||||
|
// 工程类别字典数据
|
||||||
|
const projectTypeEnum = async () => {
|
||||||
|
const res: any = await getStageOption({ dictionaryEncoding: "project_type", projectSn: store.sn });
|
||||||
|
if (res.result.length > 0) {
|
||||||
|
let newArray = res.result.map((item: any) => {
|
||||||
|
return {
|
||||||
|
name: item.name,
|
||||||
|
id: Number(item.data)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
projectTypeEnumList.value = newArray
|
||||||
|
} else {
|
||||||
|
projectTypeEnumList.value = []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
//将方法暴露给父组件
|
||||||
|
defineExpose({
|
||||||
|
projectTypeEnum
|
||||||
|
})
|
||||||
|
onMounted( async () => {
|
||||||
|
await projectTypeEnum();
|
||||||
|
})
|
||||||
|
watch(
|
||||||
|
() => props.projectData,
|
||||||
|
newVal => {
|
||||||
|
if (newVal) {
|
||||||
|
// props.xData = newVal;
|
||||||
|
projectData.value = newVal;
|
||||||
|
projectLocal.value =
|
||||||
|
projectData.value.provinceName +
|
||||||
|
projectData.value.cityName +
|
||||||
|
projectData.value.areaName +
|
||||||
|
projectData.value.projectAddress;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.leftTop {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
.mainContainer{
|
||||||
|
color: #fff;
|
||||||
|
padding: 10px;
|
||||||
|
.lineBox{
|
||||||
|
// background-color: #fff;
|
||||||
|
line-height: 18px;
|
||||||
|
height: 18px;
|
||||||
|
display: flex;
|
||||||
|
.boxInner1{
|
||||||
|
// width: 60%;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
.boxInner2{
|
||||||
|
// width: 40%;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// .projectInfo {
|
||||||
|
// width: 100%;
|
||||||
|
// height: 100%;
|
||||||
|
// color: #fff;
|
||||||
|
// padding: 2% 0 0 4%;
|
||||||
|
|
||||||
|
// div {
|
||||||
|
// width: 95%;
|
||||||
|
// height: 12%;
|
||||||
|
// font-size: 15px;
|
||||||
|
// white-space: nowrap; //单行
|
||||||
|
// overflow: hidden;
|
||||||
|
// text-overflow: ellipsis;
|
||||||
|
// span {
|
||||||
|
// margin-right: 3%;
|
||||||
|
// color: #ccc;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
::v-deep .h-card {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
30
src/views/commandScreen/liveScreen/rightBottom.vue
Normal file
30
src/views/commandScreen/liveScreen/rightBottom.vue
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<template>
|
||||||
|
<div class="rightBottom">
|
||||||
|
<Card title="安全待办">
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
import { getCurrentDayAirQualityApi } from "@/api/modules/projectOverview";
|
||||||
|
import { ref, onMounted, reactive } from "vue";
|
||||||
|
// import * as echarts from "echarts";
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
const store = GlobalStore();
|
||||||
|
|
||||||
|
onMounted( async () => {
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.rightBottom {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
31
src/views/commandScreen/liveScreen/rightTop.vue
Normal file
31
src/views/commandScreen/liveScreen/rightTop.vue
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<div class="rightTop">
|
||||||
|
<Card title="应急记录">
|
||||||
|
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import Card from "@/components/card.vue";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { GlobalStore } from "@/stores";
|
||||||
|
const store = GlobalStore();
|
||||||
|
import * as echarts from "echarts";
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.rightTop {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
::v-deep .h-card .content {
|
||||||
|
height: 80%;
|
||||||
|
}
|
||||||
|
::v-deep .h-card {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
x
Reference in New Issue
Block a user