Commit 92ecdb7d authored by 胡占生's avatar 胡占生 🇨🇳

Merge branch 'developer' of http://git.censoft.com.cn/ai-yunshou/ai-yunshou-vue into developer

parents 951203a4 4c844266
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
"element-plus": "^2.7.6", "element-plus": "^2.7.6",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.6.2", "fuse.js": "6.6.2",
"html2canvas": "^1.4.1",
"js-cookie": "3.0.5", "js-cookie": "3.0.5",
"jsencrypt": "3.3.2", "jsencrypt": "3.3.2",
"moment": "^2.30.1", "moment": "^2.30.1",
......
<template> <template>
<el-dialog v-model="algorithmManage.visible.value" width="60%" append-to-body> <el-dialog v-model="algorithmManage.visible.value" width="70%" append-to-body>
<template v-slot:header> <template v-slot:header>
<div <div
class="cleartitle" class="cleartitle"
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
<span>{{ title }}</span> <span>{{ title }}</span>
</div> </div>
</template> </template>
<el-row> <el-row class="row-box">
<el-col :span="12"> <el-col :span="12">
<el-row :gutter="10" class="mb8" style="justify-content: space-between"> <el-row :gutter="10" class="mb8" style="justify-content: space-between">
<el-col :span="1.5"> <el-col :span="1.5">
...@@ -32,9 +32,31 @@ ...@@ -32,9 +32,31 @@
:model="unref(algorithmManage.form)" :model="unref(algorithmManage.form)"
:rules="rules" :rules="rules"
label-position="left" label-position="left"
label-width="100px" label-width="110px"
class="demo-form-inline" class="demo-form-inline"
> >
<el-form-item
label="区域管理"
prop="deviceId"
v-if="unref(device.list).length"
>
<el-cascader
style="width: 100%"
v-model="unref(algorithmManage.form).regionalId"
:options="areaManger.list.value"
:props="{
children: 'children',
value: 'id',
checkStrictly: true,
}"
placeholder="请选择上级区域"
clearable
@change="handleChange"
/>
</el-form-item>
<el-form-item label="点位名称" prop="locationName">
<el-input v-model="unref(algorithmManage.form).locationName" />
</el-form-item>
<el-form-item <el-form-item
label="摄像头名称" label="摄像头名称"
prop="deviceId" prop="deviceId"
...@@ -54,7 +76,7 @@ ...@@ -54,7 +76,7 @@
</el-select> </el-select>
</el-form-item> </el-form-item>
<!-- RTSP地址 --> <!-- RTSP地址 -->
<el-form-item label="RTSP地址" prop="vedioUrl"> <el-form-item label="RTSP地址" prop="videoUrl">
<el-input <el-input
v-model="unref(algorithmManage.form).videoUrl" v-model="unref(algorithmManage.form).videoUrl"
readonly readonly
...@@ -70,10 +92,14 @@ ...@@ -70,10 +92,14 @@
/> />
</el-form-item> </el-form-item>
<el-form-item label="重新拉流时间" prop="reStreamingTime"> <el-form-item label="重新拉流时间" prop="reStreamingTime">
<el-date-picker <el-input v-model="unref(algorithmManage.form).reStreamingTime"
v-model="unref(algorithmManage.form).reStreamingTime" ><template #suffix>/秒</template></el-input
type="datetime" >
/> </el-form-item>
<el-form-item label="拉流间隔时间" prop="inferenceInterval">
<el-input v-model="unref(algorithmManage.form).inferenceInterval"
><template #suffix>/秒</template></el-input
>
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
...@@ -84,6 +110,7 @@ ...@@ -84,6 +110,7 @@
unref(algorithmManage.form).aiRegionalLocationList || unref(algorithmManage.form).aiRegionalLocationList ||
aiAlgorithm.list.value aiAlgorithm.list.value
" "
height="200px"
> >
<el-table-column <el-table-column
label="算法名称" label="算法名称"
...@@ -118,7 +145,7 @@ ...@@ -118,7 +145,7 @@
<el-button <el-button
link link
type="primary" type="primary"
@click="aiConfig(scope.$index,scope.row)" @click="aiConfig(scope.$index, scope.row)"
v-hasPermi="['system:post:remove']" v-hasPermi="['system:post:remove']"
>配置</el-button >配置</el-button
> >
...@@ -127,7 +154,7 @@ ...@@ -127,7 +154,7 @@
</el-table> </el-table>
</div> </div>
</el-col> </el-col>
<el-col :span="11" :offset="1" class="right-draw"> <el-col :span="11" :offset="1" class="right-draw" id="video-box">
<div> <div>
<el-button <el-button
@click="getPhoto" @click="getPhoto"
...@@ -135,27 +162,12 @@ ...@@ -135,27 +162,12 @@
>拍照取图</el-button >拍照取图</el-button
> >
<el-button @click="getNewPhoto" v-else>重新取图</el-button> <el-button @click="getNewPhoto" v-else>重新取图</el-button>
<el-button @click="clearDraw">重绘标记</el-button> <el-button type="primary" @click="clearDraw">重绘标记</el-button>
<el-button @click="++drawIndex">重绘下一个</el-button> <el-button type="primary" @click="++drawIndex">重绘下一个</el-button>
</div> </div>
<div class="right-draw-content"> <div class="right-draw-content">
<img <template v-if="algorithmManage.form.value.liveMap">
v-if="algorithmManage.form.value.liveMap" <svg @click="pointDraw" v-if="drawId" class="drawSvg">
:src="algorithmManage.form.value.liveMap"
class="drawImg"
alt=""
/>
<template v-else>
<video controls ref="videoEle" class="drawImg">
<source src="@/assets/movie.mp4" type="video/mp4" />
</video>
<canvas id="canvas"></canvas>
</template>
<svg
@click="pointDraw"
v-if="drawId && algorithmManage.form.value.liveMap"
class="drawSvg"
>
<title>多边形</title> <title>多边形</title>
<polygon <polygon
:fill="item.fill" :fill="item.fill"
...@@ -166,6 +178,13 @@ ...@@ -166,6 +178,13 @@
:key="item.key" :key="item.key"
/> />
</svg> </svg>
<img :src="ImgUrl" class="drawImg" alt="" />
</template>
<template v-else>
<!-- v-else -->
<canvas id="video-canvas" class="drawImg"></canvas>
<canvas id="canvas" style="display: none"></canvas>
</template>
</div> </div>
<div class="right"> <div class="right">
<el-button type="primary" @click="submit">确认</el-button> <el-button type="primary" @click="submit">确认</el-button>
...@@ -176,7 +195,11 @@ ...@@ -176,7 +195,11 @@
</el-col> </el-col>
</el-row> </el-row>
</el-dialog> </el-dialog>
<el-dialog :title="unref(aiAlgorithm.form).algorithmName" v-model="aiAlgorithm.visible.value" width="50%"> <el-dialog
:title="unref(aiAlgorithm.form).algorithmName"
v-model="aiAlgorithm.visible.value"
width="50%"
>
<el-form <el-form
ref="algorithmManage.formRef" ref="algorithmManage.formRef"
:model="aiAlgorithm.form" :model="aiAlgorithm.form"
...@@ -203,13 +226,51 @@ ...@@ -203,13 +226,51 @@
<el-form-item label="标签阈值" prop="labelThreshold"> <el-form-item label="标签阈值" prop="labelThreshold">
<el-input v-model="unref(aiAlgorithm.form).labelThreshold" /> <el-input v-model="unref(aiAlgorithm.form).labelThreshold" />
</el-form-item> </el-form-item>
<el-table :data="wrapList" > <el-table :data="unref(aiAlgorithmLabel.list)" class="labels-table">
<el-table-column label="识别标签" align="center" prop="md5Result" /> <el-table-column label="识别标签" align="center" prop="remark" />
<el-table-column label="标签阈值" align="center" prop="fileSize" /> <el-table-column label="标签阈值" align="center" prop="labelThreshold">
<el-table-column label="状态" align="center" prop="postSort" />
<el-table-column label="操作" width="180" align="center" class-name="small-padding fixed-width">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:post:edit']">修改</el-button> <span v-if="scope.row.isEdit">
<template v-if="unref(algorithmManage.form).id">
<el-input
v-model="unref(aiAlgorithmLabel.form).labelThreshold"
placeholder="请输入标签阈值"
/>
</template>
<template v-else>
<el-input
v-model="scope.row.labelThreshold"
placeholder="请输入标签阈值"
/>
</template>
</span>
<span v-else>{{ scope.row.labelThreshold }}</span>
</template>
</el-table-column>
<el-table-column label="状态" align="center" prop="postSort">
<template #default="scope">
<el-switch
v-model="scope.row.status"
:active-value="1"
:inactive-value="0"
@change="(e, e1) => changeStatus(scope.row, e, e1)"
/>
</template>
</el-table-column>
<el-table-column
label="操作"
width="180"
align="center"
class-name="small-padding fixed-width"
>
<template #default="scope">
<el-button
link
type="primary"
@click="aiAlgorithmLabelEdit(scope.row, scope.$index)"
v-hasPermi="['system:post:edit']"
>{{ scope.row.isEdit ? "确定" : "修改阈值" }}</el-button
>
<!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']">删除</el-button> --> <!-- <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:post:remove']">删除</el-button> -->
</template> </template>
</el-table-column> </el-table-column>
...@@ -226,26 +287,129 @@ ...@@ -226,26 +287,129 @@
</template> </template>
<script setup> <script setup>
import { reactify } from "@vueuse/core"; import { computed, onMounted, ref, unref, watch } from "vue";
import { onMounted, ref, unref } from "vue"; const { algorithmManage, areaManger } = defineProps({
const { algorithmManage } = defineProps({ algorithmManage: Object }); algorithmManage: Object,
areaManger: Object,
});
import { useIndex } from "../hooks"; import { useIndex } from "../hooks";
import { colors, drawImage } from "../utils"; import { colors, base64ToFile } from "../utils";
import request from "@/utils/request";
import "@/utils/jsmpeg.min";
const device = useIndex({ const device = useIndex({
list: "/yunshou/aiDevice/list", list: "/yunshou/aiDevice/list",
}); });
const aiAlgorithm = useIndex({ const aiAlgorithm = useIndex(
{
list: "/yunshou/aiAlgorithmConfig/list", list: "/yunshou/aiAlgorithmConfig/list",
detail: "/yunshou/aiAlgorithmConfig/", detail: "/yunshou/aiAlgorithmConfig/",
},
() => {},
null,
false
);
onMounted(() => {
aiAlgorithm.search.value.algorithmStatus = 0;
aiAlgorithm.getList();
}); });
const rules = {
// 区域管理
regionalId: [{ required: true, message: "请选择上级区域" }],
locationName: [
{ required: true, message: "请输入点位名称", trigger: "blur" },
],
// 摄像头名称
deviceId: [{ required: true, message: "请选择摄像头", trigger: "change" }],
// RTSP地址
videoUrl: [{ required: true, message: "请输入RTSP地址", trigger: "blur" }],
// // 是否重新拉流
// restartFlow: [
// { required: true, message: "请选择是否重新拉流", trigger: "change" },
// ],
// 是否重新拉流
videoUrl: [{ required: true, message: "请输入视频流" }],
// 重新拉流时间
reStreamingTime: [
{ required: true, message: "请输入重新拉流时间", trigger: "blur" },
],
// 拉流间隔时间
inferenceInterval: [
{ required: true, message: "请输入拉流间隔时间", trigger: "blur" },
],
};
const algLevelRef = ref(null);
watch(
() => algorithmManage.visible.value,
() => {
if (algorithmManage.visible.value) {
setTimeout(() => {
algLevelRef.value.resetFields();
algorithmManage.form.value = {
regionalId: algorithmManage.search.value.regionalId,
};
});
}
}
);
const isEdit = false;
let aiAlgorithmLabel = useIndex(
//新增调用算法label
{
list: "/yunshou/aiAlgorithmLabel/list",
detail: "/yunshou/aiAlgorithmLabel/",
edit: "/yunshou/aiAlgorithmLabel/",
},
() => {},
null,
false
);
watch(
() => algorithmManage.form.value,
(e) => {
aiAlgorithmLabel = useIndex(
//编辑调用当前标签的label
{
list: "/yunshou/aiRegionalLocationAlgorithmLabel/list",
detail: "/yunshou/aiRegionalLocationAlgorithmLabel/",
edit: "/yunshou/aiRegionalLocationAlgorithmLabel",
},
() => {},
null,
false
);
}
);
function handleDeviceChange(e, index) { function handleDeviceChange(e, index) {
const d = device.list.value.find((x) => x.id == e); const d = device.list.value.find((x) => x.id == e);
algorithmManage.form.value.videoUrl = d.videoUrl; algorithmManage.form.value.videoUrl = d.videoUrl;
getVideos();
} }
onMounted(() => {
getVideos();
});
const ImgUrl = computed(() => {
const url = algorithmManage.form.value.liveMap;
if (url) {
// 是否为base64
if (url.indexOf("data:image/png;base64") != -1) {
return url;
} else {
return import.meta.env.VITE_IMG_BASE_PATH + url;
}
}
return "";
});
function submit() { function submit() {
algLevelRef.value.validate(async (valid) => {
if (valid) {
let algorithms = []; let algorithms = [];
algorithmManage.form.value.runningState = '0'; algorithmManage.form.value.runningState = "0";
if (algorithmManage.form.value.liveMap) {
await toUpload(); //上传图片
}
if (algorithmManage.form.value.id) { if (algorithmManage.form.value.id) {
algorithms = unref(algorithmManage.form).aiRegionalLocationList; algorithms = unref(algorithmManage.form).aiRegionalLocationList;
} else { } else {
...@@ -264,9 +428,44 @@ function submit() { ...@@ -264,9 +428,44 @@ function submit() {
} }
algorithmManage.form.value.algorithms = algorithms; algorithmManage.form.value.algorithms = algorithms;
algorithmManage.toSubmit(); algorithmManage.toSubmit();
}
});
}
function aiAlgorithmLabelEdit(scope) {
if (algorithmManage.form.value.id) {
//编辑调用当前标签的label
if (!scope.isEdit) {
aiAlgorithmLabel.toEdit(scope);
}
if (scope.isEdit) {
aiAlgorithmLabel.toSubmit();
}
} else {
}
scope.isEdit = !scope.isEdit;
}
function toUpload() {
if (
algorithmManage.form.value.liveMap.indexOf("data:image/png;base64") == -1
) {
return Promise.resolve();
}
const file = base64ToFile(algorithmManage.form.value.liveMap);
const formData = new FormData();
formData.append("file", file);
return request({
url: "/common/upload",
method: "post",
data: formData,
headers: {
"Content-Type": "multipart/form-data",
},
}).then((res) => {
algorithmManage.form.value.liveMap = res.fileName;
});
} }
const configIndex = ref(0); const configIndex = ref(0);
function aiConfig(index,e) { function aiConfig(index, e) {
configIndex.value = index; configIndex.value = index;
const current = unref(aiAlgorithm.list)[index]; const current = unref(aiAlgorithm.list)[index];
aiAlgorithm.form.value = algorithmManage.form.value.id aiAlgorithm.form.value = algorithmManage.form.value.id
...@@ -275,6 +474,39 @@ function aiConfig(index,e) { ...@@ -275,6 +474,39 @@ function aiConfig(index,e) {
algorithmName: current.algorithmName, algorithmName: current.algorithmName,
}; };
aiAlgorithm.visible.value = true; aiAlgorithm.visible.value = true;
if (algorithmManage.form.value.id) {
aiAlgorithmLabel.search.value.regionalLocationAlgorithmId = e.id;
} else {
aiAlgorithmLabel.search.value.algorithmId = e.id;
}
aiAlgorithmLabel.search.value.showStatus = 0;
aiAlgorithmLabel.getList().then(() => {
if (current.params) {
aiAlgorithm.form.value = {
...current.params,
...unref(aiAlgorithm.form),
};
if (current.params.labels) {
//编辑标签
current.params.labels.forEach((x) => {
const index = unref(aiAlgorithmLabel.list).findIndex(
(y) => y.id == x.id
);
if (index > -1) {
unref(aiAlgorithmLabel.list)[index].labelThreshold =
x.labelThreshold;
unref(aiAlgorithmLabel.list)[index].isEdit = false;
unref(aiAlgorithmLabel.list)[index].status = x.status;
}
});
}
}
});
}
function changeStatus(scope, e, e1) {
scope.isEdit = false; //通过isEdit来判断是否发生变化
aiAlgorithmLabel.editSubmit(scope);
} }
// 确认配置 // 确认配置
function sureConfig() { function sureConfig() {
...@@ -287,7 +519,11 @@ function sureConfig() { ...@@ -287,7 +519,11 @@ function sureConfig() {
...unref(aiAlgorithm.form), ...unref(aiAlgorithm.form),
}; };
} else { } else {
const labels = unref(aiAlgorithmLabel.list).filter((x) => "isEdit" in x);
unref(aiAlgorithm.list)[configIndex.value].params = unref(aiAlgorithm.form); unref(aiAlgorithm.list)[configIndex.value].params = unref(aiAlgorithm.form);
unref(aiAlgorithm.list)[configIndex.value].params.labels = labels.map((x) =>
unref(x)
);
} }
aiAlgorithm.toClose(); aiAlgorithm.toClose();
} }
...@@ -295,16 +531,47 @@ let drawId = ref(); ...@@ -295,16 +531,47 @@ let drawId = ref();
let drawIndex = ref(0); let drawIndex = ref(0);
const graph = reactive({}); const graph = reactive({});
const videoEle = ref(null); const isPhoto = ref(false);
function getPhoto() { function getPhoto() {
algorithmManage.form.value.liveMap = drawImage(videoEle.value); isPhoto.value = true;
} }
let player;
function getVideos() {
let canvas = document.getElementById("video-canvas");
let url = algorithmManage.form.value.videoUrl;
if (player) {
player.destroy();
player = null;
}
player = new JSMpeg.Player("ws://192.168.4.232:9999/rtsp?url=" + btoa(url), {
canvas: canvas,
disableGl: true,
onVideoDecode: function (decoder, time) {
// 视频帧解码后立即截图
if (isPhoto.value) {
var url = canvas.toDataURL("image/png");
algorithmManage.form.value.liveMap = url;
isPhoto.value = false;
}
// 可以在这里保存图片或者进行其他操作
},
});
}
/* 重新取图 */ /* 重新取图 */
function getNewPhoto() { function getNewPhoto() {
unref(algorithmManage.form).liveMap = ""; unref(algorithmManage.form).liveMap = "";
for (let key in graph) { for (let key in graph) {
graph[key] = []; graph[key] = [];
} }
if (unref(algorithmManage.form).id) {
unref(algorithmManage.form).aiRegionalLocationList.forEach((x) => {
x.drawingArea = [];
});
}
setTimeout(() => {
getVideos();
});
} }
function beginDraw(e) { function beginDraw(e) {
drawId.value = e.id; drawId.value = e.id;
...@@ -340,6 +607,10 @@ function pointDraw(e) { ...@@ -340,6 +607,10 @@ function pointDraw(e) {
border-radius: 5px; border-radius: 5px;
padding: 0; padding: 0;
} }
.left-list {
flex: 1;
overflow: auto;
}
.form-title::before { .form-title::before {
content: ""; content: "";
display: inline-block; display: inline-block;
...@@ -352,6 +623,7 @@ function pointDraw(e) { ...@@ -352,6 +623,7 @@ function pointDraw(e) {
.drawImg { .drawImg {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: fill;
} }
.right { .right {
text-align: right; text-align: right;
...@@ -362,6 +634,7 @@ function pointDraw(e) { ...@@ -362,6 +634,7 @@ function pointDraw(e) {
gap: 20px; gap: 20px;
.right-draw-content { .right-draw-content {
position: relative; position: relative;
height: 500px;
svg { svg {
position: absolute; position: absolute;
left: 0; left: 0;
...@@ -371,4 +644,11 @@ function pointDraw(e) { ...@@ -371,4 +644,11 @@ function pointDraw(e) {
} }
} }
} }
.row-box {
height: 620px;
}
.labels-table {
height: 200px;
margin-bottom: 20px;
}
</style> </style>
\ No newline at end of file
import { onMounted, ref, watch } from "vue"; import { onMounted, ref, watch } from "vue";
import request from "@/utils/request"; import request from "@/utils/request";
import { ElMessageBox } from "element-plus"; import { ElMessageBox } from "element-plus";
function useIndex(apis, callback, listReady, immList = true ) { function useIndex(apis, callback, listReady, immList = true) {
const visible = ref(false); const visible = ref(false);
const search = ref({}); const search = ref({});
const form = ref({ const form = ref({
...@@ -51,7 +51,7 @@ function useIndex(apis, callback, listReady, immList = true ) { ...@@ -51,7 +51,7 @@ function useIndex(apis, callback, listReady, immList = true ) {
}); });
} }
function getList(params, isFirst) { function getList(params, isFirst) {
request({ return request({
url: apis.list, url: apis.list,
method: "get", method: "get",
params: { ...params, ...page.value, ...search.value }, params: { ...params, ...page.value, ...search.value },
...@@ -73,6 +73,20 @@ function useIndex(apis, callback, listReady, immList = true ) { ...@@ -73,6 +73,20 @@ function useIndex(apis, callback, listReady, immList = true ) {
return res; return res;
}); });
} }
function editSubmit(data) {
request({
url: apis.edit,
method: "put",
data,
}).then((res) => {
if (immclose) {
visible.value = false;
getList();
}
resolve();
});
}
function toSubmit(immclose = true) { function toSubmit(immclose = true) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if (form.value.id) { if (form.value.id) {
...@@ -129,9 +143,8 @@ function useIndex(apis, callback, listReady, immList = true ) { ...@@ -129,9 +143,8 @@ function useIndex(apis, callback, listReady, immList = true ) {
getList, getList,
toOpen, toOpen,
search, search,
editSubmit
}; };
} }
export { useIndex }; export { useIndex };
...@@ -88,6 +88,11 @@ ...@@ -88,6 +88,11 @@
align="center" align="center"
prop="deviceName" prop="deviceName"
/> />
<el-table-column
label="点位名称"
align="center"
prop="locationName"
/>
<el-table-column <el-table-column
label="所属区域" label="所属区域"
align="center" align="center"
...@@ -126,7 +131,7 @@ ...@@ -126,7 +131,7 @@
v-model="scope.row.runningState" v-model="scope.row.runningState"
active-value="0" active-value="0"
inactive-value="1" inactive-value="1"
@change="(e)=>changeState(scope.row, e)" @change="(e) => changeState(scope.row, e)"
/> />
</template> </template>
</el-table-column> </el-table-column>
...@@ -169,7 +174,13 @@ ...@@ -169,7 +174,13 @@
</el-scrollbar> </el-scrollbar>
</el-col> </el-col>
</el-row> </el-row>
<drawPoint ref="drawPointRef" :algorithmManage="algorithmManage" /> <template v-if="algorithmManage.visible.value">
<drawPoint
ref="drawPointRef"
:algorithmManage="algorithmManage"
:areaManger="areaManger"
/>
</template>
<el-dialog <el-dialog
title="新增区域" title="新增区域"
v-model="areaManger.visible.value" v-model="areaManger.visible.value"
...@@ -185,7 +196,6 @@ ...@@ -185,7 +196,6 @@
:props="{ children: 'children', value: 'id', checkStrictly: true }" :props="{ children: 'children', value: 'id', checkStrictly: true }"
placeholder="请选择上级区域" placeholder="请选择上级区域"
clearable clearable
@change="handleChange"
/> />
</el-form-item> </el-form-item>
<el-form-item label="区域名称" prop="regionName"> <el-form-item label="区域名称" prop="regionName">
...@@ -362,7 +372,7 @@ const areaManger = useIndex( ...@@ -362,7 +372,7 @@ const areaManger = useIndex(
(data) => { (data) => {
algorithmManage.form.value.regionalId = data[0].id; algorithmManage.form.value.regionalId = data[0].id;
algorithmManage.search.value.regionalId = data[0].id; algorithmManage.search.value.regionalId = data[0].id;
algorithmManage.getList() algorithmManage.getList();
} }
); );
...@@ -375,7 +385,7 @@ const algorithmManage = useIndex( ...@@ -375,7 +385,7 @@ const algorithmManage = useIndex(
detail: "/yunshou/aiRegionalLocation/", detail: "/yunshou/aiRegionalLocation/",
}, },
({ data }) => {}, ({ data }) => {},
()=>{}, () => {},
false false
); );
function submitAreaForm(e) { function submitAreaForm(e) {
...@@ -392,21 +402,22 @@ function submitAreaForm(e) { ...@@ -392,21 +402,22 @@ function submitAreaForm(e) {
function handleNodeClick(e) { function handleNodeClick(e) {
algorithmManage.form.value.regionalId = e.id; algorithmManage.form.value.regionalId = e.id;
algorithmManage.search.value.regionalId = e.id; algorithmManage.search.value.regionalId = e.id;
algorithmManage.search.value.status = 0;
areaManger.form.value.id = e.id; areaManger.form.value.id = e.id;
algorithmManage.getList({ regionalId: e.id }); algorithmManage.getList({ regionalId: e.id });
} }
function changeState(data, e) { function changeState(data, e) {
request({ request({
url:'/yunshou/aiRegionalLocation/updateRunningState', url: "/yunshou/aiRegionalLocation/updateRunningState",
method:'POST', method: "POST",
data:{ data: {
id:data.id, id: data.id,
runningState:e runningState: e,
} },
}).then(()=>{ }).then(() => {
algorithmManage.getList({regionalId:data.regionalId}) algorithmManage.getList({ regionalId: data.regionalId });
}) });
} }
</script> </script>
......
...@@ -7,13 +7,31 @@ export const colors = () => { ...@@ -7,13 +7,31 @@ export const colors = () => {
return `rgba(${r},${g},${b},${a})`; return `rgba(${r},${g},${b},${a})`;
}; };
export function drawImage(video) {
export function drawImage(video){
const img = video; const img = video;
const canvas = document.getElementById('canvas'); const canvas = document.getElementById("canvas");
const ctx = canvas.getContext('2d'); const ctx = canvas.getContext("2d");
canvas.width = img.offsetWidth; canvas.width = img.offsetWidth;
canvas.height = img.offsetHeight; canvas.height = img.offsetHeight;
ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 绘制图片 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 绘制图片
return canvas.toDataURL("image/jpg") return canvas.toDataURL("image/jpg");
}
export function base64ToFile(base64) {
const name = new Date().getTime();
if (typeof base64 != "string") {
return;
}
var arr = base64.split(",");
var type = arr[0].match(/:(.*?);/)[1];
var fileExt = type.split("/")[1];
var bstr = atob(arr[1]);
var n = bstr.length;
var u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], `${name}.` + fileExt, {
type: type,
});
} }
...@@ -31,7 +31,8 @@ export default defineConfig(({ mode, command }) => { ...@@ -31,7 +31,8 @@ export default defineConfig(({ mode, command }) => {
proxy: { proxy: {
// https://cn.vitejs.dev/config/#server-proxy // https://cn.vitejs.dev/config/#server-proxy
'/dev-api': { '/dev-api': {
target: 'http://192.168.3.82/ai', target: 'http://192.168.3.82:80/ai',
// target: 'http://192.168.4.206:80/ai',
// target:'http://192.168.14.43:8111/ai', // target:'http://192.168.14.43:8111/ai',
changeOrigin: true, changeOrigin: true,
rewrite: (p) => p.replace(/^\/dev-api/, '') rewrite: (p) => p.replace(/^\/dev-api/, '')
......
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