feat: 告警列表、算力分配完成

dev-deviceSetting
donghao 1 year ago
parent c06d55f769
commit 50f9cd6172

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-12 14:35:28
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-19 10:36:56
* @LastEditTime: 2024-01-22 16:41:52
* @FilePath: \General-AI-Platform-Web-Client\index.html
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
@ -18,10 +18,10 @@
/>
<title>pure-admin-thin</title>
<link rel="icon" href="/favicon.ico" />
<!-- update 2024-01-17 15:41 -->
<!-- update 2024-01-21 16:41 -->
<link
rel="stylesheet"
href="//at.alicdn.com/t/c/font_4412653_c3k3yiaknkn.css"
href="//at.alicdn.com/t/c/font_4412653_qo2xb6ruq6q.css"
/>
<script src="https://threejs.org/build/three.js"></script>
<script>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-17 13:54:43
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-18 15:37:29
* @LastEditTime: 2024-01-22 16:44:06
* @FilePath: \General-AI-Platform-Web-Client\mock\alarm.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@ -42,7 +42,7 @@ function fetchList(): Record<string, any>[] {
updateTime: "2023-10-17T02:35:41.14308Z",
name: "表面缺陷",
code: "DC00001",
level: "1",
level: Math.floor(Math.random() * 6) + 1,
deviceGroup: "设备组" + parseInt(Math.random() * 10) + 1,
remark: ""
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 463 KiB

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" width="298" height="344" viewBox="0 0 298 344" fill="none">
<path
d="M334.647 167.409L259.557 91.2169L230.295 61.5247C228.335 59.5362 225.154 59.5362 223.18 61.5247L95.7935 190.781C93.4578 193.151 89.6591 193.151 87.3234 190.781L52.584 155.532C50.2483 153.162 50.2483 149.307 52.584 146.937L159.125 38.8334C161.084 36.8448 161.084 33.6168 159.125 31.6146L130.211 2.27657C128.251 0.288017 125.07 0.288017 123.096 2.27657L-21.2977 148.817C-23.2575 150.806 -23.2575 154.034 -21.2977 156.036L54.6914 233.14L83.9542 262.832C85.914 264.821 89.0953 264.821 91.0685 262.832L223.838 128.114C226.174 125.744 229.973 125.744 232.308 128.114L267.048 163.363C269.383 165.733 269.383 169.588 267.048 171.958L134.278 306.676C132.318 308.664 132.318 311.892 134.278 313.895L162.292 342.32C164.252 344.309 167.434 344.309 169.407 342.32L334.661 174.641C336.607 172.625 336.607 169.397 334.647 167.409Z"
fill="#154DDD" />
</svg>

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 494 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

@ -0,0 +1,13 @@
<svg xmlns="http://www.w3.org/2000/svg" width="120" height="131" viewBox="0 0 120 131" fill="none">
<g opacity="0.05">
<path
d="M68.8661 8.05494L53.9961 11.2195C53.6475 11.316 53.5299 11.7569 53.7879 12.0142L65.5118 23.9102C65.7653 24.1674 66.2044 24.0526 66.2949 23.6989L69.4409 8.63825C69.536 8.28459 69.2146 7.96308 68.8661 8.05494Z"
fill="#E42F2F" />
<path
d="M76.9202 0.0121908L55.3825 5.86834C55.129 5.93723 55.0475 6.25875 55.2286 6.44707L70.9948 22.4447C71.1804 22.633 71.4973 22.5457 71.5652 22.2885L77.3366 0.434758C77.4045 0.177547 77.1737 -0.0567051 76.9202 0.0121908Z"
fill="#FAEC18" />
<path
d="M121.272 70.6188L95.9504 44.9253L86.0824 34.9124C85.4215 34.2418 84.3487 34.2418 83.6833 34.9124L40.7256 78.5005C39.9379 79.2997 38.6569 79.2997 37.8693 78.5005L26.1544 66.6137C25.3667 65.8145 25.3667 64.5147 26.1544 63.7155L62.0822 27.2604C62.7431 26.5898 62.7431 25.5013 62.0822 24.8261L52.3318 14.9326C51.671 14.262 50.5981 14.262 49.9327 14.9326L1.23981 64.3493C0.578919 65.0199 0.578919 66.1084 1.23981 66.7836L26.865 92.7849L36.7331 102.798C37.394 103.468 38.4668 103.468 39.1322 102.798L83.9051 57.3679C84.6927 56.5687 85.9737 56.5687 86.7614 57.3679L98.4763 69.2547C99.2639 70.0539 99.2639 71.3537 98.4763 72.1529L53.7034 117.583C53.0425 118.253 53.0425 119.342 53.7034 120.017L63.1505 129.603C63.8114 130.273 64.8842 130.273 65.5496 129.603L121.277 73.0577C121.933 72.378 121.933 71.2894 121.272 70.6188Z"
fill="#154DDD" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

@ -134,8 +134,17 @@ export default defineComponent({
type: Boolean,
default: undefined
}
// handleDel: {
// type: Function,
// default: () => {}
// }
// customActions: {
// type: Function,
// default: () => {}
// }
},
emits: ["change", "columnChange", "update:visibleColumn"],
emits: ["change", "columnChange", "update:visibleColumn", "actions"],
setup(props, { slots, attrs, emit }) {
const nonPropsAttrs = attrs;
const { prop: sortBy, order: sortOrder } = getDefaultSort(attrs) || {};
@ -260,9 +269,52 @@ export default defineComponent({
</ElTableColumn>
);
}
if (column.type === "action") {
return (
<ElTableColumn {...getColumnProps(column)}>
{{
default: ({ row }: { row: Record<string, any> }) => {
return (
<div>
<ul>
<li
class="flex items-center"
style={{ fontSize: "14px", color: "#E80D0D" }}
onClick={() => handleDel(row)}
>
<i class="iconfont icon-shanchu pr-[8px]"></i>
<el-button type="text">
<span
style={{
fontSize: "14px",
color: "#E80D0D"
}}
>
</span>
</el-button>
</li>
</ul>
</div>
);
}
}}
</ElTableColumn>
);
}
return <ElTableColumn {...getColumnProps(column)} />;
}
/**操作按钮事件 */
function handleDel(row) {
console.log(row, "handleDel");
emit("actions", {
type: "delete",
data: { ...row }
});
}
/**
*
*/
@ -330,8 +382,8 @@ export default defineComponent({
};
return (
<div class="x-table-pagination">
<ElPagination class="float-right mt-[50px]" {...paginationProps} />
<div class="x-table-pagination pagination_wrap">
<ElPagination {...paginationProps} />
</div>
);
}
@ -387,6 +439,29 @@ export default defineComponent({
}
return renderTableColumn(column);
})}
{/* 使用插槽引入操作栏的内容 */}
{/* <ElTableColumn label="">
{{
default: ({ row }: { row: Record<string, any> }) => {
return extraSlots.customActions?.({
row
});
}
}}
</ElTableColumn> */}
{/* <ElTableColumn label="">
<template #default="scope">
<el-button size="small" @click="handleEdit(scope.$index, scope.row)"
>Edit</el-button
>
<el-button
size="small"
type="danger"
@click="handleDelete(scope.$index, scope.row)"
>Delete</el-button>
>
</template>
</ElTableColumn> */}
</ElTable>
{showPagination.value && renderPagination()}
{!isUndefined(props.visibleColumn) && renderCustomColumn()}

@ -11,6 +11,11 @@ type ElTableSort = Pick<
"prop" | "order"
>;
type ElTableAction = {
type: "delete" | "update" | string; // 操作类型
confirmType?: "popup" | "modal"; // 确认组件
};
declare global {
type XTableSort = ElTableSort;

@ -11,31 +11,106 @@ const testDeviceTreeData = [
{
name: "车间1",
id: "分析设备",
level: 1
// childList: [
// {
// name: "控制器A1",
// id: "1101001",
// level: 2,
// childList: [
// {
// name: "控制器A1a1",
// id: "110100101",
// level: 3
// },
// {
// name: "控制器A2a2",
// id: "110100202",
// level: 3
// }
// ]
// },
// {
// name: "控制器A2",
// id: "1101002",
// level: 2
// }
// ]
level: 1,
childList: [
{
name: "控制器A1",
id: "1101001",
level: 2,
childList: [
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
},
{
name: "控制器A1a1",
id: "110100101",
level: 3
},
{
name: "控制器A2a2",
id: "110100202",
level: 3
}
]
},
{
name: "控制器A2",
id: "1101002",
level: 2
}
]
},
{
name: "车间2",

@ -169,3 +169,17 @@
box-shadow: 0 -1px 0 0 #e0e3e8, 0 -3px 6px 0 rgb(69 98 155 / 12%);
}
}
/* 分页栏 */
.pagination_wrap {
width: calc(100% - 136px);
background-color: white;
z-index: 9;
position: fixed;
display: flex;
align-items: center;
justify-content: end;
right: 0;
bottom: 0;
padding: 20px 40px 40px;
}

@ -256,3 +256,29 @@ div:focus {
content: " ";
}
}
//
::-webkit-scrollbar-track-piece {
-webkit-border-radius: 0;
}
::-webkit-scrollbar {
width: 5px;
height: 10px;
}
::-webkit-scrollbar-thumb {
height: 50px;
background-color: #ccc;
-webkit-border-radius: 6px;
outline-offset: -2px;
-moz-opacity: 0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
}
::-webkit-scrollbar-thumb:hover {
height: 50px;
background-color: #878987;
-webkit-border-radius: 6px;
}

@ -543,31 +543,6 @@
.el-menu--collapse .el-menu .el-sub-menu {
min-width: $sideBarWidth !important;
}
/* 手机端 */
.mobile {
.fixed-header {
width: 100% !important;
transition: width var(--pure-transition-duration);
}
.main-container {
margin-left: 0 !important;
}
.sidebar-container {
width: $sideBarWidth;
transition: transform var(--pure-transition-duration);
}
&.hideSidebar {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-$sideBarWidth, 0, 0);
}
}
}
}
body[layout="vertical"] {

@ -31,3 +31,75 @@ $--theme-color: #154ddd;
.main_container {
margin-left: 16px;
}
.main {
padding-top: 16px;
overflow: hidden;
position: relative;
// overflow-y: scroll;
// height: 88vh;
}
// 1
.hf-1 {
color: $--web-font1;
font-family: "PingFang SC";
font-size: 16px;
font-style: normal;
font-weight: 700;
line-height: normal;
}
//
.pf-1 {
color: $--web-font1;
font-family: "PingFang SC";
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
/* 157.143% */
}
.pf-2 {
color: $--web-font2;
font-family: "PingFang SC";
font-size: 14px;
font-style: normal;
font-weight: 400;
line-height: 22px;
}
//
.single-line {
/* 容器的高度 */
overflow: hidden;
/* 隐藏超出部分内容 */
display: -webkit-box;
/* 必须设置display为-webkit-box才能生效 */
-webkit-line-clamp: 1;
/* 指定显示的行数 */
-webkit-box-orient: vertical;
/* 设置子元素垂直排列 */
text-overflow: ellipsis;
/* 当文字溢出时显示省略号 */
white-space: pre-wrap;
/* 保持换行符不被合并 */
}
.two-line {
/* 容器的高度 */
overflow: hidden;
/* 隐藏超出部分内容 */
display: -webkit-box;
/* 必须设置display为-webkit-box才能生效 */
-webkit-line-clamp: 2;
/* 指定显示的行数 */
-webkit-box-orient: vertical;
/* 设置子元素垂直排列 */
text-overflow: ellipsis;
/* 当文字溢出时显示省略号 */
white-space: pre-wrap;
/* 保持换行符不被合并 */
}

@ -1,11 +1,15 @@
<script setup lang="ts">
import { getAlarmList } from "@/api/list";
import { onMounted, ref, reactive } from "vue";
import { onMounted, ref, reactive, h } from "vue";
import { BaseTable } from "@/components/CustomTable";
import { getConfig } from "@/config";
defineOptions({
name: "AlarmList"
});
const { EpThemeColor } = getConfig();
// TODO ~
const alarmLevelStatusEnum: Record<string, any>[] = [
{
@ -53,6 +57,10 @@ const alarmLevelStatusEnum: Record<string, any>[] = [
}
];
function handleDelete(row) {
console.log(row, "handleDelete_row");
}
const columns = [
{
type: "selection"
@ -65,24 +73,75 @@ const columns = [
label: "告警代码",
property: "code"
},
// TODO
{
label: "告警等级",
property: "level"
property: "level",
formatter: val => {
const currentLevelObj = alarmLevelStatusEnum[Number(val?.level) - 1];
return h(
"div",
{
style: {
fontSize: "14px",
color: currentLevelObj.color
}
},
[
h("i", {
class: `iconfont pr-[8px] ${
currentLevelObj.value === "1"
? "icon-xiangshangjiantouquan"
: "icon-xiala"
}`
}),
h(
"span",
{
fontSize: "14px"
},
currentLevelObj.label
)
]
);
}
},
{
label: "设备组",
property: "deviceGroup"
property: "deviceGroup",
formatter: val => {
return h(
"div",
{
style: {
fontSize: "14px",
color: EpThemeColor
}
},
[
h("i", {
class: `iconfont icon-zishebeizu pr-[8px]`
}),
h(
"span",
{
fontSize: "14px",
class: "pf-1"
},
val.deviceGroup
)
]
);
}
},
{
label: "告警日期",
property: "createTime"
},
// TODO
{
type: "action",
label: "操作"
}
// TODO
// {
// label: "",
// property: "name"
// }
];
const svg = `
@ -103,9 +162,8 @@ const listData = ref([]);
// const searchValue = ref("");
const formData = reactive({
deviceSort: "",
deviceState: "",
isEnabled: ""
name: "",
level: ""
});
const dataLoading = ref(true);
@ -133,24 +191,16 @@ onMounted(() => {
</script>
<template>
<div class="py-4 main">
<div class="main alarm_wrap">
<el-form :inline="true" :model="formData" class="demo-form-inline">
<el-form-item label="告警名称">
<el-select
v-model="formData.deviceState"
placeholder="告警名称"
clearable
>
<el-select v-model="formData.name" placeholder="告警名称" clearable>
<el-option label="名称1" value="1" />
<el-option label="名称2" value="2" />
</el-select>
</el-form-item>
<el-form-item label="告警等级">
<el-select
v-model="formData.deviceState"
placeholder="告警等级"
clearable
>
<el-select v-model="formData.level" placeholder="告警等级" clearable>
<el-option
v-for="(v, k) in alarmLevelStatusEnum"
:key="k"
@ -161,13 +211,37 @@ onMounted(() => {
</el-form-item>
</el-form>
<div
class="alarm_table"
v-loading="dataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
>
<template v-if="pagination.total > 0">
<BaseTable :total="48" :dataSource="listData" :columns="columns" />
<BaseTable
:total="48"
:dataSource="listData"
:columns="columns"
@actions="handleDelete"
>
<!-- <template v-slot:customActions="{ row }">
<el-button @click="handleDelete(row)" type="danger" size="small"
>删除</el-button
>
</template> -->
</BaseTable>
</template>
</div>
</div>
</template>
<style lang="scss">
.alarm_wrap {
.alarm_table {
/* overflow-y: scroll; */
height: calc(100vh - 220px);
overflow-x: hidden;
overflow-y: scroll;
/* background-color: red; */
}
}
</style>

@ -0,0 +1,205 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-19 09:38:33
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-23 14:51:05
* @FilePath: \General-AI-Platform-Web-Client\src\views\demo\cube.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { computed } from "vue";
import { ComputePowerPoolItem } from "../typing";
defineOptions({
name: "ComputePowerCube"
});
// TODO
const props = defineProps({
list: {
type: Array as ComputePowerPoolItem[],
defaultValue: {}
}
});
const listData = computed(() => {
let finalList = [];
const totalHeight = 262;
finalList = props.list.map(item => {
item.value = Math.floor((item.proportion / 100) * totalHeight);
return item;
});
return finalList.reverse();
});
const fetchPathValByHeight = val => {
return val - 12;
};
</script>
<template>
<div class="computePowerCube_wrap">
<div class="flex justify-start des_wrap pb-[16px]">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12 22C14.7614 22 17.2614 20.8807 19.0711 19.0711C20.8807 17.2614 22 14.7614 22 12C22 9.2386 20.8807 6.7386 19.0711 4.92893C17.2614 3.11929 14.7614 2 12 2C9.2386 2 6.7386 3.11929 4.92893 4.92893C3.11929 6.7386 2 9.2386 2 12C2 14.7614 3.11929 17.2614 4.92893 19.0711C6.7386 20.8807 9.2386 22 12 22Z"
stroke="#FAAD14"
stroke-width="2"
stroke-linejoin="round"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 18.5C12.6904 18.5 13.25 17.9404 13.25 17.25C13.25 16.5597 12.6904 16 12 16C11.3097 16 10.75 16.5597 10.75 17.25C10.75 17.9404 11.3097 18.5 12 18.5Z"
fill="#FAAD14"
/>
<path
d="M12 6V14"
stroke="#FAAD14"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<p class="pf-1 w-[196px] pl-[8px]">
可根据检测项重要性调整滑块以 配置各算法所占用的算力比例
达到目标运算需求
</p>
</div>
<div class="cube_body">
<ul class="cube_info">
<li
v-for="(v, k) in listData"
:key="k"
class="flex items-center justify-center"
>
<div
class="bg_cube"
:style="{ height: v.value + 'px', background: v.bgColor }"
>
<div class="flex items-center cube_tag" v-if="v.type === 2">
<div class="bg-black h-[2px] w-[34px]"></div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="16"
viewBox="0 0 20 16"
fill="none"
>
<path
d="M18 1C18.8284 1 19.5 1.67157 19.5 2.5V13.5C19.5 14.3284 18.8284 15 18 15H7.74624C7.32544 15 6.924 14.8233 6.63986 14.5129L1.60508 9.01334C1.08028 8.4401 1.08025 7.56095 1.605 6.98766L6.63987 1.4872C6.92402 1.17678 7.32549 1 7.74633 1H18Z"
fill="#FFBD5C"
stroke="#FA8916"
/>
</svg>
<p class="pf-1 w-[140px] h-[20px] single-line">
<span class="px-[8px]">{{ v.proportion }}%</span
><span>{{ v.name }}</span>
</p>
</div>
<div class="flex items-center cube_tag" v-if="v.type === 1">
<div class="bg-black h-[2px] w-[34px]"></div>
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="16"
viewBox="0 0 20 16"
fill="none"
>
<path
d="M18 1C18.8284 1 19.5 1.67157 19.5 2.5V13.5C19.5 14.3284 18.8284 15 18 15H7.74624C7.32544 15 6.924 14.8233 6.63986 14.5129L1.60508 9.01334C1.08028 8.4401 1.08025 7.56095 1.605 6.98766L6.63987 1.4872C6.92402 1.17678 7.32549 1 7.74633 1H18Z"
fill="#74A5FB"
stroke="#3778F2"
/>
</svg>
<p class="pf-1 w-[140px] h-[20px] single-line">
<span class="px-[8px]">{{ v.proportion }}%</span
><span>{{ v.name }}</span>
</p>
</div>
</div>
</li>
<li>
<div class="cube_info_line"></div>
</li>
</ul>
</div>
<div class="bg_body_logo"></div>
</div>
</template>
<style lang="scss">
.computePowerCube_wrap {
position: relative;
overflow: hidden;
.bg_body_logo {
/* width: 358.886px;
height: 343.026px;
bottom: 0;
position: absolute;
left: -48px;
background: url("@/assets/computePower/bgLogo.svg") no-repeat 50% 50%;
opacity: 0.02; */
}
.cube_info {
position: relative;
margin: 0 auto;
width: 42px;
border-radius: 4px;
border: 4px solid rgba(21, 77, 221, 0.4);
background: #fff;
& > li {
.bg_cube {
width: 100%;
position: relative;
}
.cube_tag {
position: absolute;
left: 0px;
top: -8px;
width: 200px;
}
}
}
.cube_info_line {
position: absolute;
left: 12px;
top: 13px;
width: 6px;
height: 233px;
background: rgba(255, 255, 255, 0.8);
filter: blur(4px);
}
.cube_body {
margin-left: 34px;
width: 45px;
border: 2px solid #b8b8b8;
border-radius: 6px;
.cube_btn {
position: relative;
width: 40px;
margin: 0 auto;
& > li {
width: 20px;
height: 20px;
position: absolute;
left: 40px;
top: 69px;
}
& > li:nth-child(2) {
top: 159px;
}
}
}
}
</style>

@ -0,0 +1,227 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-19 09:38:33
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-22 15:33:06
* @FilePath: \General-AI-Platform-Web-Client\src\views\demo\cube.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { computed } from "vue";
import { ComputePowerPoolItem } from "../typing";
defineOptions({
name: "ComputePowerCube"
});
// TODO
const props = defineProps({
list: {
type: Array as ComputePowerPoolItem[],
defaultValue: {}
}
});
const listData = computed(() => {
let finalList = [];
const totalHeight = 270;
finalList = props.list.map(item => {
switch (item.type) {
case 2:
item.value =
totalHeight -
Math.floor((props.list[0].proportion / 100) * totalHeight);
break;
case 1:
item.value = totalHeight;
break;
default:
item.value = Math.floor((item.proportion / 100) * totalHeight);
break;
}
// item.value = Math.floor((count / 100) * totalHeight);
return item;
});
return finalList.reverse();
});
const fetchPathValByHeight = val => {
return val - 12;
};
</script>
<template>
<div class="computePowerCube_wrap">
<div class="flex justify-start des_wrap">
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12 22C14.7614 22 17.2614 20.8807 19.0711 19.0711C20.8807 17.2614 22 14.7614 22 12C22 9.2386 20.8807 6.7386 19.0711 4.92893C17.2614 3.11929 14.7614 2 12 2C9.2386 2 6.7386 3.11929 4.92893 4.92893C3.11929 6.7386 2 9.2386 2 12C2 14.7614 3.11929 17.2614 4.92893 19.0711C6.7386 20.8807 9.2386 22 12 22Z"
stroke="#FAAD14"
stroke-width="2"
stroke-linejoin="round"
/>
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M12 18.5C12.6904 18.5 13.25 17.9404 13.25 17.25C13.25 16.5597 12.6904 16 12 16C11.3097 16 10.75 16.5597 10.75 17.25C10.75 17.9404 11.3097 18.5 12 18.5Z"
fill="#FAAD14"
/>
<path
d="M12 6V14"
stroke="#FAAD14"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
<p class="pf-1 w-[196px] pl-[8px]">
可根据检测项重要性调整滑块以 配置各算法所占用的算力比例
达到目标运算需求
</p>
</div>
<div class="cube_body">
<ul class="cube_info">
<li
v-for="(v, k) in listData"
:key="k"
class="flex items-center justify-center"
:style="{ left: 0, top: v.value }"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="42"
:height="v.value"
:viewBox="`0 0 42 ${v.value}`"
fill="none"
>
<path
:d="`M20.7846 90L41.5692 ${fetchPathValByHeight(
v.value
)}L20.7846 ${v.value}L0 ${fetchPathValByHeight(
v.value
)}L20.7846 90Z`"
:fill="v.color"
/>
<path
:d="`M41.5693 72L20.7847 60V90L41.5693 ${fetchPathValByHeight(
v.value
)}V72Z`"
:fill="v.color"
/>
<path
:d="`M20.7846 60L0 72V${fetchPathValByHeight(
v.value
)}L20.7846 90V60Z`"
:fill="v.color"
/>
<path
:d="`M20.7847 24L41.5693 12V${fetchPathValByHeight(
v.value
)}L20.7847 ${v.value}V24Z`"
:fill="v.color"
/>
<path
:d="`M0 12L20.7846 24V${v.value}L0 ${fetchPathValByHeight(
v.value
)}V12Z`"
:fill="v.color"
/>
<rect
width="24"
height="24"
transform="matrix(0.866025 0.5 -0.866025 0.5 20.7847 0)"
:fill="v.color"
/>
</svg>
</li>
</ul>
<ul class="cube_btn">
<li :style="{ top: listData[2].value }">
<svg
xmlns="http://www.w3.org/2000/svg"
width="15"
height="18"
viewBox="0 0 15 18"
fill="none"
>
<path
d="M-4.37114e-07 9L15 0.339744L15 17.6603L-4.37114e-07 9Z"
fill="#FAA90B"
/>
</svg>
</li>
<li :style="{ top: listData[1].value }">
<svg
xmlns="http://www.w3.org/2000/svg"
width="15"
height="18"
viewBox="0 0 15 18"
fill="none"
>
<path
d="M-4.37114e-07 9L15 0.339744L15 17.6603L-4.37114e-07 9Z"
fill="#014BE6"
/>
</svg>
</li>
</ul>
</div>
</div>
</template>
<style lang="scss">
.computePowerCube_wrap {
.cube_info {
z-index: 1;
position: relative;
width: 42px;
margin: 0 auto;
& > li {
position: absolute;
/* margin-bottom: -24px; */
/* margin-top: -10px; */
/* bottom: -30px; */
&:nth-child(1) {
margin-top: 0;
z-index: 9;
/* background-color: red; */
}
&:nth-child(2) {
z-index: 8;
}
}
}
.cube_body {
z-index: 10;
padding-top: 16px;
/* position: relative;
top: 16px; */
.cube_btn {
position: relative;
width: 40px;
margin: 0 auto;
& > li {
width: 20px;
height: 20px;
/* padding-left: 100px; */
/* padding-top: 30px; */
position: absolute;
left: 40px;
top: 69px;
}
& > li:nth-child(2) {
top: 159px;
}
}
}
}
</style>

@ -0,0 +1,104 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-19 09:38:33
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-23 11:37:11
* @FilePath: \General-AI-Platform-Web-Client\src\views\demo\cube.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { computed } from "vue";
import { ComputePowerPoolItem } from "../typing";
defineOptions({
name: "ComputePowerType"
});
const props = defineProps({
info: {
type: Object as ComputePowerPoolItem,
defaultValue: {}
}
});
const currentInfo = computed(() => props.info);
</script>
<template>
<div class="flex items-center computePowerType_wrap">
<svg
style="padding-top: 4px"
xmlns="http://www.w3.org/2000/svg"
width="24"
height="28"
viewBox="0 0 24 28"
fill="none"
>
<path
d="M12 10.9102L24 17.4556L12 24.0011L0 17.4556L12 10.9102Z"
:fill="currentInfo.color"
/>
<path
d="M24 6.54545L12 0V10.9091L24 17.4545V6.54545Z"
:fill="currentInfo.color"
/>
<path
d="M12 0L0 6.54546V17.4545L12 10.9091V0Z"
:fill="currentInfo.color"
/>
<path
d="M12 13.0923L24 6.54688V17.456L12 24.0014V13.0923Z"
:fill="currentInfo.color"
/>
<path
d="M0 6.54688L12 13.0923V24.0014L0 17.456V6.54688Z"
:fill="currentInfo.color"
/>
<rect
width="13.669"
height="13.669"
transform="matrix(0.877895 0.478853 -0.877895 0.478853 12 0)"
:fill="currentInfo.color"
/>
<g filter="url(#filter0_f_7277_81321)">
<rect x="10.8452" y="12" width="1.1547" height="12" fill="white" />
</g>
<defs>
<filter
id="filter0_f_7277_81321"
x="6.84521"
y="8"
width="9.15479"
height="20"
filterUnits="userSpaceOnUse"
color-interpolation-filters="sRGB"
>
<feFlood flood-opacity="0" result="BackgroundImageFix" />
<feBlend
mode="normal"
in="SourceGraphic"
in2="BackgroundImageFix"
result="shape"
/>
<feGaussianBlur
stdDeviation="2"
result="effect1_foregroundBlur_7277_81321"
/>
</filter>
</defs>
</svg>
<div class="flex">
<p class="pl-[8px] pf-1">{{ currentInfo.name }}</p>
<p class="pf-1">{{ currentInfo.proportion }}%</p>
<p class="pl-[8px] pf-2" v-if="currentInfo.pretreatmentEfficiency">
预计处理效率: {{ currentInfo.pretreatmentEfficiency }}/
</p>
</div>
</div>
</template>
<style lang="scss">
.computePowerType_wrap {
position: relative;
}
</style>

@ -1,4 +1,81 @@
.computePowerAllocation_wrap {
// background-color: red;
height: 100%;
// padding-top: calc(50vh - 330px - 48px);
.computePowerAllocation_body {
border-radius: 12px;
background: rgba(21, 77, 221, 0.05);
width: 1080px;
height: 660px;
margin: 0 auto;
}
.computePower_header {
text-align: center;
position: relative;
height: 46px;
& > span {
position: absolute;
line-height: 46px;
font-size: 24px;
font-weight: 700;
background: linear-gradient(180deg, #014be6 0%, #014be6 100%);
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.computePower_banner {
padding: 32px 32px 0;
.banner_left {
.banner_group {
& > li {
width: 266px;
height: 88px;
border-radius: 8px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
position: relative;
overflow: hidden;
.bg_banner_group_logo {
width: 266px;
height: 166.25px;
top: -38px;
position: absolute;
left: 52px;
background: url("@/assets/computePower/computerTypeLogo.png")
no-repeat 0 0;
background-size: cover;
opacity: 0.05;
}
}
}
}
.bg_banner_center {
width: 360px;
height: 360px;
background: url("@/assets/computePower/banner.png");
background-repeat: no-repeat;
background-size: contain;
}
.banner_right {
.computePowerCube_wrap {
padding: 16px;
width: 266px;
height: 400px;
border-radius: 8px;
background-color: white;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.1);
}
}
}
.computePower_footer {
padding: 10px;
}
}

@ -1,23 +1,143 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-19 09:22:30
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-23 11:42:27
* @FilePath: \General-AI-Platform-Web-Client\src\views\computePowerAllocation\index.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { ref } from "vue"; //api/json
import ComputePowerCube from "./components/computePowerCube.vue";
import ComputePowerType from "./components/computePowerType.vue";
import { ComputePowerPoolItem } from "./typing";
defineOptions({
name: "ComputePowerAllocation"
});
const animation1 = ref(null); //dom;
const groupList = ref<Record<string, any>[]>([
{
label: "NVIDIA GeForce 4090"
},
{
label: "NVIDIA GeForce 4090"
},
{
label: "NVIDIA GeForce 4090"
},
{
label: "NVIDIA GeForce 4090"
}
]); //dom;
const poolsData: ComputePowerPoolItem[] = [
{
name: "离岗监控",
type: 1,
proportion: 34,
pretreatmentEfficiency: 20,
color: "#3879FE",
bgColor: "linear-gradient(180deg, #015DE6 0%, #4881F6 100%)"
},
{
name: "玩手机监控",
type: 2,
proportion: 46,
pretreatmentEfficiency: 15,
color: "#FAA90B",
bgColor: "linear-gradient(180deg, #FA8316 0%, #FAAD16 100%)"
},
{
name: "空闲算力",
type: 0,
proportion: 20,
pretreatmentEfficiency: 0,
color: "#DCDCDC",
bgColor: "linear-gradient(90deg, #7B7979 0%, #C1C1C1 100%)"
}
];
</script>
<template>
<div class="main_booy_container computePowerAllocation_wrap">
<ul>
<li>
<el-card class="line-card" :body-style="{ padding: 0 }">
算力配置
</el-card>
</li>
</ul>
<img src="" alt="" />
<div
class="flex items-center justify-center main_booy_container computePowerAllocation_wrap"
>
<div class="computePowerAllocation_body">
<div class="flex justify-center computePower_header">
<svg
xmlns="http://www.w3.org/2000/svg"
width="667"
height="50"
viewBox="0 0 667 50"
fill="none"
>
<path
d="M4 1.25H2.39949L3.42366 2.47992L21.2082 23.8375C25.9105 29.4845 32.879 32.75 40.2275 32.75H169.682C173.92 32.75 178.078 33.9086 181.706 36.1005L192.922 42.8776C199.28 46.7193 206.567 48.75 213.996 48.75H316.342C317.146 48.75 317.909 48.3989 318.431 47.7889L320.231 45.6869L319.662 45.199L320.231 45.6869C320.469 45.4096 320.816 45.25 321.181 45.25H346.911C347.242 45.25 347.56 45.3818 347.795 45.6165L350.121 47.9438C350.636 48.46 351.336 48.75 352.066 48.75H443.362C450.566 48.75 457.641 46.8403 463.867 43.2154L476.417 35.9077C479.969 33.8396 484.006 32.75 488.116 32.75H630.515C638.594 32.75 646.165 28.8065 650.796 22.186L664.615 2.42988L665.44 1.25H664H4Z"
fill="url(#paint0_linear_7277_81243)"
stroke="white"
stroke-width="1.5"
/>
<defs>
<linearGradient
id="paint0_linear_7277_81243"
x1="334"
y1="10"
x2="334"
y2="48"
gradientUnits="userSpaceOnUse"
>
<stop stop-color="#154DDD" stop-opacity="0.15" />
<stop offset="1" stop-color="#154DDD" stop-opacity="0" />
</linearGradient>
</defs>
</svg>
<span>苏胜天算力资源池</span>
</div>
<div class="flex items-center justify-between computePower_banner">
<div class="banner_left">
<p class="hf-1">硬件组成</p>
<ul class="banner_group">
<li
v-for="(v, k) in groupList"
:key="k"
class="flex items-center bg-white p-[16px] mt-[16px]"
>
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M8.948 8.7975V7.3675C9.08911 7.35702 9.23051 7.35102 9.372 7.3495C13.294 7.2255 15.865 10.7235 15.865 10.7235C15.865 10.7235 13.091 14.5745 10.115 14.5745C9.72158 14.5753 9.33059 14.5128 8.957 14.3895V10.0435C10.485 10.2285 10.794 10.9005 11.704 12.4285L13.744 10.7145C13.744 10.7145 12.252 8.7625 9.744 8.7625C9.47818 8.75656 9.21227 8.76826 8.948 8.7975ZM8.948 4.0625V6.2005L9.372 6.1735C14.822 5.9885 18.382 10.6435 18.382 10.6435C18.382 10.6435 14.302 15.6075 10.052 15.6075C9.68491 15.6063 9.31858 15.5739 8.957 15.5105V16.8355C9.257 16.8705 9.567 16.8975 9.867 16.8975C13.824 16.8975 16.687 14.8745 19.46 12.4895C19.919 12.8605 21.8 13.7525 22.19 14.1415C19.557 16.3495 13.418 18.1255 9.937 18.1255C9.602 18.1255 9.284 18.1075 8.966 18.0725V19.9365H24V4.0625H8.948ZM8.948 14.3885V15.5195C5.291 14.8655 4.275 11.0595 4.275 11.0595C4.275 11.0595 6.033 9.1155 8.948 8.7975V10.0345H8.94C7.412 9.8485 6.21 11.2795 6.21 11.2795C6.21 11.2795 6.89 13.6915 8.949 14.3895M2.456 10.8995C2.456 10.8995 4.62 7.7025 8.956 7.3665V6.2005C4.153 6.5895 0 10.6525 0 10.6525C0 10.6525 2.35 17.4545 8.948 18.0725V16.8355C4.108 16.2355 2.456 10.8995 2.456 10.8995Z"
fill="#76B900"
/>
</svg>
<p class="pf-2 pl-[12px]">{{ v.label }}</p>
<div class="bg_banner_group_logo">&nbsp;</div>
</li>
</ul>
</div>
<div class="bg_banner_center"></div>
<div class="banner_right">
<p class="hf-1 pb-[16px]">算力配置</p>
<ComputePowerCube :list="poolsData" />
</div>
</div>
<ul
class="flex items-center justify-center computePower_footer mt-[70px]"
>
<li
v-for="(v, k) in poolsData"
:key="k"
class="flex items-center justify-center mx-[20px]"
>
<ComputePowerType :info="v" />
</li>
</ul>
</div>
</div>
</template>

@ -0,0 +1,16 @@
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-22 13:30:43
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-22 13:30:53
* @FilePath: \General-AI-Platform-Web-Client\src\views\computePowerAllocation\typing.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
export type ComputePowerPoolItem = {
name: string;
type: number; // 类别
color?: string; //
proportion: number;
pretreatmentEfficiency?: number;
};

@ -35,7 +35,7 @@ const fetchPathValByHeight = val => {
};
</script>
<template>
<div class="cube_wrap">
<div class="computePowerCube_wrap">
<ul class="cube_info">
<li v-for="(v, k) in listData" :key="k">
<svg
@ -106,7 +106,7 @@ const fetchPathValByHeight = val => {
</template>
<style lang="scss">
.cube_wrap {
.computePowerCube_wrap {
position: relative;
.cube_info {
& > li {

@ -1,3 +1,11 @@
<!--
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-16 15:58:56
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-23 14:05:12
* @FilePath: \General-AI-Platform-Web-Client\src\views\device\components\TreeCard.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->
<script setup lang="ts">
import { CollapseTree } from "@/components/CustomTree";
@ -13,9 +21,11 @@ defineOptions({
<style lang="scss" scoped>
.treeCard {
width: 240px;
height: 808px;
background: #fafafa;
height: calc(100% - 16px);
background: #f9f9f9;
border-radius: 12px;
box-shadow: 0 8px 16px 0 rgb(0 0 0 / 20%);
overflow-y: scroll;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
</style>

@ -106,10 +106,10 @@ onMounted(() => {
</script>
<template>
<div class="flex justify-start py-4 main">
<TreeCard />
<div class="flex justify-start h-full main device_wrap">
<TreeCard class="h-full" />
<div
class="flex-1 ml-5"
class="flex-1 ml-5 device_body"
v-loading="dataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
@ -144,6 +144,7 @@ onMounted(() => {
</el-form-item>
</el-form>
<div
class="device_table"
v-loading="dataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
@ -183,19 +184,37 @@ onMounted(() => {
<DeviceCard :device="device" />
</el-col>
</el-row>
<el-pagination
v-model:currentPage="pagination.current"
class="float-right"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 18, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
<div class="pagination_wrap">
<el-pagination
v-model:currentPage="pagination.current"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 18, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
</div>
</template>
</div>
</div>
</div>
</template>
<style lang="scss">
.device_wrap {
.device_body {
.device_table {
height: calc(100vh - 220px);
/* background-color: orange; */
overflow-x: hidden;
overflow-y: scroll;
}
}
.pagination_wrap {
width: calc(100% - 136px - 260px);
/* background-color: red; */
}
}
</style>

@ -16,6 +16,8 @@ import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from "vue";
import { useTranslationLang } from "@/layout/hooks/useTranslationLang";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import "./login.scss";
import dayIcon from "@/assets/svg/day.svg?component";
import darkIcon from "@/assets/svg/dark.svg?component";
import globalization from "@/assets/svg/globalization.svg?component";
@ -84,9 +86,8 @@ onBeforeUnmount(() => {
</script>
<template>
<div class="select-none">
<img :src="bg" class="wave" />
<div class="flex-c absolute right-5 top-3">
<div class="select-none login_wrap">
<div class="absolute flex-c right-5 top-3">
<!-- 主题 -->
<el-switch
v-model="dataTheme"

@ -0,0 +1,222 @@
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import Motion from "./utils/motion";
import { useRouter } from "vue-router";
import { message } from "@/utils/message";
import { loginRules } from "./utils/rule";
import { useNav } from "@/layout/hooks/useNav";
import type { FormInstance } from "element-plus";
import { $t, transformI18n } from "@/plugins/i18n";
import { useLayout } from "@/layout/hooks/useLayout";
import { useUserStoreHook } from "@/store/modules/user";
import { initRouter, getTopMenu } from "@/router/utils";
import { bg, avatar, illustration } from "./utils/static";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { ref, reactive, toRaw, onMounted, onBeforeUnmount } from "vue";
import { useTranslationLang } from "@/layout/hooks/useTranslationLang";
import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
import dayIcon from "@/assets/svg/day.svg?component";
import darkIcon from "@/assets/svg/dark.svg?component";
import globalization from "@/assets/svg/globalization.svg?component";
import Lock from "@iconify-icons/ri/lock-fill";
import Check from "@iconify-icons/ep/check";
import User from "@iconify-icons/ri/user-3-fill";
defineOptions({
name: "Login"
});
const router = useRouter();
const loading = ref(false);
const ruleFormRef = ref<FormInstance>();
const { initStorage } = useLayout();
initStorage();
const { t } = useI18n();
const { dataTheme, dataThemeChange } = useDataThemeChange();
dataThemeChange();
const { title, getDropdownItemStyle, getDropdownItemClass } = useNav();
const { locale, translationCh, translationEn } = useTranslationLang();
const ruleForm = reactive({
username: "admin",
password: "admin123"
});
const onLogin = async (formEl: FormInstance | undefined) => {
loading.value = true;
if (!formEl) return;
await formEl.validate((valid, fields) => {
if (valid) {
useUserStoreHook()
.loginByUsername({ username: ruleForm.username, password: "admin123" })
.then(res => {
if (res.success) {
//
initRouter().then(() => {
router.push(getTopMenu(true).path);
message("登录成功", { type: "success" });
});
}
});
} else {
loading.value = false;
return fields;
}
});
};
/** 使用公共函数,避免`removeEventListener`失效 */
function onkeypress({ code }: KeyboardEvent) {
if (code === "Enter") {
onLogin(ruleFormRef.value);
}
}
onMounted(() => {
window.document.addEventListener("keypress", onkeypress);
});
onBeforeUnmount(() => {
window.document.removeEventListener("keypress", onkeypress);
});
</script>
<template>
<div class="select-none">
<img :src="bg" class="wave" />
<div class="flex-c absolute right-5 top-3">
<!-- 主题 -->
<el-switch
v-model="dataTheme"
inline-prompt
:active-icon="dayIcon"
:inactive-icon="darkIcon"
@change="dataThemeChange"
/>
<!-- 国际化 -->
<el-dropdown trigger="click">
<globalization
class="hover:text-primary hover:!bg-[transparent] w-[20px] h-[20px] ml-1.5 cursor-pointer outline-none duration-300"
/>
<template #dropdown>
<el-dropdown-menu class="translation">
<el-dropdown-item
:style="getDropdownItemStyle(locale, 'zh')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]"
@click="translationCh"
>
<IconifyIconOffline
class="check-zh"
v-show="locale === 'zh'"
:icon="Check"
/>
简体中文
</el-dropdown-item>
<el-dropdown-item
:style="getDropdownItemStyle(locale, 'en')"
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]"
@click="translationEn"
>
<span class="check-en" v-show="locale === 'en'">
<IconifyIconOffline :icon="Check" />
</span>
English
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
<div class="login-container">
<div class="img">
<component :is="toRaw(illustration)" />
</div>
<div class="login-box">
<div class="login-form">
<avatar class="avatar" />
<Motion>
<h2 class="outline-none">{{ title }}</h2>
</Motion>
<el-form
ref="ruleFormRef"
:model="ruleForm"
:rules="loginRules"
size="large"
>
<Motion :delay="100">
<el-form-item
:rules="[
{
required: true,
message: transformI18n($t('login.usernameReg')),
trigger: 'blur'
}
]"
prop="username"
>
<el-input
clearable
v-model="ruleForm.username"
:placeholder="t('login.username')"
:prefix-icon="useRenderIcon(User)"
/>
</el-form-item>
</Motion>
<Motion :delay="150">
<el-form-item prop="password">
<el-input
clearable
show-password
v-model="ruleForm.password"
:placeholder="t('login.password')"
:prefix-icon="useRenderIcon(Lock)"
/>
</el-form-item>
</Motion>
<Motion :delay="250">
<el-button
class="w-full mt-4"
size="default"
type="primary"
:loading="loading"
@click="onLogin(ruleFormRef)"
>
{{ t("login.login") }}
</el-button>
</Motion>
</el-form>
</div>
</div>
</div>
</div>
</template>
<style scoped>
@import url("@/style/login.css");
</style>
<style lang="scss" scoped>
:deep(.el-input-group__append, .el-input-group__prepend) {
padding: 0;
}
.translation {
::v-deep(.el-dropdown-menu__item) {
padding: 5px 40px;
}
.check-zh {
position: absolute;
left: 20px;
}
.check-en {
position: absolute;
left: 20px;
}
}
</style>

@ -0,0 +1,10 @@
.login_wrap {
width: 100vw;
height: 100vh;
// top: -38px;
position: fixed;
left: 0;
top: 0;
background: url("@/assets/login/sst.png") no-repeat 0 0;
background-size: cover;
}

@ -1,4 +1,12 @@
import bg from "@/assets/login/bg.png";
/*
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-12 14:35:28
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-23 15:47:00
* @FilePath: \General-AI-Platform-Web-Client\src\views\login\utils\static.ts
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
import bg from "@/assets/login/sst.png";
import avatar from "@/assets/login/avatar.svg?component";
import illustration from "@/assets/login/illustration.svg?component";

@ -32,7 +32,7 @@ const cardClass = computed(() => [
</script>
<template>
<div :class="cardClass">
<div :class="cardClass" class="model_card_box">
<div class="model-header">
<div class="model-name">{{ device?.deviceSort }}</div>
<div class="model-icon">
@ -59,10 +59,25 @@ const cardClass = computed(() => [
<span>{{ device?.description }}</span>
</div>
</div>
<div class="bg_logo"></div>
</div>
</template>
<style lang="scss" scoped>
.model_card_box {
position: relative;
overflow: hidden;
.bg_logo {
width: 121.024px;
height: 130.104px;
bottom: -16px;
position: absolute;
right: -17px;
background: url("@/assets/svg/model/model_bg_logo.svg") no-repeat 0 0;
background-size: cover;
}
// .src\assets\svg\model\model_bg_logo.svg
}
.model-card {
box-sizing: border-box;
width: 100%;

@ -56,8 +56,9 @@ onMounted(() => {
</script>
<template>
<div class="py-4 main">
<div class="main modelList_wrap">
<div
class="modelList_body"
v-loading="dataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
@ -97,18 +98,29 @@ onMounted(() => {
<ModelCard :device="device" />
</el-col>
</el-row>
<el-pagination
v-model:currentPage="pagination.current"
class="float-right"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 24, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
<div class="pagination_wrap">
<el-pagination
v-model:currentPage="pagination.current"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 24, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
</div>
</template>
</div>
</div>
</template>
<style lang="scss">
.modelList_wrap {
.modelList_body {
height: calc(100vh - 180px);
// /* background-color: orange; */
overflow-x: hidden;
overflow-y: scroll;
}
}
</style>

@ -56,13 +56,14 @@ onMounted(() => {
</script>
<template>
<div class="py-4 main">
<div class="mt-4 mb-5">
<div class="main serve_wrap">
<div class="mb-5">
<el-button type="primary"> {{ `全部状态(${14})` }} </el-button>
<el-button> {{ `在线(${9})` }}</el-button>
<el-button>{{ `离线(${3})` }}</el-button>
</div>
<div
class="serve_body"
v-loading="dataLoading"
:element-loading-svg="svg"
element-loading-svg-view-box="-10, -10, 50, 50"
@ -102,18 +103,30 @@ onMounted(() => {
<ServerCard :device="device" />
</el-col>
</el-row>
<el-pagination
v-model:currentPage="pagination.current"
class="float-right"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 24, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
<div class="pagination_wrap">
<el-pagination
v-model:currentPage="pagination.current"
class="float-right"
:page-size="pagination.pageSize"
:total="pagination.total"
:page-sizes="[9, 24, 36]"
:background="false"
layout="total, sizes, prev, pager, next, jumper"
@size-change="onPageSizeChange"
@current-change="onCurrentChange"
/>
</div>
</template>
</div>
</div>
</template>
<style lang="scss">
.serve_wrap {
.serve_body {
height: calc(100vh - 240px);
/* background-color: orange; */
overflow-x: hidden;
overflow-y: scroll;
}
}
</style>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-01-12 15:35:09
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-01-18 16:37:24
* @LastEditTime: 2024-01-23 11:30:33
* @FilePath: \general-work-web\General-AI-Platform-Web-Client\src\views\workbench\components\SwiperShow.vue
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
-->

@ -65,7 +65,7 @@ const dataViewList = [
</script>
<template>
<div class="main">
<div class="main workbench_wrap">
<el-row :gutter="24" justify="space-around">
<re-col
v-motion
@ -292,6 +292,12 @@ const dataViewList = [
</template>
<style lang="scss" scoped>
.workbench_wrap {
overflow-x: hidden;
overflow-y: scroll;
height: calc(100% - 0px);
// background-color: red;
}
.dataView_box {
& > li {
padding-right: 16px;

Loading…
Cancel
Save