@@ -1,4 +1,4 @@ | |||
.containers { | |||
.data-container { | |||
align-items: center; | |||
color: white; | |||
@@ -9,7 +9,7 @@ import { SHARED_IMPORTS } from '@shared'; | |||
selector: 'data-v-date', | |||
standalone: true, | |||
imports: [CommonModule, ...SHARED_IMPORTS], | |||
template: ` <div class="containers"> | |||
template: ` <div class="data-container"> | |||
{{ currentTime | date: 'yyyy-MM-dd HH:mm:ss' }} | |||
</div>`, | |||
styleUrls: ['./date.component.less'] | |||
@@ -0,0 +1,34 @@ | |||
import { CommonModule } from '@angular/common'; | |||
import { ChangeDetectionStrategy, Component, HostListener } from '@angular/core'; | |||
import { I18nPipe } from '@delon/theme'; | |||
import { NzIconModule } from 'ng-zorro-antd/icon'; | |||
import screenfull from 'screenfull'; | |||
@Component({ | |||
selector: 'data-v-fullscreen', | |||
template: ` | |||
<i nz-icon [nzType]="status ? 'fullscreen-exit' : 'fullscreen'"></i> | |||
{{ (status ? '退出全屏' : '进入全屏') }} | |||
`, | |||
host: { | |||
'[class.flex-1]': 'true' | |||
}, | |||
changeDetection: ChangeDetectionStrategy.OnPush, | |||
standalone: true, | |||
imports: [CommonModule, NzIconModule, I18nPipe] | |||
}) | |||
export class DataVFullScreenComponent { | |||
status = false; | |||
@HostListener('window:resize') | |||
_resize(): void { | |||
this.status = screenfull.isFullscreen; | |||
} | |||
@HostListener('click') | |||
_click(): void { | |||
if (screenfull.isEnabled) { | |||
screenfull.toggle(); | |||
} | |||
} | |||
} |
@@ -1,6 +1,9 @@ | |||
<div class="header-container"> | |||
<div class="data-v-sysinfo mr-sm"> | |||
<data-v-user></data-v-user> | |||
<data-v-date></data-v-date> | |||
<data-v-setting class="mr-sm"></data-v-setting> | |||
<data-v-user class="mr-sm"></data-v-user> | |||
<data-v-date class="mr-sm"></data-v-date> | |||
<!-- <data-v-fullscreen></data-v-fullscreen> --> | |||
</div> | |||
</div> | |||
</div> |
@@ -1,12 +1,12 @@ | |||
.header-container { | |||
width: 100vw; | |||
min-width: 1360px; | |||
min-width: 1280px; | |||
/* 水平宽度占据整个视口宽度 */ | |||
height: 10%; | |||
/* 垂直高度占据整个视口高度 */ | |||
background-image: url('../../../../assets/dashboard/dashboard_bg_1.jpg'); | |||
background-image: url('../../../../assets/dashboard/screen_header2.png'); | |||
/* 背景图片尺寸适应 */ | |||
background-position: top; | |||
@@ -8,11 +8,14 @@ import { LayoutDefaultModule } from '@delon/theme/layout-default'; | |||
import { DataVDateComponent } from '../date/date.component'; | |||
import { DataVNavigationComponent } from '../navigation/navigation.component'; | |||
import { RouterOutlet } from '@angular/router'; | |||
import { DataVFullScreenComponent } from '../fullscreen/fullscreen.component'; | |||
import { DataVSettingComponent } from '../setting/setting.component'; | |||
@Component({ | |||
selector: 'app-data-v-header', | |||
standalone: true, | |||
imports: [DataVUserComponent, DataVDateComponent, DataVNavigationComponent, LayoutDefaultModule, RouterOutlet, ...SHARED_IMPORTS], | |||
imports: [DataVSettingComponent, DataVFullScreenComponent, DataVUserComponent, | |||
DataVDateComponent, DataVNavigationComponent, LayoutDefaultModule, RouterOutlet, ...SHARED_IMPORTS], | |||
templateUrl: './header.component.html', | |||
styleUrls: ['./header.component.less'] | |||
}) | |||
@@ -20,7 +23,7 @@ export class DataVHeaderComponent implements OnInit { | |||
private readonly http = inject(_HttpClient); | |||
private readonly modal = inject(ModalHelper); | |||
ngOnInit(): void {} | |||
ngOnInit(): void { } | |||
add(): void { | |||
// this.modal | |||
@@ -1,15 +1,9 @@ | |||
<div class="home-container"> | |||
<!-- <div class="data-v-sysinfo mr-sm"> | |||
<data-v-user></data-v-user> | |||
<data-v-date></data-v-date> | |||
</div> --> | |||
<app-data-v-header></app-data-v-header> | |||
<data-v-navigation></data-v-navigation> | |||
<img src="assets/dashboard/dashboard_menu.jpg" style="width: 100%;" /> | |||
<img src="assets/dashboard/dashboard_menu.jpg" style="width: 100%; height: 1.8rem;" /> | |||
<div style="margin: 1rem;"> | |||
<router-outlet /> | |||
</div> | |||
</div> | |||
</div> |
@@ -1,9 +1,10 @@ | |||
.home-container { | |||
width: 100vw; | |||
min-width: 1360px; | |||
min-width: 1280px; | |||
/* 水平宽度占据整个视口宽度 */ | |||
height: 100vh; | |||
min-height: 768px; | |||
background-color: #040516; | |||
/* 垂直高度占据整个视口高度 */ | |||
@@ -1,75 +1,80 @@ | |||
.navigation-container { | |||
display: flex; | |||
flex-direction: row; | |||
width: 100%; | |||
//height: 4rem; | |||
//margin-top: 2.5rem; | |||
padding-left: 2rem; | |||
display: flex; | |||
flex-direction: row; | |||
width: 100%; | |||
padding-left: 2rem; | |||
} | |||
// .menu-image-container { | |||
// position: relative;positionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionposition | |||
// overflow: hidden;overflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflowoverflow | |||
// text-align: center;text-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-aligntext-align | |||
// } | |||
// .menu-image { | |||
// height: 1.6rem;heightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheightheight // 保持图片纵横比 | |||
// margin-left: 0.5rem;margin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-leftmargin-left | |||
// background-size: cover;background-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-sizebackground-size | |||
// } | |||
// .menu-title { | |||
// position: absolute;positionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionpositionposition | |||
// top: 20%;toptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptoptop | |||
// left: 50%;leftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleftleft | |||
// transform: translate(-50%, -50%);transformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransformtransform | |||
// font-weight: 600;font-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weightfont-weight | |||
// } | |||
ul { | |||
display: inline-flex; | |||
width: max-content; | |||
margin-right: auto; | |||
margin-bottom: 0rem; | |||
li { | |||
display: inline-flex; | |||
width: max-content; | |||
margin-right: auto; | |||
li { | |||
display: inline-flex; | |||
a { | |||
clear: both; | |||
display: block; | |||
width: 100%; | |||
min-width: 4rem; | |||
margin-right: 1rem; | |||
padding: 0.5rem 1.5rem; | |||
font-weight: 600; | |||
color: #74FAFB; | |||
text-align: inherit; | |||
white-space: nowrap; | |||
background-color: #054254; | |||
border: 0 solid red; | |||
border-color: #74FAFB; | |||
&:hover, | |||
&:active, | |||
&.active { | |||
color: #000; | |||
text-decoration: none; | |||
background-color: #fff; | |||
} | |||
} | |||
.dropdown-menu { | |||
color: #fff; | |||
background-color: #337AB7; | |||
} | |||
} | |||
a { | |||
clear: both; | |||
display: block; | |||
width: 100%; | |||
margin-right: 1rem; | |||
padding: 0.5rem 2rem; | |||
font-weight: 600; | |||
color: #74FAFB; | |||
text-align: inherit; | |||
white-space: nowrap; | |||
background-color: #054254; | |||
border: 0 solid red; | |||
border-color: #74FAFB; | |||
>.dropdown-submenu { | |||
position: relative; | |||
&:hover, &:active, &.active{ | |||
color: #000; | |||
text-decoration: none; | |||
background-color: #fff; | |||
} | |||
} | |||
.dropdown-menu { | |||
position: absolute; | |||
top: 2rem; | |||
margin-top: 0; | |||
margin-left: 0; | |||
} | |||
.dropdown-menu { | |||
color: #fff; | |||
background-color: #337AB7; | |||
} | |||
&:hover>.dropdown-menu { | |||
display: block; | |||
} | |||
>.dropdown-submenu { | |||
.dropdown-submenu { | |||
position: relative; | |||
.dropdown-menu { | |||
position: absolute; | |||
top: 2rem; | |||
>a { | |||
display: block; | |||
&::after { | |||
content: "\f054"; | |||
position: absolute; | |||
right: .5rem; | |||
} | |||
} | |||
>.dropdown-menu { | |||
top: 0; | |||
bottom: unset; | |||
left: 100%; | |||
margin-top: 0; | |||
margin-left: 0; | |||
} | |||
@@ -77,38 +82,16 @@ ul { | |||
&:hover>.dropdown-menu { | |||
display: block; | |||
} | |||
.dropdown-submenu { | |||
position: relative; | |||
>a { | |||
display: block; | |||
&::after { | |||
content: "\f054"; | |||
position: absolute; | |||
right: .5rem; | |||
} | |||
} | |||
>.dropdown-menu { | |||
top: 0; | |||
bottom: unset; | |||
left: 100%; | |||
margin-top: 0; | |||
margin-left: 0; | |||
} | |||
&:hover>.dropdown-menu { | |||
display: block; | |||
} | |||
} | |||
} | |||
} | |||
&.dev-mode { | |||
a:hover, a:active, a.active{ | |||
color: #fff; | |||
background-color: #DC3545; | |||
} | |||
&.dev-mode { | |||
a:hover, | |||
a:active, | |||
a.active { | |||
color: #fff; | |||
background-color: #DC3545; | |||
} | |||
} | |||
} | |||
} |
@@ -1,6 +1,6 @@ | |||
import { CommonModule } from '@angular/common'; | |||
import { Component, OnInit, ViewChild, inject } from '@angular/core'; | |||
import { RouterOutlet } from '@angular/router'; | |||
import { Router, RouterOutlet } from '@angular/router'; | |||
import { STColumn, STComponent } from '@delon/abc/st'; | |||
import { SFSchema } from '@delon/form'; | |||
import { ModalHelper, _HttpClient } from '@delon/theme'; | |||
@@ -11,35 +11,10 @@ import { SHARED_IMPORTS } from '@shared'; | |||
standalone: true, | |||
imports: [RouterOutlet, CommonModule, ...SHARED_IMPORTS], | |||
template: ` <div class="navigation-container"> | |||
<!-- <div class="menu-image-container"> | |||
<img src="{{ imageUrl }}" class="menu-image" /> | |||
<div class="menu-title">{{ title }}</div> | |||
</div> | |||
<div class="menu-image-container"> | |||
<img src="{{ imageUrl }}" class="menu-image" /> | |||
<div class="menu-title">{{ title }}</div> | |||
</div> | |||
<div class="menu-image-container"> | |||
<img src="{{ imageUrl }}" class="menu-image" /> | |||
<div class="menu-title">{{ title }}</div> | |||
</div> --> | |||
<ul> | |||
<li class="dropdown-submenu" *ngFor="let menu of menuList" (mouseover)="menuOver(menu, $event)"> | |||
<a href="javascript:void(0);" class="menu-group" [class.active]="isActive(menu.MenuGrpCd)">{{ menu.text }}</a> | |||
<!-- <div class="dropdown-menu" *ngIf="menu && menu.SubList && menu.SubList.length > 0"> | |||
<a | |||
class="dropdown-item" | |||
href=".{{ getMenuPath(menu, subMenu) }}" | |||
*ngFor="let subMenu of menu.SubList" | |||
(click)="onMenuClick(menu, subMenu, $event)" | |||
> | |||
<span *ngIf="!changeMenuText(subMenu)" | |||
><app-text-loader *ngIf="showAppTextloader(subMenu)"></app-text-loader>{{ subMenu.MenuCd + '.title' | appLocaleText }}</span | |||
> | |||
<span *ngIf="changeMenuText(subMenu)">{{ getChangeMenuText(subMenu) }}</span> | |||
</a> | |||
</div> --> | |||
<a href="javascript:void(0);" class="menu-group" [class.active]="isActive(menu.MenuGrpCd)" | |||
(click)="navigate(menu)">{{ menu.text }}</a> | |||
</li> | |||
</ul> | |||
</div>`, | |||
@@ -48,16 +23,19 @@ import { SHARED_IMPORTS } from '@shared'; | |||
export class DataVNavigationComponent implements OnInit { | |||
private readonly http = inject(_HttpClient); | |||
private readonly modal = inject(ModalHelper); | |||
private readonly router = inject(Router); | |||
menuList: any = [ | |||
{ | |||
text: '工作站1' | |||
code: '01', | |||
text: '我的工作站' | |||
}, | |||
{ | |||
text: '工作站2' | |||
code: '02', | |||
text: '化验总览' | |||
}, | |||
{ | |||
text: '工作站3' | |||
text: '...' | |||
} | |||
]; | |||
@@ -66,11 +44,22 @@ export class DataVNavigationComponent implements OnInit { | |||
context: string = '2024-02-29 10:00'; | |||
ngOnInit(): void {} | |||
ngOnInit(): void { } | |||
add(): void { } | |||
add(): void {} | |||
menuOver(menu: any, $event: any) { } | |||
menuOver(menu: any, $event: any) {} | |||
isActive(menu: any) { } | |||
isActive(menu: any) {} | |||
// 新的 navigate 方法 | |||
navigate(menu: any) { | |||
if (menu.code == '01') { | |||
// 你可能想根据菜单项来确定导航的路径 | |||
this.router.navigateByUrl('/'); // 将'/data-v/s1'替换为正确的路径 | |||
} else if (menu.code == '02') { | |||
// 你可能想根据菜单项来确定导航的路径 | |||
this.router.navigateByUrl('/data-v/s1'); // 将'/data-v/s1'替换为正确的路径 | |||
} | |||
} | |||
} |
@@ -4,13 +4,13 @@ | |||
<div nz-row style="justify-content: center;align-items: center;"> | |||
<div nz-col nzSpan="12"> | |||
<div class="centered-element"> | |||
<div id="c1" style="width: 20rem; height: 16rem;"></div> | |||
<div id="c1" style="width: 20rem; height: 12rem;"></div> | |||
</div> | |||
<div class="sys-status-title">系统健康度</div> | |||
</div> | |||
<div nz-col nzSpan="12"> | |||
<div class="centered-element"> | |||
<div id="c2" style="width: 20rem; height: 16rem;"></div> | |||
<div id="c2" style="width: 20rem; height: 12rem;"></div> | |||
</div> | |||
<div class="sys-status-title">设备投运度</div> | |||
</div> | |||
@@ -150,17 +150,17 @@ | |||
<div nz-col nzSpan="12"> | |||
<data-v-card title="化验结果"> | |||
<div class="centered-element"> | |||
<div id="d1" style="width: 40rem; height: 14rem;"> | |||
<div id="d1" style="width: 40rem; height: 12rem;"> | |||
</div> | |||
</div> | |||
<div class="centered-element"> | |||
<div id="d2" style="width: 40rem; height: 14rem; margin-top: 1rem;"> | |||
<div id="d2" style="width: 40rem; height: 12rem; margin-top: 1rem;"> | |||
</div> | |||
</div> | |||
<div class="centered-element"> | |||
<div id="d3" style="width: 40rem; height: 14rem; margin-top: 1rem;"></div> | |||
<div id="d3" style="width: 40rem; height: 12rem; margin-top: 1rem;"></div> | |||
</div> | |||
<div class="statistic-item-container"> | |||
@@ -181,4 +181,4 @@ | |||
<div class="sys-status-title">煤样合格率:合格样量/总样量 15/16</div> | |||
</data-v-card> | |||
</div> | |||
</div> | |||
</div> |
@@ -1,4 +1,4 @@ | |||
.sys-status-title{ | |||
.sys-status-title { | |||
font-size: 18px; | |||
font-weight: 600; | |||
color: #94DDF3; | |||
@@ -23,52 +23,54 @@ | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
height: 100%; /* 如果需要垂直居中,可以设置高度为 100% */ | |||
} | |||
height: 100%; | |||
/* 如果需要垂直居中,可以设置高度为 100% */ | |||
} | |||
.status-container { | |||
.status-container { | |||
display: flex; | |||
align-items: center; | |||
padding: 0.5rem; | |||
} | |||
} | |||
.status-circle { | |||
width: 24px; | |||
height: 24px; | |||
.status-circle { | |||
width: 18px; | |||
height: 18px; | |||
border-radius: 50%; | |||
&.red{ | |||
&.red { | |||
background-color: red; | |||
} | |||
&.green{ | |||
background-color:green; | |||
&.green { | |||
background-color: green; | |||
} | |||
} | |||
} | |||
.status-text { | |||
margin-left: 10px; /* 调整文字与圆形之间的间距 */ | |||
font-size: 18px; | |||
.status-text { | |||
margin-left: 6px; | |||
/* 调整文字与圆形之间的间距 */ | |||
font-size: 16px; | |||
font-weight: 600; | |||
color: #74FAFB; | |||
} | |||
} | |||
.progress-container{ | |||
.progress-container { | |||
display: flex; | |||
color: white; | |||
} | |||
.progress-display{ | |||
.progress-display { | |||
color: white; | |||
text-align: right; | |||
} | |||
.statistic-item-container{ | |||
.statistic-item-container { | |||
display: flex; | |||
padding: 1rem 0; | |||
color: white; | |||
} | |||
.white-color-theme{ | |||
.white-color-theme { | |||
color: #74FAFB; | |||
} |
@@ -0,0 +1,46 @@ | |||
import { CommonModule } from '@angular/common'; | |||
import { Component, OnInit, ViewChild, inject } from '@angular/core'; | |||
import { STColumn, STComponent } from '@delon/abc/st'; | |||
import { SFSchema } from '@delon/form'; | |||
import { ModalHelper, _HttpClient } from '@delon/theme'; | |||
import { SHARED_IMPORTS } from '@shared'; | |||
import { DataVFullScreenComponent } from '../fullscreen/fullscreen.component'; | |||
@Component({ | |||
selector: 'data-v-setting', | |||
standalone: true, | |||
imports: [DataVFullScreenComponent, CommonModule, ...SHARED_IMPORTS], | |||
template: ` <div layout-default-header-item-trigger nz-dropdown [nzDropdownMenu]="settingsMenu" nzTrigger="click" nzPlacement="bottomRight"> | |||
<i nz-icon nzType="setting" [ngStyle]="{'color': 'white'}"></i> | |||
</div> | |||
<nz-dropdown-menu #settingsMenu="nzDropdownMenu"> | |||
<div nz-menu style="width: 8rem;"> | |||
<div nz-menu-item> | |||
<data-v-fullscreen /> | |||
</div> | |||
</div> | |||
</nz-dropdown-menu>` | |||
}) | |||
export class DataVSettingComponent implements OnInit { | |||
private readonly http = inject(_HttpClient); | |||
private readonly modal = inject(ModalHelper); | |||
currentTime: any; | |||
ngOnInit(): void { | |||
this.updateCurrentTime(); | |||
setInterval(() => { | |||
this.updateCurrentTime(); | |||
}, 1000); | |||
} | |||
add(): void { | |||
// this.modal | |||
// .createStatic(FormEditComponent, { i: { id: 0 } }) | |||
// .subscribe(() => this.st.reload()); | |||
} | |||
updateCurrentTime() { | |||
this.currentTime = new Date(); | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
<div class="alain-default__nav-item d-flex align-items-center px-sm mr-sm" nz-dropdown nzPlacement="bottomRight" | |||
<div class="alain-default__nav-item d-flex align-items-center px-sm" nz-dropdown nzPlacement="bottomRight" | |||
[nzDropdownMenu]="userMenu"> | |||
<nz-avatar [nzSrc]="user.avatar" nzSize="small" class="mr-sm" /> | |||
{{ user.name }} | |||
@@ -5,7 +5,7 @@ export const environment = { | |||
useHash: true, | |||
api: { | |||
baseUrl: './', | |||
refreshTokenEnabled: true, | |||
refreshTokenEnabled: false, | |||
refreshTokenType: 'auth-refresh' | |||
} | |||
} as Environment; |