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