feat: 服务器模块开发

dev-deviceSetting
JINGYJ 1 year ago
parent f95eca1731
commit 716aec6097

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

@ -0,0 +1,27 @@
<svg width="405" height="174" viewBox="0 0 405 174" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.6" d="M1 172V173H2H402H403V172V102.839V102.373L402.643 102.073L396.886 97.2393V74.35L402.643 69.5158L403 69.2161V68.75V2V1H402H2H1V2V172Z" fill="#071D46" stroke="#1F4885" stroke-width="2"/>
<path d="M147 172V2H403V68.75L396.886 73.8839V97.7054L403 102.839V172H147Z" fill="url(#paint0_linear_8978_108437)"/>
<path opacity="0.3" d="M364 26H277.381L238.47 10H194" stroke="url(#paint1_linear_8978_108437)" stroke-width="1.5"/>
<path opacity="0.3" d="M364 148H277.381L238.47 164H194" stroke="url(#paint2_linear_8978_108437)" stroke-width="1.5"/>
<path d="M17 173H1V157" stroke="#20A0FD" stroke-width="2"/>
<path d="M387 1H403V17" stroke="#20A0FD" stroke-width="2"/>
<path d="M387 173H403V157" stroke="#20A0FD" stroke-width="2"/>
<path d="M405 100V71L400 75V95.5L405 100Z" fill="#0A7CFE"/>
<path d="M17 2H1V18" stroke="#20A0FD" stroke-width="2"/>
<defs>
<linearGradient id="paint0_linear_8978_108437" x1="254.5" y1="2" x2="254.5" y2="134" gradientUnits="userSpaceOnUse">
<stop stop-color="#084BA1"/>
<stop offset="1" stop-color="#071E49"/>
</linearGradient>
<linearGradient id="paint1_linear_8978_108437" x1="353.697" y1="26" x2="190.566" y2="26" gradientUnits="userSpaceOnUse">
<stop stop-color="#20A0FD" stop-opacity="0"/>
<stop offset="0.48" stop-color="#20A0FD"/>
<stop offset="1" stop-color="#20A0FD" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint2_linear_8978_108437" x1="369.152" y1="148" x2="197.434" y2="148" gradientUnits="userSpaceOnUse">
<stop stop-color="#20A0FD" stop-opacity="0"/>
<stop offset="0.48" stop-color="#20A0FD"/>
<stop offset="1" stop-color="#20A0FD" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

@ -0,0 +1,14 @@
<svg width="405" height="45" viewBox="0 0 405 45" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 1H405V45H0V1Z" fill="url(#paint0_linear_10056_35901)"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M0 0H405V2H0V0Z" fill="url(#paint1_linear_10056_35901)"/>
<defs>
<linearGradient id="paint0_linear_10056_35901" x1="0" y1="30.7004" x2="405" y2="30.7004" gradientUnits="userSpaceOnUse">
<stop stop-color="#122D6E"/>
<stop offset="1" stop-color="#122D6E" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_10056_35901" x1="3.46577" y1="0" x2="405" y2="0" gradientUnits="userSpaceOnUse">
<stop stop-color="#20A0FD"/>
<stop offset="1" stop-color="#20A0FD" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 779 B

@ -0,0 +1,19 @@
<svg width="827" height="16" viewBox="0 0 827 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M390 2H396" stroke="#07A6FF" stroke-width="3"/>
<path d="M429 2H436" stroke="#07A6FF" stroke-width="3"/>
<path d="M0 1.5H400" stroke="url(#paint0_linear_8864_88592)" stroke-width="3"/>
<path d="M827 3.5H427" stroke="url(#paint1_linear_8864_88592)" stroke-width="3"/>
<path d="M401 2H405.182L412.5 13L419.063 2H424" stroke="#07A6FF" stroke-width="3"/>
<defs>
<linearGradient id="paint0_linear_8864_88592" x1="-5.99998" y1="-0.0156443" x2="376.89" y2="1.98098" gradientUnits="userSpaceOnUse">
<stop stop-color="#07A6FF" stop-opacity="0"/>
<stop offset="0.486666" stop-color="#07A6FF"/>
<stop offset="1" stop-color="#07A6FF" stop-opacity="0"/>
</linearGradient>
<linearGradient id="paint1_linear_8864_88592" x1="824.5" y1="2.0063" x2="450.099" y2="2.0063" gradientUnits="userSpaceOnUse">
<stop offset="0.00166626" stop-color="#07A6FF" stop-opacity="0"/>
<stop offset="0.476666" stop-color="#07A6FF"/>
<stop offset="1" stop-color="#07A6FF" stop-opacity="0"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -45,6 +45,7 @@
);
background-image: url("@/assets/dataScreen/modelList/inUsed.svg");
background-repeat: no-repeat;
cursor: pointer;
.model-box-state {
position: absolute;
top: 0;
@ -125,17 +126,17 @@
left: 91px;
width: 72px;
height: 88px;
background: url("@/assets/dataScreen/modelList/generalIndustry.svg")
no-repeat center center;
}
.model-box-icon-phone {
background: url("@/assets/dataScreen/modelList/phoneIndustry.svg")
no-repeat center center;
}
.model-box-icon-mechanical {
background: url("@/assets/dataScreen/modelList/mechanicalIndustry.svg")
no-repeat center center;
// background: url("@/assets/dataScreen/modelList/generalIndustry.svg")
// no-repeat center center;
}
// .model-box-icon-phone {
// background: url("@/assets/dataScreen/modelList/phoneIndustry.svg")
// no-repeat center center;
// }
// .model-box-icon-mechanical {
// background: url("@/assets/dataScreen/modelList/mechanicalIndustry.svg")
// no-repeat center center;
// }
}
.model-box-notUsed {
width: 100%;
@ -151,3 +152,58 @@
}
}
}
:deep(.modelListDialog) {
width: 640px;
height: 300px;
background: #021f4e !important;
border-radius: 8px;
border: 1px solid #438cff;
.el-dialog__body {
padding: 0 20px;
.modelListDialogBody {
.modelListDialogTitle {
margin-bottom: 8px;
font-weight: bold;
font-size: 14px;
color: #ffffff;
}
.modelListDialogContent {
// display: flex;
// justify-content: flex-start;
// align-items: center;
// flex-wrap: wrap;
font-weight: 400;
font-size: 14px;
color: #fff;
line-height: 22px;
span {
margin: 0 8px;
font-weight: bold;
font-size: 14px;
color: #ffffff;
}
.model-box-type,
.model-box-type-deep {
display: inline-block;
// margin-top: 12px;
margin-left: 0px;
// margin-bottom: 12px;
width: 56px;
height: 20px;
background: linear-gradient(180deg, #21c7ff 0%, #428cff 100%);
border-radius: 2px;
font-size: 12px;
text-align: center;
line-height: 20px;
}
.model-box-type-deep {
background: linear-gradient(180deg, #ffb21a 0%, #ff9b3e 100%);
}
.modelListState {
font-weight: 400;
color: #faad14;
}
}
}
}
}

@ -1,7 +1,6 @@
<script setup lang="ts">
// import { getList } from "@/api/list";
import { getModelList } from "@/api/list";
import { getList } from "./api";
import error from "@/assets/dataScreen/modelList/error.png";
import loading from "@/assets/dataScreen/modelList/loading.png";
import { ElLoading } from "element-plus";
@ -9,7 +8,19 @@ import "vue-waterfall-plugin-next/dist/style.css";
import InfiniteLoading from "v3-infinite-loading";
import { onMounted, reactive, ref, nextTick } from "vue";
import backTop from "@/assets/svg/back_top.svg?component";
import { LazyImg, Waterfall } from "vue-waterfall-plugin-next";
import generalIndustry from "@/assets/dataScreen/modelList/generalIndustry.png";
import phoneIndustry from "@/assets/dataScreen/modelList/phoneIndustry.png";
import photovoltaicIndustry from "@/assets/dataScreen/modelList/photovoltaicIndustry.png";
import pipeIndustry from "@/assets/dataScreen/modelList/pipeIndustry.png";
import mechanicalIndustry from "@/assets/dataScreen/modelList/mechanicalIndustry.png";
import lithiumBatteryIndustry from "@/assets/dataScreen/modelList/lithiumBatteryIndustry.png";
import healthcareIndustry from "@/assets/dataScreen/modelList/healthcareIndustry.png";
import foundryIndustry from "@/assets/dataScreen/modelList/foundryIndustry.png";
import electronicsIndustry from "@/assets/dataScreen/modelList/electronicsIndustry.png";
import bathroomIndustry from "@/assets/dataScreen/modelList/bathroomIndustry.png";
import bankIndustry from "@/assets/dataScreen/modelList/bankIndustry.png";
import PCBIndustry from "@/assets/dataScreen/modelList/PCBIndustry.png";
import { Waterfall } from "vue-waterfall-plugin-next";
defineOptions({
name: "ModelList"
});
@ -60,6 +71,8 @@ const page = ref(1);
const list = ref([]);
const pageSize = ref();
const loadingInstance = ref();
const modelDialogVisible = ref(false);
const modelInfo = ref();
/** 加载更多 */
function handleLoadMore() {
@ -83,12 +96,15 @@ function handleLoadMore() {
});
}
function handleDelete(item, index) {
list.value.splice(index, 1);
}
// function handleDelete(item, index) {
// list.value.splice(index, 1);
// }
function handleClick(item) {
console.log(item);
modelDialogVisible.value = true;
modelInfo.value = item;
console.log(modelInfo.value);
}
function getModelIcon(params: string) {
@ -98,14 +114,37 @@ function getModelIcon(params: string) {
params == "手机、电子、SMT" ||
params == "手机、液晶显示屏"
) {
return "model-box-icon-phone";
return phoneIndustry;
} else if (
params ==
"机械、金属工件、线缆、铸造、薄膜、玻璃、造纸、铝板带、铝箔、铜箔、无纺布"
) {
return "model-box-icon-mechanical";
return mechanicalIndustry;
} else if (
params == "PVC管材、金属管材、金属工件、塑料水管、汽车软管、线缆"
) {
return pipeIndustry;
} else if (params == "锂电池") {
return lithiumBatteryIndustry;
} else if (params == "食品、饮料、医疗卫生" || params == "食品、饮料") {
return healthcareIndustry;
} else if (params == "陶瓷、卫浴、瓷砖") {
return bathroomIndustry;
} else if (
params == "机加工、光伏、电子、SMT、手机、锂电池、精密零部件加工" ||
params == "光伏"
) {
return photovoltaicIndustry;
} else if (params == "钢铁、冶金、铸造") {
return foundryIndustry;
} else if (params == "银行、营业厅") {
return bankIndustry;
} else if (params == "机加工、电子、手机、精密零部件加工、汽车") {
return electronicsIndustry;
} else if (params == "PCB") {
return PCBIndustry;
} else {
return "model-box-icon";
return generalIndustry;
}
}
@ -124,7 +163,7 @@ onMounted(() => {
<div class="model-list-box w-full">
<el-scrollbar height="810px" class="content">
<Waterfall :list="list" v-bind="options">
<template #item="{ item, url, index }">
<template #item="{ item }">
<div
:class="
item.state === '在线'
@ -160,7 +199,11 @@ onMounted(() => {
适用行业{{ item.industry }}
</div>
</div>
<div :class="getModelIcon(item.industry)" />
<!-- <div :class="getModelIcon(item.industry)" /> -->
<div class="model-box-icon">
<!-- <LazyImg :url="generalIndustry" /> -->
<img :src="getModelIcon(item.industry)" />
</div>
<!-- {{ item }} -->
<!-- <div class="overflow-hidden">
<LazyImg
@ -214,6 +257,39 @@ onMounted(() => {
</div>
</div>
<div class="banner_side banner_side_right" />
<el-dialog
v-model="modelDialogVisible"
title="模型详情"
width="500"
align-center
class="modelListDialog"
>
<div class="modelListDialogBody">
<div class="modelListDialogTitle">基本信息</div>
<div class="modelListDialogContent">
模型名称:<span>{{ modelInfo.deviceSort }}</span>
<span
:class="
modelInfo.type === '经典算法'
? 'model-box-type'
: 'model-box-type-deep'
"
>{{ modelInfo.type }}</span
>
模型版本:<span>{{ modelInfo.version }}</span
>适用行业:<span>{{ modelInfo.industry }}</span>
</div>
<div class="modelListDialogContent mb-3">
模型状态:<span class="modelListState">{{
modelInfo.state === "在线" ? "使用中" : "未使用"
}}</span>
</div>
<div class="modelListDialogTitle">模型简介</div>
<div class="modelListDialogContent">
{{ modelInfo.description }}
</div>
</div>
</el-dialog>
</div>
</template>

@ -0,0 +1,191 @@
<script setup lang="ts">
import { computed, PropType, ref } from "vue";
import { AnimationPic } from "@/components/AnimationCard";
import serverIcon from "@/assets/animate/device/dataScreenServer.json";
defineOptions({
name: "ServerBox"
});
interface CardProductType {
isEnabled: boolean;
state: string;
description: string;
deviceSort: string;
}
const props = defineProps({
serverData: {
type: Object as PropType<CardProductType>
}
});
// const cardClass = computed(() => [
// "server-card",
// { "server-card_offline": props.serverData?.state === "线" }
// ]);
const stateClass = computed(() => [
"server-box-title-state",
{ "server-box-title-state_offline": props.serverData?.state === "离线" }
]);
const generateRandomTwoDecimal = () => {
// [0, 1)
const randomFraction = Math.random();
// 100
const multipliedValue = randomFraction * 100;
// 使 Math.round()
return Math.round(multipliedValue) / 100;
};
const progressData = ref([
{
label: "CPU",
percent: generateRandomTwoDecimal(),
strokeColor: "rgb(243,48,5)"
},
{
label: "内存",
percent: generateRandomTwoDecimal(),
strokeColor: "rgb(33,169,122)"
},
{
label: "存储",
percent: generateRandomTwoDecimal(),
strokeColor: "rgb(33,169,122)"
},
{
label: "GPU",
percent: generateRandomTwoDecimal(),
strokeColor: "rgb(250,173,20)"
}
]);
</script>
<template>
<div class="server-box">
<div class="server-box-title flex justify-start items-center">
<span class="server-box-title-icon" />
<span class="server-box-title-name">{{ serverData?.deviceSort }}</span>
<span :class="stateClass">{{ serverData?.state }}</span>
</div>
<div class="server-box-content">
<div class="server-box-content-left">
<AnimationPic :value="serverIcon" />
</div>
<div class="server-box-content-right">
<ul class="w-full">
<li v-for="(v, k) in progressData" :key="k">
<div class="flex items-center rectProgress_box">
<span>
{{ v.label }}
</span>
<div class="flex flex-1">
<el-progress
style="width: 100%; margin-left: 8px"
:show-text="false"
:stroke-width="10"
:percentage="100 * v.percent"
:color="v.strokeColor"
/>
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</template>
<style lang="scss" scoped>
.server-box {
box-sizing: border-box;
width: 404px;
// height: 214px;
.server-box-title {
box-sizing: border-box;
padding-left: 20px;
width: 100%;
height: 44px;
background: url("@/assets/dataScreen/serverList/serverBoxTitle.svg")
no-repeat left center;
.server-box-title-icon {
width: 12px;
height: 22px;
background: url("@/assets/dataScreen/common/subTitleIcon.svg") no-repeat;
margin-right: 12px;
}
.server-box-title-name {
margin-right: 12px;
font-family: PingFang SC, PingFang SC;
font-weight: bold;
font-size: 16px;
color: #2de6ff;
}
.server-box-title-state {
width: 48px;
height: 24px;
background: #52c41a;
border-radius: 2px;
font-weight: 400;
font-size: 12px;
color: #ffffff;
line-height: 24px;
text-align: center;
&_offline {
background-color: #ccc;
}
}
}
.server-box-content {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 174px;
background: url("@/assets/dataScreen/serverList/serverBoxBg.svg") no-repeat;
.server-box-content-left {
margin: 0 12px;
width: 120px;
}
.server-box-content-right {
box-sizing: border-box;
flex: 1;
padding: 0 20px;
// .rectProgress_box {
// }
}
}
}
:deep(.rectProgress_box) {
padding: 4px 0;
font-size: 12px;
// color: $--web-font1;
.el-progress-bar__outer {
border-radius: 2px;
background-color: #ebebeb;
}
.el-progress-bar__inner {
border-radius: 0;
}
}
</style>
<!-- <style lang="scss">
.rectProgress_box {
.el-progress-bar__outer {
border-radius: 2px;
background-color: #ebebeb;
}
.el-progress-bar__inner {
border-radius: 0;
}
}
</style> -->

@ -1,7 +1,7 @@
.serverList {
padding: 45px 32px;
padding: 45px 0px;
.banner_side {
width: 151px;
width: 130px;
height: 855px;
background: url("@/assets/dataScreen/serverList/serverListSide.svg")
no-repeat left center;
@ -9,4 +9,105 @@
.banner_side_right {
transform: rotateY(180deg);
}
.server-list-mid {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.server-list-title {
margin-bottom: 24px;
width: 827px;
height: 61px;
background: url("@/assets/dataScreen/serverList/serverListTitle.svg")
no-repeat center bottom;
font-size: 28px;
line-height: 40px;
text-align: center;
span {
background-image: -webkit-linear-gradient(
270deg,
#ffffff 41%,
#07a6ff 99%
);
background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.server-list-box {
.server-box {
box-sizing: border-box;
width: 404px;
// height: 214px;
.server-box-title {
box-sizing: border-box;
padding-left: 20px;
width: 100%;
height: 44px;
background: url("@/assets/dataScreen/serverList/serverBoxTitle.svg")
no-repeat left center;
.server-box-title-icon {
width: 12px;
height: 22px;
background: url("@/assets/dataScreen/common/subTitleIcon.svg")
no-repeat;
margin-right: 12px;
}
.server-box-title-name {
margin-right: 12px;
font-family: PingFang SC, PingFang SC;
font-weight: bold;
font-size: 16px;
color: #2de6ff;
}
.server-box-title-state {
width: 48px;
height: 24px;
background: #52c41a;
border-radius: 2px;
font-weight: 400;
font-size: 12px;
color: #ffffff;
line-height: 24px;
text-align: center;
}
}
.server-box-content {
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 174px;
background: url("@/assets/dataScreen/serverList/serverBoxBg.svg")
no-repeat;
.server-box-content-left {
margin: 0 12px;
width: 120px;
}
.server-box-content-right {
box-sizing: border-box;
flex: 1;
padding: 0 20px;
// .rectProgress_box {
// }
}
}
}
}
}
}
:deep(.rectProgress_box) {
padding: 4px 0;
font-size: 12px;
// color: $--web-font1;
.el-progress-bar__outer {
border-radius: 2px;
background-color: #ebebeb;
}
.el-progress-bar__inner {
border-radius: 0;
}
}

@ -1,13 +1,162 @@
<script setup lang="ts">
import { getServerList } from "@/api/list";
import error from "@/assets/dataScreen/modelList/error.png";
import loading from "@/assets/dataScreen/modelList/loading.png";
import { ElLoading } from "element-plus";
import "vue-waterfall-plugin-next/dist/style.css";
import InfiniteLoading from "v3-infinite-loading";
import { onMounted, reactive, ref, nextTick } from "vue";
import backTop from "@/assets/svg/back_top.svg?component";
import { Waterfall } from "vue-waterfall-plugin-next";
import ServerBox from "./components/ServerBox.vue";
defineOptions({
name: "ServerList"
});
const options = reactive({
// key
rowKey: "id",
//
gutter: 17,
// gutter
hasAroundGutter: false,
// PC
width: 400,
//
breakpoints: {
1200: {
// 1200
rowPerView: 4
},
800: {
// 800
rowPerView: 3
},
500: {
// 500
rowPerView: 2
}
},
// https://animate.style/
animationEffect: "animate__zoomInUp",
//
animationDuration: 1000,
//
animationDelay: 300,
//
backgroundColor: "transparent",
// 使 xxx.xxx.xxx
imgSelector: "src.original",
//
loadProps: {
loading,
error
},
//
lazyload: true
});
const page = ref(1);
const list = ref([]);
const pageSize = ref();
const loadingInstance = ref();
/** 加载更多 */
function handleLoadMore() {
loadingInstance.value = ElLoading.service({
target: ".content",
background: "transparent",
text: "加载中"
});
getServerList({
page: page.value,
pageSize: pageSize.value
}).then(res => {
console.log(res);
setTimeout(() => {
list.value.push(...res.data.list);
page.value += 1;
nextTick(() => {
loadingInstance.value.close();
});
}, 1000);
});
}
// function handleClick(item) {
// console.log(item);
// modelDialogVisible.value = true;
// modelInfo.value = item;
// console.log(modelInfo.value);
// }
// const stateClass = computed(() => [
// "server-state",
// { "server-state_offline": props.device?.state === "线" }
// ]);
onMounted(() => {
handleLoadMore();
});
</script>
<template>
<div class="flex justify-between serverList">
<div class="banner_side" />
<div>mid</div>
<div class="server-list-mid">
<div class="server-list-title ff1"><span>服务器运行状态</span></div>
<div class="server-list-box w-full">
<el-scrollbar height="704px" class="content">
<Waterfall :list="list" v-bind="options">
<template #item="{ item }">
<ServerBox :serverData="item" />
<!-- <div class="server-box">
<div class="server-box-title flex justify-start items-center">
<span class="server-box-title-icon" />
<span class="server-box-title-name">服务器</span>
<span class="server-box-title-state">{{ "在线" }}</span>
</div>
<div class="server-box-content">
<div class="server-box-content-left">
<AnimationPic :value="serverIcon" />
</div>
<div class="server-box-content-right">
<ul class="w-full">
<li v-for="(v, k) in progressData" :key="k">
<div class="flex items-center rectProgress_box">
<span>
{{ v.label }}
</span>
<div class="flex flex-1">
<el-progress
style="width: 100%; margin-left: 8px"
:show-text="false"
:stroke-width="10"
:percentage="100 * v.percent"
:color="v.strokeColor"
/>
</div>
</div>
</li>
</ul>
</div>
</div>
</div> -->
</template>
</Waterfall>
<el-backtop
title="回到顶部"
:right="35"
:visibility-height="400"
target=".content .el-scrollbar__wrap"
>
<backTop />
</el-backtop>
<!-- 加载更多 -->
<InfiniteLoading :firstload="false" @infinite="handleLoadMore" />
</el-scrollbar>
</div>
</div>
<div class="banner_side banner_side_right" />
</div>
</template>

Loading…
Cancel
Save