Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
ai-yunshou-vue
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
AI云守
ai-yunshou-vue
Commits
89befeef
Commit
89befeef
authored
Aug 14, 2024
by
胡占生
🇨🇳
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'developer' of
http://git.censoft.com.cn/ai-yunshou/ai-yunshou-vue
into developer
parents
e48045d6
0dbe1947
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
830 additions
and
301 deletions
+830
-301
src/assets/movie.mp4
src/assets/movie.mp4
+0
-0
src/views/videoControl/pointControl/components/drawPoint.vue
src/views/videoControl/pointControl/components/drawPoint.vue
+331
-151
src/views/videoControl/pointControl/hooks/index.js
src/views/videoControl/pointControl/hooks/index.js
+131
-0
src/views/videoControl/pointControl/index.scss
src/views/videoControl/pointControl/index.scss
+20
-0
src/views/videoControl/pointControl/index.vue
src/views/videoControl/pointControl/index.vue
+327
-149
src/views/videoControl/pointControl/utils/index.js
src/views/videoControl/pointControl/utils/index.js
+19
-0
vite.config.js
vite.config.js
+2
-1
No files found.
src/assets/movie.mp4
0 → 100644
View file @
89befeef
File added
src/views/videoControl/pointControl/components/drawPoint.vue
View file @
89befeef
<
template
>
<el-dialog
v-model=
"open"
width=
"1000px"
append-to-body
>
<template
v-slot:header
>
<
div
class=
"cleartitle"
style=
"display: flex;justify-content: flex-start;align-items: center;"
>
<img
src=
"@/assets/images/logo_video.png"
width=
"25px"
alt=
""
>
<span>
{{
title
}}
</span>
</div>
</
template
>
<el-row>
<el-col
:span=
"12"
>
<el-row
:gutter=
"10"
class=
"mb8"
style=
"justify-content: space-between;
"
>
<el-dialog
v-model=
"algorithmManage.visible.value"
width=
"60%"
append-to-body
>
<template
v-slot:header
>
<div
class=
"cleartitle"
style=
"display: flex; justify-content: flex-start; align-items: center"
>
<
img
src=
"@/assets/images/logo_video.png"
width=
"25px"
alt=
""
/
>
<span>
{{
title
}}
</span>
</div>
</
template
>
<el-row>
<el-col
:span=
"12"
>
<el-row
:gutter=
"10"
class=
"mb8"
style=
"justify-content: space-between
"
>
<el-col
:span=
"1.5"
>
<div
class=
"form-title"
style=
"display: flex;justify-content: flex-start;align-items: center;"
>
<span>
基础信息
</span>
</div>
</el-col>
<el-col
:span=
"6.8"
style=
"display: flex;"
>
<div
class=
"form-title"
style=
"
display: flex;
justify-content: flex-start;
align-items: center;
"
>
<span>
基础信息
</span>
</div>
</el-col>
<el-col
:span=
"6.8"
style=
"display: flex"
>
</el-col>
</el-row>
<el-card
class=
"left-list"
>
<el-table
v-loading=
"loading"
:data=
"algLevelList"
>
<el-table-column
label=
"告警等级名称"
align=
"center"
prop=
"alarmName"
/>
<el-table-column
label=
"告警等级颜色"
align=
"center"
prop=
"alarmColor"
>
<div
class=
"left-form"
>
<el-form
ref=
"algLevelRef"
:model=
"unref(algorithmManage.form)"
:rules=
"rules"
label-position=
"left"
label-width=
"100px"
class=
"demo-form-inline"
>
<el-form-item
label=
"摄像头名称"
prop=
"deviceId"
v-if=
"unref(device.list).length"
>
<el-select
v-model=
"unref(algorithmManage.form).deviceId"
placeholder=
"请选择摄像头"
@
change=
"handleDeviceChange"
>
<el-option
v-for=
"item in unref(device.list)"
:key=
"item.id"
:label=
"item.deviceName"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<!-- RTSP地址 -->
<el-form-item
label=
"RTSP地址"
prop=
"vedioUrl"
>
<el-input
v-model=
"unref(algorithmManage.form).videoUrl"
readonly
/>
</el-form-item>
<el-form-item
label=
"是否重新拉流"
prop=
"restartFlow"
>
<el-switch
v-model=
"unref(algorithmManage.form).restartFlow"
inline-prompt
active-text=
"是"
inactive-text=
"否"
active-value=
"true"
/>
</el-form-item>
<el-form-item
label=
"重新拉流时间"
prop=
"reStreamingTime"
>
<el-date-picker
v-model=
"unref(algorithmManage.form).reStreamingTime"
type=
"datetime"
/>
</el-form-item>
</el-form>
</div>
<div
class=
"left-list"
>
<el-table
:data=
"
unref(algorithmManage.form).aiRegionalLocationList ||
aiAlgorithm.list.value
"
>
<el-table-column
label=
"算法名称"
align=
"center"
prop=
"algorithmName"
/>
<el-table-column
label=
"选择"
align=
"center"
prop=
"alarmColor"
>
<
template
#default
="
scope
"
>
<span>
<el-tag
type=
"success"
:style=
"
{backgroundColor: scope.row.alarmColor,width:'50px'}">
{{
}}
</el-tag>
<el-switch
v-model=
"scope.row.status"
active-value=
"0"
inactive-value=
"1"
></el-switch>
</span>
</
template
>
</el-table-column>
<el-table-column
label=
"告警等级展示方式"
align=
"center"
prop=
"alarmShowType"
/>
<el-table-column
label=
"操作"
width=
"180"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
icon=
"Edit"
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button>
<el-button
link
type=
"primary"
icon=
"Delete"
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['system:post:remove']"
>
删除
</el-button>
</
template
>
<el-table-column
label=
"识别区域"
width=
"180"
align=
"center"
class-name=
"small-padding fixed-width"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
@
click=
"beginDraw(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
绘制
</el-button
>
<el-button
link
type=
"primary"
@
click=
"aiConfig(scope.$index,scope.row)"
v-hasPermi=
"['system:post:remove']"
>
配置
</el-button
>
</
template
>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</el-dialog>
</div>
</el-col>
<el-col
:span=
"11"
:offset=
"1"
class=
"right-draw"
>
<div>
<el-button
@
click=
"getPhoto"
v-if=
"!algorithmManage.form.value.liveMap"
>
拍照取图
</el-button
>
<el-button
@
click=
"getNewPhoto"
v-else
>
重新取图
</el-button>
<el-button
@
click=
"clearDraw"
>
重绘标记
</el-button>
<el-button
@
click=
"++drawIndex"
>
重绘下一个
</el-button>
</div>
<div
class=
"right-draw-content"
>
<img
v-if=
"algorithmManage.form.value.liveMap"
: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>
<polygon
:fill=
"item.fill"
stroke=
"blue"
stroke-width=
"1"
v-for=
"item in graph[drawId]"
:points=
"item.point"
:key=
"item.key"
/>
</svg>
</div>
<div
class=
"right"
>
<el-button
type=
"primary"
@
click=
"submit"
>
确认
</el-button>
<el-button
type=
"primary"
plain
@
click=
"algorithmManage.toClose"
>
取消
</el-button
>
</div>
</el-col>
</el-row>
</el-dialog>
<el-dialog
title=
"算法配置"
v-model=
"aiAlgorithm.visible.value"
width=
"30%"
>
<el-form
ref=
"algorithmManage.formRef"
:model=
"aiAlgorithm.form"
label-width=
"80px"
>
<el-form-item
label=
"算法名称"
prop=
"algorithmName"
>
<el-input
v-model=
"unref(aiAlgorithm.form).algorithmName"
readonly
/>
</el-form-item>
<el-form-item
label=
"告警间隔"
prop=
"alarmInterval"
>
<el-input
placeholder=
"单位/秒"
v-model=
"unref(aiAlgorithm.form).alarmInterval"
/>
</el-form-item>
<el-form-item
label=
"行为持续多长时间报警"
prop=
"continueWarnTime"
>
<el-input
placeholder=
"单位/秒"
v-model=
"unref(aiAlgorithm.form).continueWarnTime"
/>
</el-form-item>
<el-form-item
label=
"识别间隔(跳帧)"
prop=
"identifyIntervals"
>
<el-input
v-model=
"unref(aiAlgorithm.form).identifyIntervals"
/>
</el-form-item>
<el-form-item
label=
"标签阈值"
prop=
"labelThreshold"
>
<el-input
v-model=
"unref(aiAlgorithm.form).labelThreshold"
/>
</el-form-item>
<div
class=
"right"
>
<el-button
type=
"primary"
@
click=
"sureConfig"
>
确认
</el-button>
<el-button
type=
"primary"
plain
@
click=
"aiAlgorithm.toClose"
>
取消
</el-button
>
</div>
</el-form>
</el-dialog>
</template>
<
script
setup
>
import
{
listAlgLevel
,
detailAlgLevel
,
addAlgLevel
,
updateAlgLevel
,
deleteAlgLevel
}
from
"
@/api/algorithmList/algorithmDown.js
"
;
const
{
proxy
}
=
getCurrentInstance
();
const
emit
=
defineEmits
();
const
open
=
ref
(
false
);
const
openAdd
=
ref
(
false
);
const
butLoading
=
ref
(
false
);
const
title
=
ref
(
""
);
const
titleLevel
=
ref
(
""
);
const
loading
=
ref
(
true
);
const
algLevelList
=
ref
([]);
const
data
=
reactive
({
form
:
{},
queryParams
:
{
pageNum
:
1
,
pageSize
:
10
,
postCode
:
undefined
,
},
rules
:
{
alarmName
:
[{
required
:
true
,
message
:
"
告警等级名称不能为空
"
,
trigger
:
"
blur
"
}],
postCode
:
[{
required
:
true
,
message
:
"
岗位编码不能为空
"
,
trigger
:
"
blur
"
}],
postSort
:
[{
required
:
true
,
message
:
"
岗位顺序不能为空
"
,
trigger
:
"
blur
"
}],
}
import
{
reactify
}
from
"
@vueuse/core
"
;
import
{
onMounted
,
ref
,
unref
}
from
"
vue
"
;
const
{
algorithmManage
}
=
defineProps
({
algorithmManage
:
Object
});
import
{
useIndex
}
from
"
../hooks
"
;
import
{
colors
,
drawImage
}
from
"
../utils
"
;
const
device
=
useIndex
({
list
:
"
/yunshou/aiDevice/list
"
,
});
const
{
queryParams
,
form
,
rules
}
=
toRefs
(
data
);
/** 表单重置 */
function
reset
()
{
butLoading
.
value
=
false
;
form
.
value
=
{
id
:
undefined
,
alarmName
:
undefined
,
alarmColor
:
'
#409EFF
'
,
alarmShowType
:
[]
};
proxy
.
resetForm
(
"
algLevelRef
"
);
const
aiAlgorithm
=
useIndex
({
list
:
"
/yunshou/aiAlgorithmConfig/list
"
,
detail
:
"
/yunshou/aiAlgorithmConfig/
"
,
});
function
handleDeviceChange
(
e
,
index
)
{
const
d
=
device
.
list
.
value
.
find
((
x
)
=>
x
.
id
==
e
);
algorithmManage
.
form
.
value
.
videoUrl
=
d
.
videoUrl
;
}
/** 查询算法列表 */
function
getLevelList
()
{
loading
.
value
=
true
;
listAlgLevel
(
queryParams
.
value
).
then
(
response
=>
{
algLevelList
.
value
=
response
.
rows
loading
.
value
=
false
;
});
function
submit
()
{
let
algorithms
=
[];
if
(
algorithmManage
.
form
.
value
.
id
)
{
algorithms
=
unref
(
algorithmManage
.
form
).
aiRegionalLocationList
;
}
else
{
algorithmManage
.
form
.
value
.
runningState
=
0
;
unref
(
aiAlgorithm
.
list
).
forEach
((
val
)
=>
{
algorithms
.
push
({
algorithmId
:
val
.
id
,
drawingArea
:
graph
[
val
.
id
]
?
JSON
.
stringify
(
graph
[
val
.
id
])
:
val
.
drawingArea
?
val
.
drawingArea
:
""
,
status
:
val
.
status
,
...
val
.
params
,
});
});
}
algorithmManage
.
form
.
value
.
algorithms
=
algorithms
;
algorithmManage
.
toSubmit
();
}
/** 新增按钮操作 */
function
handleAdd
()
{
open
.
value
=
true
;
title
.
value
=
"
告警等级列表
"
;
getLevelList
()
const
configIndex
=
ref
(
0
);
function
aiConfig
(
index
,
e
)
{
configIndex
.
value
=
index
;
const
current
=
unref
(
aiAlgorithm
.
list
)[
index
];
aiAlgorithm
.
form
.
value
=
algorithmManage
.
form
.
value
.
id
?
e
:
{
algorithmName
:
current
.
algorithmName
,
};
aiAlgorithm
.
visible
.
value
=
true
;
}
/** 等级新增按钮操作 */
function
handleLevelAdd
()
{
reset
();
openAdd
.
value
=
true
;
titleLevel
.
value
=
"
新增告警等级
"
;
// 确认配置
function
sureConfig
()
{
if
(
algorithmManage
.
form
.
value
.
id
)
{
const
current
=
unref
(
algorithmManage
.
form
).
aiRegionalLocationList
[
configIndex
.
value
];
unref
(
algorithmManage
.
form
).
aiRegionalLocationList
[
configIndex
.
value
]
=
{
...
current
,
...
unref
(
aiAlgorithm
.
form
),
};
}
else
{
unref
(
aiAlgorithm
.
list
)[
configIndex
.
value
].
params
=
unref
(
aiAlgorithm
.
form
);
}
aiAlgorithm
.
toClose
();
}
let
drawId
=
ref
();
let
drawIndex
=
ref
(
0
);
const
graph
=
reactive
({});
/** 修改按钮操作 */
function
handleUpdate
(
row
)
{
reset
();
const
id
=
row
.
id
||
ids
.
value
;
detailAlgLevel
(
id
).
then
(
response
=>
{
form
.
value
=
response
.
data
;
form
.
value
.
alarmShowType
=
form
.
value
.
alarmShowType
.
split
(
'
,
'
)
openAdd
.
value
=
true
;
titleLevel
.
value
=
"
修改告警等级
"
;
});
const
videoEle
=
ref
(
null
);
function
getPhoto
()
{
algorithmManage
.
form
.
value
.
liveMap
=
drawImage
(
videoEle
.
value
);
}
/** 提交按钮 */
function
submitForm
()
{
proxy
.
$refs
[
"
algLevelRef
"
].
validate
(
valid
=>
{
if
(
valid
)
{
form
.
value
.
alarmShowType
=
form
.
value
.
alarmShowType
.
join
()
butLoading
.
value
=
true
;
if
(
form
.
value
.
id
!=
undefined
)
{
updateAlgLevel
(
form
.
value
).
then
(
response
=>
{
proxy
.
$modal
.
msgSuccess
(
"
修改成功
"
);
openAdd
.
value
=
false
;
butLoading
.
value
=
false
;
getLevelList
();
});
}
else
{
addAlgLevel
(
form
.
value
).
then
(
response
=>
{
proxy
.
$modal
.
msgSuccess
(
"
新增成功
"
);
openAdd
.
value
=
false
;
butLoading
.
value
=
false
;
getLevelList
();
});
}
}
});
/* 重新取图 */
function
getNewPhoto
()
{
unref
(
algorithmManage
.
form
).
liveMap
=
""
;
for
(
let
key
in
graph
)
{
graph
[
key
]
=
[];
}
}
function
beginDraw
(
e
)
{
drawId
.
value
=
e
.
id
;
if
(
typeof
e
.
drawingArea
==
"
string
"
&&
e
.
drawingArea
)
{
graph
[
e
.
id
]
=
JSON
.
parse
(
e
.
drawingArea
);
}
drawIndex
.
value
=
graph
[
drawId
.
value
]
?
graph
[
drawId
.
value
].
length
:
0
;
}
/** 取消按钮 */
function
cancel
()
{
openAdd
.
value
=
false
;
reset
();
function
clearDraw
()
{
graph
[
drawId
.
value
]
=
[];
drawIndex
.
value
=
0
;
}
/** 删除按钮操作 */
function
handleDelete
(
row
)
{
const
id
=
row
.
id
||
ids
.
value
;
proxy
.
$modal
.
confirm
(
'
删除后,已配置的告警等级将被清空
'
).
then
(
function
()
{
return
deleteAlgLevel
(
id
);
}).
then
(()
=>
{
getLevelList
();
p
roxy
.
$modal
.
msgSuccess
(
"
删除成功
"
);
}
).
catch
(()
=>
{})
;
function
pointDraw
(
e
)
{
if
(
!
graph
[
drawId
.
value
]
)
{
graph
[
drawId
.
value
]
=
[]
;
}
if
(
!
graph
[
drawId
.
value
][
drawIndex
.
value
])
{
graph
[
drawId
.
value
][
drawIndex
.
value
]
=
{
fill
:
colors
(),
p
oint
:
""
,
};
}
defineExpose
({
handleAdd
,
handleUpdate
})
graph
[
drawId
.
value
][
drawIndex
.
value
].
point
+=
`
${
e
.
offsetX
}
,
${
e
.
offsetY
}
`
;
}
</
script
>
<
style
scoped
lang=
"scss"
>
.form-title
{
display
:
flex
;
align-items
:center
;
/*for vertical align*/
font-size
:
16px
;
font-weight
:
600
;
border-radius
:
5px
;
padding
:
0
;
}
.
form-title
:
:
before
{
content
:
""
;
display
:
inline-block
;
width
:
10px
;
/* 矩形的宽度 */
height
:
30px
;
/* 矩形的高度 */
background-color
:
#1890FF
;
/* 矩形的背景颜色 */
margin-right
:
10px
;
border-radius
:
8px
;
.form-title
{
display
:
flex
;
align-items
:
center
;
/*for vertical align*/
font-size
:
16px
;
font-weight
:
600
;
border-radius
:
5px
;
padding
:
0
;
}
.
form-title
:
:
before
{
content
:
""
;
display
:
inline-block
;
width
:
10px
;
/* 矩形的宽度 */
height
:
30px
;
/* 矩形的高度 */
background-color
:
#1890ff
;
/* 矩形的背景颜色 */
margin-right
:
10px
;
border-radius
:
8px
;
}
.drawImg
{
width
:
100%
;
height
:
100%
;
}
.right
{
text-align
:
right
;
}
.right-draw
{
display
:
grid
;
grid-template-rows
:
30px
1fr
30px
;
gap
:
20px
;
.right-draw-content
{
position
:
relative
;
svg
{
position
:
absolute
;
left
:
0
;
top
:
0
;
height
:
100%
;
width
:
100%
;
}
}
}
</
style
>
\ No newline at end of file
src/views/videoControl/pointControl/hooks/index.js
0 → 100644
View file @
89befeef
import
{
onMounted
,
ref
,
watch
}
from
"
vue
"
;
import
request
from
"
@/utils/request
"
;
import
{
ElMessageBox
}
from
"
element-plus
"
;
function
useIndex
(
apis
,
callback
)
{
const
visible
=
ref
(
false
);
const
search
=
ref
({});
const
form
=
ref
({
regionName
:
""
,
});
const
list
=
ref
([]);
const
page
=
ref
({
pageNum
:
1
,
pageSize
:
10
,
total
:
0
,
});
watch
(
()
=>
visible
.
value
,
(
newVal
)
=>
{
if
(
newVal
==
false
)
{
form
.
value
=
{};
}
}
);
watch
([()
=>
page
.
value
.
pageNum
,
()
=>
page
.
value
.
pageSize
],
(
val
)
=>
{
getList
();
});
function
toEdit
(
data
)
{
getDetail
(
data
.
id
);
visible
.
value
=
true
;
}
function
toAdd
()
{
visible
.
value
=
true
;
}
function
toDel
(
data
,
immclose
=
true
)
{
//弹框确认
return
new
Promise
((
resolve
)
=>
{
ElMessageBox
.
confirm
(
"
是否删除?
"
).
then
(()
=>
{
request
({
url
:
apis
.
delete
+
data
.
id
,
method
:
"
delete
"
,
}).
then
((
res
)
=>
{
if
(
immclose
)
{
visible
.
value
=
false
;
getList
();
}
resolve
();
});
});
});
}
function
getList
(
params
)
{
request
({
url
:
apis
.
list
,
method
:
"
get
"
,
params
:
{
...
params
,
...
page
.
value
,
...
search
.
value
},
}).
then
((
res
)
=>
{
list
.
value
=
res
.
data
||
res
.
rows
;
page
.
value
.
total
=
res
.
total
;
});
}
function
getDetail
(
id
)
{
return
request
({
url
:
apis
.
detail
+
id
,
method
:
"
get
"
,
}).
then
((
res
)
=>
{
callback
&&
callback
(
res
);
form
.
value
=
res
.
data
;
return
res
;
});
}
function
toSubmit
(
immclose
=
true
)
{
return
new
Promise
((
resolve
,
reject
)
=>
{
if
(
form
.
value
.
id
)
{
request
({
url
:
apis
.
edit
,
method
:
"
put
"
,
data
:
form
.
value
,
}).
then
((
res
)
=>
{
if
(
immclose
)
{
visible
.
value
=
false
;
getList
();
}
resolve
();
});
}
else
{
request
({
url
:
apis
.
add
,
method
:
"
post
"
,
data
:
form
.
value
,
}).
then
((
res
)
=>
{
if
(
immclose
)
{
visible
.
value
=
false
;
getList
();
}
resolve
();
});
}
});
}
function
toClose
()
{
visible
.
value
=
false
;
}
function
toOpen
()
{
visible
.
value
=
false
;
}
onMounted
(()
=>
{
if
(
apis
.
list
)
{
getList
();
}
});
return
{
visible
,
form
,
list
,
page
,
toEdit
,
toAdd
,
toDel
,
getDetail
,
toClose
,
toSubmit
,
getList
,
toOpen
,
};
}
export
{
useIndex
};
src/views/videoControl/pointControl/index.scss
0 → 100644
View file @
89befeef
.areaNodes
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
width
:
100%
;
}
.pagination-right
{
display
:
flex
;
justify-content
:
flex-end
;
width
:
100%
;
margin-top
:
20px
;
}
.el-tree
{
:deep
(
.is-current
)
{
&
>
.el-tree-node__content
{
background-color
:
var
(
--
el-color-primary-light-9
);
}
}
}
src/views/videoControl/pointControl/index.vue
View file @
89befeef
...
...
@@ -2,7 +2,9 @@
<div
class=
"app-container home"
>
<TabTitle
:text=
"nowText"
/>
<div
class=
"add-but"
>
<el-button
type=
"primary"
icon=
"Plus"
@
click=
"handeAdd"
plain
>
新增点位
</el-button>
<el-button
type=
"primary"
icon=
"Plus"
@
click=
"algorithmManage.toAdd"
plain
>
新增点位
</el-button
>
</div>
<el-row
:gutter=
"10"
>
<el-col
:xs=
"0"
:sm=
"2"
:md=
"3"
:lg=
"4"
>
...
...
@@ -10,7 +12,7 @@
<div
class=
"head-container"
>
<el-input
v-model=
"deptName"
placeholder=
"请输入
部门名称
"
placeholder=
"请输入"
clearable
prefix-icon=
"Search"
style=
"margin-bottom: 20px"
...
...
@@ -18,8 +20,8 @@
</div>
<div
class=
"head-container"
>
<el-tree
:data=
"
deptOptions
"
:props=
"
{
label: 'label',
children: 'children' }"
:data=
"
areaManger.list
"
:props=
"
{ children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
ref="deptTreeRef"
...
...
@@ -27,7 +29,38 @@
highlight-current
default-expand-all
@node-click="handleNodeClick"
/>
>
<template
#default
="
{ node, data }">
<span
class=
"areaNodes"
>
<span>
{{
data
.
label
}}
</span>
<span>
<!-- 添加dropdown -->
<el-dropdown
trigger=
"click"
>
<el-dropdown-link
class=
"dropdown-link"
>
<el-button
type=
"text"
size=
"small"
>
<el-icon
size=
"20"
color=
"#333333"
><Setting
/></el-icon>
</el-button>
</el-dropdown-link>
<template
#dropdown
>
<el-dropdown-menu>
<el-dropdown-item
@
click=
"areaManger.toAdd(data)"
>
新增子区域
</el-dropdown-item
>
<el-dropdown-item
@
click=
"areaManger.toEdit(data)"
>
编辑该区域
</el-dropdown-item
>
<el-dropdown-item
@
click=
"areaManger.toDel(data)"
>
删除该区域
</el-dropdown-item
>
</el-dropdown-menu>
</
template
>
</el-dropdown>
</span>
</span>
</template></el-tree
>
</div>
</el-card>
</el-col>
...
...
@@ -40,182 +73,326 @@
<span>
{{
nowText
}}
</span>
</div>
</
template
>
<!-- <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain @click="handleUpdate">一分屏</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain @click="handleUpdate">四分屏</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain @click="handleDelete">六分屏</el-button>
</el-col>
</el-row> -->
<el-table
v-loading=
"loading"
:data=
"pointList"
>
<el-table-column
label=
"实况图"
align=
"center"
prop=
"postId"
/>
<el-table-column
label=
"摄像头名称"
align=
"center"
prop=
"postCode"
/>
<el-table-column
label=
"所属区域"
align=
"center"
prop=
"postName"
/>
<el-table-column
label=
"推理间隔(秒)"
align=
"center"
prop=
"postSort"
/>
<el-table-column
label=
"关联算法"
align=
"center"
prop=
"postSort"
/>
<el-table-column
label=
"时段配置"
align=
"center"
prop=
"postSort"
/>
<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
"
>
<el-button
link
type=
"primary"
icon=
"Edit"
@
click=
"handleUpdate(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button>
<el-button
link
type=
"primary"
icon=
"Delete"
@
click=
"handleDelete(scope.row)"
v-hasPermi=
"['system:post:remove']"
>
删除
</el-button>
</
template
>
</el-table-column>
</el-table>
<el-table
v-loading=
"loading"
:data=
"algorithmManage.list.value"
>
<el-table-column
label=
"实况图"
align=
"center"
prop=
"postId"
>
<
template
#default
="
scope
"
>
<img
:src=
"scope.row.liveMap"
style=
"width: 60px; height: 40px"
alt=
""
/>
</
template
>
</el-table-column>
<el-table-column
label=
"摄像头名称"
align=
"center"
prop=
"deviceName"
/>
<el-table-column
label=
"所属区域"
align=
"center"
prop=
"regionalName"
/>
<!-- <el-table-column -->
<!-- label="推理间隔(秒)" -->
<!-- align="center" -->
<!-- prop="inferenceInterval" -->
<!-- /> -->
<el-table-column
label=
"关联算法"
align=
"center"
prop=
"algorithmCount"
/>
<el-table-column
label=
"时段配置"
align=
"center"
prop=
"postSort"
>
<
template
#default
="
scope
"
>
<el-button
link
type=
"primary"
@
click=
"configProTime(scope.row)"
>
配置
</el-button
>
</
template
>
</el-table-column>
<el-table-column
label=
"运行状态"
align=
"center"
prop=
"postSort"
>
<
template
#default
="
scope
"
>
<!--
<el-tag
--
>
<!-- :type="scope.row.runningState == '1' ? 'success' : 'danger'" -->
<!-- :size="scope.row.runningState == '1' ? 'medium' : 'small'" -->
<!-- >
{{
-->
<!--
scope
.
row
.
runningState
==
"
1
"
?
"
运行中
"
:
"
未运行
"
-->
<!--
}}
</el-tag
--
>
<!-- > -->
<el-switch
v-model:value=
"scope.row.runningState"
active-value=
"0"
inactive-value=
"1"
/>
</
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"
icon=
"Edit"
@
click=
"algorithmManage.toEdit(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button
>
<el-button
link
type=
"primary"
icon=
"Delete"
@
click=
"algorithmManage.toDel(scope.row)"
v-hasPermi=
"['system:post:remove']"
>
删除
</el-button
>
</
template
>
</el-table-column>
</el-table>
<div
class=
"pagination-right"
>
<el-pagination
background
v-model:current-page=
"unref(algorithmManage.page).pageNum"
v-model:page-size=
"unref(algorithmManage.page).pageSize"
:total=
"unref(algorithmManage.page).total"
layout=
"total, sizes, prev, pager, next, jumper"
/>
</div>
</el-card>
</el-scrollbar>
</el-col>
</el-row>
<drawPoint
ref=
"drawPointRef"
/>
<drawPoint
ref=
"drawPointRef"
:algorithmManage=
"algorithmManage"
/>
<el-dialog
title=
"新增区域"
v-model=
"areaManger.visible.value"
:close-on-click-modal=
"false"
:close-on-press-escape=
"false"
width=
"50%"
>
<el-form
ref=
"areaMangerRef"
:model=
"areaManger.form"
label-width=
"120px"
>
<el-form-item
label=
"上级区域"
prop=
"regionPath"
>
<el-cascader
v-model=
"unref(areaManger.form).parents"
:options=
"areaManger.list.value"
:props=
"{ children: 'children', value: 'id', checkStrictly: true }"
placeholder=
"请选择上级区域"
clearable
@
change=
"handleChange"
/>
</el-form-item>
<el-form-item
label=
"区域名称"
prop=
"regionName"
>
<el-input
v-model=
"unref(areaManger.form).regionName"
placeholder=
"请输入区域名称"
/>
</el-form-item>
</el-form>
<
template
#footer
>
<span
class=
"dialog-footer"
>
<el-button
@
click=
"areaManger.toClose"
>
取 消
</el-button>
<el-button
type=
"primary"
@
click=
"submitAreaForm"
>
确 定
</el-button>
</span>
</
template
>
</el-dialog>
<el-dialog
title=
"时段配置"
v-model=
"aiAlarmPeriodTime.visible.value"
width=
"45%"
>
<el-button
style=
"margin-bottom: 10px"
type=
"primary"
@
click=
"time.toAdd"
>
新增时段配置
</el-button
>
<el-table
v-loading=
"loading"
:data=
"aiAlarmPeriodTime.list.value"
>
<el-table-column
label=
"设备名称"
align=
"center"
prop=
"deviceName"
/>
<el-table-column
label=
"算法名称"
align=
"center"
prop=
"algorithmName"
/>
<el-table-column
label=
"告警时段"
align=
"center"
>
<
template
#default
="
scope
"
>
{{
scope
.
row
.
startTime
}}
-
{{
scope
.
row
.
endTime
}}
</
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"
icon=
"Edit"
@
click=
"timeEdit(scope.row)"
v-hasPermi=
"['system:post:edit']"
>
修改
</el-button
>
<el-button
link
type=
"primary"
icon=
"Delete"
@
click=
"timeDel(scope.row)"
v-hasPermi=
"['system:post:remove']"
>
删除
</el-button
>
</
template
>
</el-table-column>
</el-table>
</el-dialog>
<el-dialog
title=
"时段配置"
v-model=
"time.visible.value"
width=
"20%"
>
<el-form
ref=
"aiAlarmPeriodTime.formRef"
:model=
"aiAlarmPeriodTime.form"
label-width=
"80px"
>
<el-form-item
label=
"算法名称"
prop=
"algorithmName"
>
<el-select
v-model=
"unref(aiAlarmPeriodTime.form).algorithmId"
>
<el-option
v-for=
"item in aiAlarmPeriodTimeList"
:key=
"item.id"
:label=
"item.algorithmName"
:value=
"item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label=
"开始时间"
prop=
"alarmInterval"
>
<el-time-picker
v-model=
"unref(aiAlarmPeriodTime.form).startTime"
arrow-control
value-format=
"HH:mm"
/>
</el-form-item>
<el-form-item
label=
"结束时间"
prop=
"alarmInterval"
>
<el-time-picker
v-model=
"unref(aiAlarmPeriodTime.form).endTime"
arrow-control
value-format=
"HH:mm"
/>
</el-form-item>
<div
class=
"right"
>
<el-button
type=
"primary"
@
click=
"timeSure"
>
确认
</el-button>
<el-button
type=
"primary"
plain
@
click=
"time.toClose"
>
取消
</el-button>
</div>
</el-form>
</el-dialog>
</div>
</template>
<
script
setup
name=
"Index"
>
import
drawPoint
from
'
./components/drawPoint.vue
'
import
drawPoint
from
"
./components/drawPoint.vue
"
;
import
{
ArrowDown
}
from
"
@element-plus/icons-vue
"
;
import
{
Search
}
from
"
@element-plus/icons-vue
"
;
import
{
ElMessageBox
}
from
"
element-plus
"
;
import
{
onMounted
,
reactive
,
ref
,
unref
,
watch
,
watchEffect
}
from
"
vue
"
;
import
request
from
"
@/utils/request
"
;
import
{
useIndex
}
from
"
./hooks
"
;
const
{
proxy
}
=
getCurrentInstance
();
const
drawPointRef
=
ref
(
null
);
const
nowText
=
ref
(
"
点位管理
"
);
const
deptName
=
ref
(
""
);
const
pointList
=
ref
([]);
const
loading
=
ref
(
false
);
const
deptOptions
=
ref
(
undefined
);
const
algorithmList
=
reactive
([
{
name
:
"
我的算法
"
,
value
:
1
,
},
{
name
:
"
最新算法
"
,
value
:
2
,
},
{
name
:
"
基础算法
"
,
value
:
3
,
},
{
name
:
"
智慧煤矿
"
,
value
:
4
,
},
{
name
:
"
智慧能源
"
,
value
:
5
,
},
{
name
:
"
智慧校园
"
,
value
:
6
,
},
{
name
:
"
智慧港口
"
,
value
:
7
,
},
{
name
:
"
智慧煤矿
"
,
value
:
8
,
},
{
name
:
"
智慧能源
"
,
value
:
9
,
},
{
name
:
"
智慧校园
"
,
value
:
10
,
},
]);
const
data
=
reactive
({
form
:
{
title
:
'
测试测试测试
'
},
queryParams
:
{
postCode
:
undefined
,
searchValue
:
""
,
status
:
undefined
,
},
rules
:
{
postName
:
[
{
required
:
true
,
message
:
"
岗位名称不能为空
"
,
trigger
:
"
blur
"
},
],
postCode
:
[
{
required
:
true
,
message
:
"
岗位编码不能为空
"
,
trigger
:
"
blur
"
},
],
postSort
:
[
{
required
:
true
,
message
:
"
岗位顺序不能为空
"
,
trigger
:
"
blur
"
},
],
},
});
const
{
queryParams
,
form
,
rules
}
=
toRefs
(
data
);
/** 通过条件过滤节点 */
const
filterNode
=
(
value
,
data
)
=>
{
if
(
!
value
)
return
true
;
return
data
.
label
.
indexOf
(
value
)
!==
-
1
;
};
// function closeNow(){
// const routerArr=useTagsViewStore().visitedViews
// const nowPath=location.pathname
// return routerArr.filter(item=>{return item.path==nowPath })[0]
// }
// setTimeout(() => {
// nowText=closeNow()awdasa
// }, 500);
// function goTarget(url) {
// window.open(url, '__blank')
// }
const
time
=
useIndex
({});
function
handleNodeClick
(
row
)
{
const
aiAlarmPeriodTime
=
useIndex
({
list
:
"
/yunshou/aiAlarmPeriodTime/list
"
,
add
:
"
/yunshou/aiAlarmPeriodTime
"
,
edit
:
"
/yunshou/aiAlarmPeriodTime/
"
,
delete
:
"
/yunshou/aiAlarmPeriodTime/
"
,
detail
:
"
/yunshou/aiAlarmPeriodTime/
"
,
});
const
aiAlarmPeriodTimeList
=
ref
([]);
function
configProTime
(
data
)
{
aiAlarmPeriodTime
.
getList
({
regionalLocationId
:
data
.
id
});
algorithmManage
.
getDetail
(
data
.
id
).
then
(({
data
})
=>
{
aiAlarmPeriodTimeList
.
value
=
data
.
aiRegionalLocationList
;
aiAlarmPeriodTime
.
form
.
value
.
deviceId
=
data
.
deviceId
;
aiAlarmPeriodTime
.
form
.
value
.
regionalLocationId
=
data
.
id
;
});
aiAlarmPeriodTime
.
toAdd
();
}
function
handeAdd
(
row
)
{
drawPointRef
.
value
.
handleAdd
();
function
timeSure
()
{
aiAlarmPeriodTime
.
toSubmit
(
false
).
then
(()
=>
{
aiAlarmPeriodTime
.
getList
({
regionalLocationId
:
aiAlarmPeriodTime
.
form
.
value
.
regionalLocationId
,
});
aiAlarmPeriodTime
.
form
.
value
.
startTime
=
""
;
aiAlarmPeriodTime
.
form
.
value
.
endTime
=
""
;
aiAlarmPeriodTime
.
form
.
value
.
algorithmId
=
""
;
time
.
toClose
();
});
}
function
handleSetSize
(
row
)
{
console
.
log
(
"
%c [ row ]-170
"
,
"
font-size:13px; background:pink; color:#bf2c9f;
"
,
row
);
// reset();
// const postId = row.postId || ids.value;
// getPost(postId).then(response => {
// form.value = response.data;
// open.value = true;
// title.value = "修改岗位";
// });
function
timeEdit
(
data
)
{
aiAlarmPeriodTime
.
toEdit
(
data
);
time
.
visible
.
value
=
true
;
}
function
handleUpdate
(
row
)
{
// reset();
// const postId = row.postId || ids.value;
// getPost(postId).then(response => {
// form.value = response.data;
// open.value = true;
// title.value = "修改岗位";
// });
function
timeDel
(
data
)
{
aiAlarmPeriodTime
.
toDel
(
data
,
false
).
then
(()
=>
{
aiAlarmPeriodTime
.
getList
({
regionalLocationId
:
aiAlarmPeriodTime
.
form
.
value
.
regionalLocationId
,
});
time
.
toClose
();
});
}
const
areaManger
=
useIndex
(
{
list
:
"
/yunshou/aiRegionManage/list
"
,
add
:
"
/yunshou/aiRegionManage
"
,
edit
:
"
yunshou/aiRegionManage
"
,
delete
:
"
yunshou/aiRegionManage/
"
,
detail
:
"
/yunshou/aiRegionManage/
"
,
},
({
data
})
=>
{
data
.
parents
=
data
.
regionPath
.
split
(
"
,
"
).
map
((
x
)
=>
Number
(
x
));
}
);
/** 删除按钮操作 */
function
handleDelete
(
row
)
{
// const postIds = row.postId || ids.value;
// proxy.$modal.confirm('是否确认删除岗位编号为"' + postIds + '"的数据项?').then(function() {
// return delPost(postIds);
// }).then(() => {
// getList();
// proxy.$modal.msgSuccess("删除成功");
// }).catch(() => {});
const
algorithmManage
=
useIndex
(
{
list
:
"
/yunshou/aiRegionalLocation/list
"
,
add
:
"
/yunshou/aiRegionalLocation
"
,
edit
:
"
/yunshou/aiRegionalLocation/
"
,
delete
:
"
/yunshou/aiRegionalLocation/
"
,
detail
:
"
/yunshou/aiRegionalLocation/
"
,
},
({
data
})
=>
{}
);
function
submitAreaForm
(
e
)
{
const
{
form
}
=
areaManger
;
const
valueForm
=
unref
(
form
);
valueForm
.
regionPath
=
valueForm
.
parents
.
join
(
"
,
"
);
if
(
valueForm
.
id
)
{
valueForm
.
parentId
=
valueForm
.
parents
[
valueForm
.
parents
.
length
-
2
]
??
0
;
}
else
{
valueForm
.
parentId
=
valueForm
.
parents
[
valueForm
.
parents
.
length
-
1
]
??
0
;
}
areaManger
.
toSubmit
();
}
function
handleNodeClick
(
e
)
{
algorithmManage
.
form
.
value
.
regionalId
=
e
.
id
;
areaManger
.
form
.
value
.
id
=
e
.
id
;
algorithmManage
.
getList
({
regionalId
:
e
.
id
});
}
</
script
>
<
style
scoped
lang=
"scss"
>
@import
url("./index.scss")
;
.left-list
{
min-height
:
700px
;
}
.add-but
{
.add-but
{
position
:
absolute
;
display
:
flex
;
top
:
30px
;
...
...
@@ -237,7 +414,7 @@ function handleDelete(row) {
}
}
}
.danger-list
{
.danger-list
{
min-height
:
700px
;
.alg-list
{
display
:
grid
;
...
...
@@ -252,7 +429,8 @@ function handleDelete(row) {
cursor
:
pointer
;
position
:
relative
;
}
.el-form-item--default
,
.el-form-item
{
.el-form-item--default
,
.el-form-item
{
font-size
:
12px
;
margin-bottom
:
0px
;
}
...
...
src/views/videoControl/pointControl/utils/index.js
0 → 100644
View file @
89befeef
// 随机生成十个颜色
export
const
colors
=
()
=>
{
const
r
=
Math
.
floor
(
Math
.
random
()
*
256
);
const
g
=
Math
.
floor
(
Math
.
random
()
*
256
);
const
b
=
Math
.
floor
(
Math
.
random
()
*
256
);
const
a
=
0.8
;
return
`rgba(
${
r
}
,
${
g
}
,
${
b
}
,
${
a
}
)`
;
};
export
function
drawImage
(
video
){
const
img
=
video
;
const
canvas
=
document
.
getElementById
(
'
canvas
'
);
const
ctx
=
canvas
.
getContext
(
'
2d
'
);
canvas
.
width
=
img
.
offsetWidth
;
canvas
.
height
=
img
.
offsetHeight
;
ctx
.
drawImage
(
img
,
0
,
0
,
canvas
.
width
,
canvas
.
height
);
// 绘制图片
return
canvas
.
toDataURL
(
"
image/jpg
"
)
}
\ No newline at end of file
vite.config.js
View file @
89befeef
...
...
@@ -25,7 +25,7 @@ export default defineConfig(({ mode, command }) => {
},
// vite 相关配置
server
:
{
port
:
80
,
port
:
80
90
,
host
:
true
,
open
:
true
,
proxy
:
{
...
...
@@ -33,6 +33,7 @@ export default defineConfig(({ mode, command }) => {
'
/dev-api
'
:
{
// target: 'http://192.168.14.43:8111/ai',
target
:
'
http://192.168.4.206:80/ai
'
,
// target:'http://192.168.14.43:8111/ai',
changeOrigin
:
true
,
rewrite
:
(
p
)
=>
p
.
replace
(
/^
\/
dev-api/
,
''
)
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment