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;
}
});
});
},
},
};
......
This diff is collapsed.
<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