feat: 模型列表模块开发
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 129 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 207 KiB |
@ -0,0 +1,12 @@
|
|||||||
|
export default {
|
||||||
|
path: "/model",
|
||||||
|
meta: {
|
||||||
|
title: "模型列表",
|
||||||
|
icon: "icon-moxingliebiao-weixuan",
|
||||||
|
// showLink: false,
|
||||||
|
rank: 4,
|
||||||
|
roles: ["admin", "common"]
|
||||||
|
},
|
||||||
|
component: () => import("@/views/modelList/index.vue"),
|
||||||
|
name: "ModelList"
|
||||||
|
} as RouteConfigsTable;
|
@ -0,0 +1,138 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, PropType } from "vue";
|
||||||
|
import { model_OCR, model_mark, model_colour } from "./static";
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "ModelCard"
|
||||||
|
});
|
||||||
|
|
||||||
|
interface CardProductType {
|
||||||
|
isEnabled: boolean;
|
||||||
|
state: string;
|
||||||
|
description: string;
|
||||||
|
deviceSort: string;
|
||||||
|
type: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
device: {
|
||||||
|
type: Object as PropType<CardProductType>
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const cardClass = computed(() => [
|
||||||
|
"model-card",
|
||||||
|
{ "model-card_offline": props.device?.state === "离线" }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// const stateClass = computed(() => [
|
||||||
|
// "model-state",
|
||||||
|
// { "model-state_offline": props.device?.state === "离线" }
|
||||||
|
// ]);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="cardClass">
|
||||||
|
<div class="model-header">
|
||||||
|
<div class="model-name">{{ device?.deviceSort }}</div>
|
||||||
|
<div class="model-icon">
|
||||||
|
<img :src="model_OCR" alt="" v-if="device?.type === 1" />
|
||||||
|
<img :src="model_mark" alt="" v-else-if="device?.type === 2" />
|
||||||
|
<img :src="model_colour" alt="" v-else />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="model-content">
|
||||||
|
<div class="model-version">
|
||||||
|
<i class="iconfont icon-banben model-content-icon" />
|
||||||
|
版本: <span>{{ "V1.6.25" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="model-provider">
|
||||||
|
<i class="iconfont icon-tigongfang model-content-icon" />
|
||||||
|
提供方: <span>{{ "苏胜天" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="model-updateTime">
|
||||||
|
<i class="iconfont icon-shijian model-content-icon" />
|
||||||
|
更新时间: <span>{{ "2023.09.10" }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="model-introduction">
|
||||||
|
模型简介:
|
||||||
|
<span>{{
|
||||||
|
"针对企业人员是否有违章违规的问题,首先采用高性能的深度学习目标检测算法对图像中的人员进行定位等。"
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.model-card {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: 278px;
|
||||||
|
border-radius: 8px;
|
||||||
|
box-shadow: 0 8px 16px 0 rgb(0 0 0 / 10%);
|
||||||
|
|
||||||
|
.model-header {
|
||||||
|
position: relative;
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
width: 100%;
|
||||||
|
height: 88px;
|
||||||
|
padding: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #154ddd;
|
||||||
|
background-image: url("../../../assets/model_header.png");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 100% 100%;
|
||||||
|
background-size: cover;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
|
||||||
|
.model-icon {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
height: 190px;
|
||||||
|
padding: 16px;
|
||||||
|
|
||||||
|
.model-version,
|
||||||
|
.model-provider,
|
||||||
|
.model-updateTime {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
.model-content-icon {
|
||||||
|
margin-right: 8px;
|
||||||
|
color: #154ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.model-introduction {
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 400;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
span {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,5 @@
|
|||||||
|
import model_OCR from "@/assets/svg/model/model_OCR.png";
|
||||||
|
import model_mark from "@/assets/svg/model/model_mark.png";
|
||||||
|
import model_colour from "@/assets/svg/model/model_colour.png";
|
||||||
|
|
||||||
|
export { model_OCR, model_mark, model_colour };
|
@ -0,0 +1,114 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import ModelCard from "./components/ModelCard.vue";
|
||||||
|
import { getCardList } from "@/api/list";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
defineOptions({
|
||||||
|
name: "ServerList"
|
||||||
|
});
|
||||||
|
|
||||||
|
const svg = `
|
||||||
|
<path class="path" d="
|
||||||
|
M 30 15
|
||||||
|
L 28 17
|
||||||
|
M 25.61 25.61
|
||||||
|
A 15 15, 0, 0, 1, 15 30
|
||||||
|
A 15 15, 0, 1, 1, 27.99 7.5
|
||||||
|
L 15 15
|
||||||
|
" style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const pagination = ref({ current: 1, pageSize: 12, total: 0 });
|
||||||
|
|
||||||
|
const deviceList = ref([]);
|
||||||
|
|
||||||
|
const searchValue = ref("");
|
||||||
|
const dataLoading = ref(true);
|
||||||
|
// const onSubmit = () => {
|
||||||
|
// console.log("submit!");
|
||||||
|
// };
|
||||||
|
const onPageSizeChange = (size: number) => {
|
||||||
|
pagination.value.pageSize = size;
|
||||||
|
pagination.value.current = 1;
|
||||||
|
};
|
||||||
|
const onCurrentChange = (current: number) => {
|
||||||
|
pagination.value.current = current;
|
||||||
|
};
|
||||||
|
const getCardListData = async () => {
|
||||||
|
try {
|
||||||
|
const { data } = await getCardList();
|
||||||
|
deviceList.value = data.list;
|
||||||
|
console.log(data.list);
|
||||||
|
pagination.value = {
|
||||||
|
...pagination.value,
|
||||||
|
total: data.list.length
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
console.log(e);
|
||||||
|
} finally {
|
||||||
|
setTimeout(() => {
|
||||||
|
dataLoading.value = false;
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
onMounted(() => {
|
||||||
|
getCardListData();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="main p-4">
|
||||||
|
<div
|
||||||
|
v-loading="dataLoading"
|
||||||
|
:element-loading-svg="svg"
|
||||||
|
element-loading-svg-view-box="-10, -10, 50, 50"
|
||||||
|
>
|
||||||
|
<el-empty
|
||||||
|
v-show="
|
||||||
|
deviceList
|
||||||
|
.slice(
|
||||||
|
pagination.pageSize * (pagination.current - 1),
|
||||||
|
pagination.pageSize * pagination.current
|
||||||
|
)
|
||||||
|
.filter(v =>
|
||||||
|
v.deviceSort.toLowerCase().includes(searchValue.toLowerCase())
|
||||||
|
).length === 0
|
||||||
|
"
|
||||||
|
:description="`${searchValue} 产品不存在`"
|
||||||
|
/>
|
||||||
|
<template v-if="pagination.total > 0">
|
||||||
|
<el-row :gutter="16">
|
||||||
|
<el-col
|
||||||
|
class="mb-4 w-[100%]"
|
||||||
|
v-for="(device, index) in deviceList
|
||||||
|
.slice(
|
||||||
|
pagination.pageSize * (pagination.current - 1),
|
||||||
|
pagination.pageSize * pagination.current
|
||||||
|
)
|
||||||
|
.filter(v =>
|
||||||
|
v.deviceSort.toLowerCase().includes(searchValue.toLowerCase())
|
||||||
|
)"
|
||||||
|
:key="index"
|
||||||
|
:xs="24"
|
||||||
|
:sm="24"
|
||||||
|
:md="12"
|
||||||
|
:lg="8"
|
||||||
|
:xl="6"
|
||||||
|
>
|
||||||
|
<ModelCard :device="device" />
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-pagination
|
||||||
|
v-model:currentPage="pagination.current"
|
||||||
|
class="absolute right-4 bottom-0"
|
||||||
|
:page-size="pagination.pageSize"
|
||||||
|
:total="pagination.total"
|
||||||
|
:page-sizes="[12, 24, 36]"
|
||||||
|
:background="false"
|
||||||
|
layout="total, sizes, prev, pager, next, jumper"
|
||||||
|
@size-change="onPageSizeChange"
|
||||||
|
@current-change="onCurrentChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|