import { Component, OnInit, ViewChild } from '@angular/core';
|
import { _HttpClient } from '@delon/theme';
|
import { Sensor, Device, DataCondition, MonitorPoint, Organization, LineChartCriteria, PairData } from '@business/entity/data';
|
import { TimeUnits, AreaRange, ResultCode } from '@business/enum/types.enum';
|
import { SensorsService } from '@business/services/http/sensors.service';
|
import { PageBean, ResultBean, Grid } from '@business/entity/grid';
|
import { NzTreeComponent } from 'ng-tree-antd';
|
import * as moment from 'moment';
|
import { ExampleService } from '@business/services/util/example.service';
|
import { DeviceService } from '@business/services/http/device.service';
|
import { environment } from '@env/environment';
|
import { CascaderOption } from 'ng-zorro-antd/src/cascader/nz-cascader.component';
|
import { AreacodeService } from '@business/services/http/areacode.service';
|
import { MonitorPointService } from '@business/services/http/monitor-point.service';
|
import { NzMessageService } from 'ng-zorro-antd';
|
import * as $ from 'jquery';
|
|
@Component({
|
selector: 'app-query',
|
templateUrl: './query.component.html'
|
})
|
export class QueryComponent implements OnInit {
|
public expandForm: boolean; // 搜索区 展开控制
|
// public sensors: any[] = [];
|
public sensorOptions: any[] = [];
|
/**
|
* 数据类型,下拉列表数据
|
* 注意,年度类型,对应查询数据单位为月,以此类推
|
* @memberof QueryComponent
|
*/
|
public timeUnitOptions = [
|
{label: '某年', value: TimeUnits.MONTH},
|
{label: '某月', value: TimeUnits.DAY},
|
{label: '某日', value: TimeUnits.HOUR},
|
{label: '某时', value: TimeUnits.MINUTE},
|
];
|
public timeUnit: {label: string, value: TimeUnits} = this.timeUnitOptions[2];
|
public actualTime: Date = new Date();
|
public actualYearOptions: number [];
|
public isCollapse = false;
|
// 显示使用
|
public _areas: { label: any, value: any[] };
|
public grid: Grid<any> = new Grid();
|
public gridSensorNames: string[] = [];
|
@ViewChild(NzTreeComponent) private tree: NzTreeComponent;
|
private _timeType: {showTime: boolean|{[key: string]: Function|boolean}, mode: 'month' | 'day', dateFormat: string } = {showTime: false, mode: 'day', dateFormat: 'YYYY-MM-DD'};
|
// 用key-value方式,暂存监测项目
|
private _sensors: {[key: string]: string} = {};
|
private _sensorNames: string;
|
get sensorNames(): string {
|
return this._sensorNames;
|
}
|
public toggleCollapse() {
|
this.isCollapse = !this.isCollapse;
|
}
|
public deviceOptions: Device[] = [];
|
public dataCondition: DataCondition = {areaRangeId: 320583, areaRange: AreaRange.AREA };
|
|
public monitorPointOptions: MonitorPoint[] = [];
|
|
get actualYear(): number {
|
return this.actualTime.getFullYear();
|
}
|
set actualYear(year) {
|
this.actualTime.setFullYear(Number(year));
|
}
|
monitorPointsChange(text?: string) {
|
const pageBean: PageBean = { pageIndex: 0, pageSize: 20 };
|
const example = new ExampleService();
|
let areaName = '';
|
switch (this.dataCondition.areaRange) {
|
case AreaRange.PROVINCE:
|
areaName = 'provinceCode'; break;
|
case AreaRange.CITY:
|
areaName = 'cityCode'; break;
|
case AreaRange.AREA:
|
areaName = 'areaCode'; break;
|
}
|
if (!!text) {
|
example.or().andLike({ name: 'name', value: '%' + text + '%' })
|
.andEqualTo({ name: areaName, value: this.dataCondition.areaRangeId });
|
} else {
|
example.or()
|
.andEqualTo({ name: areaName, value: this.dataCondition.areaRangeId });
|
}
|
this.monitorPointService.getPageByExample(pageBean, example).subscribe(
|
(res: PageBean) => {
|
if (!!res && !!res.data) {
|
this.monitorPointOptions = res.data;
|
}
|
}
|
);
|
}
|
devicesChange(text?: string) {
|
if (!!this.monitorPoint) {
|
const example = new ExampleService();
|
if (!!text) {
|
example.or().andEqualTo({ name: 'monitorPointId', value: this.monitorPoint.id })
|
.andLike({name: 'text', value: text});
|
}else {
|
example.or().andEqualTo({ name: 'monitorPointId', value: this.monitorPoint.id });
|
}
|
this.deviceService.getPageByExample(null, example).subscribe(
|
(res: PageBean) => {
|
if (!!res && !!res.data) {
|
this.deviceOptions = res.data;
|
}
|
}
|
);
|
} else {
|
this.deviceOptions = [];
|
}
|
}
|
constructor(
|
private http: _HttpClient,
|
private sensorsService: SensorsService,
|
private deviceService: DeviceService,
|
private areacodeService: AreacodeService,
|
private monitorPointService: MonitorPointService,
|
private msg: NzMessageService,
|
) { }
|
ngOnInit() {
|
this.initPage();
|
}
|
private initPage() {
|
this.sensorsService.getPagingList(null, null).subscribe(
|
(res: PageBean) => {
|
this.sensorOptions.push({id: -1, name: '全部', isExpanded: true, children: res.data});
|
}
|
);
|
this.actualYearOptions = this.newArray(this.actualYear - 9, 10).map(item => Number(item)).reverse();
|
// 省市区 初始值
|
this.http.get(environment.SERVER_BASH_URL + 'organization/get-my-org').subscribe(
|
(res: ResultBean<Organization>) => {
|
if (res.code === ResultCode.SUCCESS) {
|
const org = res.data;
|
if (!!org.areaNames) {
|
const areaNames = org.areaNames;
|
this._areas = { label: null, value: null };
|
this._areas.label = Object.values(areaNames).filter(
|
val => !!val
|
).join('/');
|
if (areaNames.areaName != null) {
|
this._areas.value = org.areaCode;
|
this.dataCondition.areaRange = AreaRange.AREA;
|
this.dataCondition.areaRangeId = org.areaCode;
|
} else if (areaNames.cityName != null) {
|
this._areas.value = org.cityCode;
|
this.dataCondition.areaRange = AreaRange.CITY;
|
this.dataCondition.areaRangeId = org.cityCode;
|
} else {
|
this._areas.value = org.provinceCode;
|
this.dataCondition.areaRange = AreaRange.PROVINCE;
|
this.dataCondition.areaRangeId = org.provinceCode;
|
}
|
} else {
|
this._areas = { label: '江苏省/苏州市/昆山市', value: [ 320000, 320500, 320583]};
|
this.dataCondition.areaRange = AreaRange.AREA;
|
this.dataCondition.areaRangeId = 320583;
|
}
|
// 监控点初始化
|
this.monitorPointsChange();
|
}
|
}
|
);
|
}
|
// 第一步,省市区 赋值
|
public setAreaCodes(codes: string[]) {
|
this._areas.value = codes;
|
if (!!codes && !!codes.length) {
|
const n = codes.length;
|
if (this.dataCondition.areaRangeId !== Number(codes[n - 1])) {
|
this.dataCondition.areaRangeId = Number(codes[n - 1]);
|
let changeMonitorPoint = false;
|
switch (n) {
|
case 1:
|
this.dataCondition.areaRange = AreaRange.PROVINCE;
|
if (!this.monitorPoint || this.monitorPoint.provinceCode !== this.dataCondition.areaRangeId) {
|
changeMonitorPoint = true;
|
}
|
break;
|
case 2:
|
this.dataCondition.areaRange = AreaRange.CITY;
|
if (!this.monitorPoint || this.monitorPoint.cityCode !== this.dataCondition.areaRangeId) {
|
changeMonitorPoint = true;
|
}
|
break;
|
case 3:
|
this.dataCondition.areaRange = AreaRange.AREA;
|
if (!this.monitorPoint || this.monitorPoint.areaCode !== this.dataCondition.areaRangeId) {
|
changeMonitorPoint = true;
|
}
|
break;
|
}
|
if ( this.actualYearOptions.length === 0 || changeMonitorPoint) {
|
this.monitorPointsChange();
|
this.monitorPoint = null;
|
}
|
}
|
}
|
}
|
// 第二步 设置 监控点
|
public _monitorPoint: MonitorPoint;
|
get monitorPoint(): MonitorPoint {
|
return this._monitorPoint;
|
}
|
set monitorPoint(value) {
|
if (!value || value !== this._monitorPoint ) {
|
this._monitorPoint = value;
|
if (!!value) {
|
this.dataCondition.areaRangeId = value.id;
|
this.dataCondition.areaRange = AreaRange.MONITORPOINT;
|
// 清空设备下拉选项
|
this._device = null;
|
this.devicesChange();
|
} else {
|
// 为null 设置 上一个层级
|
this.setAreaCodes(this._areas.value);
|
this._device = null;
|
this.deviceOptions = [];
|
}
|
}
|
}
|
// 第三步 设置 监控点
|
public _device: Device;
|
set device(val: Device) {
|
this._device = val;
|
if (!!val) {
|
this.dataCondition.areaRange = AreaRange.DEVICE;
|
this.dataCondition.areaRangeId = val.id;
|
} else {
|
// 如果为null 当前区域级别为监控点
|
this.monitorPoint = this._monitorPoint;
|
}
|
|
}
|
get device(): Device {
|
return this._device;
|
}
|
|
|
/**
|
* 获取 传感器名称
|
*
|
* @readonly
|
* @type {string}
|
* @memberof QueryComponent
|
*/
|
public onSensorSelect(event): void {
|
const data = event.node.data;
|
if (data.id === -1 && data.halfChecked === false) {
|
if (!!data.checked) {
|
this.sensorOptions[0].children.forEach(
|
sensor => {
|
this._sensors [sensor.id] = sensor.sensorKey;
|
}
|
);
|
} else {
|
this._sensors = {};
|
}
|
}else {
|
if (!!data.checked) {
|
this._sensors [data.id] = data.sensorKey;
|
}else {
|
delete this._sensors[data.id];
|
}
|
}
|
this._sensorNames = '';
|
this.sensorOptions[0].children.forEach(
|
sensor => {
|
const hasSensor = Object.keys(this._sensors).some(
|
id => Number(id) === Number(sensor.id)
|
);
|
if (hasSensor) {
|
this._sensorNames += sensor.name + ',';
|
}
|
}
|
);
|
}
|
public setTimeUnit(val: {label: string, value: TimeUnits} ) {
|
switch (val.value) {
|
// YYYY-MM-DD HH:mm:ss
|
case TimeUnits.MONTH:
|
this._timeType.dateFormat = 'YYYY';
|
// this._timeType.dateFormat = 'YYYY-MM';
|
// this._timeType.mode = 'month';
|
// this._timeType.endShowTime = null;
|
break;
|
case TimeUnits.DAY:
|
this._timeType.dateFormat = 'YYYY-MM';
|
this._timeType.mode = 'month';
|
this._timeType.showTime = false;
|
break;
|
case TimeUnits.HOUR:
|
this._timeType.dateFormat = 'YYYY-MM-DD';
|
this._timeType.mode = 'day';
|
this._timeType.showTime = false;
|
break;
|
case TimeUnits.MINUTE:
|
this._timeType.dateFormat = 'YYYY-MM-DD HH';
|
this._timeType.mode = 'day';
|
this._timeType.showTime = {
|
nzHideDisabledOptions: true,
|
nzDisabledHours: () => {
|
return [];
|
},
|
nzDisabledMinutes: (h) => {
|
return this.newArray(60).slice(1).map(
|
item => Number(item)
|
);
|
},
|
nzDisabledSeconds: () => {
|
return this.newArray(60).slice(1).map(
|
item => Number(item)
|
);
|
}
|
};
|
break;
|
}
|
}
|
public areaLazyLoad(event: { option: CascaderOption, index: number, resolve: (children: CascaderOption[]) => void, reject: () => void }) {
|
const index = event['index'];
|
const option = event.option;
|
switch (index) {
|
case -1:
|
this.areacodeService.getProvinces().subscribe(
|
(res: { label: string, value: string }[]) => {
|
event.resolve(res);
|
}
|
); break;
|
case 0:
|
this.areacodeService.getCities(option.value).subscribe(
|
(res: { label: string, value: string }[]) => {
|
event.resolve(res);
|
}
|
); break;
|
case 1:
|
this.areacodeService.getAreas(option.value).subscribe(
|
(res: { label: string, value: string }[]) => {
|
event.resolve(res);
|
}
|
); break;
|
}
|
}
|
private newArray = (startOrLen: number, len?: number, prefix?: string, suffix?: string) => {
|
const result = [];
|
const s = !!len ? startOrLen : 0;
|
len = !!len ? len : startOrLen;
|
suffix = !!suffix ? suffix : '';
|
prefix = !!prefix ? prefix : '';
|
for (let i = s; result.length < len; i++) {
|
result.push(prefix + i + suffix);
|
}
|
return result;
|
}
|
public loadGrid(): void {
|
// 数据检查
|
const sensors = Object.values(this._sensors);
|
if ( sensors.length === 0 ) {
|
this.msg.error(' 监测项目 不能为空');
|
return ;
|
}
|
this.grid.loading = true;
|
this.grid.data = [];
|
this.gridSensorNames = [];
|
const start: Date = this.getPeriodDate(this.actualTime , 'start');
|
const end: Date = this.getPeriodDate(this.actualTime , 'end');
|
this.dataCondition['actualTime'] = null;
|
this.dataCondition['timeUnits'] = this.timeUnit.value;
|
const dataConditions = [this.dataCondition];
|
const lineChartCriteria: LineChartCriteria = {
|
sensorKeys: sensors,
|
timePeriod: {startTime: start , endTime: end, timeUnits: this.timeUnit.value },
|
dataConditions: dataConditions
|
};
|
const timePeriod = lineChartCriteria.timePeriod;
|
switch (timePeriod.timeUnits) {
|
case TimeUnits.MONTH:
|
this.grid.columns = this.newArray(1, 12, null, '月').map(
|
item => {
|
return {text: item};
|
}
|
); break;
|
case TimeUnits.DAY:
|
const mo = moment(lineChartCriteria.timePeriod.startTime);
|
const days = mo.endOf('month').date();
|
this.grid.columns = this.newArray(1, days, null, '日').map(
|
item => {
|
return {text: item};
|
}
|
); break;
|
case TimeUnits.HOUR:
|
this.grid.columns = this.newArray(0, 24, null, '时').map(
|
item => {
|
return {text: item};
|
}
|
); break;
|
case TimeUnits.MINUTE:
|
this.grid.columns = this.newArray(0, 60, null, '分').map(
|
item => {
|
return {text: item};
|
}
|
); break;
|
}
|
this.http.post(environment.SERVER_BASH_URL + '/report/line-chart', lineChartCriteria).subscribe(
|
(res: ResultBean<{[key: string]: Array<Array<PairData>>}>) => {
|
if (res.code === 1) {
|
const series = [];
|
const data = res.data;
|
if (!!data) {
|
const sensorKeys = Object.keys(data);
|
sensorKeys.forEach(
|
key => {
|
const sensor = (<Array<Sensor>>this.sensorOptions[0].children).
|
find(item => {
|
return item.sensorKey === key;
|
});
|
this.gridSensorNames.push(sensor.name);
|
const sensorData = data[key][0].map(
|
pair => {
|
return !!pair.value ? pair.value : '-';
|
}
|
);
|
this.grid.data.push(sensorData);
|
}
|
);
|
}
|
this.grid.loading = false;
|
}
|
}
|
);
|
}
|
private getPeriodDate(value: Date , type?: 'start'|'end' ): Date {
|
let month = 0;
|
let day = 1;
|
let hour = 0;
|
let minute = 0;
|
let second = 0;
|
let millisecond = 0;
|
if ('end' === type) {
|
month = 11;
|
day = 31;
|
hour = 23;
|
minute = 59;
|
second = 59;
|
millisecond = 999;
|
}
|
const mo = moment(value);
|
switch ( this.timeUnit.value ) {
|
case TimeUnits.MONTH:
|
mo.month(month).date(day).hour(hour).minute(minute).second(second).millisecond(millisecond); break;
|
case TimeUnits.DAY:
|
mo.date(day).hour(hour).minute(minute).second(second).millisecond(millisecond); break;
|
case TimeUnits.HOUR:
|
mo.hour(hour).minute(minute).second(second).millisecond(millisecond); break;
|
case TimeUnits.MINUTE:
|
mo.minute(minute).second(second).millisecond(millisecond); break;
|
// case TimeUnits.MINUTE:
|
// mo.second(second).millisecond(millisecond); break;
|
}
|
return mo.toDate();
|
}
|
}
|