diff --git a/package.json b/package.json index 8f5640c..05a8727 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "scripts": { "ng": "ng", - "start": "ng serve --proxy-config proxy.config.json --open --port 25647", + "start": "ng serve --proxy-config proxy.config.json --open --port 25647 --host 192.168.1.86", "build": "node --max_old_space_size=5048 ./node_modules/@angular/cli/bin/ng build --prod", "test": "ng test", "lint": "ng lint", diff --git a/proxy.config.json b/proxy.config.json index 06b352a..2c66c9f 100644 --- a/proxy.config.json +++ b/proxy.config.json @@ -1,13 +1,13 @@ { "/api": { - "target": "http://10.156.134.53:8200/", + "target": "http://121.36.37.70:8200/", "测试": "http://121.36.37.70:8200/", "生产": "http://10.156.134.53:8200/", "secure": false, "changeOrigin": true }, "/signalr": { - "target": "http://10.156.134.53:8200/", + "target": "http://121.36.37.70:8200/", "secure": false, "ws": true, "logLevel": "debug" diff --git a/src/app/pages/home/home.component.html b/src/app/pages/home/home.component.html index e64d7a7..c2a0362 100644 --- a/src/app/pages/home/home.component.html +++ b/src/app/pages/home/home.component.html @@ -13,6 +13,9 @@
  • 历史纪录
  • +
  • + 统计报表 +
  • @@ -110,4 +113,4 @@ - + \ No newline at end of file diff --git a/src/app/pages/pages-routing.module.ts b/src/app/pages/pages-routing.module.ts index f4aa8cf..b29c085 100644 --- a/src/app/pages/pages-routing.module.ts +++ b/src/app/pages/pages-routing.module.ts @@ -1,19 +1,37 @@ -import { Routes, RouterModule } from '@angular/router'; -import { NgModule } from '@angular/core'; -import { AuthGuard } from '../auth.guard' -import { CriminalRecordsAdminComponent } from './criminal-records-admin/criminal-records-admin.component'; -import { OilUnloadingProcessListComponent } from './oil-unloading-process-list/oil-unloading-process-list.component'; -import { HistoriesComponent } from './histories/histories.component'; +import { Routes, RouterModule } from "@angular/router"; +import { NgModule } from "@angular/core"; +import { AuthGuard } from "../auth.guard"; +import { CriminalRecordsAdminComponent } from "./criminal-records-admin/criminal-records-admin.component"; +import { OilUnloadingProcessListComponent } from "./oil-unloading-process-list/oil-unloading-process-list.component"; +import { HistoriesComponent } from "./histories/histories.component"; +import { StatisticsComponent } from "./statistics/statistics.component"; +import { BgStationComponent } from "./statistics/bg-station/bg-station.component"; +import { BgViolationComponent } from "./statistics/bg-violation/bg-violation.component"; const routes: Routes = [ - { path: 'records', component: CriminalRecordsAdminComponent }, - { path: 'histories', component: HistoriesComponent }, - // { path: 'records/oliunloadinglist', component: OilUnloadingProcessListComponent }, - // { path: 'records/petrolStation/oliunloadinglist', component: OilUnloadingProcessListComponent }, + { path: "records", component: CriminalRecordsAdminComponent }, + { path: "histories", component: HistoriesComponent }, + // { path: 'records/oliunloadinglist', component: OilUnloadingProcessListComponent }, + // { path: 'records/petrolStation/oliunloadinglist', component: OilUnloadingProcessListComponent }, + { + path: "statistics", + component: StatisticsComponent, + children: [ + { path: '', redirectTo: 'bgStation', pathMatch: 'full' }, + { + path: "bgStation", + component: BgStationComponent, + }, + { + path: "bgViolation", + component: BgViolationComponent, + }, + ], + }, ]; @NgModule({ - imports: [RouterModule.forChild(routes)], - exports: [RouterModule] + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], }) -export class PagesRoutingModule { } +export class PagesRoutingModule {} diff --git a/src/app/pages/pages.module.ts b/src/app/pages/pages.module.ts index a0721a8..c90ed82 100644 --- a/src/app/pages/pages.module.ts +++ b/src/app/pages/pages.module.ts @@ -45,6 +45,9 @@ import { ChangePasswordComponent } from "./change-password/change-password.compo import { DisposeequipmentComponent } from "./disposeequipment/disposeequipment.component"; import { HistoriesComponent } from "./histories/histories.component"; import { ImgListComponent } from "./histories/img-list/img-list.component"; +import { StatisticsComponent } from "./statistics/statistics.component"; +import { BgStationComponent } from './statistics/bg-station/bg-station.component'; +import { BgViolationComponent } from './statistics/bg-violation/bg-violation.component'; @NgModule({ declarations: [ @@ -58,6 +61,9 @@ import { ImgListComponent } from "./histories/img-list/img-list.component"; DisposeequipmentComponent, HistoriesComponent, ImgListComponent, + StatisticsComponent, + BgStationComponent, + BgViolationComponent, ], imports: [ diff --git a/src/app/pages/statistics/bg-station/bg-station.component.html b/src/app/pages/statistics/bg-station/bg-station.component.html new file mode 100644 index 0000000..dd4922e --- /dev/null +++ b/src/app/pages/statistics/bg-station/bg-station.component.html @@ -0,0 +1,149 @@ +
    +
    + + +
    + + + + + 序号 + + 油站名称 + 推送数 + 误报数 + 总数 + 准确率 + + + + + + {{key+1}} + {{item.stationName}} + {{item.positiveCount}} + {{item.totalCount - + item.positiveCount}} + + {{item.totalCount}} + + + {{item.positiveCount/item.totalCount}} + + + + +
    +
    +
    \ No newline at end of file diff --git a/src/app/pages/statistics/bg-station/bg-station.component.scss b/src/app/pages/statistics/bg-station/bg-station.component.scss new file mode 100644 index 0000000..a31cdf4 --- /dev/null +++ b/src/app/pages/statistics/bg-station/bg-station.component.scss @@ -0,0 +1,278 @@ +.recordsboxadmin { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} + +.search { + box-sizing: border-box; + padding: 0 36px; + width: 100%; + min-height: 32px; + margin-bottom: 4px; + + form { + width: 100%; + min-height: 32px; + display: flex; + justify-content: flex-start; + flex-wrap: wrap; + + .searchParams, + .btn { + margin: 0 3px; + margin-bottom: 12px; + } + + .searchParams { + // flex: 5; + margin-bottom: 12px; + width: 150px; + } + + .searchParamsLong { + width: 250px; + margin-bottom: 12px; + } + + .searchParams2 { + width: 220px; + margin-bottom: 12px; + } + + .btn { + // flex: 1; + } + + nz-select { + color: rgba(145, 204, 255, 0.95); + } + + nz-tree-select { + color: rgba(145, 204, 255, 0.95); + } + + nz-range-picker { + background-color: rgba(0, 0, 0, 0); + width: 100%; + } + + } + + +} + +.content { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + + .title { + width: 100%; + height: 64px; + box-sizing: border-box; + padding: 0 28px; + margin: 13px 0; + position: relative; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 65px; + height: 65px; + } + + .content { + flex: 1; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + // background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%); + + .contentitem { + width: 100%; + height: 32px; + display: flex; + align-items: center; + // background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%); + + span { + margin-left: 10px; + color: #bce0ff; + font-size: 20px; + font-family: titlefont; + cursor: pointer; + } + + span:nth-child(1) { + margin-left: 12px; + } + + .grey { + color: #68829F; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 16px; + cursor: pointer; + } + } + + .tablebox { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; + box-sizing: border-box; + padding: 0 38px; + } + +} + + +// 适配125% +@media screen and (max-height: 750px) { + .search { + box-sizing: border-box; + padding: 0 30px; + height: 32px; + margin-bottom: 12px; + + form { + width: 100%; + height: 32px; + } + } + + .content { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + + .title { + height: 42px; + padding: 0 20px; + margin: 8px 0; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 46px; + height: 46px; + } + + .content { + height: 36px; + + .contentitem { + width: 100%; + height: 25px; + + span { + margin-left: 6px; + font-size: 16px; + } + + span:nth-child(1) { + margin-left: 8px; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 4px; + cursor: pointer; + } + } + + + } +} + +// 适配150% +@media screen and (max-height: 600px) { + .search { + box-sizing: border-box; + padding: 0 22px; + height: 32px; + margin-bottom: 6px; + + form { + width: 100%; + height: 32px; + } + } + + .content { + .title { + height: 36px; + padding: 0 20px; + margin: 3px 0; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 36px; + height: 36px; + } + + .content { + height: 30px; + + .contentitem { + width: 100%; + height: 22px; + + span { + margin-left: 6px; + font-size: 13px; + } + + span:nth-child(1) { + margin-left: 12px; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 2px; + cursor: pointer; + } + } + + + } +} diff --git a/src/app/pages/statistics/bg-station/bg-station.component.spec.ts b/src/app/pages/statistics/bg-station/bg-station.component.spec.ts new file mode 100644 index 0000000..5b4e75c --- /dev/null +++ b/src/app/pages/statistics/bg-station/bg-station.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BgStationComponent } from './bg-station.component'; + +describe('BgStationComponent', () => { + let component: BgStationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BgStationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BgStationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/statistics/bg-station/bg-station.component.ts b/src/app/pages/statistics/bg-station/bg-station.component.ts new file mode 100644 index 0000000..2a9ee4a --- /dev/null +++ b/src/app/pages/statistics/bg-station/bg-station.component.ts @@ -0,0 +1,325 @@ +import { HttpClient } from "@angular/common/http"; +import { Component, ElementRef, OnInit, ViewContainerRef } from "@angular/core"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { Router } from "@angular/router"; +import { fromEvent } from "rxjs"; +import { debounceTime } from "rxjs/operators"; +import * as moment from "moment"; +import { NzModalService } from "ng-zorro-antd/modal"; +import { NzMessageService } from "ng-zorro-antd/message"; +import { TreeService } from "src/app/service/tree.service"; +declare var abp: any; +import "linqjs"; +@Component({ + selector: "app-bg-station", + templateUrl: "./bg-station.component.html", + styleUrls: ["./bg-station.component.scss"], +}) +export class BgStationComponent implements OnInit { + validateForm!: FormGroup; + constructor( + private element: ElementRef, + private toTree: TreeService, + private http: HttpClient, + private fb: FormBuilder, + private router: Router, + private modal: NzModalService, + private viewContainerRef: ViewContainerRef, + private message: NzMessageService + ) {} + tableScrollHeight; + resizeListener; + startdate; + enddate; + ngOnInit(): void { + this.tableScrollHeight = "100px"; + // 页面监听 + this.resizeListener = fromEvent(window, "resize") + .pipe(debounceTime(100)) + .subscribe((event) => { + let tableHeader = + this.element.nativeElement.querySelector( + `.ant-table-header` + ).clientHeight; + this.tableScrollHeight = + document.getElementById("tablebox").clientHeight - + tableHeader - + 10 + + "px"; + }); + //当前日期 + let myDate: any = new Date(); + let nowY = myDate.getFullYear(); + let nowM = myDate.getMonth() + 1; + let nowD = myDate.getDate(); + this.enddate = + nowY + + "-" + + (nowM < 10 ? "0" + nowM : nowM) + + "-" + + (nowD < 10 ? "0" + nowD : nowD); //当前日期 + //获取三十天前日期 + let lw = new Date(myDate - 1000 * 60 * 60 * 24 * 30); //最后一个数字30可改,30天的意思 + let lastY = lw.getFullYear(); + let lastM = lw.getMonth() + 1; + let lastD = lw.getDate(); + this.startdate = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); //三十天之前日期 + + this.validateForm = this.fb.group({ + // level: [null], + // organization: [null], + // type: [null], + // event: [null], + // site: [null], + // manufacturer: [null], //厂商 + // operation: [null], //操作记录 + // disposalState: [null], + datePicker: [[this.enddate, this.enddate]], + }); + + this.warningType(); + this.tableSpin = true; + this.getAllOrganization(); + } + ngOnDestroy(): void { + this.resizeListener.unsubscribe(); + } + defaultOrId: string; + //获取所有组织机构 + nodes: any = []; + getAllOrganization() { + let OrganizationUnitId = + sessionStorage.getItem("isGasStation") == "true" + ? JSON.parse(sessionStorage.getItem("userdataOfgasstation")) + .organization.id + : JSON.parse(sessionStorage.getItem("userdata")).organization.id; + let params = { + OrganizationUnitId: OrganizationUnitId, + IsContainsChildren: "true", + }; + this.http + .get("/api/services/app/Organization/GetAll", { + params: params, + }) + .subscribe((data: any) => { + data.result.items.forEach((element) => { + if (element.id == OrganizationUnitId) { + element.parentId = null; + } + element.key = element.id; + element.title = element.displayName; + }); + this.nodes = [...this.toTree.toTree(data.result.items)]; + this.defaultOrId = JSON.parse( + sessionStorage.getItem("userdata") + ).organization.id; + this.validateForm.value.organization = this.defaultOrId; + this.getViolateRecordList(); + }); + } + + //获得违规记录列表 + SkipCount: string = "0"; + MaxResultCount: string = "50"; + list: any = []; + totalCount: string; + tableSpin: boolean = false; + getViolateRecordList() { + let ViolationIds = []; + if (this.validateForm.value.event) { + ViolationIds.push(this.validateForm.value.event); + } + if (this.validateForm.value.type && !this.validateForm.value.event) { + this.warningTypesDetails.forEach((item) => { + item.id ? ViolationIds.push(item.id) : null; + }); + } + let VendorName: any = null; + if (this.validateForm.value.manufacturer) { + VendorName = this.validateForm.value.manufacturer; + } + let NotificationState: any = "All"; + if (this.validateForm.value.operation) { + if (this.validateForm.value.operation === "null") { + NotificationState = null; + } else { + NotificationState = this.validateForm.value.operation; + } + } + let params = { + // Level: this.validateForm.value.level, + // ViolationIds: ViolationIds, + // ViolateArea: this.validateForm.value.site, + // OrganizationUnitId: this.validateForm.value.organization, + // IsContainsChildren: "true", + // CanVerify: "false", + ViolateTime: this.validateForm.value.datePicker + ? [ + moment(this.validateForm.value.datePicker[0]).format("yyyy-MM-DD") + + " 00:00:00", + moment(this.validateForm.value.datePicker[1]).format("yyyy-MM-DD") + + " 23:59:59", + ] + : null, + // SkipCount: this.SkipCount, + // MaxResultCount: this.MaxResultCount, //每页50条 + // Positive: this.validateForm.value.disposalState, + // VendorName: VendorName, + // NotificationState: NotificationState, + }; + this.tableSpin = true; + this.http + .get( + "/api/services/app/ViolateRecordVerification/GetPositiveRateByStation", + { + params: params, + } + ) + .subscribe( + (data: any) => { + this.tableSpin = false; + console.log("列表数据", data); + this.list = [...data.result.items]; + this.totalCount = data.result.totalCount; + setTimeout(() => { + let tableHeader = + this.element.nativeElement.querySelector( + `.ant-table-header` + ).clientHeight; + this.tableScrollHeight = + document.getElementById("tablebox").clientHeight - + tableHeader - + 10 + + "px"; + }, 0); + // console.log("违规记录列表", data); + // this.tableSpin = false; + // console.log(this.list.length); + }, + (err) => { + this.tableSpin = false; + this.message.create("error", err.error.error.details); + } + ); + } + + ngAfterViewInit(): void { + fromEvent( + this.element.nativeElement.querySelector(`#tbody`) as HTMLCanvasElement, + "scroll" + ) + .pipe(debounceTime(100)) + .subscribe((event: any) => { + //监听 DOM 滚动事件 + if ( + event.target.scrollHeight - + (event.target.scrollTop + event.target.clientHeight) <= + 10 + ) { + if (this.totalCount > this.list.length) { + console.log("需要加载数据了", event); + this.SkipCount = String(Number(this.SkipCount) + 50); + this.getViolateRecordList(); + } + } + }); + } + + getThirtyDays() { + //获取当前日期 + let myDate = new Date(); + var nowY = myDate.getFullYear(); + var nowM = myDate.getMonth() + 1; + var nowD = myDate.getDate(); + var enddateStr = + nowY + + "-" + + (nowM < 10 ? "0" + nowM : nowM) + + "-" + + (nowD < 10 ? "0" + nowD : nowD); //当前日期 + var enddate = new Date(enddateStr); + + //获取三十天前日期 + var lw = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 30); //最后一个数字30可改,30天的意思 + var lastY = lw.getFullYear(); + var lastM = lw.getMonth() + 1; + var lastD = lw.getDate(); + var startdateStr = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); //三十天之前日期 + var startDate = new Date(startdateStr); + + const dateList = []; + while (true) { + startDate.setDate(startDate.getDate() + 1); + if (startDate.getTime() <= enddate.getTime()) { + if (startDate.getDate() < 10) { + // startDate.getFullYear() 获取年,此处没加上年份 + dateList.push(startDate.getMonth() + 1 + ".0" + startDate.getDate()); + } else { + dateList.push(startDate.getMonth() + 1 + "." + startDate.getDate()); + } + } else { + break; + } + } + return dateList; + } + submitForm(): void { + for (const i in this.validateForm.controls) { + this.validateForm.controls[i].markAsDirty(); + this.validateForm.controls[i].updateValueAndValidity(); + } + this.list = []; + this.SkipCount = "0"; + this.getViolateRecordList(); + } + resetForm(e: MouseEvent): void { + e.preventDefault(); + this.validateForm.reset(); + for (const key in this.validateForm.controls) { + this.validateForm.controls[key].markAsPristine(); + this.validateForm.controls[key].updateValueAndValidity(); + } + this.validateForm.patchValue({ + // organization: JSON.parse(sessionStorage.getItem("userdata")).organization + // .id, + datePicker: [this.enddate, this.enddate], + }); + this.list = []; + this.SkipCount = "0"; + this.getViolateRecordList(); + } + + //预警类型接口 + warningTypes: any; //预警接口数据 + warningTypesDetails: any; + warningType() { + this.http + .get("/api/services/app/Violation/GetAllList") + .subscribe((data: any) => { + this.warningTypesDetails = data.result; + this.warningTypes = (data.result as any).groupBy((t) => { + return t.violationType; + }); + }); + } + typeChange(e: any) { + this.warningTypes.forEach((element) => { + if (element.key == e) { + this.warningTypesDetails = element; + } + }); + this.validateForm.patchValue({ + event: null, + }); + } +} diff --git a/src/app/pages/statistics/bg-violation/bg-violation.component.html b/src/app/pages/statistics/bg-violation/bg-violation.component.html new file mode 100644 index 0000000..3b4850f --- /dev/null +++ b/src/app/pages/statistics/bg-violation/bg-violation.component.html @@ -0,0 +1,147 @@ +
    +
    + + +
    + + + + + 序号 + + 预警名称 + 推送数 + 误报数 + 总数 + 准确率 + + + + + + {{key+1}} + {{item.violationName}} + {{item.positiveCount}} + {{item.totalCount - item.positiveCount}} + + {{item.totalCount}} + + {{item.positiveCount/item.totalCount}} + + + + +
    +
    +
    \ No newline at end of file diff --git a/src/app/pages/statistics/bg-violation/bg-violation.component.scss b/src/app/pages/statistics/bg-violation/bg-violation.component.scss new file mode 100644 index 0000000..c308bbd --- /dev/null +++ b/src/app/pages/statistics/bg-violation/bg-violation.component.scss @@ -0,0 +1,279 @@ +.recordsboxadmin { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + } + + .search { + box-sizing: border-box; + padding: 0 36px; + width: 100%; + min-height: 32px; + margin-bottom: 4px; + + form { + width: 100%; + min-height: 32px; + display: flex; + justify-content: flex-start; + flex-wrap: wrap; + + .searchParams, + .btn { + margin: 0 3px; + margin-bottom: 12px; + } + + .searchParams { + // flex: 5; + margin-bottom: 12px; + width: 150px; + } + + .searchParamsLong { + width: 250px; + margin-bottom: 12px; + } + + .searchParams2 { + width: 220px; + margin-bottom: 12px; + } + + .btn { + // flex: 1; + } + + nz-select { + color: rgba(145, 204, 255, 0.95); + } + + nz-tree-select { + color: rgba(145, 204, 255, 0.95); + } + + nz-range-picker { + background-color: rgba(0, 0, 0, 0); + width: 100%; + } + + } + + + } + + .content { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + + .title { + width: 100%; + height: 64px; + box-sizing: border-box; + padding: 0 28px; + margin: 13px 0; + position: relative; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 65px; + height: 65px; + } + + .content { + flex: 1; + height: 48px; + display: flex; + align-items: center; + justify-content: center; + // background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%); + + .contentitem { + width: 100%; + height: 32px; + display: flex; + align-items: center; + // background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%); + + span { + margin-left: 10px; + color: #bce0ff; + font-size: 20px; + font-family: titlefont; + cursor: pointer; + } + + span:nth-child(1) { + margin-left: 12px; + } + + .grey { + color: #68829F; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 16px; + cursor: pointer; + } + } + + .tablebox { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + overflow: hidden; + box-sizing: border-box; + padding: 0 38px; + } + + } + + + // 适配125% + @media screen and (max-height: 750px) { + .search { + box-sizing: border-box; + padding: 0 30px; + height: 32px; + margin-bottom: 12px; + + form { + width: 100%; + height: 32px; + } + } + + .content { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + + .title { + height: 42px; + padding: 0 20px; + margin: 8px 0; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 46px; + height: 46px; + } + + .content { + height: 36px; + + .contentitem { + width: 100%; + height: 25px; + + span { + margin-left: 6px; + font-size: 16px; + } + + span:nth-child(1) { + margin-left: 8px; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 4px; + cursor: pointer; + } + } + + + } + } + + // 适配150% + @media screen and (max-height: 600px) { + .search { + box-sizing: border-box; + padding: 0 22px; + height: 32px; + margin-bottom: 6px; + + form { + width: 100%; + height: 32px; + } + } + + .content { + .title { + height: 36px; + padding: 0 20px; + margin: 3px 0; + + .titlebox { + width: 100%; + height: 100%; + display: flex; + align-items: center; + + img { + width: 36px; + height: 36px; + } + + .content { + height: 30px; + + .contentitem { + width: 100%; + height: 22px; + + span { + margin-left: 6px; + font-size: 13px; + } + + span:nth-child(1) { + margin-left: 12px; + } + } + + } + } + + .packup { + position: absolute; + right: 33px; + top: 2px; + cursor: pointer; + } + } + + + } + } + \ No newline at end of file diff --git a/src/app/pages/statistics/bg-violation/bg-violation.component.spec.ts b/src/app/pages/statistics/bg-violation/bg-violation.component.spec.ts new file mode 100644 index 0000000..b2c2054 --- /dev/null +++ b/src/app/pages/statistics/bg-violation/bg-violation.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { BgViolationComponent } from './bg-violation.component'; + +describe('BgViolationComponent', () => { + let component: BgViolationComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ BgViolationComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(BgViolationComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/statistics/bg-violation/bg-violation.component.ts b/src/app/pages/statistics/bg-violation/bg-violation.component.ts new file mode 100644 index 0000000..e689aa1 --- /dev/null +++ b/src/app/pages/statistics/bg-violation/bg-violation.component.ts @@ -0,0 +1,325 @@ +import { HttpClient } from "@angular/common/http"; +import { Component, ElementRef, OnInit, ViewContainerRef } from "@angular/core"; +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { Router } from "@angular/router"; +import { fromEvent } from "rxjs"; +import { debounceTime } from "rxjs/operators"; +import * as moment from "moment"; +import { NzModalService } from "ng-zorro-antd/modal"; +import { NzMessageService } from "ng-zorro-antd/message"; +import { TreeService } from "src/app/service/tree.service"; +declare var abp: any; +import "linqjs"; +@Component({ + selector: "app-bg-violation", + templateUrl: "./bg-violation.component.html", + styleUrls: ["./bg-violation.component.scss"], +}) +export class BgViolationComponent implements OnInit { + validateForm!: FormGroup; + constructor( + private element: ElementRef, + private toTree: TreeService, + private http: HttpClient, + private fb: FormBuilder, + private router: Router, + private modal: NzModalService, + private viewContainerRef: ViewContainerRef, + private message: NzMessageService + ) {} + tableScrollHeight; + resizeListener; + startdate; + enddate; + ngOnInit(): void { + this.tableScrollHeight = "100px"; + // 页面监听 + this.resizeListener = fromEvent(window, "resize") + .pipe(debounceTime(100)) + .subscribe((event) => { + let tableHeader = + this.element.nativeElement.querySelector( + `.ant-table-header` + ).clientHeight; + this.tableScrollHeight = + document.getElementById("tablebox").clientHeight - + tableHeader - + 10 + + "px"; + }); + //当前日期 + let myDate: any = new Date(); + let nowY = myDate.getFullYear(); + let nowM = myDate.getMonth() + 1; + let nowD = myDate.getDate(); + this.enddate = + nowY + + "-" + + (nowM < 10 ? "0" + nowM : nowM) + + "-" + + (nowD < 10 ? "0" + nowD : nowD); //当前日期 + //获取三十天前日期 + let lw = new Date(myDate - 1000 * 60 * 60 * 24 * 30); //最后一个数字30可改,30天的意思 + let lastY = lw.getFullYear(); + let lastM = lw.getMonth() + 1; + let lastD = lw.getDate(); + this.startdate = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); //三十天之前日期 + + this.validateForm = this.fb.group({ + // level: [null], + // organization: [null], + // type: [null], + // event: [null], + // site: [null], + // manufacturer: [null], //厂商 + // operation: [null], //操作记录 + // disposalState: [null], + datePicker: [[this.enddate, this.enddate]], + }); + + this.warningType(); + this.tableSpin = true; + this.getAllOrganization(); + } + ngOnDestroy(): void { + this.resizeListener.unsubscribe(); + } + defaultOrId: string; + //获取所有组织机构 + nodes: any = []; + getAllOrganization() { + let OrganizationUnitId = + sessionStorage.getItem("isGasStation") == "true" + ? JSON.parse(sessionStorage.getItem("userdataOfgasstation")) + .organization.id + : JSON.parse(sessionStorage.getItem("userdata")).organization.id; + let params = { + OrganizationUnitId: OrganizationUnitId, + IsContainsChildren: "true", + }; + this.http + .get("/api/services/app/Organization/GetAll", { + params: params, + }) + .subscribe((data: any) => { + data.result.items.forEach((element) => { + if (element.id == OrganizationUnitId) { + element.parentId = null; + } + element.key = element.id; + element.title = element.displayName; + }); + this.nodes = [...this.toTree.toTree(data.result.items)]; + this.defaultOrId = JSON.parse( + sessionStorage.getItem("userdata") + ).organization.id; + this.validateForm.value.organization = this.defaultOrId; + this.getViolateRecordList(); + }); + } + + //获得违规记录列表 + SkipCount: string = "0"; + MaxResultCount: string = "50"; + list: any = []; + totalCount: string; + tableSpin: boolean = false; + getViolateRecordList() { + let ViolationIds = []; + if (this.validateForm.value.event) { + ViolationIds.push(this.validateForm.value.event); + } + if (this.validateForm.value.type && !this.validateForm.value.event) { + this.warningTypesDetails.forEach((item) => { + item.id ? ViolationIds.push(item.id) : null; + }); + } + let VendorName: any = null; + if (this.validateForm.value.manufacturer) { + VendorName = this.validateForm.value.manufacturer; + } + let NotificationState: any = "All"; + if (this.validateForm.value.operation) { + if (this.validateForm.value.operation === "null") { + NotificationState = null; + } else { + NotificationState = this.validateForm.value.operation; + } + } + let params = { + // Level: this.validateForm.value.level, + // ViolationIds: ViolationIds, + // ViolateArea: this.validateForm.value.site, + // OrganizationUnitId: this.validateForm.value.organization, + // IsContainsChildren: "true", + // CanVerify: "false", + ViolateTime: this.validateForm.value.datePicker + ? [ + moment(this.validateForm.value.datePicker[0]).format("yyyy-MM-DD") + + " 00:00:00", + moment(this.validateForm.value.datePicker[1]).format("yyyy-MM-DD") + + " 23:59:59", + ] + : null, + // SkipCount: this.SkipCount, + // MaxResultCount: this.MaxResultCount, //每页50条 + // Positive: this.validateForm.value.disposalState, + // VendorName: VendorName, + // NotificationState: NotificationState, + }; + this.tableSpin = true; + this.http + .get( + "/api/services/app/ViolateRecordVerification/GetPositiveRateByViolation", + { + params: params, + } + ) + .subscribe( + (data: any) => { + this.tableSpin = false; + console.log("列表数据", data); + this.list = [...data.result.items]; + this.totalCount = data.result.totalCount; + setTimeout(() => { + let tableHeader = + this.element.nativeElement.querySelector( + `.ant-table-header` + ).clientHeight; + this.tableScrollHeight = + document.getElementById("tablebox").clientHeight - + tableHeader - + 10 + + "px"; + }, 0); + // console.log("违规记录列表", data); + // this.tableSpin = false; + // console.log(this.list.length); + }, + (err) => { + this.tableSpin = false; + this.message.create("error", err.error.error.details); + } + ); + } + + ngAfterViewInit(): void { + fromEvent( + this.element.nativeElement.querySelector(`#tbody`) as HTMLCanvasElement, + "scroll" + ) + .pipe(debounceTime(100)) + .subscribe((event: any) => { + //监听 DOM 滚动事件 + if ( + event.target.scrollHeight - + (event.target.scrollTop + event.target.clientHeight) <= + 10 + ) { + if (this.totalCount > this.list.length) { + console.log("需要加载数据了", event); + this.SkipCount = String(Number(this.SkipCount) + 50); + this.getViolateRecordList(); + } + } + }); + } + + getThirtyDays() { + //获取当前日期 + let myDate = new Date(); + var nowY = myDate.getFullYear(); + var nowM = myDate.getMonth() + 1; + var nowD = myDate.getDate(); + var enddateStr = + nowY + + "-" + + (nowM < 10 ? "0" + nowM : nowM) + + "-" + + (nowD < 10 ? "0" + nowD : nowD); //当前日期 + var enddate = new Date(enddateStr); + + //获取三十天前日期 + var lw = new Date(new Date().getTime() - 1000 * 60 * 60 * 24 * 30); //最后一个数字30可改,30天的意思 + var lastY = lw.getFullYear(); + var lastM = lw.getMonth() + 1; + var lastD = lw.getDate(); + var startdateStr = + lastY + + "-" + + (lastM < 10 ? "0" + lastM : lastM) + + "-" + + (lastD < 10 ? "0" + lastD : lastD); //三十天之前日期 + var startDate = new Date(startdateStr); + + const dateList = []; + while (true) { + startDate.setDate(startDate.getDate() + 1); + if (startDate.getTime() <= enddate.getTime()) { + if (startDate.getDate() < 10) { + // startDate.getFullYear() 获取年,此处没加上年份 + dateList.push(startDate.getMonth() + 1 + ".0" + startDate.getDate()); + } else { + dateList.push(startDate.getMonth() + 1 + "." + startDate.getDate()); + } + } else { + break; + } + } + return dateList; + } + submitForm(): void { + for (const i in this.validateForm.controls) { + this.validateForm.controls[i].markAsDirty(); + this.validateForm.controls[i].updateValueAndValidity(); + } + this.list = []; + this.SkipCount = "0"; + this.getViolateRecordList(); + } + resetForm(e: MouseEvent): void { + e.preventDefault(); + this.validateForm.reset(); + for (const key in this.validateForm.controls) { + this.validateForm.controls[key].markAsPristine(); + this.validateForm.controls[key].updateValueAndValidity(); + } + this.validateForm.patchValue({ + // organization: JSON.parse(sessionStorage.getItem("userdata")).organization + // .id, + datePicker: [this.enddate, this.enddate], + }); + this.list = []; + this.SkipCount = "0"; + this.getViolateRecordList(); + } + + //预警类型接口 + warningTypes: any; //预警接口数据 + warningTypesDetails: any; + warningType() { + this.http + .get("/api/services/app/Violation/GetAllList") + .subscribe((data: any) => { + this.warningTypesDetails = data.result; + this.warningTypes = (data.result as any).groupBy((t) => { + return t.violationType; + }); + }); + } + typeChange(e: any) { + this.warningTypes.forEach((element) => { + if (element.key == e) { + this.warningTypesDetails = element; + } + }); + this.validateForm.patchValue({ + event: null, + }); + } +} diff --git a/src/app/pages/statistics/statistics.component.html b/src/app/pages/statistics/statistics.component.html new file mode 100644 index 0000000..9e5646b --- /dev/null +++ b/src/app/pages/statistics/statistics.component.html @@ -0,0 +1,17 @@ + +
    +
    + +
    +
    + 油站统计 + 预警统计 +
    +
    +
    +
    + +
    +
    + + diff --git a/src/app/pages/statistics/statistics.component.scss b/src/app/pages/statistics/statistics.component.scss new file mode 100644 index 0000000..05755c7 --- /dev/null +++ b/src/app/pages/statistics/statistics.component.scss @@ -0,0 +1,103 @@ +.box { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; +} + +.content { + flex: 1; +} + +.titlebox { + display: flex; + align-items: center; + height: 64px; + box-sizing: border-box; + padding: 0 28px; + margin: 13px 0; + + img { + width: 65px; + height: 65px; + } + + .content { + flex: 1; + height: 48px; + display: flex; + align-items: center; + // background-image: linear-gradient(to right, #002147, #033565, #064e8e, #064e8e, #033565, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.32) 50%, rgba(35, 153, 255, 0) 100%); + + .contentitem { + width: 100%; + height: 32px; + display: flex; + align-items: center; + // background-image: linear-gradient(to right, #002147, #0f5ca0, #1c88e6, #1c88e6, #0f5ca0, #002147); + background: linear-gradient(270deg, rgba(35, 153, 255, 0) 0%, rgba(35, 153, 255, 0.8) 50%, rgba(35, 153, 255, 0) 100%); + + span { + margin-left: 10px; + color: gray; + font-size: 20px; + font-family: titlefont; + cursor: pointer; + } + + .router-link-active { + color: #bce0ff; + } + } + + } +} + +// 适配125% +@media screen and (max-height: 750px) { + .titlebox { + img { + width: 46px; + height: 46px; + } + + .content { + height: 36px; + + .contentitem { + height: 25px; + + span { + margin-left: 6px; + font-size: 16px; + } + } + + } + } +} + +// 适配150% +@media screen and (max-height: 600px) { + .titlebox { + img { + width: 36px; + height: 36px; + } + + .content { + height: 28px; + + .contentitem { + height: 20px; + + span { + margin-left: 6px; + font-size: 13px; + } + } + + } + } +} diff --git a/src/app/pages/statistics/statistics.component.spec.ts b/src/app/pages/statistics/statistics.component.spec.ts new file mode 100644 index 0000000..30693b4 --- /dev/null +++ b/src/app/pages/statistics/statistics.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { StatisticsComponent } from './statistics.component'; + +describe('StatisticsComponent', () => { + let component: StatisticsComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ StatisticsComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(StatisticsComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/statistics/statistics.component.ts b/src/app/pages/statistics/statistics.component.ts new file mode 100644 index 0000000..d87a5e9 --- /dev/null +++ b/src/app/pages/statistics/statistics.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-statistics', + templateUrl: './statistics.component.html', + styleUrls: ['./statistics.component.scss'] +}) +export class StatisticsComponent implements OnInit { + + constructor() { } + + ngOnInit(): void { + } + +} diff --git a/src/theme.less b/src/theme.less index 0b68d87..ee8fcbc 100644 --- a/src/theme.less +++ b/src/theme.less @@ -183,7 +183,106 @@ ::-webkit-scrollbar-track { background-color: #061d3c; } + + + .ant-tree .ant-tree-node-content-wrapper:hover, + .ant-tree .ant-tree-node-content-wrapper.ant-tree-node-selected { + background: linear-gradient(90deg, rgba(0, 13, 33, 0) 0%, #2399FF 50%, rgba(0, 13, 33, 0) 100%); + } + + .ant-tree .ant-tree-node-content-wrapper { + padding: 2px 15px; + } + + nz-tree { + nz-tree-node { + margin-left: 20px; + } + + nz-tree-node:nth-child(1) { + margin-left: 0px; + } + } + + .ant-table table { + border-collapse: collapse; + } + + + nz-table { + flex: 1; + width: 100%; + } + + .ant-table { + background: none; + } + + .ant-table-thead>tr { + height: 40px; + line-height: 40px; + background: rgba(35, 153, 255, 0.2); + border: 1px solid rgba(35, 217, 255, 0.4); + box-shadow: 0 0 3px 0 rgba(35, 217, 255, 0.4) inset; + } + + .ant-table-thead>tr>th { + background: none; + border-bottom: none; + padding: 0; + color: #23D9FF; + line-height: 28px; + } + + .ant-table-tbody>tr { + height: 40px; + line-height: 40px; + border-bottom: 1px solid #0d3761; + } + + .ant-table-tbody>tr>td { + font-weight: 300; + font-family: synormal; + background: none; + border-bottom: none; + padding: 0; + color: #C4E2FC; + } + + .look { + color: #36A2FF; + cursor: pointer; + } + + .ant-table-measure-now { + display: none; + } + + .ant-empty-description { + color: #23D9FF; + } + + .ant-table-tbody>tr>td { + border-bottom: none; + } + + .ant-table-tbody>tr>td:hover { + background: none; + } + + .ant-select, + .ant-select-arrow { + color: #fff; + } } -.ant-pagination-prev,.ant-pagination-next{ + +.ant-pagination-prev, +.ant-pagination-next { overflow: hidden; -} \ No newline at end of file +} + +.ant-table table { + border-collapse: collapse; +} + +