Commit c31afea9 authored by lei's avatar lei

add:接口联调(算法配置)

parent 469da564
import request from '@/utils/request'
//获取报警日志列表
export function getAlarmLogList(query) {
return request({
url: '/system/log/list',
method: 'get',
params: query
})
}
//删除报警日志
export function delAlarmLog(id) {
return request({
url: '/system/log/' + id,
method: 'delete'
})
}
//修改报警日志
export function updateAlarmLog(data) {
return request({
url: '/system/log',
method: 'put',
data: data
})
}
\ No newline at end of file
import request from '@/utils/request'
//获取算法配置列表
export function getAlgorithmList(query) {
return request({
url: '/system/algorithmConfig/list',
method: 'get',
params: query
})
}
//新增算法配置
export function addAlgorithm(data) {
return request({
url: '/system/algorithmConfig',
method: 'post',
data: data
})
}
//修改算法配置
export function updateAlgorithm(data) {
return request({
url: '/system/algorithmConfig',
method: 'put',
data: data
})
}
//删除算法配置
export function delAlgorithm(id) {
return request({
url: '/system/algorithmConfig/' + id,
method: 'delete'
})
}
\ No newline at end of file
import request from '@/utils/request'
// 获取摄像头表格数据
export function getCameraList(query) {
return request({
url: '/system/cameraConfig/list',
method: 'get',
params: query
})
}
// 新增摄像头
export function addCamera(data) {
return request({
url: '/system/cameraConfig',
method: 'post',
data: data
})
}
// 修改摄像头
export function updateCamera(data) {
return request({
url: '/system/cameraConfig',
method: 'put',
data: data
})
}
// 删除摄像头
export function delCamera(id) {
return request({
url: '/system/cameraConfig/' + id,
method: 'delete'
})
}
//获取摄像头位置列表
export function getCameraPositionList() {
return request({
url: '/system/position/treeList',
method: 'get'
})
}
//新增摄像头位置
export function addCameraPosition(data) {
return request({
url: '/system/position',
method: 'post',
data: data
})
}
//修改摄像头位置
export function updateCameraPosition(data) {
return request({
url: '/system/position',
method: 'put',
data: data
})
}
//删除摄像头位置
export function delCameraPosition(id) {
return request({
url: '/system/position/' + id,
method: 'delete'
})
}
\ No newline at end of file
......@@ -16,7 +16,7 @@
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:class="{hide: this.fileList.length >= this.limit}"
:class="{ hide: this.fileList.length >= this.limit }"
>
<i class="el-icon-plus"></i>
</el-upload>
......@@ -24,8 +24,12 @@
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
请上传
<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template>
<template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>
<template v-if="fileSize">
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
</template>
<template v-if="fileType">
格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
</template>
的文件
</div>
......@@ -36,7 +40,7 @@
append-to-body
>
<img
:src="dialogImageUrl"
:src="baseUrl + dialogImageUrl"
style="display: block; max-width: 100%; margin: 0 auto"
/>
</el-dialog>
......@@ -53,20 +57,20 @@ export default {
// 上传接口地址
action: {
type: String,
default: "/common/upload"
default: "/common/upload",
},
// 上传携带的参数
data: {
type: Object
type: Object,
},
// 图片数量限制
limit: {
type: Number,
default: 5,
default: 1,
},
// 大小限制(MB)
fileSize: {
type: Number,
type: Number,
default: 5,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
......@@ -77,8 +81,8 @@ export default {
// 是否显示提示
isShowTip: {
type: Boolean,
default: true
}
default: true,
},
},
data() {
return {
......@@ -92,7 +96,7 @@ export default {
headers: {
Authorization: "Bearer " + getToken(),
},
fileList: []
fileList: [],
};
},
watch: {
......@@ -100,14 +104,14 @@ export default {
handler(val) {
if (val) {
// 首先将值转为数组
const list = Array.isArray(val) ? val : this.value.split(',');
const list = Array.isArray(val) ? val : this.value.split(",");
// 然后将数组转为对象数组
this.fileList = list.map(item => {
this.fileList = list.map((item) => {
if (typeof item === "string") {
if (item.indexOf(this.baseUrl) === -1 && !isExternal(item)) {
item = { name: this.baseUrl + item, url: this.baseUrl + item };
item = { name: this.baseUrl + item, url: this.baseUrl + item };
} else {
item = { name: item, url: item };
item = { name: item, url: item };
}
}
return item;
......@@ -118,8 +122,8 @@ export default {
}
},
deep: true,
immediate: true
}
immediate: true,
},
},
computed: {
// 是否显示提示
......@@ -136,7 +140,7 @@ export default {
if (file.name.lastIndexOf(".") > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
}
isImg = this.fileType.some(type => {
isImg = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true;
if (fileExtension && fileExtension.indexOf(type) > -1) return true;
return false;
......@@ -146,11 +150,13 @@ export default {
}
if (!isImg) {
this.$modal.msgError(`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`);
this.$modal.msgError(
`文件格式不正确,请上传${this.fileType.join("/")}图片格式文件!`
);
return false;
}
if (file.name.includes(',')) {
this.$modal.msgError('文件名不正确,不能包含英文逗号!');
if (file.name.includes(",")) {
this.$modal.msgError("文件名不正确,不能包含英文逗号!");
return false;
}
if (this.fileSize) {
......@@ -170,7 +176,7 @@ export default {
// 上传成功回调
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push({ name: res.fileName, url: res.fileName });
this.uploadList.push({ name: res.fileName, url: res.url });
this.uploadedSuccessfully();
} else {
this.number--;
......@@ -182,7 +188,7 @@ export default {
},
// 删除图片
handleDelete(file) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
const findex = this.fileList.map((f) => f.name).indexOf(file.name);
if (findex > -1) {
this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
......@@ -217,25 +223,25 @@ export default {
strs += list[i].url.replace(this.baseUrl, "") + separator;
}
}
return strs != '' ? strs.substr(0, strs.length - 1) : '';
}
}
return strs != "" ? strs.substr(0, strs.length - 1) : "";
},
},
};
</script>
<style scoped lang="scss">
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
display: none;
display: none;
}
// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
transition: all 0s;
}
::v-deep .el-list-enter, .el-list-leave-active {
::v-deep .el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: translateY(0);
}
</style>
......@@ -53,7 +53,7 @@
<el-table :data="tableList">
<el-table-column
label="摄像头ID"
prop="id"
prop="cameraId"
align="center"
></el-table-column>
<el-table-column
......@@ -125,6 +125,11 @@
</template>
<script>
import {
getAlarmLogList,
delAlarmLog,
updateAlarmLog,
} from "@/api/business/alarmlog.js";
export default {
dicts: ["algorithm_level"],
name: "Alarmlog",
......@@ -142,18 +147,7 @@ export default {
algorithmLevel: 1, // 算法报警等级
alarmStatus: 0, // 报警处理状态
},
tableList: [
{
id: 1, // 摄像头ID
videoAnlysisTasksName: "yi", // 视频分析任务名称
cameraName: "er", // 摄像头名称
alarmImg: "1121", // 报警图片
alarmTime: "1212", // 报警时间
algorithmName: "1212", // 算法名称
algorithmLevel: 1, // 算法报警等级
alarmStatus: 0, // 报警处理状态
},
],
tableList: [],
cameraAdderss: [
{
name: "摄像头1", // 摄像头名称
......@@ -170,7 +164,9 @@ export default {
},
computed: {},
watch: {},
created() {},
created() {
this.getList();
},
mounted() {},
methods: {
// 搜索
......@@ -186,7 +182,14 @@ export default {
// 编辑
editBut(row) {},
// 获取数据列表
getList() {},
getList() {
getAlarmLogList(this.queryParams).then((res) => {
if (res.code == 200) {
this.tableList = res.rows;
this.total = res.total;
}
});
},
},
};
</script>
......
......@@ -8,25 +8,30 @@
empty-text
>
<el-table-column
prop="name"
prop="algorithmId"
align="center"
label="算法ID"
width="100"
></el-table-column>
<el-table-column
prop="address"
prop="algorithmVersion"
align="center"
label="算法版本"
width="100"
></el-table-column>
<el-table-column
prop="videoAdress"
prop="algorithmName"
label="算法名称"
align="center"
></el-table-column>
<el-table-column
prop="imageUrl"
align="center"
label="算法等级"
></el-table-column>
<el-table-column prop="algorithmLevel" align="center" label="算法等级">
<template slot-scope="scope">
<dict-tag
:options="dict.type.algorithm_level"
:value="Number(scope.row.algorithmLevel)"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button type="text" size="mini" @click="tableEdit(scope.row)">
......@@ -43,11 +48,47 @@
@pagination="getList"
/>
</div>
// 修改弹窗部分的模板
<el-dialog
title="修改等级"
:visible.sync="editDialogVisible"
:close-on-click-modal="false"
width="30%"
center
>
<el-form :model="form" :rules="rules" ref="form" inline>
<el-form-item label="算法等级" prop="algorithmLevel">
<el-select
v-model="form.algorithmLevel"
placeholder="请选择等级"
style="width: 100%"
>
<el-option
v-for="dict in dict.type.algorithm_level"
:key="dict.value"
:label="dict.label"
:value="parseInt(dict.value)"
/>
</el-select>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="editDialogVisible = false">取 消</el-button>
<el-button type="primary" @click="handleEditConfirm">确 定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {
getAlgorithmList,
addAlgorithm,
updateAlgorithm,
delAlgorithm,
} from "@/api/business/algorithmconfig.js";
export default {
dicts: ["algorithm_level"],
name: "AlgorithmConfig",
props: {},
components: {},
......@@ -60,17 +101,59 @@ export default {
pageNum: 1,
pageSize: 10,
},
editDialogVisible: false,
form: {
algorithmId: null,
algorithmLevel: null,
},
rules: {
algorithmLevel: [
{ required: true, message: "请选择算法等级", trigger: "change" },
],
},
};
},
computed: {},
watch: {},
created() {},
created() {
this.getList();
},
mounted() {},
methods: {
//编辑
tableEdit(row) {},
//获取列表
getList() {
//获取列表
getAlgorithmList(this.queryParams).then((res) => {
if (res.code == 200) {
this.tableList = res.rows;
this.total = res.total;
} else {
this.$modal.msgError(res.msg);
}
});
},
// 编辑按钮点击事件
tableEdit(row) {
this.form = {
algorithmId: row.algorithmId,
algorithmLevel: Number(row.algorithmLevel),
};
this.editDialogVisible = true;
},
// 确认修改方法
handleEditConfirm() {
this.$refs.form.validate((valid) => {
if (!valid) return;
updateAlgorithm(data).then((res) => {
if (res.code === 200) {
this.$modal.msgSuccess("修改成功");
this.getList();
this.editDialogVisible = false;
}
});
});
},
},
};
......
......@@ -17,7 +17,8 @@
</div>
<el-tree
:data="data"
node-key="id"
node-key="positionId"
:props="treeProps"
default-expand-all
:expand-on-click-node="false"
@node-click="handleClickChange"
......@@ -63,10 +64,19 @@
plain
size="mini"
@click="addCamera"
:disabled="clickId == null"
:disabled="clickData.positionId == null"
>
<i class="el-icon-plus el-icon--left"></i>新增摄像头</el-button
>
<el-tag
closable
type="success"
@close="closeTag"
v-if="clickData.positionName"
style="margin-left: 10px"
>
{{ clickData.positionName }}
</el-tag>
</el-col>
<el-col :span="6">
<span></span>
......@@ -98,25 +108,29 @@
empty-text
>
<el-table-column
prop="name"
prop="cameraName"
align="center"
label="名称"
></el-table-column>
<el-table-column
prop="address"
prop="cameraPosition"
align="center"
label="地址"
></el-table-column>
<el-table-column
prop="videoAdress"
prop="cameraAddress"
label="视频地址"
align="center"
></el-table-column>
<el-table-column
prop="imageUrl"
align="center"
label="图片地址"
></el-table-column>
<el-table-column prop="cameraImage" align="center" label="图片地址">
<template slot-scope="scope">
<image-preview
:src="scope.row.cameraImage"
:width="100"
:height="60"
/>
</template>
</el-table-column>
<el-table-column label="操作" width="200" align="center">
<template slot-scope="scope">
<el-button
......@@ -129,7 +143,7 @@
<el-button
type="text"
size="mini"
@click="tableDelete(scope.row)"
@click="tableDelete(scope.row.cameraId)"
>
删除
</el-button>
......@@ -159,28 +173,34 @@
label-width="100px"
size="mini"
>
<el-form-item label="摄像头位置" prop="address">
<el-form-item label="摄像头位置" prop="cameraPosition">
<el-input
:disabled="visibleType !== 'addAddress'"
v-model="form.address"
:disabled="
visibleType !== 'addPosition' && visibleType !== 'editPosition'
"
v-model="form.cameraPosition"
></el-input>
</el-form-item>
<el-form-item
v-if="visibleType === 'addCamera'"
v-if="visibleType === 'addCamera' || visibleType === 'editCamera'"
label="摄像头名称"
prop="name"
prop="cameraName"
>
<el-input v-model="form.name"></el-input>
<el-input v-model="form.cameraName"></el-input>
</el-form-item>
<el-form-item
v-if="visibleType === 'addCamera'"
v-if="visibleType === 'addCamera' || visibleType === 'editCamera'"
label="视频地址"
prop="videoAdress"
prop="cameraAddress"
>
<el-input v-model="form.videoAdress"></el-input>
<el-input v-model="form.cameraAddress"></el-input>
</el-form-item>
<el-form-item v-if="visibleType === 'addCamera'" label="摄像头封面">
<ImageUpload />
<el-form-item
v-if="visibleType === 'addCamera' || visibleType === 'editCamera'"
label="摄像头封面"
prop="cameraImage"
>
<image-upload :value="form.cameraImage" @input="getImageUrl" />
</el-form-item>
</el-form>
......@@ -193,56 +213,59 @@
</template>
<script>
import {
getCameraList,
addCamera,
updateCamera,
delCamera,
getCameraPositionList,
addCameraPosition,
updateCameraPosition,
delCameraPosition,
} from "@/api/business/cameraconfig.js";
export default {
name: "Cameraconfig",
props: {},
components: {},
data() {
const data = [
{
id: 1,
label: "一级 1",
children: [
{
id: 4,
label: "二级 1-1",
children: [
{
id: 9,
label: "三级 1-1-1",
},
{
id: 10,
label: "三级 1-1-2",
},
],
},
],
},
];
return {
data: JSON.parse(JSON.stringify(data)),
data: [],
treeProps: {
// tree节点配置
label: "positionName",
children: "children",
},
id: 11,
dialogVisible: false,
visibleType: "addAddress", // 'addAddress' 或 'addCamera'
/**
* 新增摄像头 addCamera
* 新增摄像头位置 addPosition
* 编辑摄像头 editCamera
* 编辑摄像头位置 editPosition
*/
visibleType: "addPosition",
form: {
address: "",
cameraPosition: "",
cameraImage: "", // 确保初始化为空字符串而不是 null
},
rules: {
address: [
cameraPosition: [
{ required: true, message: "请输入摄像头地址", trigger: "blur" },
],
name: [
cameraName: [
{ required: true, message: "请输入摄像头名称", trigger: "blur" },
],
videoAdress: [
cameraAddress: [
{ required: true, message: "请输入视频地址", trigger: "blur" },
],
},
selectedData: null, // 新增变量,用于保存当前选中的节点数据
isEditing: false, // 新增编辑状态变量
state: "", // 搜索框的值
clickId: null, // 点击的id
clickData: {
positionId: null, // 点击的id
positionName: null, // 点击的名称
}, // 点击的id
/**table数据 */
total: 0,
queryParams: {
......@@ -254,83 +277,123 @@ export default {
},
computed: {},
watch: {},
created() {},
created() {
this.getCameraPositionList();
this.getList();
},
mounted() {},
methods: {
/**
* 树状操作部分
*/
getCameraPositionList() {
getCameraPositionList().then((res) => {
this.data = res.data;
});
},
// 添加摄像头位置
append(data) {
this.dialogVisible = true;
this.selectedData = data; // 保存当前操作的节点数据
this.visibleType = "addPosition"; // 设置为添加摄像头位置
this.form.cameraPosition = ""; // 清空表单数据
},
//编辑
edit(node, data) {
this.isEditing = true;
this.dialogVisible = true;
this.selectedData = data; // 保存当前操作的节点数据
this.form.address = data.label; // 编辑时填充表单数据
this.form.cameraPosition = data.positionName; // 编辑时填充表单数据
this.visibleType = "editPosition"; // 设置为编辑摄像头位置
},
//删除
remove(node, data) {
const parent = node.parent;
const children = parent.data.children || parent.data;
const index = children.findIndex((d) => d.id === data.id);
children.splice(index, 1);
},
// 添加节点逻辑统一处理
handleAddNode(parent, newChild) {
if (!parent) {
this.data.push(newChild);
return;
}
if (!parent.children) {
this.$set(parent, "children", []);
}
parent.children.push(newChild);
},
// 确认操作拆分
handleConfirmAdd() {
const newChild = {
id: this.id++,
label: this.form.address,
children: [],
};
this.handleAddNode(this.selectedData, newChild);
delCameraPosition(data.positionId).then((res) => {
if (res.code === 200) {
this.getCameraPositionList();
} else {
this.$modal.msgError(res.msg);
}
});
},
// 弹窗状态重置
resetForm() {
this.dialogVisible = false;
this.form = { address: "" };
this.form = { cameraPosition: "" };
this.selectedData = null;
this.isEditing = false;
},
// 优化后的确认方法
conform() {
this.$refs.form.validate((valid) => {
if (!valid) return;
if (this.isEditing) {
this.$set(this.selectedData, "label", this.form.address);
} else {
this.handleConfirmAdd();
//新增摄像头信息
if (this.visibleType === "addCamera") {
addCamera({ ...this.form }).then((res) => {
if (res.code === 200) {
this.$modal.msgSuccess("添加成功");
this.getList();
} else {
this.$modal.msgError(res.msg);
}
});
}
//编辑摄像头信息
if (this.visibleType === "editCamera") {
updateCamera({ ...this.form }).then((res) => {
if (res.code === 200) {
this.$modal.msgSuccess("编辑成功");
this.getList();
} else {
this.$modal.msgError(res.msg);
}
});
}
//新增摄像头位置
if (this.visibleType === "addPosition") {
// this.handleConfirmAdd();
let param = {
cameraPosition: this.form.cameraPosition,
parentId: this.clickData.positionId,
};
addCameraPosition(param).then((res) => {
if (res.code === 200) {
this.getCameraPositionList();
} else {
this.$modal.msgError(res.msg);
}
});
}
//编辑摄像头位置
if (this.visibleType === "editPosition") {
let param = {
cameraPosition: this.form.cameraPosition,
positionId: this.clickData.positionId,
};
updateCameraPosition({ ...param }).then((res) => {
if (res.code === 200) {
this.getCameraPositionList();
} else {
this.$modal.msgError(res.msg);
}
});
}
this.resetForm();
});
},
// 保持原有递归方法但简化实现
updateNodeById(nodes, targetId, newLabel) {
nodes.some((node) => {
if (node.id === targetId) return (node.label = newLabel);
return (
node.children &&
this.updateNodeById(node.children, targetId, newLabel)
);
});
},
//选中的tree数据
handleClickChange(data, checked, indeterminate) {
this.clickId = data.id;
this.clickData = data;
this.getList();
},
closeTag() {
this.clickData = {
positionId: null, // 点击的id
positionName: null, // 点击的名称
};
this.getList();
},
getImageUrl(val) {
this.form.cameraImage = val;
},
/**
* 表格操作部分
......@@ -354,24 +417,46 @@ export default {
//新增摄像头
addCamera() {
this.visibleType = "addCamera";
this.form.cameraPosition = this.clickData.positionName;
this.form.positionId = this.clickData.positionId;
this.dialogVisible = true;
},
//导出按钮操作
handleExport() {
this.download(
"system/post/export",
"/system/cameraConfig/export",
{
...this.queryParams,
},
`post_${new Date().getTime()}.xlsx`
`摄像头列表_${new Date().getTime()}.xlsx`
);
},
//获取表格数据
getList() {},
getList() {
getCameraList({
...this.queryParams,
positionId: this.clickData.positionId,
}).then((res) => {
this.tableList = res.rows;
this.total = res.total;
});
},
//表格编辑
tableEdit() {},
tableEdit(data) {
this.form = { ...data };
this.dialogVisible = true;
this.visibleType = "editCamera";
},
//表格删除
tableDelete() {},
tableDelete(id) {
delCamera(id).then((res) => {
if (res.code === 200) {
this.getList();
} else {
this.$modal.msgError(res.msg);
}
});
},
},
};
</script>
......
<template>
<div :class="className" :style="{height:height,width:width}" />
<div :class="className" :style="{ height: height, width: width }" />
</template>
<script>
import * as echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
import * as echarts from "echarts";
require("echarts/theme/macarons"); // echarts theme
import resize from "./mixins/resize";
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
default: "chart",
},
width: {
type: String,
default: '100%'
default: "100%",
},
height: {
type: String,
default: '300px'
}
default: "300px",
},
},
data() {
return {
chart: null
}
chart: null,
};
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return
return;
}
this.chart.dispose()
this.chart = null
this.chart.dispose();
this.chart = null;
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart = echarts.init(this.$el, "macarons");
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
trigger: "item",
formatter: "{a} <br/>{b} : {c} ({d}%)",
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
left: "center",
top: "5%",
data: ["已启动", "未启动"],
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
name: "监控摄像头",
type: "pie",
radius: ["45%", "75%"],
center: ["50%", "55%"],
color: ["#67C23A", "#F56C6C"], // 新增颜色数组配置
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
{ value: 320, name: "已启动" },
{ value: 240, name: "未启动" },
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 10,
borderColor: "#fff",
borderWidth: 2,
},
emphasis: {
label: {
show: true,
fontSize: 40,
fontWeight: "bold",
},
},
label: {
position: "center",
},
},
],
});
},
},
};
</script>
......@@ -34,12 +34,18 @@ export default {
}
},
initListener() {
// 创建防抖的resize事件处理器(100ms延迟)
this.$_resizeHandler = debounce(() => {
this.resize()
this.resize() // 触发图表重绘
}, 100)
// 监听窗口resize事件
window.addEventListener('resize', this.$_resizeHandler)
// 获取侧边栏DOM元素
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
// 监听侧边栏过渡动画结束事件(当侧边栏展开/折叠时)
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
destroyListener() {
......
......@@ -18,18 +18,30 @@
<div class="status-container">
<h3 class="status-title">视频分析任务启动状态</h3>
<div class="status-group">
<div class="status-item">
<bar-chart />
<div class="status-item" style="height: 300px">
<pie-chart />
</div>
</div>
</div>
</el-col>
<el-col :span="13">
<el-card
shadow="hover"
:body-style="{ padding: '20px', height: 'calc(100vh - 200px)' }"
>
</el-card>
<div class="status-container">
<h3 class="status-title both-end">
<span
><span>{{ selectVidoe.name }}</span
><span>正在查看</span></span
>
<el-select v-model="selectVidoe" value-key="url" placeholder="">
<el-option
v-for="item in videoList"
:key="item.id"
:label="item.name"
:value="item"
></el-option>
</el-select>
</h3>
<div class="video-box"></div>
</div>
</el-col>
<el-col :span="6">
<el-card
......@@ -43,12 +55,20 @@
</template>
<script>
import { barChart } from "./dashboard/BarChart";
import PieChart from "./dashboard/PieChart.vue";
export default {
name: "Index",
components: { barChart },
components: { PieChart },
data() {
return {};
return {
selectVidoe: {}, // 选择视频
videoList: [
// 视频列表
{ name: "视频1", url: "URL_ADDRESS ", id: 1 },
{ name: "视频2", url: "URL_ADDRESS:8080/video1.mp4", id: 2 },
{ name: "视频3", url: "URL_ADDRESSlhost:8080/video1.mp4", id: 3 },
],
};
},
methods: {},
};
......@@ -68,27 +88,28 @@ export default {
background: #f8f9fa;
border-radius: 5px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
.status-title {
margin: 0 0 20px 0;
font-size: 16px;
color: #333;
.title-icon {
margin-right: 8px;
font-size: 20px;
color: #409eff;
}
}
.both-end {
display: flex;
justify-content: space-between;
align-items: center;
}
.status-group {
display: flex;
gap: 20px;
.status-item {
flex: 1;
text-align: center;
.count {
font-size: 32px;
font-weight: bold;
......@@ -102,11 +123,9 @@ export default {
color: #f56c6c;
}
}
.label {
font-size: 14px;
color: #666;
.svg-icon {
vertical-align: middle;
margin-right: 5px;
......@@ -115,6 +134,11 @@ export default {
}
}
}
.video-box {
height: 440px;
width: 100%;
background: #409eff;
}
}
}
</style>
......@@ -29,10 +29,10 @@ module.exports = {
productionSourceMap: false,
transpileDependencies: ['quill'],
// webpack-dev-server 相关配置
hot: true,
headers: {
'Cache-Control': 'no-store'
},
// hot: true,
// headers: {
// 'Cache-Control': 'no-store'
// },
devServer: {
host: '0.0.0.0',
port: port,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment