Files
2022-12-01 13:53:11 +08:00

341 lines
8.1 KiB
Vue

<template>
<div class="wrap flex justify-between relative">
<NConfigProvider :theme="darkTheme">
<n-tabs
type="segment"
class="absolute right-3 w-80"
style="top: -45px"
v-model:value="mode"
>
<n-tab-pane name="camera" tab="摄像头列表"></n-tab-pane>
<n-tab-pane name="image" tab="图片列表"></n-tab-pane>
</n-tabs>
</NConfigProvider>
<div class="monitor-switcher">
<div class="title">项目列表</div>
<!-- <input type="text" class="search" placeholder="搜索摄像头" /> -->
<ul class="localtion-list">
<li
v-for="(item, index) in projectList"
:key="index"
@click="projectClicked(index)"
:class="`localtion-item flex items-center ${
index == activeIndex ? 'active' : ''
}`"
>
<img
src="../../assets/location-fill@3x.png"
:style="{
width: `18px`,
height: `18px`,
marginRight: `10px`,
marginLeft: `26px`,
}"
alt=""
/>
<div>{{ item.PRONAME }}</div>
</li>
</ul>
</div>
<div v-if="mode === 'camera'" class="monitor-list grid grid-cols-2">
<Camera
v-for="(item, index) in cameraList"
:source="item.flvUrl"
:key="index"
:name="item.address"
></Camera>
<!-- <div
v-for="(item, index) in projectList.slice(0, 9)"
:key="index"
:class="`monitor-item flex items-center flex-col`"
>
<img src="../../assets/screen.png" class="monitor-screen" />
<div class="flex w-full justify-between pt-2 pl-4 pr-4">
<div class="controls flex justify-between">
<img src="../../assets/prev.png" alt="" />
<img src="../../assets/play.png" alt="" />
<img src="../../assets/next.png" alt="" />
</div>
<div class="desc">{{ item.name }}</div>
</div>
</div> -->
</div>
<div
v-else-if="mode === 'image'"
class="monitor-list image-list grid grid-cols-2"
>
<!-- <div :key="item"> -->
<n-image
:style="{
// width: `500px`,
height: `420px`,
}"
v-for="item in imageList.slice(imageIndexStart, 4)"
object-fit="cover"
class="image-item"
:img-props="{
style: {
width: `100%`,
height: `100%`,
},
}"
:key="item"
:src="`${protocol}//${host}/portal/r/${item}`"
width="100%"
></n-image>
</div>
<div
v-if="cameraList.length && mode == 'camera'"
class="controls flex flex-col justify-end pb-8"
>
<el-pagination
background
:total="total"
v-model:current-page="currentPage"
:page-size="4"
layout="pager"
:pager-count="5"
></el-pagination>
</div>
<div
v-else-if="imageList.length && mode == 'image'"
class="controls flex flex-col justify-end pb-8"
>
<el-pagination
background
:total="imageList.length"
v-model:current-page="currentImagePage"
:page-size="4"
layout="pager"
:pager-count="5"
></el-pagination>
</div>
</div>
</template>
<script setup name="Monitor">
import axios from "axios";
import { computed, onMounted, reactive, ref } from "vue";
import { ElPagination } from "element-plus";
import Camera from "./camera.vue";
import { NImage, NTabs, NTabPane, NConfigProvider, darkTheme } from "naive-ui";
const protocol = ref("");
protocol.value = location.protocol;
const host = ref("");
host.value = location.host;
const mode = ref("camera");
const projectList = ref([]);
const cameraList = ref([]);
const imageList = ref([]);
const total = ref(0);
const queryParams = reactive({
cmd: "com.awspaas.user.apps.cmp_camera_list",
pageNum: 1,
pageSize: 4,
sid: sid,
query: "",
});
const currentPage = computed({
get() {
return queryParams.pageNum;
},
set(val) {
queryParams.pageNum = val;
loadCameraList();
},
});
const imageIndexStart = ref(0);
const currentImagePage = computed({
get() {
return Math.floor(imageIndexStart.value / 4) + 1;
},
set(val) {
imageIndexStart.value = (val - 1) * 4;
},
});
const activeIndex = ref(0);
const loadProjectList = async () => {
const resp = await axios.get(
"./jd?cmd=com.awspaas.user.apps.cmp_screen_getProjectList&sid=" + sid
);
return resp.data;
};
const loadCameraList = async () => {
const resp = await axios(`./jd`, {
params: queryParams,
});
cameraList.value = resp.data.rows;
total.value = resp.data.total;
// if (total.value === 0) {
// loadImageList();
// }
};
const loadImageList = async () => {
const resp = await axios(
`./jd?cmd=com.awspaas.user.apps.cmp_photo_list&sid=${sid}&proId=${queryParams.query}`
);
imageList.value = resp.data;
};
const projectClicked = (index) => {
activeIndex.value = index;
const proid = projectList.value[index].PROID;
queryParams.query = proid;
queryParams.pageNum = 1;
loadCameraList();
loadImageList();
};
loadProjectList()
.then((data) => {
projectList.value = data;
return projectList.value[0].PROID;
})
.then((proid) => {
queryParams.query = proid;
queryParams.pageNum = 1;
loadCameraList();
loadImageList();
});
</script>
<style lang="scss" scoped>
.wrap {
margin-top: 38px;
margin-left: 28px;
margin-right: 28px;
.monitor-switcher {
background-image: linear-gradient(
180deg,
rgba(4, 53, 99, 0.4) 0%,
rgba(4, 53, 99, 0.4) 100%
);
display: flex;
flex-direction: column;
align-items: center;
width: 350px;
height: 935px;
.title {
width: 100%;
padding-top: 6px;
padding-bottom: 6px;
font-family: PingFangSC-Regular;
font-size: 20px;
color: #ffffff;
letter-spacing: 0;
line-height: 30px;
text-shadow: 0 0 9px #158eff;
font-weight: 400;
padding-left: 38px;
background-image: linear-gradient(
90deg,
#05294b 0%,
#021f3a 0%,
rgba(5, 41, 75, 0) 100%
);
}
.search {
margin-top: 32px;
width: 300px;
height: 32px;
border-radius: 16px;
background: rgba(12, 99, 181, 0.56);
}
.localtion-list {
margin-top: 20px;
overflow-y: auto;
.localtion-item {
width: 336px;
height: 42px;
user-select: none;
cursor: pointer;
font-family: PingFangSC-Regular;
font-size: 16px;
color: #ffffff;
letter-spacing: 0;
line-height: 30px;
text-shadow: 0 0 9px #158eff;
font-weight: 400;
}
.localtion-item.active {
background-image: linear-gradient(
90deg,
#0057a6 0%,
rgba(35, 53, 168, 0) 100%
);
}
}
}
.monitor-list {
// row-gap: 45px;
flex: 1;
column-gap: 45px;
// .monitor-item {
// width: 400px;
// height: 280px;
// // background-color: #158eff;
// background-image: url(../../assets/monitor.png);
// background-size: 100% 100%;
// .monitor-screen {
// margin-top: 10%;
// width: 98%;
// height: 65%;
// }
// .controls {
// width: 100px;
// img {
// width: 28px;
// height: 28px;
// }
// }
// .desc {
// font-family: PingFangSC-Medium;
// font-size: 16px;
// color: #ffffff;
// letter-spacing: 0;
// line-height: 24px;
// text-shadow: 0 0 7px #158eff;
// font-weight: 500;
// }
// }
}
.image-list {
// flex: 1;
margin-left: 80px;
// :deep(.image-item) {
// img {
// width: 100%;
// height: 100%;
// }
// }
}
.controls {
width: 260px;
.page {
width: 24px;
height: 24px;
color: white;
}
.page.active {
border-width: 1px;
border-style: solid;
border-color: #b1e1ff;
background-image: linear-gradient(90deg, #0e4b84 1%, #000407 100%);
border-radius: 2.18px;
}
}
}
</style>