menu style
@ -1,8 +1,8 @@
|
||||
# 页面标题
|
||||
VITE_APP_TITLE = 若依管理系统
|
||||
VITE_APP_TITLE = 木鸢物联平台
|
||||
|
||||
# 开发环境配置
|
||||
VITE_APP_ENV = 'development'
|
||||
|
||||
# 若依管理系统/开发环境
|
||||
# 木鸢物联平台/开发环境
|
||||
VITE_APP_BASE_API = '/dev-api'
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 页面标题
|
||||
VITE_APP_TITLE = 若依管理系统
|
||||
VITE_APP_TITLE = 木鸢物联平台
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'production'
|
||||
|
||||
# 若依管理系统/生产环境
|
||||
# 木鸢物联平台/生产环境
|
||||
VITE_APP_BASE_API = '/prod-api'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 页面标题
|
||||
VITE_APP_TITLE = 若依管理系统
|
||||
VITE_APP_TITLE = 木鸢物联平台
|
||||
|
||||
# 生产环境配置
|
||||
VITE_APP_ENV = 'staging'
|
||||
|
||||
# 若依管理系统/生产环境
|
||||
# 木鸢物联平台/生产环境
|
||||
VITE_APP_BASE_API = '/stage-api'
|
||||
|
||||
# 是否在打包时开启压缩,支持 gzip 和 brotli
|
||||
|
@ -9,7 +9,7 @@
|
||||
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
|
||||
/>
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<title>若依管理系统</title>
|
||||
<title>木鸢物联平台</title>
|
||||
<!--[if lt IE 11
|
||||
]><script>
|
||||
window.location.href = "/html/ie.html";
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "ruoyi",
|
||||
"version": "3.8.5",
|
||||
"description": "若依管理系统",
|
||||
"description": "木鸢物联平台",
|
||||
"author": "若依",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@ -17,6 +17,7 @@
|
||||
"url": "https://gitee.com/y_project/RuoYi-Vue.git"
|
||||
},
|
||||
"dependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
"@element-plus/icons-vue": "2.0.10",
|
||||
"@vueuse/core": "9.5.0",
|
||||
"axios": "0.27.2",
|
||||
|
44
src/api/device/setFunctionLog.js
Normal file
@ -0,0 +1,44 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
// 查询服务调用日志列表
|
||||
export function listSetFunctionLog(query) {
|
||||
return request({
|
||||
url: "/device/setFunctionLog/list",
|
||||
method: "get",
|
||||
params: query,
|
||||
});
|
||||
}
|
||||
|
||||
// 查询服务调用日志详细
|
||||
export function getSetFunctionLog(id) {
|
||||
return request({
|
||||
url: "/device/setFunctionLog/" + id,
|
||||
method: "get",
|
||||
});
|
||||
}
|
||||
|
||||
// 新增服务调用日志
|
||||
export function addSetFunctionLog(data) {
|
||||
return request({
|
||||
url: "/device/setFunctionLog",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 修改服务调用日志
|
||||
export function updateSetFunctionLog(data) {
|
||||
return request({
|
||||
url: "/device/setFunctionLog",
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
}
|
||||
|
||||
// 删除服务调用日志
|
||||
export function delSetFunctionLog(id) {
|
||||
return request({
|
||||
url: "/device/setFunctionLog/" + id,
|
||||
method: "delete",
|
||||
});
|
||||
}
|
@ -42,3 +42,21 @@ export function delDevice(deviceId) {
|
||||
method: "delete",
|
||||
});
|
||||
}
|
||||
|
||||
export function fetchOperatingStatus(deviceSn) {
|
||||
return request({
|
||||
url: `/iot/device/runInfo/${deviceSn}`,
|
||||
method: "GET",
|
||||
});
|
||||
}
|
||||
|
||||
export function selectIdentifierHistory(params) {
|
||||
return request({
|
||||
url: `/iot/device/selectIdentifierHistory/${params.deviceSn}/${params.identifier}`,
|
||||
method: "GET",
|
||||
params: {
|
||||
pageNum: params.pageNum,
|
||||
pageSize: params.pageSize,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
1
src/assets/icons/svg/_log.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489634101" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="49390" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M864 56H216c-17.6 0-32 14.4-32 32v104h112c17.6 0 32 14.4 32 32v32c0 17.6-14.4 32-32 32H184v88h112c17.6 0 32 14.4 32 32v32c0 17.6-14.4 32-32 32H184v88h112c17.6 0 32 14.4 32 32v32c0 17.6-14.4 32-32 32H184v64.8c2.4-0.8 5.6-0.8 8-0.8h112c17.6 0 32 14.4 32 32v32c0 17.6-14.4 32-32 32H192c-2.4 0-5.6-0.8-8-0.8V928c0 17.6 14.4 32 32 32h648c17.6 0 32-14.4 32-32V88c0-17.6-14.4-32-32-32z m-104 744H528c-17.6 0-32-14.4-32-32s14.4-32 32-32h232c17.6 0 32 14.4 32 32s-14.4 32-32 32z m0-160H528c-17.6 0-32-14.4-32-32s14.4-32 32-32h232c17.6 0 32 14.4 32 32s-14.4 32-32 32z m0-192H528c-17.6 0-32-14.4-32-32s14.4-32 32-32h232c17.6 0 32 14.4 32 32s-14.4 32-32 32z m0-168H528c-17.6 0-32-14.4-32-32s14.4-32 32-32h232c17.6 0 32 14.4 32 32s-14.4 32-32 32z" fill="#3FA7F7" p-id="49391"></path><path d="M160 280h112c17.6 0 32-14.4 32-32v-16c0-17.6-14.4-32-32-32H160c-17.6 0-32 14.4-32 32v16c0 17.6 14.4 32 32 32zM160 464h112c17.6 0 32-14.4 32-32v-16c0-17.6-14.4-32-32-32H160c-17.6 0-32 14.4-32 32v16c0 17.6 14.4 32 32 32zM160 648h112c17.6 0 32-14.4 32-32v-16c0-17.6-14.4-32-32-32H160c-17.6 0-32 14.4-32 32v16c0 17.6 14.4 32 32 32zM304 776v-16c0-17.6-14.4-32-32-32H160c-17.6 0-32 14.4-32 32v16c0 17.6 14.4 32 32 32h112c17.6 0 32-14.4 32-32z" fill="#3FA7F7" p-id="49392"></path><path d="M760 216H528c-17.6 0-32 14.4-32 32s14.4 32 32 32h232c17.6 0 32-14.4 32-32s-14.4-32-32-32zM760 384H528c-17.6 0-32 14.4-32 32s14.4 32 32 32h232c17.6 0 32-14.4 32-32s-14.4-32-32-32zM760 576H528c-17.6 0-32 14.4-32 32s14.4 32 32 32h232c17.6 0 32-14.4 32-32s-14.4-32-32-32zM760 736H528c-17.6 0-32 14.4-32 32s14.4 32 32 32h232c17.6 0 32-14.4 32-32s-14.4-32-32-32z" fill="#F4D576" p-id="49393"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
1
src/assets/icons/svg/_monitor.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680487521506" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4917" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M42.674 789.304c-11.766 0-21.344-9.562-21.344-21.312V127.994c0-11.766 9.578-21.328 21.344-21.328h938.634c11.782 0 21.376 9.562 21.376 21.328v639.998c0 11.75-9.594 21.312-21.376 21.312H42.674z" fill="#5D9CEC" p-id="4918"></path><path d="M981.308 85.322H42.674C19.112 85.322 0.004 104.432 0.004 127.994v639.998c0 23.56 19.108 42.686 42.67 42.686h938.634c23.562 0 42.688-19.124 42.688-42.686V127.994c0-23.562-19.124-42.672-42.688-42.672z m0 682.67H42.674V127.994h938.634v639.998z" fill="#E6E9ED" p-id="4919"></path><path d="M682.688 938.678H341.33l42.546-170.498 256.186-0.062z" fill="#CCD1D9" p-id="4920"></path><path d="M31.892 682.68H992.12v122.06H31.892z" fill="#E6E9ED" p-id="4921"></path><path d="M533.328 746.68c0 11.75-9.546 21.312-21.328 21.312s-21.328-9.562-21.328-21.312c0-11.812 9.546-21.376 21.328-21.376s21.328 9.564 21.328 21.376z" fill="#434A54" p-id="4922"></path><path d="M682.688 895.99H341.33c-11.782 0-21.328 9.562-21.328 21.312 0 11.812 9.546 21.376 21.328 21.376h341.358c11.75 0 21.308-9.562 21.308-21.376 0-11.75-9.558-21.312-21.308-21.312z" fill="#E6E9ED" p-id="4923"></path><path d="M634.688 682.68H512l128-554.686h122.684z" fill="#FFFFFF" opacity=".1" p-id="4924"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/icons/svg/_rules.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488421474" class="icon" viewBox="0 0 1049 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15033" xmlns:xlink="http://www.w3.org/1999/xlink" width="131.125" height="128"><path d="M23.599001 23.599001h943.960054v943.960054h-943.960054v-943.960054z" fill="#16D0FF" fill-opacity=".149" p-id="15034"></path><path d="M759.683319 591.595498H538.371884a23.284348 23.284348 0 1 1 0-46.600161h221.311435a23.284348 23.284348 0 0 0 23.30008-23.300081V312.010263a23.284348 23.284348 0 0 0-23.30008-23.300081h-119.757066a92.995798 92.995798 0 0 1-89.912195 69.900242 93.18459 93.18459 0 0 1 0-186.384912 92.980065 92.980065 0 0 1 89.912195 69.884509h119.757066a69.900242 69.900242 0 0 1 69.884509 69.900242V521.695256a69.884509 69.884509 0 0 1-69.884509 69.900242zM550.045523 218.794208a46.615894 46.615894 0 1 0 0 93.216055 46.615894 46.615894 0 0 0 0-93.216055zM387.133751 681.42903c0.47198 12.44454 10.666749 22.29319 23.111288 22.324655h205.83049c9.817185-43.768281 48.849933-76.633824 95.528758-76.633823a98.156113 98.156113 0 0 1 98.030251 98.045984 98.156113 98.156113 0 0 1-98.030251 98.045984c-45.29435 0-83.131415-31.02482-94.333075-72.826518H410.245039a69.853044 69.853044 0 0 1-69.77438-68.846153 92.995798 92.995798 0 0 1-70.010371-89.943661h-23.284348a69.884509 69.884509 0 0 1-69.884509-69.900242V312.010263a69.900242 69.900242 0 0 1 69.884509-69.900242h151.426925a23.315813 23.315813 0 0 1 0 46.600161h-151.426925a23.284348 23.284348 0 0 0-23.300081 23.300081V521.695256a23.284348 23.284348 0 0 0 23.300081 23.300081h36.216601c16.141717-27.736693 45.844993-46.584429 80.252337-46.584429a92.964333 92.964333 0 0 1 23.488873 183.018122z m324.470536 100.547479c31.308008 0 56.79493-25.486921 56.794929-56.810663a56.873593 56.873593 0 0 0-56.794929-56.810663c-31.308008 0-56.79493 25.486921-56.79493 56.810663a56.873593 56.873593 0 0 0 56.79493 56.810663zM363.676343 544.995337a46.615894 46.615894 0 1 0 0 93.216055 46.615894 46.615894 0 0 0 0-93.216055z m347.31437 174.380887l20.137814 21.11324-10.745412 14.33246-26.399416-27.658029v-40.590283h17.007014v32.802612z" fill="#1E1E1E" p-id="15035"></path></svg>
|
After Width: | Height: | Size: 2.2 KiB |
1
src/assets/icons/svg/_template.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488202008" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11089" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M319.786667 234.88a64 64 0 0 1 64-64h366.336a64 64 0 0 1 64 64v451.242667a64 64 0 0 1-64 64H319.786667V234.88z m430.336 451.242667V234.88H383.786667v451.242667h366.336z" fill="#0D50C1" p-id="11090"></path><path d="M277.333333 789.333333h437.333334v64h-405.333334a96 96 0 0 1-96-96V298.666667h64v490.666666z" fill="#FF6600" p-id="11091"></path><path d="M448 298.666667h192v64h-192z" fill="#0D50C1" p-id="11092"></path></svg>
|
After Width: | Height: | Size: 757 B |
1
src/assets/icons/svg/_user.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488852350" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29477" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M1003.988341 918.424806c0 47.254822-38.308713 85.563535-85.563535 85.563535H105.575194c-47.254822 0-85.563535-38.308713-85.563535-85.563535s38.308713-85.563535 85.563535-85.563535h812.849612c47.254822 0 85.563535 38.308713 85.563535 85.563535z" fill="#DBD8D2" p-id="29478"></path><path d="M661.734202 169.74586c0 82.697922-67.036279 149.74214-149.734202 149.74214s-149.734202-67.044217-149.734202-149.74214c0-82.697922 67.036279-149.734202 149.734202-149.734201s149.734202 67.036279 149.734202 149.734201z" fill="#A384E2" p-id="29479"></path><path d="M768.690605 661.734202v272.733271H255.309395V661.734202c0-141.764465 114.92614-256.690605 256.690605-256.690605s256.690605 114.92614 256.690605 256.690605zM490.607132 62.789457c-47.254822 0-85.563535 38.308713-85.563535 85.571473 0 47.246884 38.308713 85.555597 85.571473 85.555597 47.246884 0 85.555597-38.308713 85.555597-85.563535S537.861953 62.789457 490.607132 62.789457z" fill="#B69CF7" p-id="29480"></path><path d="M765.817054 623.219101c1.897178 12.565829 2.87355 25.425364 2.873551 38.515101v272.733271H255.309395V743.035039c35.324031 54.081488 96.367132 89.826233 165.776869 89.826232 109.282233 0 197.87014-88.587907 197.870139-197.862201 0-90.953426 133.326388-101.717333 146.860651-11.779969z" fill="#A384E2" p-id="29481"></path><path d="M512 335.530667c91.413829 0 165.776868-74.378915 165.776868-165.784807C677.776868 78.347907 603.413829 3.968992 512 3.968992S346.223132 78.339969 346.223132 169.74586C346.223132 261.15969 420.586171 335.538605 512 335.538605z m0-299.476341c73.720062 0 133.691535 59.979411 133.691535 133.691534 0 73.720062-59.971473 133.691535-133.691535 133.691535-73.712124 0-133.691535-59.971473-133.691535-133.691535 0-73.712124 59.979411-133.691535 133.691535-133.691534z m406.424806 780.764279H784.733271V661.734202c0-150.385116-122.348155-272.733271-272.733271-272.733272-150.385116 0-272.733271 122.348155-272.733271 272.733272V816.818605H105.575194c-56.026295 0-101.606202 45.579907-101.606202 101.606201 0 56.026295 45.579907 101.606202 101.606202 101.606202h812.849612c56.026295 0 101.606202-45.579907 101.606202-101.606202 0-56.026295-45.579907-101.606202-101.606202-101.606201zM271.352062 661.734202c0-132.691349 107.956589-240.647938 240.647938-240.647938s240.647938 107.956589 240.647938 240.647938v240.647938H271.352062V661.734202z m647.072744 326.211472H105.575194c-38.332527 0-69.520868-31.188341-69.520868-69.520868 0-38.332527 31.188341-69.520868 69.520868-69.520868h133.691535v53.478202H126.968062a16.042667 16.042667 0 0 0 0 32.085333h770.063876a16.042667 16.042667 0 0 0 0-32.085333H784.733271v-53.478202H918.424806c38.332527 0 69.520868 31.188341 69.520868 69.520868 0 38.332527-31.188341 69.520868-69.520868 69.520868z" fill="#4C4C4C" p-id="29482"></path></svg>
|
After Width: | Height: | Size: 3.0 KiB |
1
src/assets/icons/svg/category.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488612544" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="21049" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M220.624 485.52c-30.4-121.584-26.88-201.056 10.48-238.416 37.36-37.376 116.832-40.864 238.416-10.48l338.576 338.56a64 64 0 0 1 0 90.528l-158.4 158.4a64 64 0 0 1-90.496 0L220.624 485.504z" fill="#488AFF" p-id="21050"></path><path d="M320 336m-48 0a48 48 0 1 0 96 0 48 48 0 1 0-96 0Z" fill="#FFFFFF" p-id="21051"></path><path d="M664.704 557.696l-15.536 8.848c3.616 7.008 5.52 14.768 5.536 22.64-0.08 7.52-1.28 15.008-3.552 22.192l13.664 7.776a13.968 13.968 0 0 1 5.264 19.264 14.512 14.512 0 0 1-19.616 5.12l-12.432-7.04a78.88 78.88 0 0 1-47.792 28.784v8.448c0 7.888-6.416 14.272-14.32 14.272a14.304 14.304 0 0 1-14.336-14.272v-8.448a78.928 78.928 0 0 1-47.744-28.736l-12.368 7.04a14.432 14.432 0 0 1-19.552-5.168 13.872 13.872 0 0 1 5.248-19.2l13.504-7.728a76.8 76.8 0 0 1-3.616-22.304c0.08-9.12 2.56-18.08 7.184-25.968l-9.84-5.568a13.968 13.968 0 0 1-5.248-19.2 14.48 14.48 0 0 1 19.6-5.2l11.872 6.768a78.832 78.832 0 0 1 40.96-21.28v-8.464c0-7.888 6.416-14.272 14.336-14.272 7.904 0 14.32 6.4 14.32 14.272v8.448a79.12 79.12 0 0 1 43.616 23.936l16.56-9.344a14.464 14.464 0 0 1 19.552 5.12 13.92 13.92 0 0 1-5.264 19.264z m-88.768-5.12A39.488 39.488 0 0 0 536.384 592a39.488 39.488 0 0 0 39.552 39.424A39.488 39.488 0 0 0 615.488 592c0-10.464-4.16-20.48-11.568-27.888a39.584 39.584 0 0 0-27.984-11.536z" fill="#FFFFFF" p-id="21052"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
src/assets/icons/svg/control.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488542165" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19002" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#B7EB81" p-id="19003"></path><path d="M471.04 399.36h81.92v225.28h-81.92z" fill="#00BB74" p-id="19004"></path><path d="M512 296.96m-133.12 0a133.12 133.12 0 1 0 266.24 0 133.12 133.12 0 1 0-266.24 0Z" fill="#FFFFFF" p-id="19005"></path><path d="M778.24 634.88c0-22.60992-18.30912-40.96-40.89856-40.96H286.65856A40.93952 40.93952 0 0 0 245.76 634.88v122.88c0 22.60992 18.30912 40.96 40.89856 40.96h450.68288A40.93952 40.93952 0 0 0 778.24 757.76V634.88z" fill="#FFFFFF" p-id="19006"></path><path d="M675.84 696.32m-40.96 0a40.96 40.96 0 1 0 81.92 0 40.96 40.96 0 1 0-81.92 0Z" fill="#00BB74" p-id="19007"></path><path d="M327.77216 675.84a20.48 20.48 0 1 0 0 40.96h81.73568a20.48 20.48 0 1 0 0-40.96H327.7824z" fill="#00BB74" p-id="19008"></path></svg>
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/icons/svg/dept.svg
Normal file
After Width: | Height: | Size: 10 KiB |
1
src/assets/icons/svg/dictionary.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489173131" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37808" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M726.0928 793.6H204.8V256a102.4 102.4 0 0 1 102.4-102.4h409.6a102.4 102.4 0 0 1 102.4 102.4v446.1568h-1.664A91.5456 91.5456 0 0 0 726.0928 793.6z" fill="#D5663C" p-id="37809"></path><path d="M814.08 896H297.6a92.8 92.8 0 0 1 0-185.6H814.08a92.8256 92.8256 0 0 0 0 185.5488z" fill="#D8D8D8" p-id="37810"></path><path d="M557.1584 153.6v274.4064l76.8-76.8 76.8 76.8V153.6z" fill="#FFFFFF" p-id="37811"></path></svg>
|
After Width: | Height: | Size: 747 B |
1
src/assets/icons/svg/firmware.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488776893" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="27409" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M102.4 665.6h819.2v153.6a102.4 102.4 0 0 1-102.4 102.4H204.8a102.4 102.4 0 0 1-102.4-102.4v-153.6z" fill="#334466" p-id="27410"></path><path d="M254.208 171.5712A102.4 102.4 0 0 1 351.0784 102.4h321.8432a102.4 102.4 0 0 1 96.8704 69.1712L921.6 614.4H102.4l151.808-442.8288zM768 742.4a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4zM614.4 742.4a51.2 51.2 0 1 1 0 102.4 51.2 51.2 0 0 1 0-102.4z" fill="#B8BECC" p-id="27411"></path><path d="M640 358.4c0 42.3936-57.344 76.8-128 76.8S384 400.7936 384 358.4 441.344 281.6 512 281.6s128 34.4064 128 76.8z" fill="#6B7A99" p-id="27412"></path></svg>
|
After Width: | Height: | Size: 926 B |
1
src/assets/icons/svg/generate.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489767068" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="52356" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M225.6 226.496a403.072 403.072 0 0 0-118.272 276.992 9.088 9.088 0 0 1-9.024 8.96H29.696a9.152 9.152 0 0 1-9.152-9.408A491.136 491.136 0 0 1 511.424 20.992a488.448 488.448 0 0 1 385.856 188.16l54.592-42.752a9.088 9.088 0 0 1 14.72 7.168l-0.896 184.576a9.152 9.152 0 0 1-11.328 8.768l-179.2-43.712a9.152 9.152 0 0 1-3.392-16.128l57.152-44.672a402.944 402.944 0 0 0-474.88-122.624 402.944 402.944 0 0 0-128.448 86.72zM925.696 512.448h68.608a9.088 9.088 0 0 1 9.152 9.344 491.136 491.136 0 0 1-490.88 482.048 489.728 489.728 0 0 1-386.048-187.84l-54.656 42.688a9.088 9.088 0 0 1-14.72-7.168l0.896-184.832c0-5.76 5.632-10.176 11.328-8.768l179.2 43.776a9.152 9.152 0 0 1 3.392 16.128l-56.96 44.672a402.944 402.944 0 0 0 317.568 154.368 402.304 402.304 0 0 0 285.696-118.464 403.072 403.072 0 0 0 118.272-277.056 9.216 9.216 0 0 1 9.152-8.96z" fill="#1296db" p-id="52357"></path><path d="M507.968 744.704a9.152 9.152 0 0 1-3.2-2.56l-128-162.112A9.088 9.088 0 0 1 384 565.312h84.672V288.384c0-4.992 4.096-9.152 9.152-9.152h68.544c5.056 0 9.152 4.16 9.152 9.152v277.056H640a9.152 9.152 0 0 1 7.168 14.72l-128 161.92a9.152 9.152 0 0 1-11.2 2.624z" fill="#1296db" p-id="52358"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
1
src/assets/icons/svg/home.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489934006" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="56093" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M256 384H192v416a128 128 0 0 0 128 128h384a128 128 0 0 0 128-128V384h-64v416a64 64 0 0 1-64 64H320a64 64 0 0 1-64-64V384z" fill="#2B82D8" p-id="56094"></path><path d="M544 704a96 96 0 0 1 96 96v128h-192v-128a96 96 0 0 1 96-96z" fill="#CAE705" p-id="56095"></path><path d="M512 171.552L117.696 535.52a32 32 0 1 1-43.392-47.04l416-384a32 32 0 0 1 43.424 0l416 384a32 32 0 0 1-43.392 47.04L512 171.552z" fill="#2B82D8" p-id="56096"></path><path d="M736 160a32 32 0 0 1 32 32v128a32 32 0 0 1-64 0V192a32 32 0 0 1 32-32zM448 864h128v-128a64 64 0 1 0-128 0v128z m64-256a128 128 0 0 1 128 128v192h-256v-192a128 128 0 0 1 128-128z" fill="#2B82D8" p-id="56097"></path></svg>
|
After Width: | Height: | Size: 999 B |
1
src/assets/icons/svg/login.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489658882" class="icon" viewBox="0 0 1340 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="50382" xmlns:xlink="http://www.w3.org/1999/xlink" width="167.5" height="128"><path d="M1338.521494 852.052454c0 93.912412-76.177155 170.026227-169.561732 170.026226H620.929742c-93.384577 0-169.561732-76.388289-169.561732-170.026226V741.988289a33.612536 33.612536 0 0 1 33.580866-33.675877 33.612536 33.612536 0 0 1 33.591423 33.675877v110.064165c0 56.678928 46.14334 102.948948 102.663917 102.948948h547.755546c56.520577 0 102.663918-46.270021 102.663918-102.948948V172.496495c0-56.689485-46.14334-102.948948-102.663918-102.948949H621.47869c-56.531134 0-102.674474 46.270021-102.674474 102.948949v110.064165a33.612536 33.612536 0 0 1-33.591423 33.675876 33.612536 33.612536 0 0 1-33.580866-33.675876V172.496495c0-93.637938 76.177155-170.036784 169.561732-170.036784h547.755547c93.384577 0 169.561732 76.398845 169.561732 170.036784v679.555959zM9.833989 536.090392a33.781443 33.781443 0 0 1 0-47.631835l229.090969-229.713815a33.232495 33.232495 0 0 1 47.241237 0 33.443629 33.443629 0 0 1 0 47.357361l-172.021443 172.496495h627.754227a33.612536 33.612536 0 0 1 33.580866 33.675876 33.612536 33.612536 0 0 1-33.580866 33.675877h-627.490309l172.032 172.496494a33.443629 33.443629 0 0 1 0 47.367918 33.211381 33.211381 0 0 1-23.752578 9.849402c-8.740948 0-17.207423-3.283134-23.752577-9.849402L9.823433 536.100948z" fill="#20A0FF" p-id="50383"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
1
src/assets/icons/svg/menu.svg
Normal file
After Width: | Height: | Size: 18 KiB |
1
src/assets/icons/svg/multi_user.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488909088" class="icon" viewBox="0 0 1177 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29932" xmlns:xlink="http://www.w3.org/1999/xlink" width="147.125" height="128"><path d="M936.512808 529.241534a236.487317 236.487317 0 0 1-128.623766 38.00175 31.828064 31.828064 0 0 1-31.732101-30.804449c-0.031988 0.415844-0.255904 0.735724-0.255904 1.183557a31.988004 31.988004 0 0 0 31.988005 31.988004c168.32088 0 305.229539 136.908659 305.229539 305.229539a31.988004 31.988004 0 1 0 63.976009 0c0-158.276646-100.34637-293.202049-240.581782-345.598401z" fill="#5BABFC" p-id="29933"></path><path d="M807.889042 567.243284c47.374235 0 91.485693-14.042734 128.623766-38.00175a238.054729 238.054729 0 0 0 109.590903-200.180932c0-131.310758-106.871923-238.182681-238.214669-238.182681a31.988004 31.988004 0 1 0 0 63.976009 174.398601 174.398601 0 0 1 174.23866 174.206672 174.430589 174.430589 0 0 1-174.23866 174.238661 31.988004 31.988004 0 0 0-31.988005 31.988004c0 0.447832 0.223916 0.767712 0.255904 1.183556 0.63976 17.081594 14.490566 30.77246 31.732101 30.772461zM63.976009 991.660127c0-116.340372 50.668999-226.539048 139.019868-302.382606a31.988004 31.988004 0 1 0-41.68037-48.525803A461.906785 461.906785 0 0 0 0 991.660127a31.988004 31.988004 0 1 0 63.976009 0zM924.645258 991.660127c0-204.659253-133.773835-378.418093-318.376609-439.099337a293.234037 293.234037 0 0 1-143.94602 37.745845c-4.798201 0-9.468449-0.511808-14.234662-0.703736a31.604148 31.604148 0 0 0 14.234662 3.710608c219.629639 0 398.34662 178.716981 398.34662 398.34662a31.988004 31.988004 0 1 0 63.976009 0z" fill="#5BABFC" p-id="29934"></path><path d="M606.268649 552.56079c90.078221-50.605023 151.207297-146.952893 151.207298-257.407472 0-162.627015-132.270399-294.961389-294.833438-295.153318h-0.63976C299.407722 0.191928 167.2013 132.526303 167.2013 295.185306c0 157.956766 124.785206 286.9324 280.886667 294.417593 4.734225 0.223916 9.436461 0.703736 14.234662 0.703736a293.234037 293.234037 0 0 0 143.94602-37.745845zM231.177309 295.185306C231.177309 167.713108 334.850431 64.007997 462.322629 64.007997s231.177309 103.705111 231.177309 231.177309-103.705111 231.177309-231.177309 231.177308c-127.472198-0.031988-231.145321-103.737099-231.14532-231.177308z" fill="#5BABFC" p-id="29935"></path></svg>
|
After Width: | Height: | Size: 2.4 KiB |
1
src/assets/icons/svg/notice.svg
Normal file
After Width: | Height: | Size: 4.9 KiB |
1
src/assets/icons/svg/params.svg
Normal file
After Width: | Height: | Size: 5.2 KiB |
@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680058036883" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="19378" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M1024 512c0 282.767-229.242 512-512 512C229.233 1024 0 794.767 0 512S229.233 0 512 0c282.758 0 512 229.233 512 512z" fill="#EEF5FF" p-id="19379"></path><path d="M197 760.979l292.014-168.58V180.911L197 349.523z" fill="#33A272" p-id="19380"></path><path d="M293.697 392.237l-78.002-45.04 264.643-152.821 77.971 45.065z" fill="#F7F7F7" p-id="19381"></path><path d="M186.727 343.572l290.912-167.866 11.375 5.197L208.92 342.655l75.66 43.547 278.975-161.024 11.355 5.221-291.959 168.587z" fill="#66B995" p-id="19382"></path><path d="M186.727 755.062l96.224 55.406V398.986l-96.224-55.414z" fill="#008B4F" p-id="19383"></path><path d="M282.951 810.468L574.91 641.871V230.399L282.951 398.986z" fill="#33A272" p-id="19384"></path><path d="M218.385 676.738l6.152 3.544V439.631l-6.152-3.547zM232.99 612.698l6.153 3.544V447.79l-6.153-3.545zM230.365 743.527c5.496 3.171 9.938 10.865 9.92 17.182s-4.486 8.861-9.984 5.688c-5.494-3.172-9.939-10.866-9.922-17.183 0.019-6.315 4.492-8.86 9.986-5.687z m-0.058 20.502c4.361 2.519 7.906 0.5 7.922-4.511 0.014-5.011-3.51-11.109-7.871-13.627-4.357-2.517-7.902-0.498-7.916 4.514-0.014 5.009 3.509 11.109 7.865 13.624" fill="#FFFFFF" p-id="19385"></path><path d="M301.154 823.065l326.633-188.632V87.561L301.154 276.185z" fill="#00346D" p-id="19386"></path><path d="M409.277 323.967l-87.256-50.381 296.088-170.964 87.291 50.389z" fill="#F7F7F7" p-id="19387"></path><path d="M289.643 816.461l107.648 61.968v-546.88l-107.648-62.003z" fill="#00529F" p-id="19388"></path><path d="M397.291 878.429l326.65-188.65V142.916l-326.65 188.633z" fill="#00346D" p-id="19389"></path><path d="M317.939 710.287l6.157 3.545V400.98l-6.157-3.545zM332.545 575.492l6.156 3.543V409.141l-6.156-3.547zM346.809 610.401l6.152 3.544V416.613l-6.152-3.546zM334.252 794.402c5.496 3.174 9.939 10.867 9.922 17.185-0.02 6.315-4.492 8.861-9.986 5.688-5.492-3.174-9.938-10.865-9.92-17.182 0.017-6.318 4.49-8.864 9.984-5.691z m-0.059 20.506c4.361 2.517 7.908 0.497 7.922-4.513s-3.51-11.109-7.871-13.627c-4.357-2.516-7.902-0.498-7.918 4.513-0.013 5.01 3.51 11.111 7.867 13.627" fill="#FFFFFF" p-id="19390"></path><path d="M289.643 269.546L615.068 81.72l12.719 5.841L314.43 268.483l84.627 48.759 312.115-180.176 12.769 5.85-326.65 188.633z" fill="#6697C6" p-id="19391"></path><path d="M416.627 886.934l326.652-188.65V237.926L416.627 426.551z" fill="#46ABFF" p-id="19392"></path><path d="M524.789 474.341l-87.207-50.398 296.086-170.947 87.24 50.37z" fill="#F7F7F7" p-id="19393"></path><path d="M405.152 880.295L512.82 942.28V481.871l-107.668-61.959z" fill="#46ABFF" p-id="19394"></path><path d="M512.82 942.28l326.664-188.632V293.272L512.82 481.871z" fill="#1F95FF" p-id="19395"></path><path d="M437.957 658.186l6.152 3.542V522.156l-6.152-3.546zM452.561 796.304l6.15 3.544V530.316l-6.15-3.545zM449.936 869.372c5.492 3.173 9.938 10.866 9.92 17.182-0.018 6.318-4.49 8.862-9.984 5.689s-9.936-10.865-9.918-17.183c0.017-6.315 4.485-8.861 9.982-5.688z m-0.059 20.504c4.357 2.518 7.908 0.498 7.922-4.511 0.014-5.01-3.512-11.111-7.871-13.628-4.361-2.516-7.902-0.497-7.916 4.513s3.506 11.11 7.865 13.626" fill="#FFFFFF" p-id="19396"></path><path d="M405.152 419.912l325.411-187.836 12.716 5.85-313.338 180.907 84.637 48.725 312.154-180.124 12.752 5.838L512.82 481.871z" fill="#76CCF3" p-id="19397"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488680740" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="24195" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M278.741333 326.442667c0-1.749333 0.682667-3.114667 1.493334-3.968 0.810667-0.853333 1.578667-1.066667 2.218666-1.066667h537.258667c0.64 0 1.450667 0.213333 2.218667 1.066667 0.853333 0.853333 1.493333 2.218667 1.493333 3.968v454.016a5.674667 5.674667 0 0 1-1.493333 4.010666c-0.768 0.853333-1.578667 1.066667-2.218667 1.066667h-242.304a256.682667 256.682667 0 0 1-21.12 59.733333h263.424c36.138667 0 63.488-30.122667 63.488-64.810666V326.485333c0-34.688-27.306667-64.853333-63.488-64.853333H282.453333c-36.138667 0-63.445333 30.165333-63.445333 64.853333v170.325334a257.877333 257.877333 0 0 1 59.733333-18.816V326.442667z m0 212.608c-21.162667 5.162667-41.386667 13.824-59.733333 25.557333v215.893333c0 34.645333 27.306667 64.768 63.445333 64.768h204.288c13.013333-18.176 22.826667-38.4 29.056-59.733333h-233.386666c-0.597333 0-1.365333-0.256-2.176-1.066667a5.674667 5.674667 0 0 1-1.493334-4.010666v-241.408z" fill="#000000" fill-opacity=".85" p-id="24196"></path><path d="M420.48 493.098667a29.866667 29.866667 0 0 1 29.866667-29.866667h201.514666a29.866667 29.866667 0 1 1 0 59.733333h-201.514666a29.866667 29.866667 0 0 1-29.866667-29.866666zM342.272 153.088a29.866667 29.866667 0 0 1 24.149333-12.245333h369.365334a29.866667 29.866667 0 0 1 24.149333 12.245333l117.504 161.194667a29.866667 29.866667 0 0 1-48.256 35.2l-108.586667-148.906667H381.568L272.981333 349.44a29.866667 29.866667 0 0 1-48.213333-35.2l117.504-161.194667z" fill="#000000" fill-opacity=".85" p-id="24197"></path><path d="M128 730.453333c0 52.309333 20.864 102.485333 57.941333 139.434667a198.186667 198.186667 0 0 0 279.765334 0 196.821333 196.821333 0 0 0 0-278.826667 198.144 198.144 0 0 0-279.765334 0A196.821333 196.821333 0 0 0 128 730.496z" fill="#0078FF" p-id="24198"></path><path d="M342.272 810.581333l85.418667-86.698666-85.418667-86.698667v48.768c-49.706667 0-112.64 23.210667-112.64 135.466667 20.181333-68.138667 106.410667-61.141333 112.64-61.141334v50.304z" fill="#F4F9FF" p-id="24199"></path></svg>
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.3 KiB |
1
src/assets/icons/svg/roles.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680488955450" class="icon" viewBox="0 0 1109 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="30927" xmlns:xlink="http://www.w3.org/1999/xlink" width="138.625" height="128"><path d="M937.728 416a127.936 127.936 0 0 1-127.872-128c0-70.698667 57.237333-128 127.872-128a127.936 127.936 0 0 1 127.872 128c0 70.698667-57.258667 128-127.872 128zM618.026667 384c140.565333 0 239.722667 63.68 223.786666 128l-95.914666 384c-6.08 64.32-82.645333 128-159.850667 128h-63.936c-80.768 0-156.864-63.68-159.829333-128l-95.914667-384c-15.530667-64.32 84.181333-128 223.786667-128z m95.893333 256c2.944-25.6 2.944-44.330667 0-64-20.48-2.816-40.021333-2.816-63.936 0l-127.872 160-63.936-64c-23.893333-15.68-43.093333-15.68-63.936 0-2.944 7.125333-2.944 25.536 0 32l95.914667 96c10.517333 2.816 30.037333 2.816 31.957333 0zM394.261333 160c0-88.362667 71.573333-160 159.850667-160s159.829333 71.637333 159.829333 160-71.552 160-159.829333 160-159.850667-71.637333-159.850667-160z m-223.786666 256a127.914667 127.914667 0 0 1-127.850667-128c0-70.698667 57.258667-128 127.872-128a127.936 127.936 0 0 1 127.872 128c0 70.698667-57.258667 128-127.872 128zM203.605333 448c-17.322667 0-9.472 54.954667 0 122.816L267.52 896H171.605333c-38.165333 0-91.2-44.608-95.893333-96l-63.936-256C0.96 492.544 70.272 448 171.605333 448h31.978667z m702.165334 0h31.978666c101.333333 0 170.645333 44.544 159.829334 96l-63.936 256c-4.736 51.392-57.770667 96-95.893334 96H841.813333l63.936-325.184c9.429333-67.861333 17.322667-122.816 0-122.816z" fill="#FCCE01" p-id="30928"></path></svg>
|
After Width: | Height: | Size: 1.7 KiB |
1
src/assets/icons/svg/setting.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680487445155" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2972" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M859.3 569.7l0.2 0.1c3.1-18.9 4.6-38.2 4.6-57.3 0-17.1-1.3-34.3-3.7-51.1 2.4 16.7 3.6 33.6 3.6 50.5 0 19.4-1.6 38.8-4.7 57.8zM99 398.1c-0.5-0.4-0.9-0.8-1.4-1.3 0.7 0.7 1.4 1.4 2.2 2.1l65.5 55.9v-0.1L99 398.1z m536.6-216h0.1l-15.5-83.8c-0.2-1-0.4-1.9-0.7-2.8 0.1 0.5 0.3 1.1 0.4 1.6l15.7 85z m54 546.5l31.4-25.8 92.8 32.9c17-22.9 31.3-47.5 42.6-73.6l-74.7-63.9 6.6-40.1c2.5-15.1 3.8-30.6 3.8-46.1s-1.3-31-3.8-46.1l-6.5-39.9 74.7-63.9c-11.4-26-25.6-50.7-42.6-73.6l-92.8 32.9-31.4-25.8c-23.9-19.6-50.6-35-79.3-45.8l-38.1-14.3-17.9-97a377.5 377.5 0 0 0-85 0l-17.9 97.2-37.9 14.3c-28.5 10.8-55 26.2-78.7 45.7l-31.4 25.9-93.4-33.2c-17 22.9-31.3 47.5-42.6 73.6l75.5 64.5-6.5 40c-2.5 14.9-3.7 30.2-3.7 45.5 0 15.2 1.3 30.6 3.7 45.5l6.5 40-75.5 64.5c11.4 26 25.6 50.7 42.6 73.6l93.4-33.2 31.4 25.9c23.7 19.5 50.2 34.9 78.7 45.7l37.8 14.5 17.9 97.2c28.2 3.2 56.9 3.2 85 0l17.9-97 38.1-14.3c28.8-10.8 55.4-26.2 79.3-45.8z m-177.1-50.3c-30.5 0-59.2-7.8-84.3-21.5C373.3 627 336 568.9 336 502c0-97.2 78.8-176 176-176 66.9 0 125 37.3 154.8 92.2 13.7 25 21.5 53.7 21.5 84.3 0 97.1-78.7 175.8-175.8 175.8zM207.2 812.8c-5.5 1.9-11.2 2.3-16.6 1.2 5.7 1.2 11.7 1 17.5-1l81.4-29c-0.1-0.1-0.3-0.2-0.4-0.3l-81.9 29.1z m717.6-414.7l-65.5 56c0 0.2 0.1 0.5 0.1 0.7l65.4-55.9c7.1-6.1 11.1-14.9 11.2-24-0.3 8.8-4.3 17.3-11.2 23.2z" fill="#D9D9D9" p-id="2973"></path><path d="M935.8 646.6c0.5 4.7 0 9.5-1.7 14.1l-0.9 2.6a446.02 446.02 0 0 1-79.7 137.9l-1.8 2.1a32 32 0 0 1-35.1 9.5l-81.3-28.9a350 350 0 0 1-99.7 57.6l-15.7 85a32.05 32.05 0 0 1-25.8 25.7l-2.7 0.5a445.2 445.2 0 0 1-79.2 7.1h0.3c26.7 0 53.4-2.4 79.4-7.1l2.7-0.5a32.05 32.05 0 0 0 25.8-25.7l15.7-84.9c36.2-13.6 69.6-32.9 99.6-57.5l81.2 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.5-87.4 79.6-137.7l0.9-2.6c1.6-4.7 2.1-9.7 1.5-14.5z" fill="#D9D9D9" p-id="2974"></path><path d="M688 502c0-30.3-7.7-58.9-21.2-83.8C637 363.3 578.9 326 512 326c-97.2 0-176 78.8-176 176 0 66.9 37.3 125 92.2 154.8 24.9 13.5 53.4 21.2 83.8 21.2 97.2 0 176-78.8 176-176z m-288 0c0-29.9 11.7-58 32.8-79.2C454 401.6 482.1 390 512 390c29.9 0 58 11.6 79.2 32.8A111.6 111.6 0 0 1 624 502c0 29.9-11.7 58-32.8 79.2A111.6 111.6 0 0 1 512 614c-29.9 0-58-11.7-79.2-32.8A111.6 111.6 0 0 1 400 502z" p-id="2975"></path><path d="M594.1 952.2a32.05 32.05 0 0 0 25.8-25.7l15.7-85a350 350 0 0 0 99.7-57.6l81.3 28.9a32 32 0 0 0 35.1-9.5l1.8-2.1c34.8-41.1 61.6-87.5 79.7-137.9l0.9-2.6c1.7-4.6 2.2-9.4 1.7-14.1-0.9-7.9-4.7-15.4-11-20.9l-65.3-55.9-0.2-0.1c3.1-19 4.7-38.4 4.7-57.8 0-16.9-1.2-33.9-3.6-50.5-0.3-2.2-0.7-4.4-1-6.6 0-0.2-0.1-0.5-0.1-0.7l65.5-56c6.9-5.9 10.9-14.4 11.2-23.2 0.1-4-0.5-8.1-1.9-12l-0.9-2.6a443.74 443.74 0 0 0-79.7-137.9l-1.8-2.1a32.12 32.12 0 0 0-35.1-9.5l-81.3 28.9c-30-24.6-63.4-44-99.6-57.6h-0.1l-15.7-85c-0.1-0.5-0.2-1.1-0.4-1.6a32.08 32.08 0 0 0-25.4-24.1l-2.7-0.5c-52.1-9.4-106.9-9.4-159 0l-2.7 0.5a32.05 32.05 0 0 0-25.8 25.7l-15.8 85.4a351.86 351.86 0 0 0-99 57.4l-81.9-29.1a32 32 0 0 0-35.1 9.5l-1.8 2.1a446.02 446.02 0 0 0-79.7 137.9l-0.9 2.6a32.09 32.09 0 0 0 7.9 33.9c0.5 0.4 0.9 0.9 1.4 1.3l66.3 56.6v0.1c-3.1 18.8-4.6 37.9-4.6 57 0 19.2 1.5 38.4 4.6 57.1L99 625.5a32.03 32.03 0 0 0-9.3 35.2l0.9 2.6c18.1 50.4 44.9 96.9 79.7 137.9l1.8 2.1c4.9 5.7 11.4 9.4 18.5 10.7 5.4 1 11.1 0.7 16.6-1.2l81.9-29.1c0.1 0.1 0.3 0.2 0.4 0.3 29.7 24.3 62.8 43.6 98.6 57.1l15.8 85.4a32.05 32.05 0 0 0 25.8 25.7l2.7 0.5c26.1 4.7 52.8 7.1 79.5 7.1h0.3c26.6 0 53.3-2.4 79.2-7.1l2.7-0.5z m-39.8-66.5a377.5 377.5 0 0 1-85 0l-17.9-97.2-37.8-14.5c-28.5-10.8-55-26.2-78.7-45.7l-31.4-25.9-93.4 33.2c-17-22.9-31.2-47.6-42.6-73.6l75.5-64.5-6.5-40c-2.4-14.9-3.7-30.3-3.7-45.5 0-15.3 1.2-30.6 3.7-45.5l6.5-40-75.5-64.5c11.3-26.1 25.6-50.7 42.6-73.6l93.4 33.2 31.4-25.9c23.7-19.5 50.2-34.9 78.7-45.7l37.9-14.3 17.9-97.2c28.1-3.2 56.8-3.2 85 0l17.9 97 38.1 14.3c28.7 10.8 55.4 26.2 79.3 45.8l31.4 25.8 92.8-32.9c17 22.9 31.2 47.6 42.6 73.6L781.8 426l6.5 39.9c2.5 15.1 3.8 30.6 3.8 46.1s-1.3 31-3.8 46.1l-6.6 40.1 74.7 63.9a370.03 370.03 0 0 1-42.6 73.6L721 702.8l-31.4 25.8c-23.9 19.6-50.5 35-79.3 45.8l-38.1 14.3-17.9 97z" p-id="2976"></path></svg>
|
After Width: | Height: | Size: 4.3 KiB |
@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680053113699" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="12498" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M511.998 1023.988c-71.133166 0-129.004488-57.871322-129.004488-129.002488v-8.793897a393.981383 393.981383 0 0 1-44.34948-18.399784l-6.241927 6.239926c-24.283715 24.287715-56.677336 37.665559-91.216931 37.665559s-66.933216-13.377843-91.222931-37.665559c-50.293411-50.299411-50.293411-132.140451 0-182.441862l6.239927-6.235926a394.031382 394.031382 0 0 1-18.397785-44.349481h-8.793897C57.875322 641.002488 0.004 583.129166 0.004 511.996s57.873322-129.004488 129.004488-129.004488h8.789897a393.827385 393.827385 0 0 1 18.399785-44.34948l-6.239927-6.239927c-50.293411-50.299411-50.293411-132.140451 0-182.439862 24.289715-24.289715 56.683336-37.667559 91.222931-37.667559s66.933216 13.377843 91.218931 37.667559l6.239927 6.235927a393.981383 393.981383 0 0 1 44.34948-18.399785v-8.789897c0-71.133166 57.873322-129.004488 129.004488-129.004488s129.004488 57.873322 129.004488 129.004488V137.798385a394.727374 394.727374 0 0 1 44.349481 18.399785l6.239926-6.239927c24.287715-24.287715 56.681336-37.665559 91.218931-37.665559s66.933216 13.377843 91.222931 37.665559c50.293411 50.299411 50.293411 132.140451 0 182.441862-11.501865 11.501865-30.155647 11.501865-41.665511 0-11.503865-11.503865-11.503865-30.155647 0-41.661512 27.32368-27.32768 27.32368-71.791159 0-99.118839-13.159846-13.161846-30.75964-20.409761-49.55742-20.40976s-36.395573 7.247915-49.555419 20.40976l-21.547747 21.547748a29.449655 29.449655 0 0 1-35.243587 4.859943 334.960075 334.960075 0 0 0-72.911146-30.249646 29.457655 29.457655 0 0 1-21.469748-28.355667V129.010488c0-38.645547-31.439632-70.085179-70.085179-70.085179s-70.085179 31.439632-70.085179 70.085179v30.423644a29.461655 29.461655 0 0 1-21.469748 28.355667 335.000074 335.000074 0 0 0-72.911146 30.249646 29.459655 29.459655 0 0 1-35.243587-4.859943l-21.547747-21.547748c-13.159846-13.161846-30.75564-20.409761-49.555419-20.409761s-36.397573 7.247915-49.55742 20.409761c-27.32368 27.32368-27.32368 71.787159 0 99.118839l21.547748 21.543747a29.455655 29.455655 0 0 1 4.859943 35.243587 334.836076 334.836076 0 0 0-30.249646 72.911146 29.453655 29.453655 0 0 1-28.355667 21.469748H129.008488c-38.645547 0-70.085179 31.439632-70.085179 70.085179s31.439632 70.085179 70.085179 70.085179h30.423644a29.459655 29.459655 0 0 1 28.355667 21.467748 335.156072 335.156072 0 0 0 30.249646 72.913146 29.461655 29.461655 0 0 1-4.863943 35.243587l-21.547748 21.543747c-27.32168 27.32368-27.32168 71.787159 0.002 99.114839 13.159846 13.161846 30.75964 20.409761 49.55742 20.40976s36.395573-7.247915 49.555419-20.40976l21.549747-21.543748a29.457655 29.457655 0 0 1 35.237587-4.863943 335.180072 335.180072 0 0 0 72.913146 30.249646 29.457655 29.457655 0 0 1 21.469748 28.355667v30.425644c0 38.643547 31.439632 70.083179 70.085179 70.083178s70.085179-31.439632 70.085179-70.083178V864.569868a29.461655 29.461655 0 0 1 21.469748-28.355667 335.138073 335.138073 0 0 0 72.913146-30.249646 29.459655 29.459655 0 0 1 35.237587 4.863943l21.547747 21.543748c13.161846 13.161846 30.75964 20.409761 49.557419 20.40976s36.397573-7.247915 49.55742-20.40976c27.32368-27.32368 27.32368-71.789159 0-99.118839l-21.543748-21.543747a29.455655 29.455655 0 0 1-4.863943-35.243587 335.156072 335.156072 0 0 0 30.249646-72.913146 29.459655 29.459655 0 0 1 28.355667-21.467748h30.423644c38.645547 0 70.085179-31.439632 70.085179-70.085179 0-19.269774-8.171904-37.939555-22.419738-51.2194-11.903861-11.09387-12.561853-29.733652-1.467982-41.635512 11.09387-11.901861 29.739651-12.555853 41.635512-1.467983C1008.984176 442.06082 1023.992 476.438417 1023.992 512c0 71.133166-57.873322 129.004488-129.004488 129.004488H886.193615a394.777374 394.777374 0 0 1-18.397784 44.349481l6.235926 6.235926c50.297411 50.299411 50.297411 132.140451 0.002 182.439862-24.289715 24.289715-56.683336 37.667559-91.222931 37.667559s-66.933216-13.377843-91.220931-37.667559l-6.239926-6.235926a393.239392 393.239392 0 0 1-44.349481 18.399784v8.793897C641.002488 966.120678 583.129166 1023.988 511.998 1023.988z" fill="#2D527C" p-id="12499"></path><path d="M511.99 511.988m-235.149244 0a235.149244 235.149244 0 1 0 470.298488 0 235.149244 235.149244 0 1 0-470.298488 0Z" fill="#CEE8FA" p-id="12500"></path><path d="M511.998 776.614899c-145.91029 0-264.614899-118.706609-264.614899-264.614899S366.08771 247.381101 511.998 247.381101s264.614899 118.708609 264.614899 264.618899S657.90829 776.614899 511.998 776.614899z m0-470.316488c-113.420671 0-205.69559 92.274919-205.695589 205.697589 0 113.420671 92.274919 205.69559 205.695589 205.69559s205.69559-92.274919 205.69559-205.69559c0-113.422671-92.274919-205.697589-205.69559-205.697589z" fill="#2D527C" p-id="12501"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680572969586" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="29208" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M844.8 580.266667c2.133333-14.933333 4.266667-29.866667 4.266667-46.933334s-2.133333-32-4.266667-46.933333l96-68.266667c8.533333-6.4 12.8-19.2 6.4-29.866666L853.333333 230.4c-6.4-10.666667-17.066667-14.933333-27.733333-8.533333l-106.666667 49.066666c-25.6-19.2-51.2-34.133333-81.066666-46.933333L627.2 106.666667c-2.133333-10.666667-10.666667-19.2-21.333333-19.2h-183.466667c-10.666667 0-21.333333 8.533333-21.333333 19.2l-10.666667 117.333333c-29.866667 12.8-57.6 27.733333-81.066667 46.933333l-106.666666-49.066666c-10.666667-4.266667-23.466667 0-27.733334 8.533333l-91.733333 157.866667c-6.4 10.666667-2.133333 23.466667 6.4 29.866666l96 68.266667c-2.133333 14.933333-4.266667 29.866667-4.266667 46.933333s2.133333 32 4.266667 46.933334L85.333333 648.533333c-8.533333 6.4-12.8 19.2-6.4 29.866667L170.666667 836.266667c6.4 10.666667 17.066667 14.933333 27.733333 8.533333l106.666667-49.066667c25.6 19.2 51.2 34.133333 81.066666 46.933334l10.666667 117.333333c2.133333 10.666667 10.666667 19.2 21.333333 19.2h183.466667c10.666667 0 21.333333-8.533333 21.333333-19.2l10.666667-117.333333c29.866667-12.8 57.6-27.733333 81.066667-46.933334l106.666666 49.066667c10.666667 4.266667 23.466667 0 27.733334-8.533333l91.733333-157.866667c6.4-10.666667 2.133333-23.466667-6.4-29.866667l-89.6-68.266666zM512 746.666667c-117.333333 0-213.333333-96-213.333333-213.333334s96-213.333333 213.333333-213.333333 213.333333 96 213.333333 213.333333-96 213.333333-213.333333 213.333334z" fill="#607D8B" p-id="29209"></path><path d="M512 277.333333c-140.8 0-256 115.2-256 256s115.2 256 256 256 256-115.2 256-256-115.2-256-256-256z m0 362.666667c-59.733333 0-106.666667-46.933333-106.666667-106.666667s46.933333-106.666667 106.666667-106.666666 106.666667 46.933333 106.666667 106.666666-46.933333 106.666667-106.666667 106.666667z" fill="#455A64" p-id="29210"></path></svg>
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 2.1 KiB |
1
src/assets/icons/svg/timing.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489540809" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="48360" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M699.733333 633.386667m-196.266666 0a196.266667 196.266667 0 1 0 392.533333 0 196.266667 196.266667 0 1 0-392.533333 0Z" fill="#FFCA5F" p-id="48361"></path><path d="M246.186667 206.08m-46.293334 0a46.293333 46.293333 0 1 0 92.586667 0 46.293333 46.293333 0 1 0-92.586667 0Z" fill="#FFCA5F" p-id="48362"></path><path d="M677.76 654.506667l-199.893333-125.013334v-202.666666h64v167.253333l169.813333 106.026667-33.92 54.4z" fill="#5C1CF7" p-id="48363"></path><path d="M509.866667 901.76A378.453333 378.453333 0 0 1 207.146667 296.106667l51.2 38.4A314.026667 314.026667 0 1 0 362.666667 245.12l-29.866667-56.746667a378.666667 378.666667 0 1 1 177.066667 713.386667z" fill="#5C1CF7" p-id="48364"></path></svg>
|
After Width: | Height: | Size: 1.0 KiB |
1
src/assets/icons/svg/tools.svg
Normal file
After Width: | Height: | Size: 11 KiB |
1
src/assets/icons/svg/work.svg
Normal file
@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1680489278898" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="40942" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M852.8 901.6h-688c-66.4 0-120-53.6-120-120V368.8c0-66.4 53.6-120 120-120h688c66.4 0 120 53.6 120 120v413.6c0 65.6-53.6 119.2-120 119.2z" fill="#D6AB7F" p-id="40943"></path><path d="M146.4 687.2h730.4c35.2 0 68-11.2 95.2-31.2V368c0-66.4-53.6-120-120-120h-688c-66.4 0-120 53.6-120 120v283.2c29.6 23.2 64.8 36 102.4 36z" fill="#0D1014" p-id="40944"></path><path d="M852.8 909.6h-688c-70.4 0-128-57.6-128-128V368.8c0-70.4 57.6-128 128-128h688c70.4 0 128 57.6 128 128v413.6c0 69.6-57.6 127.2-128 127.2z m-688-652.8c-61.6 0-112 50.4-112 112v413.6c0 61.6 50.4 112 112 112h688c61.6 0 112-50.4 112-112V368.8c0-61.6-50.4-112-112-112h-688z" fill="#6A576D" p-id="40945"></path><path d="M508.8 729.6c-22.4 0-40-17.6-40-40v-45.6h80v45.6c0 21.6-17.6 40-40 40z" fill="#FFFFFF" p-id="40946"></path><path d="M508.8 737.6c-26.4 0-48-21.6-48-48V640c0-4.8 3.2-8 8-8h80c4.8 0 8 3.2 8 8v49.6c0 26.4-21.6 48-48 48z m-32-90.4v41.6c0 17.6 14.4 32 32 32s32-14.4 32-32v-41.6h-64z" fill="#6A576D" p-id="40947"></path><path d="M247.2 214.4H148.8c-62.4 0-113.6 50.4-114.4 113.6L32 523.2c-0.8 64 50.4 116 114.4 116h730.4c64 0 115.2-52 114.4-116l-2.4-196c-0.8-62.4-52-113.6-114.4-113.6H247.2" fill="#938993" p-id="40948"></path><path d="M877.6 647.2H146.4c-32.8 0-64-12.8-87.2-36.8C36 587.2 24 556 24 523.2l2.4-196c0.8-67.2 56-120.8 122.4-120.8h726.4c67.2 0 121.6 54.4 122.4 120.8l2.4 196c0 32.8-12 64-35.2 88-23.2 23.2-54.4 36-87.2 36zM148.8 222.4c-58.4 0-105.6 47.2-106.4 105.6L40 523.2c0 28.8 10.4 56 30.4 76 20 20.8 47.2 32 76 32h730.4c28.8 0 56-11.2 76-32s31.2-47.2 30.4-76l-2.4-196c-0.8-58.4-48.8-105.6-106.4-105.6H148.8z" fill="#6A576D" p-id="40949"></path><path d="M509.6 505.6h-1.6c-37.6 0-68 31.2-68 67.2v70.4h137.6v-70.4c0.8-36-29.6-67.2-68-67.2z" fill="#EC7BB0" p-id="40950"></path><path d="M577.6 647.2H440c-2.4 0-4-0.8-5.6-2.4-1.6-1.6-2.4-3.2-2.4-5.6l0.8-66.4c0-41.6 34.4-75.2 76-75.2h1.6c41.6 0 76 33.6 76 75.2l-0.8 66.4c0 4.8-3.2 8-8 8z m-129.6-16h121.6v-58.4c0-32.8-27.2-59.2-60-59.2h-1.6c-32.8 0-60 26.4-60 59.2v58.4zM680.8 222.4c-4.8 0-8-3.2-8-8 0-26.4-6.4-45.6-19.2-58.4-25.6-25.6-76.8-25.6-136-25.6h-17.6c-59.2 0-110.4 0-136 25.6-12.8 12.8-19.2 32-19.2 58.4 0 4.8-3.2 8-8 8s-8-3.2-8-8c0-31.2 8-53.6 24-69.6 30.4-30.4 84-30.4 147.2-30.4h17.6c62.4 0 116.8 0 147.2 30.4 16 16 24 38.4 24 69.6 0 4-4 8-8 8z" fill="#6A576D" p-id="40951"></path></svg>
|
After Width: | Height: | Size: 2.6 KiB |
BIN
src/assets/images/mark_bs.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/images/model-alert.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
7
src/assets/images/model-alert.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="101" height="36">
|
||||
<rect x="0" y="0" width="101" height="36" fill="rgb(255,255,255,0)" stroke="#000000" stroke-width="0"/>
|
||||
<text x="50%" y="50%" dominant-baseline="middle" stroke="#ff0000" text-anchor="middle" font-size="14"
|
||||
font-family="Arial">
|
||||
请先添加产品
|
||||
</text>
|
||||
</svg>
|
After Width: | Height: | Size: 356 B |
@ -94,3 +94,27 @@
|
||||
.el-dropdown .el-dropdown-link {
|
||||
color: var(--el-color-primary) !important;
|
||||
}
|
||||
|
||||
.el-radio-group.ios-style-radio {
|
||||
padding: 3px;
|
||||
background-color: #eeefef;
|
||||
border-radius: 6px;
|
||||
|
||||
.el-radio-button {
|
||||
.el-radio-button__inner {
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: #303133;
|
||||
box-shadow: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
.el-radio-button__inner {
|
||||
background-color: #fefffe;
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1),
|
||||
0 2px 4px -2px rgb(0 0 0 / 0.1) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -110,6 +110,37 @@
|
||||
background-color: $base-sub-menu-hover !important;
|
||||
}
|
||||
}
|
||||
|
||||
& .router-link-active:not(.sidebar-logo-link) {
|
||||
position: relative;
|
||||
|
||||
li {
|
||||
.menu-title,
|
||||
.svg-icon {
|
||||
position: relative;
|
||||
z-index: 2101;
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: "";
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 90%;
|
||||
height: 72%;
|
||||
background-color: aliceblue;
|
||||
//margin: 0 20px;
|
||||
z-index: 2100;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
top: 50%;
|
||||
border-radius: 28px;
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1),
|
||||
0 2px 4px -2px rgb(0 0 0 / 0.1), inset 0 2px 4px 0 rgb(0 0 0 / 0.05);
|
||||
}
|
||||
|
||||
//background-color: aliceblue;
|
||||
}
|
||||
}
|
||||
|
||||
.hideSidebar {
|
||||
@ -156,6 +187,7 @@
|
||||
visibility: hidden;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
& > i {
|
||||
height: 0;
|
||||
width: 0;
|
||||
|
159
src/components/MapSelect/index.vue
Normal file
@ -0,0 +1,159 @@
|
||||
<template>
|
||||
<div id="map-container">
|
||||
<div class="search-bar">
|
||||
<el-input
|
||||
v-model="keyword"
|
||||
placeholder="请输入关键词"
|
||||
size="small"
|
||||
@keyup.enter="searchPoint"
|
||||
>
|
||||
<template #suffix>
|
||||
<el-icon @click="searchPoint">
|
||||
<Search />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { loadMap } from "@/utils/amap";
|
||||
import { onMounted, ref, shallowRef, toRefs } from "vue";
|
||||
import markBsPng from "@/assets/images/mark_bs.png";
|
||||
import { Search } from "@element-plus/icons-vue";
|
||||
|
||||
const props = defineProps({
|
||||
lat: Number,
|
||||
lng: Number,
|
||||
lnglat: Array,
|
||||
});
|
||||
const { lnglat } = toRefs(props);
|
||||
const emit = defineEmits(["selected"]);
|
||||
const AMap = shallowRef();
|
||||
const map = shallowRef();
|
||||
const placeSearch = shallowRef(null);
|
||||
const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
|
||||
const resultInfoWindow = shallowRef(null);
|
||||
|
||||
const handleMapClick = (event) => {
|
||||
map.value.clearMap();
|
||||
const { lnglat } = event;
|
||||
const marker = new AMap.value.Marker({
|
||||
position: lnglat,
|
||||
});
|
||||
map.value.add(marker);
|
||||
emit("selected", lnglat);
|
||||
};
|
||||
|
||||
// 鼠标悬停搜索结果标记
|
||||
const handleResultHover = (ev) => {
|
||||
console.log(ev);
|
||||
resultInfoWindow.value.setContent(`
|
||||
<div>
|
||||
${ev.target.getExtData().name}</div>
|
||||
`);
|
||||
resultInfoWindow.value.open(map.value, [ev.lnglat.lng, ev.lnglat.lat]);
|
||||
};
|
||||
|
||||
// 搜索结果点击
|
||||
const handleResultClick = async (ev) => {
|
||||
map.value.clearMap();
|
||||
searchResultMarkers.value = [];
|
||||
const lnglat = ev.target.getExtData()?.location;
|
||||
// if (!lnglat) return ElMessage.error("获取经纬度失败");
|
||||
// addFencePath(lnglat);
|
||||
const marker = new AMap.value.Marker({
|
||||
position: lnglat,
|
||||
});
|
||||
map.value.add(marker);
|
||||
map.value.setFitView([marker]);
|
||||
emit("selected", lnglat);
|
||||
};
|
||||
|
||||
// 根据名称搜索地图标点
|
||||
const keyword = ref("");
|
||||
const searchPoint = (val /** 搜索建议选项 */, type) => {
|
||||
map.value.clearMap();
|
||||
placeSearch.value.search(keyword.value, (status, result) => {
|
||||
// TODO: 添加搜索结果标记
|
||||
if (status === "complete") {
|
||||
console.log(status, result);
|
||||
searchResultMarkers.value = result.poiList.pois.map((el, index) => {
|
||||
const marker = new AMap.value.Marker({
|
||||
map: map.value,
|
||||
position: el.location,
|
||||
anchor: "bottom-center",
|
||||
extData: el,
|
||||
content: `
|
||||
<div
|
||||
style="
|
||||
background-image: url(${markBsPng});
|
||||
width: 19px;
|
||||
height: 31px;
|
||||
background-size: cover;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
/*padding-top: 3px;*/
|
||||
"
|
||||
>
|
||||
${index + 1}
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
marker.on("mouseover", handleResultHover);
|
||||
marker.on("click", handleResultClick);
|
||||
marker.on("mouseout", (ev) => {
|
||||
resultInfoWindow.value.close();
|
||||
});
|
||||
return marker;
|
||||
});
|
||||
map.value.setFitView(searchResultMarkers.value);
|
||||
} else {
|
||||
console.log(status, result);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
AMap.value = await loadMap(["AMap.PlaceSearch"]);
|
||||
map.value = new AMap.value.Map("map-container", { zoom: 11 });
|
||||
map.value.on("click", handleMapClick);
|
||||
// 地点搜索插件
|
||||
placeSearch.value = new AMap.value.PlaceSearch({
|
||||
// map: map.value
|
||||
// city: "0551"
|
||||
});
|
||||
resultInfoWindow.value = new AMap.value.InfoWindow({
|
||||
anchor: "bottom-center",
|
||||
offset: new AMap.value.Pixel(0, -31),
|
||||
});
|
||||
if (lnglat.value.length === 2) {
|
||||
const marker = new AMap.value.Marker({
|
||||
position: lnglat.value,
|
||||
});
|
||||
map.value.add(marker);
|
||||
map.value.setFitView([marker]);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
#map-container {
|
||||
width: 100%;
|
||||
height: 300px;
|
||||
//margin-left: 140px;
|
||||
//margin-bottom: 18px;
|
||||
position: relative;
|
||||
|
||||
.search-bar {
|
||||
//display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 10px;
|
||||
padding: 0 10px;
|
||||
z-index: 2023;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -115,7 +115,6 @@ watchEffect(() => {
|
||||
});
|
||||
|
||||
const handleOpen = () => {
|
||||
console.log("open");
|
||||
if (list.value) {
|
||||
selectedProperties.value = cloneDeep(list.value);
|
||||
}
|
||||
@ -133,7 +132,6 @@ function getList() {
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
console.log("cancel");
|
||||
selectedProperties.value = [];
|
||||
emit("update:modelValue", false);
|
||||
};
|
||||
|
@ -197,3 +197,21 @@ export const deviceGroupStatusDict = [
|
||||
elTagType: "danger",
|
||||
},
|
||||
];
|
||||
|
||||
export const setFunctionLogStatusDict = [
|
||||
{
|
||||
label: "未知",
|
||||
value: "0",
|
||||
elTagType: "info",
|
||||
},
|
||||
{
|
||||
label: "成功",
|
||||
value: "1",
|
||||
elTagType: "success",
|
||||
},
|
||||
{
|
||||
label: "未知",
|
||||
value: "2",
|
||||
elTagType: "danger",
|
||||
},
|
||||
];
|
||||
|
@ -60,7 +60,7 @@ defineProps({
|
||||
},
|
||||
});
|
||||
|
||||
const title = ref("若依管理系统");
|
||||
const title = ref("木鸢物联平台");
|
||||
const settingsStore = useSettingsStore();
|
||||
const sideTheme = computed(() => settingsStore.sideTheme);
|
||||
</script>
|
||||
|
@ -273,6 +273,8 @@ function handleScroll() {
|
||||
height: 26px;
|
||||
line-height: 26px;
|
||||
border: 1px solid #d8dce5;
|
||||
border-radius: 5px;
|
||||
border: none;
|
||||
color: #495060;
|
||||
background: #fff;
|
||||
padding: 0 8px;
|
||||
@ -289,6 +291,8 @@ function handleScroll() {
|
||||
background-color: #42b983;
|
||||
color: #fff;
|
||||
border-color: #42b983;
|
||||
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1),
|
||||
0 4px 6px -4px rgb(0 0 0 / 0.1);
|
||||
&::before {
|
||||
content: "";
|
||||
background: #fff;
|
||||
|
11
src/main.js
@ -4,9 +4,7 @@ import Cookies from "js-cookie";
|
||||
|
||||
import ElementPlus from "element-plus";
|
||||
import locale from "element-plus/lib/locale/lang/zh-cn"; // 中文语言
|
||||
|
||||
import "@/assets/styles/index.scss"; // global css
|
||||
|
||||
import App from "./App";
|
||||
import store from "./store";
|
||||
import router from "./router";
|
||||
@ -23,13 +21,12 @@ import SvgIcon from "@/components/SvgIcon";
|
||||
import elementIcons from "@/components/SvgIcon/svgicon";
|
||||
|
||||
import "./permission"; // permission control
|
||||
|
||||
import { useDict } from "@/utils/dict";
|
||||
import {
|
||||
parseTime,
|
||||
resetForm,
|
||||
addDateRange,
|
||||
handleTree,
|
||||
parseTime,
|
||||
resetForm,
|
||||
selectDictLabel,
|
||||
selectDictLabels,
|
||||
} from "@/utils/ruoyi";
|
||||
@ -49,6 +46,10 @@ import TreeSelect from "@/components/TreeSelect";
|
||||
// 字典标签组件
|
||||
import DictTag from "@/components/DictTag";
|
||||
|
||||
window._AMapSecurityConfig = {
|
||||
securityJsCode: "2b65e7751cb17e4605f4c4cdccf885f6",
|
||||
};
|
||||
|
||||
const app = createApp(App);
|
||||
|
||||
// 全局方法挂载
|
||||
|
@ -76,7 +76,7 @@ export const constantRoutes = [
|
||||
path: "/index",
|
||||
component: () => import("@/views/index"),
|
||||
name: "Index",
|
||||
meta: { title: "首页", icon: "dashboard", affix: true },
|
||||
meta: { title: "首页", icon: "home", affix: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
|
@ -6,7 +6,7 @@ export default {
|
||||
/**
|
||||
* 侧边栏主题 深色主题theme-dark,浅色主题theme-light
|
||||
*/
|
||||
sideTheme: "theme-dark",
|
||||
sideTheme: "theme-light",
|
||||
/**
|
||||
* 是否系统布局配置
|
||||
*/
|
||||
|
17
src/utils/amap.js
Normal file
@ -0,0 +1,17 @@
|
||||
import AMapLoader from "@amap/amap-jsapi-loader";
|
||||
|
||||
export const loadMap = async (plugins) => {
|
||||
try {
|
||||
return await AMapLoader.load({
|
||||
key: "377d7c36dd385e2a722f29d4c6e1ffbf",
|
||||
version: "2.0",
|
||||
plugins,
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
};
|
||||
|
||||
// export const loadMapPlugin = () => new Promise((resolve, reject) => {
|
||||
// AMap.plugin()
|
||||
// });
|
8
src/utils/inputFilter.js
Normal file
@ -0,0 +1,8 @@
|
||||
export const inputFilter = (event) => {
|
||||
const regex = /^[0-9.]*$/; // 只允许数字和小数点
|
||||
const inputText = event.target.value;
|
||||
const lastChar = inputText.charAt(inputText.length - 1);
|
||||
if (!regex.test(lastChar)) {
|
||||
event.target.value = inputText.slice(0, -1); // 将最后一个非法字符删除
|
||||
}
|
||||
};
|
@ -1,64 +1,64 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
v-show="showSearch"
|
||||
ref="queryRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
:model="queryParams"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="告警名称" prop="alertName">
|
||||
<el-input
|
||||
v-model="queryParams.alertName"
|
||||
placeholder="请输入告警名称"
|
||||
clearable
|
||||
placeholder="请输入告警名称"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警级别" prop="alertLevel">
|
||||
<el-input
|
||||
v-model="queryParams.alertLevel"
|
||||
placeholder="请输入告警级别"
|
||||
clearable
|
||||
placeholder="请输入告警级别"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品ID" prop="productId">
|
||||
<el-input
|
||||
v-model="queryParams.productId"
|
||||
placeholder="请输入产品ID"
|
||||
clearable
|
||||
placeholder="请输入产品ID"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备ID" prop="deviceId">
|
||||
<el-input
|
||||
v-model="queryParams.deviceId"
|
||||
placeholder="请输入设备ID"
|
||||
clearable
|
||||
placeholder="请输入设备ID"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="租户ID" prop="tenantId">
|
||||
<el-input
|
||||
v-model="queryParams.tenantId"
|
||||
placeholder="请输入租户ID"
|
||||
clearable
|
||||
placeholder="请输入租户ID"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="用户ID" prop="userId">
|
||||
<el-input
|
||||
v-model="queryParams.userId"
|
||||
placeholder="请输入用户ID"
|
||||
clearable
|
||||
placeholder="请输入用户ID"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="Search" type="primary" @click="handleQuery"
|
||||
>搜索
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -66,45 +66,45 @@
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Plus"
|
||||
@click="handleAdd"
|
||||
v-hasPermi="['device:alertLog:add']"
|
||||
>新增</el-button
|
||||
>
|
||||
icon="Plus"
|
||||
plain
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="success"
|
||||
plain
|
||||
icon="Edit"
|
||||
:disabled="single"
|
||||
@click="handleUpdate"
|
||||
v-hasPermi="['device:alertLog:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
:disabled="single"
|
||||
icon="Edit"
|
||||
plain
|
||||
type="success"
|
||||
@click="handleUpdate"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="danger"
|
||||
plain
|
||||
icon="Delete"
|
||||
:disabled="multiple"
|
||||
@click="handleDelete"
|
||||
v-hasPermi="['device:alertLog:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
:disabled="multiple"
|
||||
icon="Delete"
|
||||
plain
|
||||
type="danger"
|
||||
@click="handleDelete"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
type="warning"
|
||||
plain
|
||||
icon="Download"
|
||||
@click="handleExport"
|
||||
v-hasPermi="['device:alertLog:export']"
|
||||
>导出</el-button
|
||||
>
|
||||
icon="Download"
|
||||
plain
|
||||
type="warning"
|
||||
@click="handleExport"
|
||||
>导出
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@ -117,57 +117,57 @@
|
||||
:data="alertLogList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="告警ID" align="center" prop="alertLogId" />
|
||||
<el-table-column label="告警名称" align="center" prop="alertName" />
|
||||
<el-table-column label="告警级别" align="center" prop="alertLevel" />
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column align="center" label="告警ID" prop="alertLogId" />
|
||||
<el-table-column align="center" label="告警名称" prop="alertName" />
|
||||
<el-table-column align="center" label="告警级别" prop="alertLevel" />
|
||||
<el-table-column
|
||||
label="处理状态(1不需要处理 2=未处理 3已处理)"
|
||||
align="center"
|
||||
label="处理状态(1不需要处理 2=未处理 3已处理)"
|
||||
prop="status"
|
||||
/>
|
||||
<el-table-column label="产品ID" align="center" prop="productId" />
|
||||
<el-table-column label="设备ID" align="center" prop="deviceId" />
|
||||
<el-table-column label="租户ID" align="center" prop="tenantId" />
|
||||
<el-table-column label="用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="备注" align="center" prop="remark" />
|
||||
<el-table-column label="类型" align="center" prop="type" />
|
||||
<el-table-column align="center" label="产品ID" prop="productId" />
|
||||
<el-table-column align="center" label="设备ID" prop="deviceId" />
|
||||
<el-table-column align="center" label="租户ID" prop="tenantId" />
|
||||
<el-table-column align="center" label="用户ID" prop="userId" />
|
||||
<el-table-column align="center" label="备注" prop="remark" />
|
||||
<el-table-column align="center" label="类型" prop="type" />
|
||||
<el-table-column
|
||||
label="操作"
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
label="操作"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
icon="Edit"
|
||||
@click="handleUpdate(scope.row)"
|
||||
v-hasPermi="['device:alertLog:edit']"
|
||||
>修改</el-button
|
||||
>
|
||||
<el-button
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
icon="Delete"
|
||||
@click="handleDelete(scope.row)"
|
||||
@click="handleUpdate(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-hasPermi="['device:alertLog:remove']"
|
||||
>删除</el-button
|
||||
>
|
||||
icon="Delete"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
:total="total"
|
||||
v-model:page="queryParams.pageNum"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
v-model:page="queryParams.pageNum"
|
||||
:total="total"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改设备告警日志对话框 -->
|
||||
<el-dialog :title="title" v-model="open" width="500px" append-to-body>
|
||||
<el-dialog v-model="open" :title="title" append-to-body width="500px">
|
||||
<el-form
|
||||
ref="alertLogRef"
|
||||
:model="form"
|
||||
@ -195,8 +195,8 @@
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
type="textarea"
|
||||
placeholder="请输入内容"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -210,14 +210,15 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="AlertLog">
|
||||
<script name="AlertLog" setup>
|
||||
import {
|
||||
listAlertLog,
|
||||
getAlertLog,
|
||||
delAlertLog,
|
||||
addAlertLog,
|
||||
delAlertLog,
|
||||
getAlertLog,
|
||||
listAlertLog,
|
||||
updateAlertLog,
|
||||
} from "@/api/device/alertLog";
|
||||
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
|
412
src/views/device/setFunctionLog/index.vue
Normal file
@ -0,0 +1,412 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
v-show="showSearch"
|
||||
ref="queryRef"
|
||||
:inline="true"
|
||||
:model="queryParams"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="产品SN" prop="productSn">
|
||||
<el-input
|
||||
v-model="queryParams.productSn"
|
||||
clearable
|
||||
placeholder="请输入产品SN"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备SN" prop="deviceSn">
|
||||
<el-input
|
||||
v-model="queryParams.deviceSn"
|
||||
clearable
|
||||
placeholder="请输入设备SN"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="${comment}" prop="version">
|
||||
<el-input
|
||||
v-model="queryParams.version"
|
||||
clearable
|
||||
placeholder="请输入${comment}"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="${comment}" prop="method">
|
||||
<el-input
|
||||
v-model="queryParams.method"
|
||||
clearable
|
||||
placeholder="请输入${comment}"
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="设置时间" prop="setTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.setTime"
|
||||
clearable
|
||||
placeholder="请选择设置时间"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="返回时间" prop="returnTime">
|
||||
<el-date-picker
|
||||
v-model="queryParams.returnTime"
|
||||
clearable
|
||||
placeholder="请选择返回时间"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button icon="Search" type="primary" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:add']"
|
||||
icon="Plus"
|
||||
plain
|
||||
type="primary"
|
||||
@click="handleAdd"
|
||||
>新增
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:edit']"
|
||||
:disabled="single"
|
||||
icon="Edit"
|
||||
plain
|
||||
type="success"
|
||||
@click="handleUpdate"
|
||||
>修改
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:remove']"
|
||||
:disabled="multiple"
|
||||
icon="Delete"
|
||||
plain
|
||||
type="danger"
|
||||
@click="handleDelete"
|
||||
>删除
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:export']"
|
||||
icon="Download"
|
||||
plain
|
||||
type="warning"
|
||||
@click="handleExport"
|
||||
>导出
|
||||
</el-button>
|
||||
</el-col>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
@queryTable="getList"
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="setFunctionLogList"
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<el-table-column align="center" label="${comment}" prop="id" />
|
||||
<el-table-column align="center" label="产品SN" prop="productSn" />
|
||||
<el-table-column align="center" label="设备SN" prop="deviceSn" />
|
||||
<el-table-column align="center" label="${comment}" prop="version" />
|
||||
<el-table-column align="center" label="${comment}" prop="method" />
|
||||
<el-table-column align="center" label="${comment}" prop="payload" />
|
||||
<el-table-column align="center" label="状态" prop="status">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="setFunctionLogStatusDict" :value="[row.status]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="设备返回信息" prop="msg" />
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="设置时间"
|
||||
prop="setTime"
|
||||
width="180"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.setTime, "{y}-{m}-{d}") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="返回时间"
|
||||
prop="returnTime"
|
||||
width="180"
|
||||
>
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.returnTime, "{y}-{m}-{d}") }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
label="操作"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:edit']"
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleUpdate(scope.row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
v-hasPermi="['device:setFunctionLog:remove']"
|
||||
icon="Delete"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination
|
||||
v-show="total > 0"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
v-model:page="queryParams.pageNum"
|
||||
:total="total"
|
||||
@pagination="getList"
|
||||
/>
|
||||
|
||||
<!-- 添加或修改服务调用日志对话框 -->
|
||||
<el-dialog v-model="open" :title="title" append-to-body width="500px">
|
||||
<el-form
|
||||
ref="setFunctionLogRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-width="80px"
|
||||
>
|
||||
<el-form-item label="产品SN" prop="productSn">
|
||||
<el-input v-model="form.productSn" placeholder="请输入产品SN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备SN" prop="deviceSn">
|
||||
<el-input v-model="form.deviceSn" placeholder="请输入设备SN" />
|
||||
</el-form-item>
|
||||
<el-form-item label="${comment}" prop="version">
|
||||
<el-input v-model="form.version" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
<el-form-item label="${comment}" prop="method">
|
||||
<el-input v-model="form.method" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备返回信息" prop="msg">
|
||||
<el-input
|
||||
v-model="form.msg"
|
||||
placeholder="请输入内容"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="设置时间" prop="setTime">
|
||||
<el-date-picker
|
||||
v-model="form.setTime"
|
||||
clearable
|
||||
placeholder="请选择设置时间"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="返回时间" prop="returnTime">
|
||||
<el-date-picker
|
||||
v-model="form.returnTime"
|
||||
clearable
|
||||
placeholder="请选择返回时间"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script name="SetFunctionLog" setup>
|
||||
import {
|
||||
addSetFunctionLog,
|
||||
delSetFunctionLog,
|
||||
getSetFunctionLog,
|
||||
listSetFunctionLog,
|
||||
updateSetFunctionLog,
|
||||
} from "@/api/device/setFunctionLog";
|
||||
import DictTag from "@/components/DictTag/index.vue";
|
||||
import { setFunctionLogStatusDict } from "@/constant/dict";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const setFunctionLogList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref("");
|
||||
|
||||
const data = reactive({
|
||||
form: {},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
productSn: null,
|
||||
deviceSn: null,
|
||||
version: null,
|
||||
method: null,
|
||||
payload: null,
|
||||
status: null,
|
||||
msg: null,
|
||||
setTime: null,
|
||||
returnTime: null,
|
||||
},
|
||||
rules: {},
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询服务调用日志列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
listSetFunctionLog(queryParams.value).then((response) => {
|
||||
setFunctionLogList.value = response.rows;
|
||||
total.value = response.total;
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
|
||||
// 取消按钮
|
||||
function cancel() {
|
||||
open.value = false;
|
||||
reset();
|
||||
}
|
||||
|
||||
// 表单重置
|
||||
function reset() {
|
||||
form.value = {
|
||||
id: null,
|
||||
productSn: null,
|
||||
deviceSn: null,
|
||||
version: null,
|
||||
method: null,
|
||||
payload: null,
|
||||
status: null,
|
||||
msg: null,
|
||||
setTime: null,
|
||||
returnTime: null,
|
||||
};
|
||||
proxy.resetForm("setFunctionLogRef");
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
function resetQuery() {
|
||||
proxy.resetForm("queryRef");
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
function handleAdd() {
|
||||
reset();
|
||||
open.value = true;
|
||||
title.value = "添加服务调用日志";
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
function handleUpdate(row) {
|
||||
reset();
|
||||
const _id = row.id || ids.value;
|
||||
getSetFunctionLog(_id).then((response) => {
|
||||
form.value = response.data;
|
||||
open.value = true;
|
||||
title.value = "修改服务调用日志";
|
||||
});
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs["setFunctionLogRef"].validate((valid) => {
|
||||
if (valid) {
|
||||
if (form.value.id != null) {
|
||||
updateSetFunctionLog(form.value).then((response) => {
|
||||
proxy.$modal.msgSuccess("修改成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
} else {
|
||||
addSetFunctionLog(form.value).then((response) => {
|
||||
proxy.$modal.msgSuccess("新增成功");
|
||||
open.value = false;
|
||||
getList();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
function handleDelete(row) {
|
||||
const _ids = row.id || ids.value;
|
||||
proxy.$modal
|
||||
.confirm('是否确认删除服务调用日志编号为"' + _ids + '"的数据项?')
|
||||
.then(function () {
|
||||
return delSetFunctionLog(_ids);
|
||||
})
|
||||
.then(() => {
|
||||
getList();
|
||||
proxy.$modal.msgSuccess("删除成功");
|
||||
})
|
||||
.catch(() => {});
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
function handleExport() {
|
||||
proxy.download(
|
||||
"device/setFunctionLog/export",
|
||||
{
|
||||
...queryParams.value,
|
||||
},
|
||||
`setFunctionLog_${new Date().getTime()}.xlsx`
|
||||
);
|
||||
}
|
||||
|
||||
getList();
|
||||
</script>
|
7
src/views/iot/device/detail-panes/DeviceLog.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container"></div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style scoped></style>
|
148
src/views/iot/device/detail-panes/OperatingStatus.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-radio-group
|
||||
v-model="modelType"
|
||||
:style="{
|
||||
marginBottom: '8px',
|
||||
}"
|
||||
class="ios-style-radio"
|
||||
size="small"
|
||||
>
|
||||
<el-radio-button :label="1">属性</el-radio-button>
|
||||
<el-radio-button :label="3">事件</el-radio-button>
|
||||
</el-radio-group>
|
||||
<el-table :data="modelList.filter((el) => el.type === modelType)">
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="物模型名称"
|
||||
prop="modelName"
|
||||
></el-table-column>
|
||||
<el-table-column align="center" label="值" prop="value">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
dataList.find((el) => el.identifier === row.identifier)?.value ??
|
||||
"-"
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="更新时间" prop="createTime">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
dataList.find((el) => el.identifier === row.identifier)
|
||||
?.createTime ?? "-"
|
||||
}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="操作">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
icon="list"
|
||||
link
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="handleShowHistory(row.identifier)"
|
||||
>历史
|
||||
</el-button>
|
||||
<el-button icon="plus" link size="small" type="primary"
|
||||
>下发</el-button
|
||||
>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-dialog v-model="showHistoryDialog" :width="500" title="历史记录">
|
||||
<el-table v-loading="historyLoading" :data="historyList">
|
||||
<el-table-column align="center" label="值" prop="value" />
|
||||
<el-table-column align="center" label="更新时间" prop="createTime" />
|
||||
</el-table>
|
||||
<pagination
|
||||
v-show="historyTotal > 0"
|
||||
v-model:limit="queryParams.pageSize"
|
||||
v-model:page="queryParams.pageNum"
|
||||
:total="historyTotal"
|
||||
@pagination="getHistoryList"
|
||||
/>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, toRefs, watchEffect } from "vue";
|
||||
import {
|
||||
fetchOperatingStatus,
|
||||
selectIdentifierHistory,
|
||||
} from "@/api/iot/device";
|
||||
import { listModel } from "@/api/thingsmodel/model";
|
||||
|
||||
const props = defineProps({
|
||||
deviceSn: {
|
||||
type: String,
|
||||
},
|
||||
productId: {
|
||||
type: Number,
|
||||
},
|
||||
});
|
||||
|
||||
const { deviceSn, productId } = toRefs(props);
|
||||
const modelType = ref(1);
|
||||
const dataList = ref([]);
|
||||
const modelList = ref([]);
|
||||
const showHistoryDialog = ref(false);
|
||||
const historyList = ref([]);
|
||||
const historyLoading = ref(false);
|
||||
const historyTotal = ref(0);
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
pageSize: 10,
|
||||
pageNum: 1,
|
||||
identifier: "",
|
||||
deviceSn: "",
|
||||
},
|
||||
});
|
||||
|
||||
const { queryParams } = toRefs(data);
|
||||
|
||||
const getHistoryList = () => {
|
||||
historyLoading.value = true;
|
||||
selectIdentifierHistory(queryParams.value)
|
||||
.then((resp) => {
|
||||
historyList.value = resp.data.list;
|
||||
historyLoading.value = false;
|
||||
})
|
||||
.catch(() => {
|
||||
historyLoading.value = false;
|
||||
});
|
||||
};
|
||||
const handleShowHistory = (identifier) => {
|
||||
showHistoryDialog.value = true;
|
||||
queryParams.value.identifier = identifier;
|
||||
queryParams.value.deviceSn = deviceSn.value;
|
||||
getHistoryList();
|
||||
};
|
||||
// 获取运行状态
|
||||
const getOperatingStatus = () => {
|
||||
if (deviceSn.value) {
|
||||
fetchOperatingStatus(deviceSn.value).then((resp) => {
|
||||
dataList.value = resp.data;
|
||||
});
|
||||
}
|
||||
};
|
||||
watchEffect(() => {
|
||||
getOperatingStatus();
|
||||
});
|
||||
// 获取物模型列表
|
||||
const getThingsModel = () => {
|
||||
if (productId.value) {
|
||||
listModel({
|
||||
productId: productId.value,
|
||||
}).then((resp) => {
|
||||
modelList.value = resp.rows?.filter((el) => el.type !== 2) ?? [];
|
||||
});
|
||||
}
|
||||
};
|
||||
watchEffect(() => {
|
||||
getThingsModel();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
7
src/views/iot/device/detail-panes/UpgradeLog.vue
Normal file
@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<div class="app-container"></div>
|
||||
</template>
|
||||
|
||||
<script setup></script>
|
||||
|
||||
<style scoped></style>
|
304
src/views/iot/device/detail.vue
Normal file
@ -0,0 +1,304 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-tabs>
|
||||
<el-tab-pane label="基础信息" lazy>
|
||||
<el-row :gutter="48">
|
||||
<el-col :offset="6" :span="12">
|
||||
<el-form
|
||||
ref="deviceRef"
|
||||
:model="form"
|
||||
:rules="rules"
|
||||
label-position="left"
|
||||
label-width="140px"
|
||||
>
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
<el-input
|
||||
v-model="form.deviceName"
|
||||
placeholder="请输入设备名称"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品" prop="productId">
|
||||
<!-- <el-input v-model="form.productId" placeholder="请输入产品ID" />-->
|
||||
<el-select
|
||||
v-model="form.productId"
|
||||
:remote-method="getProductOptions"
|
||||
clearable
|
||||
filterable
|
||||
placeholder="请选择产品"
|
||||
remote
|
||||
remote-show-suffix
|
||||
>
|
||||
<el-option
|
||||
v-for="item in productOptions"
|
||||
:key="item.productId"
|
||||
:label="item.productName"
|
||||
:value="item.productId"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备编号" prop="serialNumber">
|
||||
<el-input
|
||||
v-model="form.serialNumber"
|
||||
placeholder="请输入设备编号"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="固件版本" prop="firmwareVersion">
|
||||
<el-input
|
||||
v-model="form.firmwareVersion"
|
||||
placeholder="请输入固件版本"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="激活时间" prop="activeTime">
|
||||
<el-date-picker
|
||||
v-model="form.activeTime"
|
||||
clearable
|
||||
placeholder="请选择激活时间"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
>
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="启用设备影子" prop="isShadow">
|
||||
<el-switch
|
||||
v-model="form.isShadow"
|
||||
:active-value="1"
|
||||
:inactive-value="0"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="定位方式" prop="locationWay">
|
||||
<el-select
|
||||
v-model="form.locationWay"
|
||||
placeholder="请输入定位方式"
|
||||
>
|
||||
<el-option :value="1" label="ip自动定位" />
|
||||
<el-option :value="2" label="设备定位" />
|
||||
<el-option :value="3" label="自定义" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="设备所在地址" prop="networkAddress">
|
||||
<el-input
|
||||
v-model="form.networkAddress"
|
||||
placeholder="请输入设备所在地址"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="10">
|
||||
<el-form-item label="设备经度" prop="longitude">
|
||||
<el-input
|
||||
v-model="form.longitude"
|
||||
placeholder="请输入设备经度"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-form-item label="设备纬度" prop="latitude">
|
||||
<el-input
|
||||
v-model="form.latitude"
|
||||
placeholder="请输入设备纬度"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<map-select
|
||||
:lat="form.latitude"
|
||||
:lng="form.longitude"
|
||||
:lnglat="[form.longitude, form.latitude]"
|
||||
@selected="handleMapSelected"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="设备入网IP" prop="networkIp">
|
||||
<el-input
|
||||
v-model="form.networkIp"
|
||||
placeholder="请输入设备入网IP"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item label="图片地址" prop="imgUrl">
|
||||
<image-upload v-model="form.imgUrl" />
|
||||
</el-form-item>
|
||||
<el-form-item label="备注" prop="remark">
|
||||
<el-input
|
||||
v-model="form.remark"
|
||||
placeholder="请输入内容"
|
||||
type="textarea"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-button color="#010ef2" round type="primary" @click="submitForm"
|
||||
>编辑</el-button
|
||||
>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="运行状态" lazy>
|
||||
<operating-status
|
||||
:device-sn="form.serialNumber"
|
||||
:product-id="form.productId"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="设备日志" lazy>
|
||||
<device-log />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="升级日志" lazy>
|
||||
<upgrade-log />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import ImageUpload from "@/components/ImageUpload/index.vue";
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
import { listProduct } from "@/api/product/product";
|
||||
import OperatingStatus from "@/views/iot/device/detail-panes/OperatingStatus.vue";
|
||||
import { addDevice, getDevice, updateDevice } from "@/api/iot/device";
|
||||
import { useRoute } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
import DeviceLog from "@/views/iot/device/detail-panes/DeviceLog.vue";
|
||||
import UpgradeLog from "@/views/iot/device/detail-panes/UpgradeLog.vue";
|
||||
import MapSelect from "@/components/MapSelect/index.vue";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const productOptions = ref([]);
|
||||
const deviceRef = ref();
|
||||
const data = reactive({
|
||||
form: {},
|
||||
rules: {
|
||||
deviceName: [
|
||||
{ required: true, message: "设备名称不能为空", trigger: "blur" },
|
||||
],
|
||||
productId: [{ required: true, message: "产品ID不能为空", trigger: "blur" }],
|
||||
},
|
||||
});
|
||||
const { form, rules } = toRefs(data);
|
||||
|
||||
// 表单重置
|
||||
function reset() {
|
||||
form.value = {
|
||||
deviceId: null,
|
||||
deviceName: null,
|
||||
productId: null,
|
||||
userId: null,
|
||||
tenantId: null,
|
||||
serialNumber: null,
|
||||
firmwareVersion: null,
|
||||
status: null,
|
||||
rssi: null,
|
||||
isShadow: null,
|
||||
locationWay: null,
|
||||
thingsModelValue: null,
|
||||
networkAddress: null,
|
||||
networkIp: null,
|
||||
longitude: null,
|
||||
latitude: null,
|
||||
activeTime: null,
|
||||
summary: null,
|
||||
imgUrl: null,
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
remark: null,
|
||||
};
|
||||
if (deviceRef.value) {
|
||||
deviceRef.value.resetFields();
|
||||
}
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
deviceRef.value.validate((valid) => {
|
||||
if (valid) {
|
||||
if (form.value.deviceId != null) {
|
||||
updateDevice(form.value).then((response) => {
|
||||
ElMessage.success("修改成功");
|
||||
getDeviceDetail();
|
||||
});
|
||||
} else {
|
||||
addDevice(form.value).then((response) => {
|
||||
ElMessage.success("新增成功");
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function getProductOptions(keyword) {
|
||||
listProduct({
|
||||
productName: keyword,
|
||||
pageNum: 1,
|
||||
pageSize: 20,
|
||||
}).then((resp) => {
|
||||
productOptions.value = resp.rows;
|
||||
});
|
||||
}
|
||||
|
||||
/*获取设备详情*/
|
||||
function getDeviceDetail() {
|
||||
getDevice(route.query.id).then((resp) => {
|
||||
form.value = resp.data;
|
||||
});
|
||||
}
|
||||
|
||||
const handleMapSelected = (lnglat) => {
|
||||
form.value.latitude = lnglat.lat;
|
||||
form.value.longitude = lnglat.lng;
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
getDeviceDetail();
|
||||
// AMap.value = await loadMap(["AMap.PlaceSearch"]);
|
||||
// map.value = new AMap.value.Map("map-container", { zoom: 11 });
|
||||
// map.value.on("click", handleMapClick);
|
||||
// map.value.clearMap();
|
||||
// if (form.value.longitude && form.value.latitude) {
|
||||
// const marker = new AMap.value.Marker({
|
||||
// position: [form.value.longitude, form.value.latitude]
|
||||
// });
|
||||
// map.value.add(marker);
|
||||
// map.value.setFitView([marker]);
|
||||
// }
|
||||
});
|
||||
reset();
|
||||
|
||||
getProductOptions();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-container {
|
||||
padding: 0 20%;
|
||||
}
|
||||
|
||||
:deep(.el-tabs__nav-wrap) {
|
||||
&::after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-tabs__nav-scroll {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
//#map-container {
|
||||
// width: calc(100% - 140px);
|
||||
// height: 300px;
|
||||
// margin-left: 140px;
|
||||
// margin-bottom: 18px;
|
||||
// position: relative;
|
||||
//
|
||||
// .search-bar {
|
||||
// display: none;
|
||||
// position: absolute;
|
||||
// left: 0;
|
||||
// top: 10px;
|
||||
// padding: 0 10px;
|
||||
// z-index: 2023;
|
||||
// }
|
||||
//}
|
||||
</style>
|
@ -5,6 +5,7 @@
|
||||
ref="queryRef"
|
||||
:inline="true"
|
||||
:model="queryParams"
|
||||
:size="productId ? 'small' : 'default'"
|
||||
label-width="68px"
|
||||
>
|
||||
<el-form-item label="设备名称" prop="deviceName">
|
||||
@ -15,7 +16,7 @@
|
||||
@keyup.enter="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品" prop="productId">
|
||||
<el-form-item v-if="!productId" label="产品" prop="productId">
|
||||
<el-select
|
||||
v-model="queryParams.productId"
|
||||
:remote-method="getProductOptions"
|
||||
@ -156,6 +157,7 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['iot:device:add']"
|
||||
:size="productId ? 'small' : 'default'"
|
||||
icon="Plus"
|
||||
plain
|
||||
type="primary"
|
||||
@ -167,6 +169,7 @@
|
||||
<el-button
|
||||
v-hasPermi="['iot:device:edit']"
|
||||
:disabled="single"
|
||||
:size="productId ? 'small' : 'default'"
|
||||
icon="Edit"
|
||||
plain
|
||||
type="success"
|
||||
@ -178,6 +181,7 @@
|
||||
<el-button
|
||||
v-hasPermi="['iot:device:remove']"
|
||||
:disabled="multiple"
|
||||
:size="productId ? 'small' : 'default'"
|
||||
icon="Delete"
|
||||
plain
|
||||
type="danger"
|
||||
@ -188,6 +192,7 @@
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
v-hasPermi="['iot:device:export']"
|
||||
:size="productId ? 'small' : 'default'"
|
||||
icon="Download"
|
||||
plain
|
||||
type="warning"
|
||||
@ -258,7 +263,7 @@
|
||||
<!-- <el-table-column align="center" label="图片地址" prop="imgUrl" />-->
|
||||
<el-table-column align="center" label="分组名称" prop="groupName">
|
||||
<template #default="{ row }">
|
||||
<el-tag v-if="row.groupName" type="primary">
|
||||
<el-tag v-if="row.groupName">
|
||||
{{ row.groupName }}
|
||||
</el-tag>
|
||||
</template>
|
||||
@ -270,12 +275,21 @@
|
||||
label="操作"
|
||||
>
|
||||
<template #default="scope">
|
||||
<!-- <el-button-->
|
||||
<!-- v-hasPermi="['iot:device:edit']"-->
|
||||
<!-- icon="Edit"-->
|
||||
<!-- link-->
|
||||
<!-- type="primary"-->
|
||||
<!-- @click="handleUpdate(scope.row)"-->
|
||||
<!-- >-->
|
||||
<!-- 修改-->
|
||||
<!-- </el-button>-->
|
||||
<el-button
|
||||
v-hasPermi="['iot:device:edit']"
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleUpdate(scope.row)"
|
||||
@click="handleDetail(scope.row)"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
@ -322,6 +336,7 @@
|
||||
<!-- <el-input v-model="form.productId" placeholder="请输入产品ID" />-->
|
||||
<el-select
|
||||
v-model="form.productId"
|
||||
:disabled="productId"
|
||||
:remote-method="getProductOptions"
|
||||
clearable
|
||||
filterable
|
||||
@ -446,6 +461,16 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item>
|
||||
<map-select
|
||||
:lat="form.latitude"
|
||||
:lng="form.longitude"
|
||||
:lnglat="[form.longitude, form.latitude]"
|
||||
@selected="handleMapSelected"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <div id="map-container"-->
|
||||
<!-- style="width: calc(100% - 140px);height: 300px;margin-left: 140px;margin-bottom: 18px"></div>-->
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="设备入网IP" prop="networkIp">
|
||||
@ -496,12 +521,30 @@ import ImageUpload from "@/components/ImageUpload/index.vue";
|
||||
import { listProduct } from "@/api/product/product";
|
||||
import { deviceStatusMap, isShadowDict, locationWayMap } from "@/constant/dict";
|
||||
import UserTreeSelect from "@/components/UserTreeSelect/index.vue";
|
||||
import { getCurrentInstance, reactive, ref, toRefs } from "vue";
|
||||
import {
|
||||
getCurrentInstance,
|
||||
reactive,
|
||||
ref,
|
||||
shallowRef,
|
||||
toRefs,
|
||||
watchEffect,
|
||||
} from "vue";
|
||||
import DictTag from "@/components/DictTag/index.vue";
|
||||
import { parseTime } from "@/utils/ruoyi";
|
||||
import { useRouter } from "vue-router";
|
||||
import { loadMap } from "@/utils/amap";
|
||||
import MapSelect from "@/components/MapSelect/index.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const props = defineProps({
|
||||
productId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
});
|
||||
|
||||
const deviceList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
@ -548,6 +591,11 @@ const data = reactive({
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
watchEffect(() => {
|
||||
queryParams.value.productId = props.productId;
|
||||
getList();
|
||||
});
|
||||
|
||||
/** 查询设备列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
@ -608,15 +656,22 @@ function resetQuery() {
|
||||
// 多选框选中数据
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.deviceId);
|
||||
single.value = selection.length != 1;
|
||||
single.value = selection.length !== 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
function handleAdd() {
|
||||
async function handleAdd() {
|
||||
reset();
|
||||
form.value.productId = props.productId;
|
||||
open.value = true;
|
||||
title.value = "添加设备";
|
||||
if (!AMap.value) AMap.value = await loadMap([]);
|
||||
if (!map.value)
|
||||
map.value = new AMap.value.Map("map-container", {
|
||||
zoom: 11,
|
||||
});
|
||||
map.value.on("click", handleMapClick);
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
@ -630,6 +685,10 @@ function handleUpdate(row) {
|
||||
});
|
||||
}
|
||||
|
||||
function handleDetail(row) {
|
||||
router.push(`/device/device/detail?id=${row.deviceId}`);
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
function submitForm() {
|
||||
proxy.$refs["deviceRef"].validate((valid) => {
|
||||
@ -693,6 +752,23 @@ const handleUserSelected = (data) => {
|
||||
userOpen.value = false;
|
||||
};
|
||||
|
||||
getList();
|
||||
const AMap = shallowRef();
|
||||
const map = shallowRef();
|
||||
const handleMapClick = (event) => {
|
||||
map.value.clearMap();
|
||||
const { lnglat } = event;
|
||||
form.value.latitude = lnglat.lat;
|
||||
form.value.longitude = lnglat.lng;
|
||||
const marker = new AMap.value.Marker({
|
||||
position: lnglat,
|
||||
});
|
||||
map.value.add(marker);
|
||||
};
|
||||
|
||||
const handleMapSelected = (lnglat) => {
|
||||
form.value.latitude = lnglat.lat;
|
||||
form.value.longitude = lnglat.lng;
|
||||
};
|
||||
|
||||
getProductOptions();
|
||||
</script>
|
||||
|
@ -11,8 +11,8 @@
|
||||
<el-tab-pane label="密码登录" name="password"></el-tab-pane>
|
||||
<el-tab-pane label="验证码登录" name="captcha"></el-tab-pane>
|
||||
</el-tabs>
|
||||
<Transition name="slide-left">
|
||||
<div v-if="loginMethod === 'password'" class="input-container">
|
||||
<Transition mode="out-in" name="slide">
|
||||
<div v-if="loginMethod === 'password'" class="input-container password">
|
||||
<el-form-item prop="username">
|
||||
<el-input
|
||||
v-model="loginForm.username"
|
||||
@ -69,9 +69,10 @@
|
||||
>记住密码
|
||||
</el-checkbox>
|
||||
</div>
|
||||
</Transition>
|
||||
<Transition name="slide-right">
|
||||
<div v-if="loginMethod === 'captcha'" class="input-container">
|
||||
<div
|
||||
v-else-if="loginMethod === 'captcha'"
|
||||
class="input-container captcha"
|
||||
>
|
||||
<el-form-item prop="phone">
|
||||
<el-input
|
||||
v-model="loginForm.phone"
|
||||
@ -138,6 +139,8 @@
|
||||
</el-form-item>
|
||||
</div>
|
||||
</Transition>
|
||||
<!-- <Transition mode="out-in" name="slide-right">-->
|
||||
<!-- </Transition>-->
|
||||
|
||||
<el-form-item style="width: 100%">
|
||||
<el-button
|
||||
@ -322,6 +325,7 @@ getCookie();
|
||||
}
|
||||
|
||||
.login-form {
|
||||
overflow: hidden;
|
||||
border-radius: 6px;
|
||||
background: #ffffff;
|
||||
width: 400px;
|
||||
@ -329,6 +333,11 @@ getCookie();
|
||||
transition: all 1s linear;
|
||||
box-shadow: 0 20px 25px -5px rgb(0 0 0 / 0.1),
|
||||
0 8px 10px -6px rgb(0 0 0 / 0.1);
|
||||
//position: relative;
|
||||
|
||||
.input-container {
|
||||
//width: 200%;
|
||||
}
|
||||
|
||||
.login-method-tabs {
|
||||
:deep(.el-tabs__nav-wrap) {
|
||||
@ -415,22 +424,26 @@ getCookie();
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
//.slide-left-enter-active {
|
||||
// transition: all 0.3s ease-out;
|
||||
//}
|
||||
//
|
||||
//.slide-left-leave-active {
|
||||
// transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
//}
|
||||
//
|
||||
//.slide-left-enter-from,
|
||||
//.slide-left-leave-to {
|
||||
// transform: translateX(-500px);
|
||||
// position: relative;
|
||||
// left: -500px;
|
||||
// opacity: 0;
|
||||
//}
|
||||
//
|
||||
.slide-enter-active {
|
||||
transition: all 0.3s ease-out;
|
||||
}
|
||||
|
||||
.slide-leave-active {
|
||||
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
|
||||
}
|
||||
|
||||
.slide-enter-from.password,
|
||||
.slide-leave-to.password {
|
||||
transform: translateX(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-enter-from.captcha,
|
||||
.slide-leave-to.captcha {
|
||||
transform: translateX(100%);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
//.slide-right-enter-active {
|
||||
// transition: all 0.3s ease-out;
|
||||
//}
|
||||
@ -441,7 +454,22 @@ getCookie();
|
||||
//
|
||||
//.slide-right-enter-from,
|
||||
//.slide-right-leave-to {
|
||||
// transform: translateX(500px);
|
||||
// transform: translateX(100%);
|
||||
// opacity: 0;
|
||||
//}
|
||||
|
||||
//.slide-right-enter-to,
|
||||
//.slide-right-leave-from {
|
||||
// position: absolute;
|
||||
// right: 0;
|
||||
// //transform: translateX(100%);
|
||||
// opacity: 0;
|
||||
//}
|
||||
//.slide-enter-to,
|
||||
//.slide-leave-from {
|
||||
// position: absolute;
|
||||
// left: 0;
|
||||
// transform: translateX(0%);
|
||||
// opacity: 0;
|
||||
//}
|
||||
</style>
|
||||
|
@ -88,16 +88,16 @@
|
||||
>刷新
|
||||
</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button
|
||||
:size="productId ? 'small' : ''"
|
||||
icon="refresh"
|
||||
plain
|
||||
type="success"
|
||||
@click="showSelect = true"
|
||||
>刷新
|
||||
</el-button>
|
||||
</el-col>
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <el-button-->
|
||||
<!-- :size="productId ? 'small' : ''"-->
|
||||
<!-- icon="refresh"-->
|
||||
<!-- plain-->
|
||||
<!-- type="success"-->
|
||||
<!-- @click="showSelect = true"-->
|
||||
<!-- >刷新-->
|
||||
<!-- </el-button>-->
|
||||
<!-- </el-col>-->
|
||||
<!-- <el-col :span="1.5">-->
|
||||
<!-- <el-button-->
|
||||
<!-- v-hasPermi="['device:alert:edit']"-->
|
||||
@ -136,12 +136,12 @@
|
||||
></right-toolbar>
|
||||
</el-row>
|
||||
|
||||
<table-select
|
||||
v-model="showSelect"
|
||||
:request-method="listDevice"
|
||||
select-key="deviceId"
|
||||
@select-add="handleAddSelect"
|
||||
/>
|
||||
<!-- <table-select-->
|
||||
<!-- v-model="showSelect"-->
|
||||
<!-- :request-method="listDevice"-->
|
||||
<!-- select-key="deviceId"-->
|
||||
<!-- @select-add="handleAddSelect"-->
|
||||
<!-- />-->
|
||||
<el-table
|
||||
v-loading="loading"
|
||||
:data="alertList"
|
||||
@ -225,7 +225,7 @@
|
||||
></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="告警状态">
|
||||
<el-form-item label="启动状态">
|
||||
<el-switch
|
||||
v-model="form.status"
|
||||
:active-value="1"
|
||||
@ -255,6 +255,7 @@
|
||||
<el-option
|
||||
v-for="item in triggerConditions"
|
||||
:key="item.value"
|
||||
:disabled="form.triggers.length === 1 && item.value === '2'"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
>
|
||||
@ -651,7 +652,6 @@ import { useDict } from "@/utils/dict";
|
||||
import { listProduct } from "@/api/product/product";
|
||||
import { listDevice } from "@/api/iot/device";
|
||||
import { listModel } from "@/api/thingsmodel/model";
|
||||
import TableSelect from "@/components/TableSelect/index.vue";
|
||||
import DictTag from "@/components/DictTag/index.vue";
|
||||
import { alertStatusDict } from "@/constant/dict";
|
||||
|
||||
@ -668,10 +668,6 @@ const props = defineProps({
|
||||
});
|
||||
|
||||
const { product, productId } = toRefs(props);
|
||||
const showSelect = ref(false); // TODO:test,待删
|
||||
const handleAddSelect = (data) => {
|
||||
console.log(data);
|
||||
};
|
||||
const timerWeeks = [
|
||||
{
|
||||
value: 1,
|
||||
@ -809,7 +805,7 @@ const { iot_alert_level, sys_job_status } = useDict(
|
||||
);
|
||||
const data = reactive({
|
||||
form: {
|
||||
conditions: "all", // 触发器条件
|
||||
conditions: "1", // 触发器条件
|
||||
triggers: [],
|
||||
actions: [],
|
||||
},
|
||||
@ -842,19 +838,6 @@ const data = reactive({
|
||||
|
||||
const { queryParams, form, rules, productInfo } = toRefs(data);
|
||||
|
||||
// watch(product, (val) => {
|
||||
// productInfo.value = val;
|
||||
// if (productInfo.value && productInfo.value.productId !== 0) {
|
||||
// queryParams.value.productId = productInfo.value.productId;
|
||||
// getList();
|
||||
// console.log(queryParams.value);
|
||||
// // TODO:获取缓存的Json物模型
|
||||
// // getModel(val.productId).then(response => {
|
||||
// // thingsModel.value = JSON.parse(response.data);
|
||||
// // });
|
||||
// }
|
||||
// });
|
||||
|
||||
/** 查询设备告警列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
@ -885,10 +868,11 @@ function reset() {
|
||||
createBy: null,
|
||||
createTime: null,
|
||||
remark: null,
|
||||
conditions: "2", // 触发器条件
|
||||
conditions: "1", // 触发器条件
|
||||
triggers: [
|
||||
{
|
||||
productId: productId.value,
|
||||
productSn: product.value?.productSn,
|
||||
modelValue: null,
|
||||
triggerType: "1", //1=设备,2=定时,3=告警输出
|
||||
modelType: "1", // 1=属性,2=功能
|
||||
@ -957,7 +941,7 @@ function handleUpdate(row) {
|
||||
} catch (e) {
|
||||
console.log("fail parse triggers str");
|
||||
}
|
||||
form.value.conditions = form.value.triggers[0]?.conditions ?? "2";
|
||||
form.value.conditions = form.value.triggers[0]?.conditions;
|
||||
try {
|
||||
form.value.actions = JSON.parse(response.data.actionsStr);
|
||||
} catch (e) {
|
||||
@ -972,11 +956,13 @@ function handleUpdate(row) {
|
||||
function submitForm() {
|
||||
proxy.$refs["alertRef"].validate((valid) => {
|
||||
if (valid) {
|
||||
if (productId.value) {
|
||||
form.value.productId = productId.value;
|
||||
if (product.value) {
|
||||
form.value.productId = product.value.productId;
|
||||
form.value.productSn = product.value.productSn;
|
||||
}
|
||||
form.value.triggers.forEach((el) => {
|
||||
el.conditions = form.value.conditions;
|
||||
el.status = form.value.status;
|
||||
});
|
||||
if (form.value.alertId != null) {
|
||||
updateAlertRule(form.value).then((response) => {
|
||||
@ -1079,12 +1065,13 @@ const addTriggerItem = () => {
|
||||
// setTriggerSource();
|
||||
form.value.triggers.push({
|
||||
productId: productId.value,
|
||||
productSn: product.value?.productSn,
|
||||
triggerType: "1", // 1=设备,2=定时,3=告警输出
|
||||
modelType: "1", // 1=属性,2=功能
|
||||
cronExpression: null,
|
||||
modelKey: null,
|
||||
modelValue: null,
|
||||
conditions: "2",
|
||||
// conditions: "2",
|
||||
operator: null,
|
||||
modelId: null,
|
||||
// value: "",
|
||||
@ -1099,6 +1086,9 @@ const addTriggerItem = () => {
|
||||
/** 删除触发器 */
|
||||
const removeTriggerItem = (index) => {
|
||||
form.value.triggers.splice(index, 1);
|
||||
if (form.value.triggers.length === 1) {
|
||||
form.value.conditions = "1";
|
||||
}
|
||||
// setTriggerSource();
|
||||
};
|
||||
/** cron表达式按钮操作 */
|
||||
@ -1179,15 +1169,13 @@ const getThingsModelOptions = (productId) => {
|
||||
productId,
|
||||
}).then((resp) => {
|
||||
modelList.value = resp.rows;
|
||||
console.log(modelList.value);
|
||||
});
|
||||
};
|
||||
|
||||
const handleModelTypeChange = () => {};
|
||||
const handleTriggerModelChange = (data, index) => {
|
||||
form.value.triggers[index].modelKey = modelList.value.find(
|
||||
(el) => el.modelId === data
|
||||
).identifier;
|
||||
const _model = modelList.value.find((el) => el.modelId === data);
|
||||
form.value.triggers[index].modelKey = _model?.identifier;
|
||||
form.value.triggers[index].datatype = _model?.datatype;
|
||||
};
|
||||
const handleActionsModelChange = (data, index) => {
|
||||
form.value.actions[index].modelKey = modelList.value.find(
|
||||
@ -1205,6 +1193,7 @@ watch(
|
||||
immediate: true,
|
||||
}
|
||||
);
|
||||
|
||||
if (!productId.value) {
|
||||
getProductOptions();
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
:model="queryParams"
|
||||
label-position="left"
|
||||
label-width="100px"
|
||||
@submit.prevent
|
||||
>
|
||||
<!-- <el-form-item label="父ID" prop="parentId">-->
|
||||
<!-- <el-input-->
|
||||
@ -42,8 +43,8 @@
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item>
|
||||
<el-button icon="Search" type="primary" @click="handleQuery"
|
||||
>搜索</el-button
|
||||
>
|
||||
>搜索
|
||||
</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -178,13 +179,13 @@
|
||||
},
|
||||
]"
|
||||
:default-expanded-keys="[form.parentId]"
|
||||
node-key="categoryId"
|
||||
:props="{
|
||||
value: 'categoryId',
|
||||
label: 'name',
|
||||
children: 'children',
|
||||
}"
|
||||
check-strictly
|
||||
node-key="categoryId"
|
||||
placeholder="选择上级分类"
|
||||
value-key="categoryId"
|
||||
/>
|
||||
|
@ -17,8 +17,8 @@
|
||||
marginTop: '20px',
|
||||
}"
|
||||
>
|
||||
<el-form-item label="产品编码SN" prop="productSn">
|
||||
<el-input v-model="form.productSn" placeholder="请输入产品编码SN">
|
||||
<el-form-item label="编码SN" prop="productSn">
|
||||
<el-input v-model="form.productSn" placeholder="请输入编码SN">
|
||||
<template #suffix>
|
||||
<el-icon v-if="isProductSnUnique === true" color="green">
|
||||
<SuccessFilled />
|
||||
@ -32,13 +32,10 @@
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item label="产品名称" prop="productName">
|
||||
<el-input
|
||||
v-model="form.productName"
|
||||
placeholder="请输入产品名称"
|
||||
/>
|
||||
<el-form-item label="名称" prop="productName">
|
||||
<el-input v-model="form.productName" placeholder="请输入名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="产品分类" prop="categoryId">
|
||||
<el-form-item label="分类" prop="categoryId">
|
||||
<el-tree-select
|
||||
v-model="form.categoryId"
|
||||
:data="categoryOptions"
|
||||
@ -228,11 +225,6 @@
|
||||
<el-tab-pane :disabled="!form.productId" label="固件管理" lazy>
|
||||
<firmware v-if="form.productId" :product-id="form.productId" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:disabled="!form.productId"
|
||||
label="设备授权"
|
||||
lazy
|
||||
></el-tab-pane>
|
||||
<el-tab-pane :disabled="!form.productId" label="告警配置" lazy>
|
||||
<alert
|
||||
v-if="form.productId"
|
||||
@ -240,17 +232,16 @@
|
||||
:product-id="form.productId"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:disabled="!form.productId"
|
||||
label="控制界面"
|
||||
lazy
|
||||
></el-tab-pane>
|
||||
<el-tab-pane :disabled="!form.productId" label="设备列表" lazy>
|
||||
<device v-if="form.productId" :product-id="form.productId"></device>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Firmware from "@/views/product/firmware/index.vue";
|
||||
import Device from "@/views/iot/device/index.vue";
|
||||
import { onMounted, reactive, ref, toRefs } from "vue";
|
||||
import Model from "@/views/product/product/panes/model.vue";
|
||||
import { useRoute } from "vue-router";
|
||||
@ -309,6 +300,18 @@ const data = reactive({
|
||||
validator: checkProductSnUnique,
|
||||
trigger: "change",
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: "产品编号SN不能为空",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
deviceType: [
|
||||
{
|
||||
required: true,
|
||||
message: "设备类型不能为空",
|
||||
trigger: "change",
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
@ -410,9 +413,34 @@ getCategoryList();
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-tabs__nav-wrap) {
|
||||
overflow: unset;
|
||||
|
||||
.el-tabs__nav-scroll {
|
||||
overflow: unset;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-tabs__item.is-disabled) {
|
||||
&:hover {
|
||||
//cursor: url("../../../assets/images/model-alert.svg"), not-allowed;
|
||||
}
|
||||
|
||||
&:hover::before {
|
||||
content: "请先添加产品";
|
||||
position: absolute;
|
||||
background-color: tomato;
|
||||
line-height: 1;
|
||||
color: #fff;
|
||||
padding: 4px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
|
||||
display: block;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
top: 110%;
|
||||
backdrop-filter: blur(16px);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -7,6 +7,7 @@
|
||||
:model="queryParams"
|
||||
label-position="left"
|
||||
label-width="100px"
|
||||
@submit.prevent
|
||||
>
|
||||
<!-- <el-form-item label="产品编码SN" prop="productSn">-->
|
||||
<!-- <el-input-->
|
||||
@ -151,24 +152,31 @@
|
||||
>
|
||||
<el-table-column align="center" type="selection" width="55" />
|
||||
<!-- <el-table-column align="center" label="产品ID" prop="productId" />-->
|
||||
<el-table-column align="center" label="产品编码SN" prop="productSn" />
|
||||
<el-table-column align="center" label="产品名称" prop="productName" />
|
||||
<el-table-column align="center" label="产品分类" prop="categoryId">
|
||||
<el-table-column align="center" label="名称" prop="productName" />
|
||||
<el-table-column align="center" label="编码SN" prop="productSn" />
|
||||
<el-table-column align="center" label="分类" prop="categoryId">
|
||||
<template #default="{ row }">
|
||||
{{ findNode(categoryOptions, row.categoryId)?.name }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="租户" prop="tenantName">
|
||||
<!-- <el-table-column align="center" label="租户" prop="tenantName">-->
|
||||
<!-- <template #default="{ row }">-->
|
||||
<!-- {{-->
|
||||
<!-- tenantOptions.find((el) => el.tenantId === row.tenantId)-->
|
||||
<!-- ?.tenantName ?? "未知"-->
|
||||
<!-- }}-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column align="center" label="设备类型" prop="deviceType">
|
||||
<template #default="{ row }">
|
||||
{{
|
||||
tenantOptions.find((el) => el.tenantId === row.tenantId)
|
||||
?.tenantName ?? "未知"
|
||||
}}
|
||||
<dict-tag :options="deviceTypeDict" :value="[row.deviceType]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="mqtt账号" prop="mqttAccount" />
|
||||
<el-table-column align="center" label="mqtt密码" prop="mqttPassword" />
|
||||
<el-table-column align="center" label="产品秘钥" prop="mqttSecret" />
|
||||
<el-table-column align="center" label="厂商" prop="companyName" />
|
||||
<el-table-column align="center" label="型号" prop="model" />
|
||||
<!-- <el-table-column align="center" label="mqtt账号" prop="mqttAccount" />-->
|
||||
<!-- <el-table-column align="center" label="mqtt密码" prop="mqttPassword" />-->
|
||||
<!-- <el-table-column align="center" label="产品秘钥" prop="mqttSecret" />-->
|
||||
<el-table-column align="center" label="状态" prop="status">
|
||||
<template #default="{ row }">
|
||||
<dict-tag :options="productStatusMap" :value="[row.status]" />
|
||||
@ -179,16 +187,16 @@
|
||||
<dict-tag :options="deviceTypeDict" :value="[row.deviceType]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="认证方式" prop="vertificateMethod">
|
||||
<template #default="{ row }">
|
||||
<!-- {{ vertificateMethodOptions.get(row.vertificateMethod) ?? "未知" }}-->
|
||||
<dict-tag
|
||||
:options="vertificateMethodDict"
|
||||
:value="[row.vertificateMethod]"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="产品图片" prop="imgUrl">
|
||||
<!-- <el-table-column align="center" label="认证方式" prop="vertificateMethod">-->
|
||||
<!-- <template #default="{ row }">-->
|
||||
<!-- <!– {{ vertificateMethodOptions.get(row.vertificateMethod) ?? "未知" }}–>-->
|
||||
<!-- <dict-tag-->
|
||||
<!-- :options="vertificateMethodDict"-->
|
||||
<!-- :value="[row.vertificateMethod]"-->
|
||||
<!-- />-->
|
||||
<!-- </template>-->
|
||||
<!-- </el-table-column>-->
|
||||
<el-table-column align="center" label="图片" prop="imgUrl">
|
||||
<template #default="{ row }">
|
||||
<el-image
|
||||
:preview-src-list="[`${baseUrl}/${row.imgUrl}`]"
|
||||
@ -201,11 +209,18 @@
|
||||
align="center"
|
||||
class-name="small-padding fixed-width"
|
||||
label="操作"
|
||||
width="190px"
|
||||
>
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
v-hasPermi="['product:product:remove']"
|
||||
link
|
||||
type="success"
|
||||
@click="handleDelete(scope.row)"
|
||||
>发布
|
||||
</el-button>
|
||||
<el-button
|
||||
v-hasPermi="['product:product:edit']"
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleUpdate(scope.row)"
|
||||
@ -213,9 +228,8 @@
|
||||
</el-button>
|
||||
<el-button
|
||||
v-hasPermi="['product:product:remove']"
|
||||
icon="Delete"
|
||||
link
|
||||
type="primary"
|
||||
type="danger"
|
||||
@click="handleDelete(scope.row)"
|
||||
>删除
|
||||
</el-button>
|
||||
@ -290,11 +304,7 @@ import {
|
||||
updateProduct,
|
||||
} from "@/api/product/product";
|
||||
import { useRouter } from "vue-router";
|
||||
import {
|
||||
deviceTypeDict,
|
||||
productStatusMap,
|
||||
vertificateMethodDict,
|
||||
} from "@/constant/dict";
|
||||
import { deviceTypeDict, productStatusMap } from "@/constant/dict";
|
||||
import { listTenant } from "@/api/system/tenant";
|
||||
import { ref } from "vue";
|
||||
import { listCategory } from "@/api/product/category";
|
||||
|
@ -148,7 +148,11 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="模型类别" prop="type">
|
||||
<el-radio-group v-model="form.type" @change="typeChange(form.type)">
|
||||
<el-radio-group
|
||||
v-model="form.type"
|
||||
class="ios-style-radio"
|
||||
@change="typeChange(form.type)"
|
||||
>
|
||||
<el-radio-button :label="1">属性</el-radio-button>
|
||||
<el-radio-button :label="2">功能</el-radio-button>
|
||||
<el-radio-button :label="3">事件</el-radio-button>
|
||||
@ -188,30 +192,10 @@
|
||||
>
|
||||
<el-option key="integer" label="整数" value="integer"></el-option>
|
||||
<el-option key="decimal" label="小数" value="decimal"></el-option>
|
||||
<el-option
|
||||
key="bool"
|
||||
:disabled="form.type === 1"
|
||||
label="布尔"
|
||||
value="bool"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="enum"
|
||||
:disabled="form.type === 1"
|
||||
label="枚举"
|
||||
value="enum"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="string"
|
||||
:disabled="form.type === 1"
|
||||
label="字符串"
|
||||
value="string"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="array"
|
||||
:disabled="form.type === 1"
|
||||
label="数组"
|
||||
value="array"
|
||||
></el-option>
|
||||
<el-option key="bool" label="布尔" value="bool"></el-option>
|
||||
<el-option key="enum" label="枚举" value="enum"></el-option>
|
||||
<el-option key="string" label="字符串" value="string"></el-option>
|
||||
<el-option key="array" label="数组" value="array"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
@ -243,9 +227,12 @@
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="步长">
|
||||
<!-- oninput="value=value.replace(/[^0-9.]/,'')"-->
|
||||
<!-- :formatter="formatInput"-->
|
||||
<!-- oninput="value=value.replace(/[^0-9.]/g, '')"-->
|
||||
<el-input
|
||||
v-model="form.specs.step"
|
||||
oninput="value=value.replace(/[^\d]/g,'')"
|
||||
:step="form.datatype === 'decimal' ? 0.1 : 1"
|
||||
placeholder="请输入步长,例如:1"
|
||||
style="width: 385px"
|
||||
type="number"
|
||||
@ -462,6 +449,20 @@ const checkIdIsUnique = (rule, value, callback) => {
|
||||
}
|
||||
callback();
|
||||
};
|
||||
|
||||
function formatInput(value) {
|
||||
const regex = /^[0-9.]*$/; // 只允许数字和小数点
|
||||
const lastChar = value.charAt(value.length - 1);
|
||||
if (!regex.test(lastChar)) {
|
||||
return value.slice(0, -1); // 将最后一个非法字符删除
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
function handleStepInput(value) {
|
||||
form.value.specs.step = form.value.specs.step.replace(/[^0-9.]/g, "");
|
||||
}
|
||||
|
||||
const data = reactive({
|
||||
// 物模型
|
||||
thingsModel: {},
|
||||
|
@ -145,7 +145,7 @@
|
||||
<el-table-column align="center" label="物模型ID" prop="modelId" />
|
||||
<el-table-column align="center" label="物模型名称" prop="modelName" />
|
||||
<el-table-column align="center" label="产品ID" prop="productId" />
|
||||
<el-table-column align="center" label="租户ID" prop="tenantId" />
|
||||
<!-- <el-table-column align="center" label="租户ID" prop="tenantId" />-->
|
||||
<el-table-column
|
||||
align="center"
|
||||
label="标识符,产品下唯一"
|
||||
@ -153,7 +153,7 @@
|
||||
/>
|
||||
<el-table-column align="center" label="模型类别" prop="type">
|
||||
<template #default="{ row }">
|
||||
<model-type-tags :type="row.type" />
|
||||
<dict-tag :options="modelTypeDict" :value="[row.type]"></dict-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column align="center" label="数据类型" prop="datatype">
|
||||
@ -182,13 +182,13 @@
|
||||
class-name="small-padding fixed-width"
|
||||
label="操作"
|
||||
>
|
||||
<template #default="scope">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
v-hasPermi="['thingsmodel:model:edit']"
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleUpdate(scope.row)"
|
||||
@click="handleUpdate(row)"
|
||||
>修改
|
||||
</el-button>
|
||||
<el-button
|
||||
@ -196,7 +196,7 @@
|
||||
icon="Delete"
|
||||
link
|
||||
type="primary"
|
||||
@click="handleDelete(scope.row)"
|
||||
@click="handleDelete(row)"
|
||||
>删除
|
||||
</el-button>
|
||||
</template>
|
||||
@ -294,30 +294,10 @@
|
||||
>
|
||||
<el-option key="integer" label="整数" value="integer"></el-option>
|
||||
<el-option key="decimal" label="小数" value="decimal"></el-option>
|
||||
<el-option
|
||||
key="bool"
|
||||
:disabled="form.type === 1"
|
||||
label="布尔"
|
||||
value="bool"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="enum"
|
||||
:disabled="form.type === 1"
|
||||
label="枚举"
|
||||
value="enum"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="string"
|
||||
:disabled="form.type === 1"
|
||||
label="字符串"
|
||||
value="string"
|
||||
></el-option>
|
||||
<el-option
|
||||
key="array"
|
||||
:disabled="form.type === 1"
|
||||
label="数组"
|
||||
value="array"
|
||||
></el-option>
|
||||
<el-option key="bool" label="布尔" value="bool"></el-option>
|
||||
<el-option key="enum" label="枚举" value="enum"></el-option>
|
||||
<el-option key="string" label="字符串" value="string"></el-option>
|
||||
<el-option key="array" label="数组" value="array"></el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div v-if="form.datatype === 'integer' || form.datatype === 'decimal'">
|
||||
@ -350,6 +330,7 @@
|
||||
<el-form-item label="步长">
|
||||
<el-input
|
||||
v-model="form.specs.step"
|
||||
:step="form.datatype === 'decimal' ? 0.1 : 1"
|
||||
placeholder="请输入步长,例如:1"
|
||||
style="width: 385px"
|
||||
type="number"
|
||||
@ -454,9 +435,9 @@ import {
|
||||
import { formatSpecsDisplay } from "@/utils/thingsmodel";
|
||||
import { listProduct } from "@/api/product/product";
|
||||
import { listTenant } from "@/api/system/tenant";
|
||||
import ModelTypeTags from "@/views/components/model-type-tags";
|
||||
import { dataTypeDict } from "../../../constant/dict";
|
||||
import { ref } from "vue";
|
||||
import { dataTypeDict, modelTypeDict } from "@/constant/dict";
|
||||
import { getCurrentInstance, ref } from "vue";
|
||||
import DictTag from "@/components/DictTag/index.vue";
|
||||
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
|
@ -319,6 +319,7 @@
|
||||
<el-form-item label="步长">
|
||||
<el-input
|
||||
v-model="form.specs.step"
|
||||
:step="form.datatype === 'decimal' ? 0.1 : 1"
|
||||
placeholder="请输入步长,例如:1"
|
||||
style="width: 385px"
|
||||
type="number"
|
||||
|
@ -31,7 +31,7 @@ export default defineConfig(({ mode, command }) => {
|
||||
proxy: {
|
||||
// https://cn.vitejs.dev/config/#server-proxy
|
||||
"/dev-api": {
|
||||
target: "http://192.168.1.6:1616",
|
||||
target: "http://192.168.1.3:1616",
|
||||
changeOrigin: true,
|
||||
rewrite: (p) => p.replace(/^\/dev-api/, ""),
|
||||
},
|
||||
|