ocean2 1 год назад
Родитель
Сommit
98f7fd06ab
27 измененных файлов: 2999 добавлений и 2371 удалений
  1. +1
    -1
      angular.json
  2. +8
    -20
      package-lock.json
  3. +1
    -0
      package.json
  4. +8
    -7
      src/app/routes/data-v/card/card.component.less
  5. +8
    -7
      src/app/routes/data-v/card/card.component.ts
  6. +15
    -6
      src/app/routes/data-v/date/date.component.ts
  7. +6
    -0
      src/app/routes/data-v/header/header.component.html
  8. +23
    -0
      src/app/routes/data-v/header/header.component.less
  9. +30
    -0
      src/app/routes/data-v/header/header.component.ts
  10. +9
    -9
      src/app/routes/data-v/home/home.component.html
  11. +11
    -5
      src/app/routes/data-v/home/home.component.less
  12. +11
    -3
      src/app/routes/data-v/home/home.component.ts
  13. +107
    -26
      src/app/routes/data-v/navigation/navigation.component.less
  14. +48
    -14
      src/app/routes/data-v/navigation/navigation.component.ts
  15. +4
    -8
      src/app/routes/data-v/routes.ts
  16. +184
    -0
      src/app/routes/data-v/s1/s1.component.html
  17. +84
    -0
      src/app/routes/data-v/s1/s1.component.less
  18. +384
    -3
      src/app/routes/data-v/s1/s1.component.ts
  19. +8
    -6
      src/app/routes/data-v/title/title.component.less
  20. +0
    -14
      src/app/routes/data-v/workstation/workstation.component.html
  21. +25
    -18
      src/app/routes/data-v/workstation/workstation.component.less
  22. +2
    -4
      src/app/routes/passport/login/login.component.ts
  23. +11
    -5
      src/app/routes/routes.ts
  24. +1
    -1
      src/app/shared/shared.module.ts
  25. Двоичные данные
      src/assets/dashboard/dashboard_menu.jpg
  26. Двоичные данные
      src/assets/dashboard/screen_header.png
  27. +2010
    -2214
      yarn.lock

+ 1
- 1
angular.json Просмотреть файл

@@ -62,7 +62,7 @@
"styles": [
"src/styles.less"
],
"scripts": [],
"scripts": [ "node_modules/echarts/dist/echarts.js"],
"allowedCommonJsDependencies": [
"ajv",
"ajv-formats",


+ 8
- 20
package-lock.json Просмотреть файл

@@ -26,6 +26,7 @@
"@delon/theme": "^17.1.0",
"@delon/util": "^17.1.0",
"ag-grid-angular": "^31.0.2",
"echarts": "^5.5.0",
"moment": "^2.30.1",
"ng-alain": "^17.1.0",
"ng-zorro-antd": "^17.1.0",
@@ -56,7 +57,6 @@
"eslint-plugin-jsdoc": "~48.0.2",
"eslint-plugin-prefer-arrow": "~1.2.3",
"eslint-plugin-prettier": "~5.1.3",
"husky": "^8.0.3",
"jasmine-core": "~5.1.0",
"karma": "~6.4.0",
"karma-chrome-launcher": "~3.2.0",
@@ -7387,12 +7387,12 @@
"dev": true
},
"node_modules/echarts": {
"version": "5.4.3",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.4.3.tgz",
"integrity": "sha512-mYKxLxhzy6zyTi/FaEbJMOZU1ULGEQHaeIeuMR5L+JnJTpz+YR03mnnpBhbR4+UYJAgiXgpyTVLffPAjOTLkZA==",
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.5.0.tgz",
"integrity": "sha512-rNYnNCzqDAPCr4m/fqyUFv7fD9qIsd50S6GDFgO1DxZhncCsNsG7IfUlAlvZe5oSEQxtsjnHiUuppzccry93Xw==",
"dependencies": {
"tslib": "2.3.0",
"zrender": "5.4.4"
"zrender": "5.5.0"
}
},
"node_modules/echarts/node_modules/tslib": {
@@ -9581,18 +9581,6 @@
"node": ">=10.17.0"
}
},
"node_modules/husky": {
"version": "8.0.3",
"resolved": "https://registry.npmmirror.com/husky/-/husky-8.0.3.tgz",
"integrity": "sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==",
"dev": true,
"bin": {
"husky": "lib/bin.js"
},
"engines": {
"node": ">=14"
}
},
"node_modules/iconv-lite": {
"version": "0.4.24",
"resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -18125,9 +18113,9 @@
}
},
"node_modules/zrender": {
"version": "5.4.4",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.4.4.tgz",
"integrity": "sha512-0VxCNJ7AGOMCWeHVyTrGzUgrK4asT4ml9PEkeGirAkKNYXYzoPJCLvmyfdoOXcjTHPs10OZVMfD1Rwg16AZyYw==",
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.5.0.tgz",
"integrity": "sha512-O3MilSi/9mwoovx77m6ROZM7sXShR/O/JIanvzTwjN3FORfLSr81PsUGd7jlaYOeds9d8tw82oP44+3YucVo+w==",
"dependencies": {
"tslib": "2.3.0"
}


+ 1
- 0
package.json Просмотреть файл

@@ -39,6 +39,7 @@
"@delon/theme": "^17.1.0",
"@delon/util": "^17.1.0",
"ag-grid-angular": "^31.0.2",
"echarts": "^5.5.0",
"moment": "^2.30.1",
"ng-alain": "^17.1.0",
"ng-zorro-antd": "^17.1.0",


+ 8
- 7
src/app/routes/data-v/card/card.component.less Просмотреть файл

@@ -1,15 +1,16 @@
.card-content {
height: 18rem;
overflow: hidden;
//height: 18rem;
padding: 1rem 1.5rem;
//position: relative;
background-image: url('../../../../assets/dashboard/dashboard_card_bg.jpg');
background-size: cover;
/* 背景图片尺寸适应 */
background-position: top;
}
background-size: cover;
.card-content-title {
margin-bottom: 0.5rem;
font-size: 18px;
color: #94DDF3;
font-weight: 600;
margin-bottom: 0.5rem;
color: #74FAFB;
}
}

+ 8
- 7
src/app/routes/data-v/card/card.component.ts Просмотреть файл

@@ -2,16 +2,17 @@
import { Component, Input } from '@angular/core';

@Component({
selector: 'data-v-card',
standalone: true,
template: `
selector: 'data-v-card',
standalone: true,
template: `
<div class="card-content">
<div class="card-content-title">{{title}}</div>
<!-- <img src="assets/dashboard/dashboard_card_bg.jpg" style="width: 100%;" /> -->
<div class="card-content-title">{{ title }}</div>
<ng-content></ng-content>
</div>
`,
styleUrls: ['./card.component.less']
styleUrls: ['./card.component.less']
})
export class DataVCardComponent {
@Input() title: string = "";
}
@Input() title: string = '';
}

+ 15
- 6
src/app/routes/data-v/date/date.component.ts Просмотреть файл

@@ -1,3 +1,4 @@
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';
@@ -7,10 +8,9 @@ import { SHARED_IMPORTS } from '@shared';
@Component({
selector: 'data-v-date',
standalone: true,
imports: [...SHARED_IMPORTS],
template: `
<div class="containers">
{{context}}
imports: [CommonModule, ...SHARED_IMPORTS],
template: ` <div class="containers">
{{ currentTime | date: 'yyyy-MM-dd HH:mm:ss' }}
</div>`,
styleUrls: ['./date.component.less']
})
@@ -18,13 +18,22 @@ export class DataVDateComponent implements OnInit {
private readonly http = inject(_HttpClient);
private readonly modal = inject(ModalHelper);

context: string = '2024-02-29 10:00';
currentTime: any;

ngOnInit(): void { }
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();
}
}

+ 6
- 0
src/app/routes/data-v/header/header.component.html Просмотреть файл

@@ -0,0 +1,6 @@
<div class="header-container">
<div class="data-v-sysinfo mr-sm">
<data-v-user></data-v-user>
<data-v-date></data-v-date>
</div>
</div>

+ 23
- 0
src/app/routes/data-v/header/header.component.less Просмотреть файл

@@ -0,0 +1,23 @@
.header-container {
width: 100vw;
min-width: 1360px;

/* 水平宽度占据整个视口宽度 */
height: 10%;

/* 垂直高度占据整个视口高度 */
background-image: url('../../../../assets/dashboard/dashboard_bg_1.jpg');

/* 背景图片尺寸适应 */
background-position: top;
background-size: cover;

/* 图片居中显示 */
}

.data-v-sysinfo {
display: flex;
align-items: center;
justify-content: right;
text-align: right;
}

+ 30
- 0
src/app/routes/data-v/header/header.component.ts Просмотреть файл

@@ -0,0 +1,30 @@
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 { DataVUserComponent } from '../user/user.component';
import { LayoutDefaultModule } from '@delon/theme/layout-default';
import { DataVDateComponent } from '../date/date.component';
import { DataVNavigationComponent } from '../navigation/navigation.component';
import { RouterOutlet } from '@angular/router';

@Component({
selector: 'app-data-v-header',
standalone: true,
imports: [DataVUserComponent, DataVDateComponent, DataVNavigationComponent, LayoutDefaultModule, RouterOutlet, ...SHARED_IMPORTS],
templateUrl: './header.component.html',
styleUrls: ['./header.component.less']
})
export class DataVHeaderComponent implements OnInit {
private readonly http = inject(_HttpClient);
private readonly modal = inject(ModalHelper);

ngOnInit(): void {}

add(): void {
// this.modal
// .createStatic(FormEditComponent, { i: { id: 0 } })
// .subscribe(() => this.st.reload());
}
}

+ 9
- 9
src/app/routes/data-v/home/home.component.html Просмотреть файл

@@ -1,15 +1,15 @@
<div class="home-container">
<div class="data-v-sysinfo mr-sm">
<!-- <div class="data-v-sysinfo mr-sm">
<data-v-user></data-v-user>
<data-v-date></data-v-date>
</div>
</div> -->
<app-data-v-header></app-data-v-header>
<data-v-navigation></data-v-navigation>

<div>
<data-v-navigation></data-v-navigation>
</div>
<img src="assets/dashboard/dashboard_menu.jpg" style="width: 100%;" />

<div style="margin: 1rem;">
<router-outlet />
</div>
<div style="margin: 1rem;">
<router-outlet />
</div>

</div>
</div>

+ 11
- 5
src/app/routes/data-v/home/home.component.less Просмотреть файл

@@ -1,18 +1,24 @@
.home-container {
width: 100vw;
min-width: 1360px;

/* 水平宽度占据整个视口宽度 */
height: 100vh;
background-color: #040516;

/* 垂直高度占据整个视口高度 */
background-image: url('../../../../assets/dashboard/dashboard_bg_1.jpg');
background-size: cover;
//background-image: url('../../../../assets/dashboard/dashboard_bg_1.jpg');
/* 背景图片尺寸适应 */
background-position: top;
//background-position: top;
//background-size: cover;

/* 图片居中显示 */
}

.data-v-sysinfo {
align-items: center;
display: flex;
text-align: right;
align-items: center;
justify-content: right;
text-align: right;
}

+ 11
- 3
src/app/routes/data-v/home/home.component.ts Просмотреть файл

@@ -8,11 +8,20 @@ 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 { DataVHeaderComponent } from '../header/header.component';

@Component({
selector: 'app-data-v-home',
standalone: true,
imports: [DataVUserComponent, DataVDateComponent, DataVNavigationComponent, LayoutDefaultModule, RouterOutlet, ...SHARED_IMPORTS],
imports: [
DataVHeaderComponent,
DataVUserComponent,
DataVDateComponent,
DataVNavigationComponent,
LayoutDefaultModule,
RouterOutlet,
...SHARED_IMPORTS
],
templateUrl: './home.component.html',
styleUrls: ['./home.component.less']
})
@@ -20,12 +29,11 @@ export class DataVHomeComponent implements OnInit {
private readonly http = inject(_HttpClient);
private readonly modal = inject(ModalHelper);

ngOnInit(): void { }
ngOnInit(): void {}

add(): void {
// this.modal
// .createStatic(FormEditComponent, { i: { id: 0 } })
// .subscribe(() => this.st.reload());
}

}

+ 107
- 26
src/app/routes/data-v/navigation/navigation.component.less Просмотреть файл

@@ -1,33 +1,114 @@


.navigation-container {
width: 100%;
margin-top: 2.5rem;
height: 4rem;
/* 水平宽度占据整个视口宽度 */
background-image: url('../../../../assets/dashboard/dashboard_menu.jpg');
background-size: cover;
/* 背景图片尺寸适应 */
background-position: top;
display: flex;
flex-direction: row;
padding-left: 5rem;
width: 100%;
//height: 4rem;
//margin-top: 2.5rem;
padding-left: 2rem;
}

.menu-image-container {
overflow: hidden;
position: relative;
text-align: center;
}
// .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; // 保持图片纵横比
background-size: cover;
margin-left: 0.5rem;
}
// .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;

li {
display: inline-flex;

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;

&:hover, &:active, &.active{
color: #000;
text-decoration: none;
background-color: #fff;
}
}

.dropdown-menu {
color: #fff;
background-color: #337AB7;
}
}

>.dropdown-submenu {
position: relative;

.dropdown-menu {
position: absolute;
top: 2rem;
margin-top: 0;
margin-left: 0;
}

&: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;
}
}
}

.menu-title {
position: absolute;
top: 20%;
left: 50%;
transform: translate(-50%, -50%);
font-weight: 600;
}
&.dev-mode {
a:hover, a:active, a.active{
color: #fff;
background-color: #DC3545;
}
}
}

+ 48
- 14
src/app/routes/data-v/navigation/navigation.component.ts Просмотреть файл

@@ -1,3 +1,4 @@
import { CommonModule } from '@angular/common';
import { Component, OnInit, ViewChild, inject } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { STColumn, STComponent } from '@delon/abc/st';
@@ -8,21 +9,39 @@ import { SHARED_IMPORTS } from '@shared';
@Component({
selector: 'data-v-navigation',
standalone: true,
imports: [RouterOutlet, ...SHARED_IMPORTS],
template: `
<div class="navigation-container">
<div class="menu-image-container">
<img src="{{imageUrl}}" class="menu-image"/>
<div class="menu-title">{{title}}</div>
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>
<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>
<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> -->
</li>
</ul>
</div>`,
styleUrls: ['./navigation.component.less']
})
@@ -30,13 +49,28 @@ export class DataVNavigationComponent implements OnInit {
private readonly http = inject(_HttpClient);
private readonly modal = inject(ModalHelper);

menuList: any = [
{
text: '工作站1'
},
{
text: '工作站2'
},
{
text: '工作站3'
}
];

imageUrl: string = 'assets/dashboard/menu_btn_l.png';
title: string = 'Label';

context: string = '2024-02-29 10:00';

ngOnInit(): void { }
ngOnInit(): void {}

add(): void {}

menuOver(menu: any, $event: any) {}

add(): void {
}
isActive(menu: any) {}
}

+ 4
- 8
src/app/routes/data-v/routes.ts Просмотреть файл

@@ -7,11 +7,7 @@ import { DataVS1Component } from './s1/s1.component';

export const routes: Routes = [
{
path: 'home',
component: DataVHomeComponent,
children: [
{ path: '', component: DataVWorkstationComponent },
{ path: 's1', component: DataVS1Component }
]
}];

path: 's1',
component: DataVS1Component
}
];

+ 184
- 0
src/app/routes/data-v/s1/s1.component.html Просмотреть файл

@@ -0,0 +1,184 @@
<div nz-row [nzGutter]="16">
<div nz-col nzSpan="12">
<data-v-card title="系统状态">
<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>
<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>
<div class="sys-status-title">设备投运度</div>
</div>
</div>
</data-v-card>

<data-v-card title="系统运行状态">
<div nz-row [nzGutter]="16">
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#1机器人</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">#1量热仪</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">#1水灰炉</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">全水分析系统</span>
</div>
</div>
</div>

<div nz-row [nzGutter]="16">
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">#1机器人</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#1量热仪</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#1水灰炉</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">全水分析系统</span>
</div>
</div>
</div>

<div nz-row [nzGutter]="16">
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#2机器人</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#2量热仪</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#2水灰炉</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#2全硫仪</span>
</div>
</div>
</div>

<div nz-row [nzGutter]="16">
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">称重机器人</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle red"></div>
<span class="status-text">#1全硫仪</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">#1</span>
</div>
</div>
<div nz-col nzSpan="6">
<div class="status-container">
<div class="status-circle green"></div>
<span class="status-text">#2</span>
</div>
</div>
</div>
</data-v-card>

<data-v-card title="系统报警信息">
<ag-grid-angular [rowData]="rowData" [columnDefs]="colDefs2" class="ag-theme-datav">
</ag-grid-angular>
</data-v-card>

<data-v-card title="">
<div class="progress-display">完成样品数量/时长 16/8</div>
<div class="progress-container">
<span class="status-text" style="width: 8rem;">化验效率:</span>
<nz-progress [nzPercent]="64" style="width: 100%;"></nz-progress>
</div>

<div class="progress-display">完成样品数量/时长 16/8</div>
<div class="progress-container">
<span class="status-text" style="width: 8rem;">完 成 率 :</span>
<nz-progress [nzPercent]="60" style="width: 100%;"></nz-progress>
</div>
</data-v-card>
</div>

<div nz-col nzSpan="12">
<data-v-card title="化验结果">
<div class="centered-element">
<div id="d1" style="width: 40rem; height: 14rem;">

</div>
</div>
<div class="centered-element">
<div id="d2" style="width: 40rem; height: 14rem; margin-top: 1rem;">

</div>
</div>
<div class="centered-element">
<div id="d3" style="width: 40rem; height: 14rem; margin-top: 1rem;"></div>
</div>

<div class="statistic-item-container">
<label nz-checkbox [ngModel]="'true'">全水</label>
<label nz-checkbox [ngModel]="'true'">热值</label>
<label nz-checkbox [ngModel]="'true'">全硫</label>
<label nz-checkbox [ngModel]="'false'">内水</label>
<label nz-checkbox [ngModel]="'false'">灰分</label>
<label nz-checkbox [ngModel]="'false'">挥发分</label>
<label nz-checkbox [ngModel]="'false'">碳</label>
<label nz-checkbox [ngModel]="'false'">氢</label>
<label nz-checkbox [ngModel]="'false'">氮</label>
</div>
</data-v-card>

<data-v-card title="">
<div class="sys-status-title">煤样超差率:超差样量/总样量 03/16</div>
<div class="sys-status-title">煤样合格率:合格样量/总样量 15/16</div>
</data-v-card>
</div>
</div>

+ 84
- 0
src/app/routes/data-v/s1/s1.component.less Просмотреть файл

@@ -0,0 +1,84 @@
.sys-status-title{
font-size: 18px;
font-weight: 600;
color: #94DDF3;
text-align: center;
}

.ag-theme-datav {
--ag-border-color: #74FAFB;
--ag-foreground-color: #74FAFB;
--ag-background-color: #0A1632;
--ag-header-foreground-color: #74FAFB;
--ag-header-background-color: #0A1632;
--ag-odd-row-background-color: #0A1632;
--ag-header-column-resize-handle-color: rgb(126 46 132);
--ag-font-size: 17px;
--ag-font-family: monospace;

height: 6rem;
}

.centered-element {
display: flex;
align-items: center;
justify-content: center;
height: 100%; /* 如果需要垂直居中,可以设置高度为 100% */
}

.status-container {
display: flex;
align-items: center;
padding: 0.5rem;
}

.status-circle {
width: 24px;
height: 24px;
border-radius: 50%;

&.red{
background-color: red;
}

&.green{
background-color:green;
}
}

.status-text {
margin-left: 10px; /* 调整文字与圆形之间的间距 */
font-size: 18px;
font-weight: 600;
color: #74FAFB;
}

.progress-container{
display: flex;
color: white;
}

.progress-display{
color: white;
text-align: right;
}

.statistic-item-container{
display: flex;
padding: 1rem 0;
color: white;
}


/* 设置 Checkbox 组件中文字的颜色 */
::ng-deep .ant-checkbox-wrapper input {
color: red; /* 这里设置文字颜色为红色,你可以根据需要修改颜色值 */
}

// ::ng-deep .ant-checkbox-inner::after {
// color: white;colorcolorcolorcolorcolor
// }

// ::ng-deep .ant-checkbox-input:focus + .ant-checkbox-inner::after {
// border-color: #1890ff;border-colorborder-colorborder-colorborder-colorborder-color
// }

+ 384
- 3
src/app/routes/data-v/s1/s1.component.ts Просмотреть файл

@@ -3,20 +3,401 @@ import { STColumn, STComponent } from '@delon/abc/st';
import { SFSchema } from '@delon/form';
import { ModalHelper, _HttpClient } from '@delon/theme';
import { SHARED_IMPORTS } from '@shared';
import { DataVCardComponent } from '../card/card.component';
import * as echarts from 'echarts';
import { AgGridAngular } from 'ag-grid-angular';
import { DataVTitleComponent } from '../title/title.component';
import { ColDef } from 'ag-grid-community'; // Column Definition Type Interface
import { NzProgressModule } from 'ng-zorro-antd/progress';
import { NzBadgeModule } from 'ng-zorro-antd/badge';

// 基于准备好的dom,初始化echarts实例
//var myChart = echarts.init(document.getElementById('c1'));
type EChartsOption = echarts.EChartsOption;

@Component({
selector: 'app-data-v-s1',
standalone: true,
imports: [...SHARED_IMPORTS],
imports: [NzBadgeModule, NzProgressModule, AgGridAngular, DataVCardComponent, DataVTitleComponent, ...SHARED_IMPORTS],
templateUrl: './s1.component.html',
styleUrls: ['./s1.component.less']
})
export class DataVS1Component implements OnInit {
private readonly http = inject(_HttpClient);
private readonly modal = inject(ModalHelper);

ngOnInit(): void { }
rowData = [
{
rwmc: '任务1',
rwms: '任务描述1',
kssj: '2024-1-1',
jhwcsj: '2024-1-2',
sfcq: '否',
dqzt: '正常',
dqjd: '节点1',
sjwcsj: '2024-1-2',
bjmc: '报警1',
bjms: '报警描述1',
bjsj: '2024-1-1',
gzyy: '-',
clff: '-',
tzsj: '2024-1-2',
zycd: '一般',
tzmc: '系统提示',
tznr: '账户登录',
fj: '-'
},
{
rwmc: '任务2',
rwms: '任务描述2',
kssj: '2024-1-2',
jhwcsj: '2024-1-3',
sfcq: '否',
dqzt: '正常',
dqjd: '节点2',
sjwcsj: '2024-1-2',
bjmc: '报警2',
bjms: '报警描述2',
bjsj: '2024-1-2',
gzyy: '-',
clff: '-',
tzsj: '2024-1-2',
zycd: '一般',
tzmc: '系统提示',
tznr: '账户登录',
fj: '-'
},
{
rwmc: '任务3',
rwms: '任务描述3',
kssj: '2024-1-3',
jhwcsj: '2024-1-4',
sfcq: '否',
dqzt: '正常',
dqjd: '节点3',
sjwcsj: '2024-1-2',
bjmc: '报警3',
bjms: '报警描述3',
bjsj: '2024-1-3',
gzyy: '-',
clff: '-',
tzsj: '2024-1-2',
zycd: '一般',
tzmc: '系统提示',
tznr: '账户登录',
fj: '-'
},
{
rwmc: '任务4',
rwms: '任务描述4',
kssj: '2024-1-4',
jhwcsj: '2024-1-5',
sfcq: '否',
dqzt: '正常',
dqjd: '节点4',
sjwcsj: '2024-1-2',
bjmc: '报警4',
bjms: '报警描述4',
bjsj: '2024-1-4',
gzyy: '-',
clff: '-',
tzsj: '2024-1-2',
zycd: '一般',
tzmc: '系统提示',
tznr: '账户登录',
fj: '-'
},
{
rwmc: '任务5',
rwms: '任务描述5',
kssj: '2024-1-5',
jhwcsj: '2024-1-6',
sfcq: '否',
dqzt: '正常',
dqjd: '节点5',
sjwcsj: '2024-1-2',
bjmc: '报警5',
bjms: '报警描述5',
bjsj: '2024-1-5',
gzyy: '-',
clff: '-',
tzsj: '2024-1-2',
zycd: '一般',
tzmc: '系统提示',
tznr: '账户登录',
fj: '-'
}
];

colDefs1: ColDef[] = [
{ headerName: '时间', field: 'rwmc', flex: 1 },
{ headerName: '系统/设备', field: 'rwms', flex: 1 },
{ headerName: '操作描述', field: 'kssj', flex: 1 },
{ headerName: '操作人员', field: 'jhwcsj', flex: 1 }
];

colDefs2: ColDef[] = [
{ headerName: '序号', field: 'rwmc', flex: 1 },
{ headerName: '时间', field: 'kssj', flex: 2 },
{ headerName: '任务描述', field: 'rwms', flex: 1 },
{ headerName: '等级', field: 'dqzt', flex: 1.5 }
];

ngOnInit(): void {
var c1 = document.getElementById('c1')!;
//c1.style.left = '10%';
//c1.style.top = '50%';
//c1.style.transform = 'translate(-50%, -50%)';

var c1Chart = echarts.init(c1);
var c2 = document.getElementById('c2')!;
var c2Chart = echarts.init(c2);
let optionC = {
tooltip: {
formatter: '{a} <br/>{b} : {c}%'
},
series: [
{
name: 'Pressure',
type: 'gauge',
progress: {
show: true
},
detail: {
valueAnimation: true,
formatter: '{value}'
},
data: [
{
value: 97,
name: '百分比'
}
]
}
]
};

var d1 = document.getElementById('d1');
var d1Chart = echarts.init(d1, 'dark');
var d2 = document.getElementById('d2');
var d2Chart = echarts.init(d2, 'dark');
var d3 = document.getElementById('d3');
var d3Chart = echarts.init(d3, 'dark');

add(): void {
var optionD1;
optionD1 = {
title: {
text: '全水',
subtext: '(kg/kg)'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['超差样数量', '不合格样数量']
},
toolbox: {
show: false,
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: 'category',
// prettier-ignore
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '超差样数量',
type: 'line',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' }
]
}
},
{
name: '不合格样数量',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
markPoint: {
data: [
{ name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
{ name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
]
},
markLine: {
data: [{ type: 'average', name: 'Avg' }]
}
}
]
};

var optionD2;
optionD2 = {
title: {
text: '热值',
subtext: '(kg/kg)'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['超差样数量', '不合格样数量']
},
toolbox: {
show: false,
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: 'category',
// prettier-ignore
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '超差样数量',
type: 'line',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' }
]
}
},
{
name: '不合格样数量',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
markPoint: {
data: [
{ name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
{ name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
]
},
markLine: {
data: [{ type: 'average', name: 'Avg' }]
}
}
]
};

var optionD3;
optionD3 = {
title: {
text: '全硫',
subtext: '(kg/kg)'
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['超差样数量', '不合格样数量']
},
toolbox: {
show: false,
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true }
}
},
calculable: true,
xAxis: [
{
type: 'category',
// prettier-ignore
data: ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: '超差样数量',
type: 'line',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' }
]
}
},
{
name: '不合格样数量',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
markPoint: {
data: [
{ name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
{ name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 }
]
},
markLine: {
data: [{ type: 'average', name: 'Avg' }]
}
}
]
};

optionD1 && d1Chart.setOption(optionD1);
optionD2 && d2Chart.setOption(optionD2);
optionD3 && d3Chart.setOption(optionD3);

c1Chart.setOption(optionC);
c2Chart.setOption(optionC);

// myChart.setOption({
// title: {
// text: 'ECharts 入门示例'
// },
// tooltip: {},
// xAxis: {
// data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
// },
// yAxis: {},
// series: [
// {
// name: '销量',
// type: 'bar',
// data: [5, 20, 36, 10, 10, 20]
// }
// ]
// });
}

add(): void {}
}

+ 8
- 6
src/app/routes/data-v/title/title.component.less Просмотреть файл

@@ -1,18 +1,20 @@
.title-container {
width: 100%;
height: 2rem;
height: 10%;
// /* 水平宽度占据整个视口宽度 */
// background-image: url('../../../../assets/dashboard/dashboard_workstation.jpg');
// background-size: cover;
// background-image: url('../../../../assets/dashboard/dashboard_workstation.jpg');background-imagebackground-image
// background-size: cover;background-sizebackground-size
// /* 背景图片尺寸适应 */
// background-position: top;
// background-position: top;background-positionbackground-position
}

img {
/* 高度自适应,保持宽高比 */
display: block;
width: 100%;

/* 图片宽度占满父容器 */
height: auto;
/* 高度自适应,保持宽高比 */
display: block;

/* 将图片显示为块级元素 */
}

+ 0
- 14
src/app/routes/data-v/workstation/workstation.component.html Просмотреть файл

@@ -1,4 +1,3 @@
<data-v-title></data-v-title>
<div nz-row [nzGutter]="[8, 8]">
<data-v-card nz-col nzSpan="12" title="待办任务">
<ag-grid-angular [rowData]="rowData" [columnDefs]="colDefs1" class="ag-theme-datav">
@@ -17,16 +16,3 @@
</ag-grid-angular>
</data-v-card>
</div>
<div nz-row [nzGutter]="16">

</div>
<!-- <div class="workstation-content" nz-col nzSpan="12">
<div class="workstation-content-title">报警信息</div>
<ag-grid-angular [rowData]="rowData" [columnDefs]="colDefs3" class="ag-theme-datav">
</ag-grid-angular>
</div>
<div class="workstation-content" nz-col nzSpan="12">
<div class="workstation-content-title">通知</div>
<ag-grid-angular [rowData]="rowData" [columnDefs]="colDefs4" class="ag-theme-datav">
</ag-grid-angular>
</div> -->

+ 25
- 18
src/app/routes/data-v/workstation/workstation.component.less Просмотреть файл

@@ -1,38 +1,39 @@
// .workstation-header {
// width: 100%;
// height: 3rem;
// width: 100%;widthwidth
// height: 3rem;heightheight
// /* 水平宽度占据整个视口宽度 */
// background-image: url('../../../../assets/dashboard/dashboard_workstation.jpg');
// background-size: cover;
// background-image: url('../../../../assets/dashboard/dashboard_workstation.jpg');background-imagebackground-image
// background-size: cover;background-sizebackground-size
// /* 背景图片尺寸适应 */
// background-position: top;
// background-position: top;background-positionbackground-position
// }
// .workstation-content {
// height: 18rem;
// padding: 1rem 1.5rem;
// background-image: url('../../../../assets/dashboard/dashboard_card_bg.jpg');
// background-size: cover;
// height: 18rem;heightheight
// padding: 1rem 1.5rem;paddingpadding
// background-image: url('../../../../assets/dashboard/dashboard_card_bg.jpg');background-imagebackground-image
// background-size: cover;background-sizebackground-size
// /* 背景图片尺寸适应 */
// background-position: top;
// background-position: top;background-positionbackground-position
// }

.workstation-content-title {
margin-bottom: 0.5rem;
font-size: 18px;
color: #94DDF3;
font-weight: 600;
margin-bottom: 0.5rem;
color: #94DDF3;
}

.ag-theme-datav {
--ag-border-color: #74FAFB;
--ag-foreground-color: #74FAFB;
--ag-background-color: #273069;
--ag-background-color: #0A1632;
--ag-header-foreground-color: #74FAFB;
--ag-header-background-color: #273069;
--ag-odd-row-background-color: #273069;
--ag-header-column-resize-handle-color: rgb(126, 46, 132);
--ag-header-background-color: #0A1632;
--ag-odd-row-background-color: #0A1632;
--ag-header-column-resize-handle-color: rgb(126 46 132);
--ag-font-size: 17px;
--ag-font-family: monospace;

height: 14rem;
}

@@ -44,27 +45,33 @@
/* 设置滚动条滑块的样式 */
.ag-theme-datav ::ng-deep .ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb {
background-color: red;
/* 滚动条滑块的背景颜色 */
border-radius: 6px;

/* 圆角 */
border: 2px solid orange;

/* 滚动条滑块的背景颜色 */
border-radius: 6px;

/* 滚动条滑块的边框 */
}

/* 设置滚动条轨道的样式 */
.ag-theme-datav ::ng-deep .ag-body-vertical-scroll-viewport::-webkit-scrollbar-track {
background-color: yellow;

/* 滚动条轨道的背景颜色 */
}

/* 设置滚动条滑块悬浮时的样式 */
.ag-theme-datav ::ng-deep .ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb:hover {
background-color: darkred;

/* 滚动条滑块悬浮时的背景颜色 */
}

/* 设置滚动条滑块激活(即正在拖动滑块)时的样式 */
.ag-theme-datav ::ng-deep .ag-body-vertical-scroll-viewport::-webkit-scrollbar-thumb:active {
background-color: #a00;

/* 滚动条滑块激活时的背景颜色 */
}

+ 2
- 4
src/app/routes/passport/login/login.component.ts Просмотреть файл

@@ -150,13 +150,11 @@ export class UserLoginComponent implements OnDestroy {
this.tokenService.set(res.user);
// 重新获取 StartupService 内容,我们始终认为应用信息一般都会受当前用户授权范围而影响
this.startupSrv.load().subscribe(() => {
let url = this.tokenService.referrer!.url || '/data-v/home';
let url = this.tokenService.referrer!.url || '/';
if (url.includes('/passport')) {
url = '/data-v/home';
url = '/';
}

url = '/data-v/home';

this.router.navigateByUrl(url);
//window.location.href = 'http://112.33.111.160:8084';
});


+ 11
- 5
src/app/routes/routes.ts Просмотреть файл

@@ -4,22 +4,28 @@ import { authSimpleCanActivate, authSimpleCanActivateChild } from '@delon/auth';

import { DashboardComponent } from './dashboard/dashboard.component';
import { LayoutBasicComponent, LayoutBlankComponent } from '../layout';
import { DataVHomeComponent } from './data-v/home/home.component';
import { DataVWorkstationComponent } from './data-v/workstation/workstation.component';

export const routes: Routes = [
{
path: '',
path: 'home',
component: LayoutBasicComponent,
canActivate: [startPageGuard, authSimpleCanActivate],
canActivateChild: [authSimpleCanActivateChild],
data: {},
children: [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'sys', loadChildren: () => import('./sys/routes').then((m) => m.routes) }]
{ path: 'sys', loadChildren: () => import('./sys/routes').then(m => m.routes) }
]
},
{
path: 'data-v',
component: LayoutBlankComponent,
children: [{ path: '', loadChildren: () => import('./data-v/routes').then(m => m.routes) }]
path: '',
component: DataVHomeComponent,
children: [
{ path: '', component: DataVWorkstationComponent },
{ path: 'data-v', loadChildren: () => import('./data-v/routes').then(m => m.routes) }
]
},
{ path: '', loadChildren: () => import('./passport/routes').then(m => m.routes) },
{ path: 'exception', loadChildren: () => import('./exception/routes').then(m => m.routes) },


+ 1
- 1
src/app/shared/shared.module.ts Просмотреть файл

@@ -63,4 +63,4 @@ const DIRECTIVES: Array<Type<void>> = [];
...DIRECTIVES
]
})
export class SharedModule { }
export class SharedModule {}

Двоичные данные
src/assets/dashboard/dashboard_menu.jpg Просмотреть файл

До После
Ширина: 5739  |  Высота: 257  |  Размер: 72KB Ширина: 1917  |  Высота: 52  |  Размер: 13KB

Двоичные данные
src/assets/dashboard/screen_header.png Просмотреть файл

До После
Ширина: 1342  |  Высота: 129  |  Размер: 3.8KB

+ 2010
- 2214
yarn.lock
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


Загрузка…
Отмена
Сохранить