update code

main
haha 2024-05-22 01:03:00 +08:00
parent 2e176e5be5
commit 57385ce330
34 changed files with 156 additions and 828 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

@ -11,20 +11,20 @@ class MenuAPI {
{
path: "/split",
component: "Layout",
redirect: "/split/index",
redirect: "/split/split1",
name: "/split",
meta: {
title: "算法分割",
icon: "project",
icon: "split",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
},
children: [
{
path: "user",
component: "system/user/index",
name: "User",
path: "split1",
component: "split/split1/index",
name: "split1",
meta: {
title: "算法分割1",
icon: "user",
@ -35,9 +35,9 @@ class MenuAPI {
},
},
{
path: "role",
component: "system/role/index",
name: "Role",
path: "/split2",
component: "split/split1/index",
name: "/split2",
meta: {
title: "算法分割2",
icon: "role",
@ -56,7 +56,7 @@ class MenuAPI {
name: "/internetProtocol",
meta: {
title: "互联协议",
icon: "api",
icon: "web",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
@ -97,7 +97,7 @@ class MenuAPI {
name: "/simulationEvaluation",
meta: {
title: "仿真评估",
icon: "client",
icon: "simu",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
@ -138,16 +138,16 @@ class MenuAPI {
name: "/operatorLibrary",
meta: {
title: "算子库管理",
icon: "dict",
icon: "oper",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
},
children: [
{
path: "user",
component: "system/user/index",
name: "User",
path: "operatorLibrary",
component: "/operatorLibrary/index",
name: "operatorLibrary",
meta: {
title: "算子库管理1",
icon: "user",
@ -158,9 +158,9 @@ class MenuAPI {
},
},
{
path: "role",
component: "system/role/index",
name: "Role",
path: "operatorLibrary2",
component: "/operatorLibrary/index2",
name: "operatorLibrary2",
meta: {
title: "算子库管理2",
icon: "role",
@ -179,7 +179,7 @@ class MenuAPI {
name: "/dataMgr",
meta: {
title: "数据管理",
icon: "edit",
icon: "db",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
@ -220,7 +220,7 @@ class MenuAPI {
name: "/tester",
meta: {
title: "算法测试仪管理",
icon: "link",
icon: "test",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,
@ -261,7 +261,7 @@ class MenuAPI {
name: "/system",
meta: {
title: "系统管理",
icon: "menu",
icon: "system",
hidden: false,
roles: ["GUEST", "ADMIN", "ADMIN6"],
alwaysShow: false,

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 7.9 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 16 KiB

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8564"><path d="M612.8128 221.3376a100.8128 100.8128 0 1 1-201.6256 0 100.8128 100.8128 0 0 1 201.6256 0z m-51.2 0a49.6128 49.6128 0 1 0-99.2256 0 49.6128 49.6128 0 0 0 99.2256 0zM516.864 548.9664a25.1904 25.1904 0 1 0 0-50.432 25.1904 25.1904 0 0 0 0 50.432zM365.056 276.2752a38.4 38.4 0 0 1-20.5824 50.2272l-53.4016 22.3744L433.152 428.544l0.6656 0.3584c22.1696-19.456 51.2-31.1808 82.9952-31.1808 34.5088 0 65.792 13.824 88.576 36.352l131.9936-83.3024-57.856-24.2688a38.4 38.4 0 0 1 29.6448-70.8608l125.952 52.7872a38.4 38.4 0 0 1 23.6032 35.4304v151.3984a38.4 38.4 0 1 1-76.8 0V413.5424L644.096 500.4288a39.424 39.424 0 0 1-3.072 1.7408 126.0544 126.0544 0 0 1-84.0704 141.056v163.2768l78.0288-46.5408a38.4 38.4 0 0 1 39.3728 65.9456l-136.0896 81.2032a38.4 38.4 0 0 1-38.8608 0.3072l-140.9536-81.2032a38.4 38.4 0 1 1 38.3488-66.56l83.4048 48.0256v-163.328a126.0544 126.0544 0 0 1-86.016-149.6576L242.0224 409.3952v87.8592a38.4 38.4 0 1 1-76.8 0V343.8592a38.4 38.4 0 0 1 23.552-35.4304l126.0032-52.736a38.4 38.4 0 0 1 50.2784 20.5824z m151.808 322.304a74.8032 74.8032 0 1 0 0-149.6576 74.8032 74.8032 0 0 0 0 149.6576zM329.6256 684.032a100.864 100.864 0 1 1-201.6256 0 100.864 100.864 0 0 1 201.6256 0z m-51.2 0a49.664 49.664 0 1 0-99.2256 0 49.664 49.664 0 0 0 99.2256 0zM795.1872 784.7936a100.864 100.864 0 1 0 0-201.6256 100.864 100.864 0 0 0 0 201.6256z m0-51.2a49.6128 49.6128 0 1 1 0-99.2256 49.6128 49.6128 0 0 1 0 99.2256z" p-id="8565"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1.0546875em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1080 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7741"><path d="M755.882667 460.231111a28.444444 28.444444 0 0 1 0 46.648889l-284.444445 199.111111A28.444444 28.444444 0 0 1 426.666667 682.666667V284.444444a28.444444 28.444444 0 0 1 44.771555-23.324444l284.444445 199.111111zM483.555556 339.057778v288.995555l206.392888-144.497777L483.555556 339.057778z" fill="#515151" p-id="7742"></path><path d="M983.324444 378.88a113.777778 113.777778 0 1 1-60.814222-7.964444 398.392889 398.392889 0 0 0-749.340444-41.528889 28.444444 28.444444 0 1 1-52.451556-22.072889A455.168 455.168 0 0 1 983.324444 378.88z m-17.009777-5.688889a23.153778 23.153778 0 0 0-7.964445-2.787555l-3.527111-0.568889a28.330667 28.330667 0 0 1 11.491556 3.356444z m-19.171556 54.101333a56.888889 56.888889 0 1 0 6.314667 1.308445 28.672 28.672 0 0 1-6.314667-1.308445zM105.244444 648.078222a113.777778 113.777778 0 1 1 61.155556 3.584 398.449778 398.449778 0 0 0 737.848889 25.201778 28.444444 28.444444 0 1 1 51.939555 23.210667 455.281778 455.281778 0 0 1-850.944-51.996445z m36.977778-50.744889a56.888889 56.888889 0 1 0 0-113.777777 56.888889 56.888889 0 0 0 0 113.777777z" fill="#515151" p-id="7743"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4529"><path d="M908.8 399.36H112A97.28 97.28 0 0 1 14.72 302.08V97.92a32.64 32.64 0 0 1 64 0v204.16a32 32 0 0 0 32 32H908.8a32 32 0 0 0 32-32V97.92a32.64 32.64 0 0 1 64 0v204.16a97.92 97.92 0 0 1-96 97.28zM973.44 942.08a32.64 32.64 0 0 1-32.64-32.64V704a32 32 0 0 0-32-32H112a32 32 0 0 0-32 32v204.16a32.64 32.64 0 0 1-64 0V704a97.28 97.28 0 0 1 96-96H908.8a97.92 97.92 0 0 1 97.28 96v204.16a32.64 32.64 0 0 1-32.64 33.92zM864.64 538.88L155.52 533.76a33.28 33.28 0 0 1-32-33.28 32 32 0 0 1 32.64-32l708.48 5.12a33.92 33.92 0 0 1 32.64 33.28 32 32 0 0 1-32.64 32z" fill="#323333" p-id="4530"></path></svg>

After

Width:  |  Height:  |  Size: 792 B

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1.142578125em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1170 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11717"><path d="M608.914177 179.748722V292.571559H969.142684a54.857133 54.857133 0 0 1 54.857133 54.857133v621.714175a54.857133 54.857133 0 0 1-54.857133 54.857133H201.142821a54.857133 54.857133 0 0 1-54.857133-54.857133V347.428692a54.857133 54.857133 0 0 1 54.857133-54.857133h362.057078V180.205865A91.465127 91.465127 0 0 1 585.142753 0.000183a91.428555 91.428555 0 0 1 23.771424 179.748539zM210.285677 338.285837a18.285711 18.285711 0 0 0-18.285711 18.285711v603.428463a18.285711 18.285711 0 0 0 18.285711 18.285711h749.714152a18.285711 18.285711 0 0 0 18.285711-18.285711v-603.428463a18.285711 18.285711 0 0 0-18.285711-18.285711h-749.714152zM585.142753 137.143016a45.714278 45.714278 0 1 0 0-91.428556 45.714278 45.714278 0 0 0 0 91.428556zM22.857139 566.857224c12.617141 0 22.857139 10.239998 22.857139 22.857139v137.142833a22.857139 22.857139 0 0 1-45.714278 0v-137.142833C0 577.097223 10.239998 566.857224 22.857139 566.857224z m73.142844-91.428555c12.617141 0 22.857139 10.239998 22.857139 22.857139v319.999943a22.857139 22.857139 0 0 1-45.714278 0v-319.999943c0-12.617141 10.239998-22.857139 22.857139-22.857139z m1051.428384 91.428555c12.617141 0 22.857139 10.239998 22.857138 22.857139v137.142833a22.857139 22.857139 0 0 1-45.714277 0v-137.142833c0-12.617141 10.239998-22.857139 22.857139-22.857139z m-73.142845-91.428555c12.617141 0 22.857139 10.239998 22.857139 22.857139v319.999943a22.857139 22.857139 0 0 1-45.714277 0v-319.999943c0-12.617141 10.239998-22.857139 22.857138-22.857139zM810.422712 781.952043c8.137141-0.365714 14.53714 1.462857 19.181711 5.558856 4.644571 4.077714 7.314284 8.722284 8.063999 13.897141 0.731428 5.211428-0.64 10.313141-4.169142 15.323426-3.529142 4.991999-9.362284 8.429713-17.535997 10.294855-19.291425 0.731428-38.473136 1.005714-57.59999 0.822857-19.090282-0.182857-38.290279-0.274286-57.581704-0.274286-8.155427-1.097143-14.189712-3.986285-18.084568-8.630855-3.894856-4.626285-5.741713-9.63657-5.558856-15.012569 0.182857-5.375999 2.413714-10.294855 6.674284-14.756569 4.278856-4.443428 10.477712-6.857142 18.651426-7.222856h16.402282c5.394285 0 10.861712 0.182857 16.420569 0.548572V539.337229h-35.053708c-8.155427-1.097143-14.189712-3.986285-18.084568-8.612569-3.894856-4.644571-5.741713-9.654855-5.558857-15.030855 0.182857-5.375999 2.413714-10.294855 6.674285-14.738283 4.260571-4.461713 10.477712-6.875427 18.651425-7.241142h114.614837c7.039999 2.230857 12.251426 5.558856 15.579426 10.02057 3.327999 4.443428 4.918856 8.99657 4.735999 13.622855-0.182857 4.644571-2.139428 9.087998-5.851428 13.348569-3.711999 4.278856-9.087998 7.149713-16.127997 8.630855h-33.956565v243.730243a376.393076 376.393076 0 0 0 29.494852-1.115429z m-261.68681 13.951998l-15.963426-41.965707h-135.935975l-15.963426 42.879992c-6.217142 16.71314-11.556569 28.013709-15.963426 33.865137-4.406856 5.851428-11.629712 8.777141-21.668567 8.777141-8.521141 0-11.812569-2.852571-17.023997-9.343998-5.211428-6.509713-6.217142-13.311998-6.217142-21.211425 0-4.571428 0.676571-9.270855 2.194285-14.134854 1.517714-4.863999 4.187428-11.647998 7.679999-20.29714l85.39427-217.124532c2.194285-5.66857 8.466284-21.650282 8.777142-22.473139a113.554265 113.554265 0 0 1 10.971426-21.759996c3.876571-5.79657 10.697141-12.543998 14.134855-14.829712 3.419428-2.285714 7.990856-4.571428 15.414854-4.571428 7.442284 0 9.50857-0.786286 16.58514 4.571428 2.889142 2.194285 9.234284 8.959998 13.110855 14.591998 3.876571 5.613713 7.20457 11.666284 9.874284 18.121139 2.669714 6.473142 5.942856 15.085712 10.057141 25.892567l87.405699 215.753104c6.838856 16.420568 10.239998 28.342852 10.239998 35.803422 0 7.753141-1.554285 14.40914-6.034285 21.32114-2.742857 4.205714-8.722284 9.691427-17.846854 9.691426-5.321142 0-9.874284-0.950857-13.677712-2.852571a28.031995 28.031995 0 0 1-9.581712-7.753141c-2.596571-3.273142-5.357713-8.283427-8.319999-15.04914-2.980571-6.765713-5.522285-12.726855-7.643427-17.901711z m-134.107405-92.818269h99.89484l-50.413706-137.983976-49.481134 137.983976z" fill="#000000" p-id="11718"></path></svg>

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6501"><path d="M954.393689 486.469534l-0.686638 0c-12.847609-233.459123-206.825532-419.442978-443.425182-419.442978-244.88536 0-444.116937 199.2326-444.116937 444.11796 0 244.881267 199.230554 444.11182 444.116937 444.11182 244.87922 0 444.110797-199.230554 444.110797-444.11182 0-7.686053-0.196475-15.32708-0.584308-22.917966L954.393689 486.469534zM133.620253 670.664649c-20.203134-45.630247-31.872918-95.331205-32.783661-147.187247l149.923568 0c0.415462 52.483328 5.799076 102.237499 15.438621 148.039661L140.183739 671.517063 133.620253 670.664649zM522.615779 301.420981 522.615779 104.037495l-3.165086-1.36509c72.194252 9.844206 140.828422 89.218998 180.866301 198.748576L522.615779 301.420981zM712.405309 338.429873c13.33675 46.076408 21.698185 96.252181 23.50432 148.039661L522.615779 486.469534 522.615779 338.429873 712.405309 338.429873zM485.605863 103.310947l0 198.111057L319.439356 301.422004C355.426989 194.099696 416.442644 115.572202 485.605863 103.310947zM485.605863 338.429873l0 148.039661L285.99464 486.469534c2.227738-51.738361 10.053983-101.926414 22.338774-148.039661L485.605863 338.429873zM251.29535 486.469534 101.93767 486.469534c3.980661-52.02898 18.043958-102.143355 40.190351-148.039661l129.105427 0C260.119319 384.294456 253.228375 434.136631 251.29535 486.469534zM285.376563 523.477402l200.230324 0L485.606887 671.517063 304.672024 671.517063C292.826232 625.425306 285.915845 575.352887 285.376563 523.477402zM485.605863 708.524932l0 208.085222c-69.969585-18.518772-134.104277-99.099019-170.09191-208.085222L485.605863 708.524932zM522.615779 920.448576 522.615779 708.524932l184.212512 0C669.565619 829.42242 600.75851 915.840628 522.615779 920.448576zM522.615779 671.517063 522.615779 523.477402l213.471906 0c-1.218758 51.758828-7.944949 101.857852-19.11229 148.039661L522.615779 671.517063zM769.797437 523.477402l149.928684 0c-0.862647 52.178383-11.979846 102.176101-31.397081 148.039661l-133.971247 0C763.998361 625.714901 769.382998 575.960731 769.797437 523.477402zM769.262248 486.469534c-1.933025-52.331879-8.823969-102.175077-19.937075-148.039661L876.148627 338.429873c23.269983 45.896306 38.175461 96.009657 42.399669 148.039661L769.262248 486.469534zM855.012238 301.420981 739.183186 301.420981c-22.285562-72.507384-55.711859-132.844587-96.890724-174.137039C729.395262 160.310126 804.862048 222.909859 855.012238 301.420981zM384.27706 121.440863c-43.940768 41.34157-79.541591 103.97712-102.902648 179.981141L162.274874 301.422004C213.143425 218.003106 291.867394 152.545278 384.27706 121.440863zM152.848177 708.524932l122.2943 0c21.618367 78.83244 56.549947 143.574976 100.562347 186.930413C282.002722 861.058954 201.997574 793.811364 152.848177 708.524932zM639.005602 901.045667c46.76714-43.283806 83.842547-110.22645 106.408495-192.520735l124.977409 0C820.87065 798.700721 737.902006 868.711238 639.005602 901.045667z" fill="#2A2B2B" p-id="6502"></path></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -0,0 +1 @@
<svg class="icon" style="width: 1em;height: 1em;vertical-align: middle;fill: currentColor;overflow: hidden;" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2806"><path d="M507.49297778 501.08444446v494.93333332L936.11662222 748.55111112l-0.02275556-494.93333334z" fill="#C3D2FB" p-id="2807"></path><path d="M78.86933333 253.61777778l428.62364445 247.46666667v494.93333333L78.86933333 748.55111112z" fill="#3D4265" p-id="2808"></path><path d="M507.49297778 501.08444446L936.11662222 253.61777778 507.49297778 6.15111111 78.86933333 253.61777778z" fill="#386BF3" p-id="2809"></path></svg>

After

Width:  |  Height:  |  Size: 618 B

View File

@ -1,5 +1,6 @@
<template>
<section class="app-main">
<el-scrollbar max-height="calc(100vh - 76px)">
<router-view>
<template #default="{ Component, route }">
<transition
@ -12,6 +13,7 @@
</transition>
</template>
</router-view>
</el-scrollbar>
</section>
</template>
@ -25,9 +27,8 @@ const cachedViews = computed(() => useTagsViewStore().cachedViews); // 缓存页
.app-main {
position: relative;
width: 100%;
min-height: calc(100vh - $navbar-height);
overflow: hidden;
background-color: var(--el-bg-color-page);
min-height: calc(100vh - 100px);
overflow: hidden;
}
.hasTagsView .app-main {

View File

@ -1,19 +0,0 @@
<template>
<div class="flex">
<hamburger
:is-active="appStore.sidebar.opened"
@toggle-click="toggleSideBar"
/>
<breadcrumb />
</div>
</template>
<script setup lang="ts">
import { useAppStore } from "@/store";
const appStore = useAppStore();
function toggleSideBar() {
appStore.toggleSidebar();
}
</script>

View File

@ -1,25 +1,18 @@
<template>
<div class="flex">
<template v-if="!isMobile">
<div class="flex" style="height: 100%;align-items: center;">
<div style="flex-grow: 1;display: flex;align-items: center;">
<img src="@/assets/logo.svg" class="logo-image" />
<span class="logo-title" style="margin-left: 12px;font-weight: bold;font-size: 20px;"> {{ "算法测试验证软件平台" }}</span>
</div>
<div>
<!--全屏 -->
<div class="setting-item" @click="toggle">
<svg-icon
:icon-class="isFullscreen ? 'fullscreen-exit' : 'fullscreen'"
/>
</div>
<!-- 布局大小 -->
<el-tooltip
:content="$t('sizeSelect.tooltip')"
effect="dark"
placement="bottom"
>
<size-select class="setting-item" />
</el-tooltip>
<!-- 语言选择
<lang-select class="setting-item" />-->
</template>
<!-- 用户头像 -->
<el-dropdown class="setting-item" trigger="click">
@ -31,29 +24,18 @@
<span>{{ userStore.user.username }}</span>
</div>
<template #dropdown>
<el-dropdown-menu>
<a
target="_blank"
href="https://gitee.com/youlaiorg/vue3-element-admin"
>
<el-dropdown-item>{{ $t("navbar.gitee") }}</el-dropdown-item>
</a>
<a target="_blank" href="https://juejin.cn/post/7228990409909108793">
<el-dropdown-item>{{ $t("navbar.document") }}</el-dropdown-item>
</a>
<el-dropdown-item divided @click="logout">
{{ $t("navbar.logout") }}
<el-dropdown-menu>
<el-dropdown-item >
修改密码
</el-dropdown-item>
<el-dropdown-item @click="logout">
注销登录
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<!-- 设置 -->
<template v-if="defaultSettings.showSettings">
<div class="setting-item" @click="settingStore.settingsVisible = true">
<svg-icon icon-class="setting" />
</div>
</template>
</div>
</div>
</template>
<script setup lang="ts">
@ -113,7 +95,10 @@ function logout() {
background: rgb(0 0 0 / 10%);
}
}
.logo-image {
width: 24px;
height: 24px;
}
.layout-top,
.layout-mix {
.setting-item,

View File

@ -1,18 +0,0 @@
<template>
<!-- 顶部导航栏 -->
<div class="navbar-container">
<!-- 导航栏左侧 -->
<NavbarLeft />
<!-- 导航栏右侧 -->
<NavbarRight />
</div>
</template>
<style lang="scss" scoped>
.navbar-container {
@apply flex-x-between;
height: $navbar-height;
background: var(--el-bg-color);
}
</style>

View File

@ -1,108 +0,0 @@
<template>
<div class="flex flex-wrap justify-around w-full h-12">
<el-tooltip content="左侧模式" placement="bottom">
<div
class="layout-item left"
:class="{ 'is-active': modelValue === LayoutEnum.LEFT }"
@click="updateValue(LayoutEnum.LEFT)"
>
<div></div>
<div></div>
</div>
</el-tooltip>
<el-tooltip content="顶部模式" placement="bottom">
<div
class="layout-item top"
:class="{ 'is-active': modelValue === LayoutEnum.TOP }"
@click="updateValue(LayoutEnum.TOP)"
>
<div></div>
<div></div>
</div>
</el-tooltip>
<el-tooltip content="混合模式" placement="bottom">
<div
class="layout-item mix"
:class="{ 'is-active': modelValue === LayoutEnum.MIX }"
@click="updateValue(LayoutEnum.MIX)"
>
<div></div>
<div></div>
</div>
</el-tooltip>
</div>
</template>
<script lang="ts" setup>
import { LayoutEnum } from "@/enums/LayoutEnum";
const props = defineProps({
modelValue: String,
});
const emit = defineEmits(["update:modelValue"]);
function updateValue(layout: string) {
emit("update:modelValue", layout);
}
</script>
<style scoped>
.layout-selector {
display: flex;
flex-wrap: wrap;
justify-content: space-around;
width: 100%;
height: 50px;
}
.layout-item {
position: relative;
width: 18%;
height: 45px;
overflow: hidden;
cursor: pointer;
background: #f0f2f5;
border-radius: 4px;
&.mix div:nth-child(1),
&.top div:nth-child(1) {
width: 100%;
height: 30%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&.mix div:nth-child(2) {
position: absolute;
bottom: 0;
left: 0;
width: 30%;
height: 70%;
background: #1b2a47;
box-shadow: 0 0 1px #888;
}
&.left div:nth-child(1) {
width: 30%;
height: 100%;
background: #1b2a47;
}
&.left div:nth-child(2) {
position: absolute;
top: 0;
right: 0;
width: 70%;
height: 30%;
background: #fff;
box-shadow: 0 0 1px #888;
}
}
.layout-item.is-active {
border: 2px solid var(--el-color-primary);
}
</style>

View File

@ -1,41 +0,0 @@
<template>
<el-color-picker
v-model="currentColor"
:predefine="colorPresets"
popper-class="theme-picker-dropdown"
/>
</template>
<script lang="ts" setup>
const props = defineProps({
modelValue: String,
});
const emit = defineEmits(["update:modelValue"]);
//
const colorPresets = [
"#409EFF",
"#ff4500",
"#ff8c00",
"#90ee90",
"#00ced1",
"#1e90ff",
"#c71585",
"rgba(255, 69, 0, 0.68)",
"rgb(255, 120, 0)",
"hsva(120, 40, 94)",
];
const currentColor = ref(props.modelValue);
watch(currentColor, (newValue) => {
emit("update:modelValue", newValue);
});
</script>
<style scoped>
:deep(.theme-picker-dropdown) {
z-index: 99999 !important;
}
</style>

View File

@ -1,144 +0,0 @@
<template>
<el-drawer
v-model="settingsVisible"
size="300"
:title="$t('settings.project')"
>
<el-divider>{{ $t("settings.theme") }}</el-divider>
<div class="flex-center">
<el-switch
v-model="isDark"
active-icon="Moon"
inactive-icon="Sunny"
@change="changeTheme"
/>
</div>
<el-divider>{{ $t("settings.interface") }}</el-divider>
<div class="settings-option">
<span class="text-xs">{{ $t("settings.themeColor") }}</span>
<ThemeColorPicker
v-model="settingsStore.themeColor"
@update:model-value="changeThemeColor"
/>
</div>
<div class="settings-option">
<span class="text-xs">{{ $t("settings.tagsView") }}</span>
<el-switch v-model="settingsStore.tagsView" />
</div>
<div class="settings-option">
<span class="text-xs">{{ $t("settings.fixedHeader") }}</span>
<el-switch v-model="settingsStore.fixedHeader" />
</div>
<div class="settings-option">
<span class="text-xs">{{ $t("settings.sidebarLogo") }}</span>
<el-switch v-model="settingsStore.sidebarLogo" />
</div>
<div class="settings-option">
<span class="text-xs">{{ $t("settings.watermark") }}</span>
<el-switch v-model="settingsStore.watermarkEnabled" />
</div>
<el-divider>{{ $t("settings.navigation") }}</el-divider>
<LayoutSelect
v-model="settingsStore.layout"
@update:model-value="changeLayout"
/>
</el-drawer>
</template>
<script setup lang="ts">
import { useSettingsStore, usePermissionStore, useAppStore } from "@/store";
import { LayoutEnum } from "@/enums/LayoutEnum";
import { ThemeEnum } from "@/enums/ThemeEnum";
const route = useRoute();
const appStore = useAppStore();
const settingsStore = useSettingsStore();
const permissionStore = usePermissionStore();
const settingsVisible = computed({
get() {
return settingsStore.settingsVisible;
},
set() {
settingsStore.settingsVisible = false;
},
});
/**
* 切换主题颜色
*/
function changeThemeColor(color: string) {
settingsStore.changeThemeColor(color);
}
/**
* 切换主题
*/
const isDark = ref<boolean>(settingsStore.theme === ThemeEnum.DARK);
const changeTheme = (val: any) => {
isDark.value = val;
settingsStore.changeTheme(isDark.value ? ThemeEnum.DARK : ThemeEnum.LIGHT);
};
/**
* 切换布局
*/
function changeLayout(layout: string) {
settingsStore.changeLayout(layout);
if (layout === LayoutEnum.MIX) {
route.name && againActiveTop(route.name as string);
} else if (layout === LayoutEnum.TOP) {
appStore.openSideBar();
}
}
function againActiveTop(newVal: string) {
const parent = findOutermostParent(permissionStore.routes, newVal);
if (appStore.activeTopMenu !== parent.path) {
appStore.activeTopMenu(parent.path);
}
}
function findOutermostParent(tree: any[], findName: string) {
let parentMap: any = {};
function buildParentMap(node: any, parent: any) {
parentMap[node.name] = parent;
if (node.children) {
for (let i = 0; i < node.children.length; i++) {
buildParentMap(node.children[i], node);
}
}
}
for (let i = 0; i < tree.length; i++) {
buildParentMap(tree[i], null);
}
let currentNode = parentMap[findName];
while (currentNode) {
if (!parentMap[currentNode.name]) {
return currentNode;
}
currentNode = parentMap[currentNode.name];
}
return null;
}
</script>
<style lang="scss" scoped>
.settings-option {
@apply py-1 flex-x-between;
}
</style>

View File

@ -1,64 +0,0 @@
<template>
<div class="logo-container">
<transition enter-active-class="animate__animated animate__fadeInLeft">
<router-link v-if="collapse" class="wh-full flex-center" to="/">
<img v-if="settingsStore.sidebarLogo" :src="logo" class="logo-image" />
</router-link>
<router-link v-else class="wh-full flex-center" to="/">
<img v-if="settingsStore.sidebarLogo" :src="logo" class="logo-image" />
<span class="logo-title"> {{ "算法测试验证软件平台" }}</span>
</router-link>
</transition>
</div>
</template>
<script lang="ts" setup>
import defaultSettings from "@/settings";
import { useSettingsStore } from "@/store";
const settingsStore = useSettingsStore();
defineProps({
collapse: {
type: Boolean,
required: true,
},
});
const logo = ref(new URL(`../../../../assets/logo2.png`, import.meta.url).href);
</script>
<style lang="scss" scoped>
.logo-container {
width: 100%;
height: $navbar-height;
background-color: $sidebar-logo-background;
.logo-image {
width: 20px;
height: 20px;
}
.logo-title {
flex-shrink: 0; /* 防止容器在空间不足时缩小 */
margin-left: 10px;
font-size: 14px;
font-weight: bold;
color: white;
}
}
.layout-top,
.layout-mix {
.logo-container {
width: $sidebar-width;
}
&.hideSidebar {
.logo-container {
width: $sidebar-width-collapsed;
}
}
}
</style>

View File

@ -1,22 +1,9 @@
<!-- 左侧边菜单包括左侧布局(left)顶部布局(all)混合布局(left) -->
<template>
<el-menu
:default-active="currentRoute.path"
:collapse="!appStore.sidebar.opened"
:background-color="variables['menu-background']"
:text-color="variables['menu-text']"
:active-text-color="variables['menu-active-text']"
:unique-opened="false"
:collapse-transition="false"
:mode="layout === 'top' ? 'horizontal' : 'vertical'"
>
<SidebarMenuItem
v-for="route in menuList"
:key="route.path"
:item="route"
:base-path="resolvePath(route.path)"
:is-collapse="!appStore.sidebar.opened"
/>
<el-menu :default-active="currentRoute.path" :collapse="!appStore.sidebar.opened" :unique-opened="false"
:collapse-transition="false" :mode="layout === 'top' ? 'horizontal' : 'vertical'">
<SidebarMenuItem v-for="route in menuList" :key="route.path" :item="route" :base-path="resolvePath(route.path)"
:is-collapse="!appStore.sidebar.opened" />
</el-menu>
</template>

View File

@ -3,10 +3,7 @@
<el-scrollbar>
<el-menu
mode="horizontal"
:default-active="activePath"
:background-color="variables['menu-background']"
:text-color="variables['menu-text']"
:active-text-color="variables['menu-active-text']"
:default-active="activePath"
@select="handleMenuSelect"
>
<el-menu-item

View File

@ -1,20 +1,7 @@
<template>
<div :class="{ 'has-logo': sidebarLogo }">
<!--混合布局-->
<div class="flex w-full" v-if="layout == LayoutEnum.MIX">
<SidebarLogo v-if="sidebarLogo" :collapse="!appStore.sidebar.opened" />
<SidebarMixTopMenu class="flex-1" />
<NavbarRight />
</div>
<!--左侧布局 || 顶部布局 -->
<template v-else>
<SidebarLogo v-if="sidebarLogo" :collapse="!appStore.sidebar.opened" />
<el-scrollbar>
<template>
<el-scrollbar max-height="calc(100vh - 100px)">
<SidebarMenu :menu-list="permissionStore.routes" base-path="" />
</el-scrollbar>
<NavbarRight v-if="layout === LayoutEnum.TOP" />
</template>
</div>
</el-scrollbar>
</template>
<script setup lang="ts">
@ -25,7 +12,7 @@ const appStore = useAppStore();
const settingsStore = useSettingsStore();
const permissionStore = usePermissionStore();
const sidebarLogo = computed(() => settingsStore.sidebarLogo);
const layout = computed(() => settingsStore.layout);
</script>

View File

@ -1,35 +1,16 @@
<template>
<div class="tags-container">
<el-scrollbar
class="scroll-container"
:vertical="false"
@wheel.prevent="handleScroll"
>
<router-link
ref="tagRef"
v-for="tag in visitedViews"
:key="tag.fullPath"
:class="'tags-item ' + (isActive(tag) ? 'active' : '')"
:to="{ path: tag.path, query: tag.query }"
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''"
@contextmenu.prevent="openContentMenu(tag, $event)"
>
<el-scrollbar class="scroll-container" :vertical="false" @wheel.prevent="handleScroll">
<router-link ref="tagRef" v-for="tag in visitedViews" :key="tag.fullPath"
:class="'tags-item ' + (isActive(tag) ? 'active' : '')" :to="{ path: tag.path, query: tag.query }"
@click.middle="!isAffix(tag) ? closeSelectedTag(tag) : ''" @contextmenu.prevent="openContentMenu(tag, $event)">
{{ translateRouteTitle(tag.title) }}
<i-ep-close
class="close-icon"
size="12px"
v-if="!isAffix(tag)"
@click.prevent.stop="closeSelectedTag(tag)"
/>
<i-ep-close class="close-icon" size="12px" v-if="!isAffix(tag)" @click.prevent.stop="closeSelectedTag(tag)" />
</router-link>
</el-scrollbar>
<!-- tag标签操作菜单 -->
<ul
v-show="contentMenuVisible"
class="contextmenu"
:style="{ left: left + 'px', top: top + 'px' }"
>
<ul v-show="contentMenuVisible" class="contextmenu" :style="{ left: left + 'px', top: top + 'px' }">
<li @click="refreshSelectedTag(selectedTag)">
<svg-icon icon-class="refresh" />
刷新

View File

@ -1,67 +1,27 @@
<template>
<div class="wh-full" :class="classObj">
<!-- 遮罩层 -->
<div
v-if="isMobile && isOpenSidebar"
class="wh-full fixed-lt z-999 bg-black bg-opacity-30"
@click="handleOutsideClick"
></div>
<!-- 公用侧边栏 -->
<Sidebar class="sidebar-container" />
<!-- 混合布局 -->
<div v-if="layout === LayoutEnum.MIX" class="mix-container">
<div class="mix-container__left">
<SidebarMenu :menu-list="mixLeftMenus" :base-path="activeTopMenuPath" />
<div class="sidebar-toggle">
<hamburger
:is-active="appStore.sidebar.opened"
@toggle-click="toggleSidebar"
/>
</div>
</div>
<div :class="{ hasTagsView: showTagsView }" class="main-container">
<div :class="{ 'fixed-header': fixedHeader }">
<TagsView v-if="showTagsView" />
</div>
<AppMain />
<Settings v-if="defaultSettings.showSettings" />
</div>
</div>
<!-- 左侧和顶部布局 -->
<div v-else :class="{ hasTagsView: showTagsView }" class="main-container">
<div :class="{ 'fixed-header': fixedHeader }">
<NavBar v-if="layout === 'left'" />
<TagsView v-if="showTagsView" />
</div>
<AppMain />
<Settings v-if="defaultSettings.showSettings" />
</div>
</div>
<template>
<el-container class="wh-full main-container">
<el-header><NavbarRight /></el-header>
<el-container class="center-container">
<el-aside width="240px">
<Sidebar class="sidebar-container" />
</el-aside>
<el-main>
<AppMain />
</el-main>
</el-container>
</el-container>
</template>
<script setup lang="ts">
import { useAppStore, useSettingsStore, usePermissionStore } from "@/store";
import defaultSettings from "@/settings";
import { useAppStore, usePermissionStore } from "@/store";
import { DeviceEnum } from "@/enums/DeviceEnum";
import { LayoutEnum } from "@/enums/LayoutEnum";
const appStore = useAppStore();
const settingsStore = useSettingsStore();
const permissionStore = usePermissionStore();
const width = useWindowSize().width;
const WIDTH_DESKTOP = 992; // >=1200px >=992px >=768px
const isMobile = computed(() => appStore.device === DeviceEnum.MOBILE);
const isOpenSidebar = computed(() => appStore.sidebar.opened);
const fixedHeader = computed(() => settingsStore.fixedHeader); // header
const showTagsView = computed(() => settingsStore.tagsView); // tagsView
const layout = computed(() => settingsStore.layout); // left top mix
const activeTopMenuPath = computed(() => appStore.activeTopMenuPath); // path
const mixLeftMenus = computed(() => permissionStore.mixLeftMenus); //
watch(
() => activeTopMenuPath.value,
@ -74,13 +34,6 @@ watch(
}
);
const classObj = computed(() => ({
hideSidebar: !appStore.sidebar.opened,
openSidebar: appStore.sidebar.opened,
mobile: appStore.device === DeviceEnum.MOBILE,
[`layout-${settingsStore.layout}`]: true,
}));
watchEffect(() => {
appStore.toggleDevice(
width.value < WIDTH_DESKTOP ? DeviceEnum.MOBILE : DeviceEnum.DESKTOP
@ -92,13 +45,8 @@ watchEffect(() => {
}
});
function handleOutsideClick() {
appStore.closeSideBar();
}
function toggleSidebar() {
appStore.toggleSidebar();
}
const route = useRoute();
watch(route, () => {
@ -107,240 +55,41 @@ watch(route, () => {
}
});
</script>
<style lang="scss" scoped>
.fixed-header {
position: fixed;
top: 0;
right: 0;
z-index: 9;
width: calc(100% - $sidebar-width);
transition: width 0.28s;
}
.sidebar-container {
position: fixed;
top: 0;
bottom: 0;
left: 0;
z-index: 999;
width: $sidebar-width;
height: 100%;
overflow: hidden;
background-color: $menu-background;
transition: width 0.28s;
:deep(.el-menu) {
border: none;
<style lang="scss">
.main-container{
background-color: #F3F8FB;
.el-menu-item {
&.is-active{
background-color: #EEF3FB;
border-right:solid 3px var(--el-color-primary);
}
}
.el-header{
background-color: #fff;
}
.center-container{
padding-top:12px;
.el-aside{
background-color: #fff;
.el-scrollbar{
padding:12px;
}
.el-menu{
border-right:none;
}
}
.el-main{
padding:0px;
}
}
}
</style>
<style lang="scss" scoped>
.main-container {
position: relative;
min-height: 100%;
margin-left: $sidebar-width;
transition: margin-left 0.28s;
}
.layout-top {
.fixed-header {
top: $navbar-height;
width: 100%;
}
.sidebar-container {
z-index: 999;
display: flex;
width: 100% !important;
height: $navbar-height;
:deep(.el-scrollbar) {
flex: 1;
height: $navbar-height;
}
:deep(.el-menu-item),
:deep(.el-sub-menu__title),
:deep(.el-menu--horizontal) {
height: $navbar-height;
line-height: $navbar-height;
}
:deep(.el-menu--collapse) {
width: 100%;
}
}
.main-container {
min-height: calc(100vh - $navbar-height);
padding-top: $navbar-height;
margin-left: 0;
}
}
.layout-mix {
.sidebar-container {
width: 100% !important;
height: $navbar-height;
:deep(.el-scrollbar) {
flex: 1;
height: $navbar-height;
}
:deep(.el-menu-item),
:deep(.el-sub-menu__title),
:deep(.el-menu--horizontal) {
height: $navbar-height;
line-height: $navbar-height;
}
:deep(.el-menu--horizontal.el-menu) {
border: none;
}
}
.mix-container {
display: flex;
height: 100%;
padding-top: $navbar-height;
.mix-container__left {
position: relative;
width: $sidebar-width;
height: 100%;
:deep(.el-menu) {
height: 100%;
border: none;
}
.sidebar-toggle {
position: absolute;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 50px;
line-height: 50px;
box-shadow: 0 0 6px -2px var(--el-color-primary);
div:hover {
background-color: var(--menu-background);
}
:deep(svg) {
color: var(--el-color-primary) !important;
}
}
}
.main-container {
flex: 1;
min-width: 0;
margin-left: 0;
.fixed-header {
top: $navbar-height;
}
}
}
}
.hideSidebar {
.fixed-header {
left: $sidebar-width-collapsed;
width: calc(100% - $sidebar-width-collapsed);
}
.main-container {
margin-left: $sidebar-width-collapsed;
}
&.layout-top {
.fixed-header {
left: 0;
width: 100%;
}
.main-container {
margin-left: 0;
}
}
&.layout-mix {
.fixed-header {
left: $sidebar-width-collapsed;
width: calc(100% - $sidebar-width-collapsed);
}
.sidebar-container {
width: 100% !important;
}
.mix-container {
.mix-container__left {
width: $sidebar-width-collapsed;
}
}
}
}
.layout-left.hideSidebar {
.sidebar-container {
width: $sidebar-width-collapsed !important;
}
.main-container {
margin-left: $sidebar-width-collapsed;
}
&.mobile {
.sidebar-container {
pointer-events: none;
transition-duration: 0.3s;
transform: translate3d(-210px, 0, 0);
}
.main-container {
margin-left: 0;
}
}
}
.mobile {
.fixed-header {
left: 0;
width: 100%;
}
.main-container {
margin-left: 0;
}
&.layout-top {
.sidebar-container {
z-index: 999;
display: flex;
width: 100% !important;
height: $navbar-height;
:deep(.el-scrollbar) {
flex: 1;
min-width: 0;
height: $navbar-height;
}
}
.main-container {
padding-top: $navbar-height;
margin-left: 0;
overflow: hidden;
}
//
--el-menu-item-height: $navbar-height;
}
}
</style>

View File

@ -11,7 +11,7 @@ const defaultSettings: AppSettings = {
showSettings: true,
tagsView: true,
fixedHeader: true,
sidebarLogo: true,
sidebarLogo: false,
layout: LayoutEnum.LEFT,
theme: ThemeEnum.LIGHT,
size: SizeEnum.DEFAULT,

View File

@ -22,8 +22,7 @@ export const useUserStore = defineStore("user", () => {
function login(loginData: LoginData) {
return new Promise<void>((resolve, reject) => {
AuthAPI.login(loginData)
.then((data) => {
debugger
.then((data) => {
const { tokenType, accessToken } = data;
localStorage.setItem(TOKEN_KEY, tokenType + " " + accessToken); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx
resolve();

View File

@ -24,6 +24,7 @@ html {
body {
width: 100%;
height: 100%;
overflow: hidden;
margin: 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;

View File

@ -1,11 +1,11 @@
/** 全局SCSS变量 */
:root {
--menu-background: #304156;
--menu-background: #FFFFFF;
--menu-text: #bfcbd9;
--menu-active-text: var(--el-menu-active-color);
--menu-hover: #263445;
--sidebar-logo-background: #2d3748;
--menu-hover: #EEF3FB;
--sidebar-logo-background: #fff;
}
/** 暗黑主题 */

View File

@ -90,8 +90,7 @@ declare module "vue" {
RouterLink: (typeof import("vue-router"))["RouterLink"];
RouterView: (typeof import("vue-router"))["RouterView"];
Settings: (typeof import("./../layout/components/Settings/index.vue"))["default"];
Sidebar: (typeof import("./../layout/components/Sidebar/index.vue"))["default"];
SidebarLogo: (typeof import("./../layout/components/Sidebar/components/SidebarLogo.vue"))["default"];
Sidebar: (typeof import("./../layout/components/Sidebar/index.vue"))["default"];
SidebarMenu: (typeof import("./../layout/components/Sidebar/components/SidebarMenu.vue"))["default"];
SidebarMenuItem: (typeof import("./../layout/components/Sidebar/components/SidebarMenuItem.vue"))["default"];
SidebarMenuItemTitle: (typeof import("./../layout/components/Sidebar/components/SidebarMenuItemTitle.vue"))["default"];

View File

@ -4,9 +4,7 @@
<el-row :gutter="10" class="mt-3" style="margin-bottom: 12px;">
<el-col :span="4" v-for="(it,idx) in topInfos" :key="idx">
<el-card shadow="always" class="top-row1">
<el-icon class="top-icon">
<Edit />
</el-icon>
<img :src="it.icon" class="top-icon"/>
<div class="top-row">
<div class="div-title">{{it.title}}</div>
<div class="div-num">{{it.count}}</div>
@ -76,12 +74,12 @@
<script setup lang="ts">
import {reactive} from 'vue'
let topInfos=reactive([
{title:'模型总数',count:158,clsName:'c1'},
{title:'算子总数',count:158,clsName:'c1'},
{title:'数据集总数',count:158,clsName:'c1'},
{title:'评估报告总数',count:158,clsName:'c1'},
{title:'互联总数',count:158,clsName:'c1'},
{title:'总访问量',count:158,clsName:'c1'},
{title:'模型总数',count:158,clsName:'c1',icon:"images/nav/nav1.png"},
{title:'算子总数',count:158,clsName:'c1',icon:"images/nav/nav2.png"},
{title:'数据集总数',count:158,clsName:'c1',icon:"images/nav/nav3.png"},
{title:'评估报告总数',count:158,clsName:'c1',icon:"images/nav/nav4.png"},
{title:'互联总数',count:158,clsName:'c1',icon:"images/nav/nav5.png"},
{title:'总访问量',count:158,clsName:'c1',icon:"images/nav/nav1.png"},
]);
let devInfos=reactive([
@ -91,6 +89,12 @@ let devInfos=reactive([
{id:1004,name:'设备名称4',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1005,name:'设备名称5',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1006,name:'设备名称6',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1007,name:'设备名称1',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1008,name:'设备名称2',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1009,name:'设备名称3',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1010,name:'设备名称4',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1011,name:'设备名称5',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
{id:1012,name:'设备名称6',netType:'network001',modelName:'模型名称',state:0,temperature:25,memory:85,cpu:51},
])
</script>
@ -154,8 +158,12 @@ let devInfos=reactive([
.top-row{
padding-left: 40px;
line-height:30px;
text-align: center;
color:#666;
text-align: center;
.div-title{
font-weight: bold;
font-size:14px;
color:#333;
}
.div-num{
font-size:20px;
font-weight: bolder;

View File

@ -0,0 +1,20 @@
<template>
<div class="split-split1-index">
<div style="text-align: center;">
<svg-icon icon-class="build" style="width:100px;height:100px;" />
</div>
<div style="text-align: center;">
建设中
</div>
</div>
</template>
<script lang='ts' setup>
</script>
<style scoped lang='scss'>
.split-split1-index{
position: relative;
padding: 12px 24px;
}
</style>