|
@@ -1,15 +1,26 @@
|
|
|
import { InstanceModel, service } from '@/pages/device/Instance';
|
|
import { InstanceModel, service } from '@/pages/device/Instance';
|
|
|
import { useParams } from 'umi';
|
|
import { useParams } from 'umi';
|
|
|
-import { DatePicker, Modal, Radio, Select, Space, Table, Tabs, Tooltip as ATooltip } from 'antd';
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ DatePicker,
|
|
|
|
|
+ Modal,
|
|
|
|
|
+ Radio,
|
|
|
|
|
+ Select,
|
|
|
|
|
+ Space,
|
|
|
|
|
+ Spin,
|
|
|
|
|
+ Table,
|
|
|
|
|
+ Tabs,
|
|
|
|
|
+ Tooltip as ATooltip,
|
|
|
|
|
+} from 'antd';
|
|
|
import type { PropertyMetadata } from '@/pages/device/Product/typings';
|
|
import type { PropertyMetadata } from '@/pages/device/Product/typings';
|
|
|
import encodeQuery from '@/utils/encodeQuery';
|
|
import encodeQuery from '@/utils/encodeQuery';
|
|
|
import { useEffect, useState } from 'react';
|
|
import { useEffect, useState } from 'react';
|
|
|
import moment from 'moment';
|
|
import moment from 'moment';
|
|
|
-import { Axis, Chart, LineAdvance, Legend, Slider, Tooltip, Point } from 'bizcharts';
|
|
|
|
|
import FileComponent from '../../Running/Property/FileComponent';
|
|
import FileComponent from '../../Running/Property/FileComponent';
|
|
|
import { DownloadOutlined, SearchOutlined } from '@ant-design/icons';
|
|
import { DownloadOutlined, SearchOutlined } from '@ant-design/icons';
|
|
|
import Detail from './Detail';
|
|
import Detail from './Detail';
|
|
|
import AMap from './AMap';
|
|
import AMap from './AMap';
|
|
|
|
|
+import Charts from './Charts';
|
|
|
|
|
+
|
|
|
interface Props {
|
|
interface Props {
|
|
|
close: () => void;
|
|
close: () => void;
|
|
|
data: Partial<PropertyMetadata>;
|
|
data: Partial<PropertyMetadata>;
|
|
@@ -34,6 +45,7 @@ const PropertyLog = (props: Props) => {
|
|
|
const [current, setCurrent] = useState<any>('');
|
|
const [current, setCurrent] = useState<any>('');
|
|
|
|
|
|
|
|
const [geoList, setGeoList] = useState<any>({});
|
|
const [geoList, setGeoList] = useState<any>({});
|
|
|
|
|
+ const [loading, setLoading] = useState<boolean>(true);
|
|
|
|
|
|
|
|
const columns = [
|
|
const columns = [
|
|
|
{
|
|
{
|
|
@@ -119,6 +131,7 @@ const PropertyLog = (props: Props) => {
|
|
|
];
|
|
];
|
|
|
|
|
|
|
|
const handleSearch = (param: any, startTime?: number, endTime?: number) => {
|
|
const handleSearch = (param: any, startTime?: number, endTime?: number) => {
|
|
|
|
|
+ setLoading(true);
|
|
|
service
|
|
service
|
|
|
.getPropertyData(
|
|
.getPropertyData(
|
|
|
params.id,
|
|
params.id,
|
|
@@ -132,6 +145,7 @@ const PropertyLog = (props: Props) => {
|
|
|
}),
|
|
}),
|
|
|
)
|
|
)
|
|
|
.then((resp) => {
|
|
.then((resp) => {
|
|
|
|
|
+ setLoading(false);
|
|
|
if (resp.status === 200) {
|
|
if (resp.status === 200) {
|
|
|
setDataSource(resp.result);
|
|
setDataSource(resp.result);
|
|
|
}
|
|
}
|
|
@@ -139,6 +153,7 @@ const PropertyLog = (props: Props) => {
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const queryChartsList = async (startTime?: number, endTime?: number) => {
|
|
const queryChartsList = async (startTime?: number, endTime?: number) => {
|
|
|
|
|
+ setLoading(true);
|
|
|
const resp = await service.queryPropertieList(params.id, data.id || '', {
|
|
const resp = await service.queryPropertieList(params.id, data.id || '', {
|
|
|
paging: false,
|
|
paging: false,
|
|
|
terms: [
|
|
terms: [
|
|
@@ -150,32 +165,59 @@ const PropertyLog = (props: Props) => {
|
|
|
],
|
|
],
|
|
|
sorts: [{ name: 'timestamp', order: 'asc' }],
|
|
sorts: [{ name: 'timestamp', order: 'asc' }],
|
|
|
});
|
|
});
|
|
|
|
|
+ setLoading(false);
|
|
|
if (resp.status === 200) {
|
|
if (resp.status === 200) {
|
|
|
- const dataList: any[] = [];
|
|
|
|
|
|
|
+ const dataList: any[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ year: start,
|
|
|
|
|
+ value: undefined,
|
|
|
|
|
+ type: data?.name || '',
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
resp.result.data.forEach((i: any) => {
|
|
resp.result.data.forEach((i: any) => {
|
|
|
dataList.push({
|
|
dataList.push({
|
|
|
- year: moment(i.timestamp).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
|
|
+ ...i,
|
|
|
|
|
+ year: i.timestamp, //moment(i.timestamp).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
value: i.value,
|
|
value: i.value,
|
|
|
type: data?.name || '',
|
|
type: data?.name || '',
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
- setChartsList(dataList);
|
|
|
|
|
|
|
+ dataList.push({
|
|
|
|
|
+ year: end,
|
|
|
|
|
+ value: undefined,
|
|
|
|
|
+ type: data?.name || '',
|
|
|
|
|
+ });
|
|
|
|
|
+ console.log(dataList.length);
|
|
|
|
|
+ setChartsList(dataList || []);
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
const queryChartsAggList = async (datas: any) => {
|
|
const queryChartsAggList = async (datas: any) => {
|
|
|
|
|
+ setLoading(true);
|
|
|
const resp = await service.queryPropertieInfo(params.id, datas);
|
|
const resp = await service.queryPropertieInfo(params.id, datas);
|
|
|
|
|
+ setLoading(false);
|
|
|
if (resp.status === 200) {
|
|
if (resp.status === 200) {
|
|
|
- const dataList: any[] = [];
|
|
|
|
|
|
|
+ const dataList: any[] = [
|
|
|
|
|
+ {
|
|
|
|
|
+ year: start,
|
|
|
|
|
+ value: undefined,
|
|
|
|
|
+ type: data?.name || '',
|
|
|
|
|
+ },
|
|
|
|
|
+ ];
|
|
|
resp.result.forEach((i: any) => {
|
|
resp.result.forEach((i: any) => {
|
|
|
dataList.push({
|
|
dataList.push({
|
|
|
...i,
|
|
...i,
|
|
|
- year: moment(i.time).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
|
|
|
|
+ year: i.time, // moment(i.time).format('YYYY-MM-DD HH:mm:ss'),
|
|
|
value: Number(i[data.id || '']),
|
|
value: Number(i[data.id || '']),
|
|
|
type: data?.name || '',
|
|
type: data?.name || '',
|
|
|
});
|
|
});
|
|
|
});
|
|
});
|
|
|
- setChartsList(dataList.reverse());
|
|
|
|
|
|
|
+ dataList.push({
|
|
|
|
|
+ year: end,
|
|
|
|
|
+ value: undefined,
|
|
|
|
|
+ type: data?.name || '',
|
|
|
|
|
+ });
|
|
|
|
|
+ setChartsList((dataList || []).reverse());
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
@@ -186,16 +228,6 @@ const PropertyLog = (props: Props) => {
|
|
|
setEnd(new Date().getTime());
|
|
setEnd(new Date().getTime());
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
- const scale = {
|
|
|
|
|
- value: { min: 0 },
|
|
|
|
|
- year: {
|
|
|
|
|
- type: 'time',
|
|
|
|
|
- mask: 'YYYY-MM-DD HH:mm:ss',
|
|
|
|
|
- max: end,
|
|
|
|
|
- min: start,
|
|
|
|
|
- },
|
|
|
|
|
- };
|
|
|
|
|
-
|
|
|
|
|
const renderComponent = (type: string) => {
|
|
const renderComponent = (type: string) => {
|
|
|
switch (type) {
|
|
switch (type) {
|
|
|
case 'table':
|
|
case 'table':
|
|
@@ -298,21 +330,8 @@ const PropertyLog = (props: Props) => {
|
|
|
</div>
|
|
</div>
|
|
|
)}
|
|
)}
|
|
|
</div>
|
|
</div>
|
|
|
- <div style={{ marginTop: 10 }}>
|
|
|
|
|
- <Chart height={400} data={chartsList} scale={scale} padding="auto" autoFit>
|
|
|
|
|
- <Legend />
|
|
|
|
|
- <Axis name="year" />
|
|
|
|
|
- <Axis
|
|
|
|
|
- name="value"
|
|
|
|
|
- label={{
|
|
|
|
|
- formatter: (val) => parseFloat(val).toLocaleString(),
|
|
|
|
|
- }}
|
|
|
|
|
- />
|
|
|
|
|
- <Tooltip shared />
|
|
|
|
|
- <Point position="year*value" />
|
|
|
|
|
- <LineAdvance position="year*value" shape="smooth" area />
|
|
|
|
|
- <Slider />
|
|
|
|
|
- </Chart>
|
|
|
|
|
|
|
+ <div>
|
|
|
|
|
+ <Charts data={chartsList} min={start} max={end} />
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
);
|
|
);
|
|
@@ -352,6 +371,7 @@ const PropertyLog = (props: Props) => {
|
|
|
});
|
|
});
|
|
|
}
|
|
}
|
|
|
} else if (tab === 'geo') {
|
|
} else if (tab === 'geo') {
|
|
|
|
|
+ setLoading(true);
|
|
|
service
|
|
service
|
|
|
.getPropertyData(
|
|
.getPropertyData(
|
|
|
params.id,
|
|
params.id,
|
|
@@ -362,6 +382,7 @@ const PropertyLog = (props: Props) => {
|
|
|
}),
|
|
}),
|
|
|
)
|
|
)
|
|
|
.then((resp) => {
|
|
.then((resp) => {
|
|
|
|
|
+ setLoading(false);
|
|
|
if (resp.status === 200) {
|
|
if (resp.status === 200) {
|
|
|
setGeoList(resp.result);
|
|
setGeoList(resp.result);
|
|
|
}
|
|
}
|
|
@@ -380,118 +401,122 @@ const PropertyLog = (props: Props) => {
|
|
|
onOk={() => close()}
|
|
onOk={() => close()}
|
|
|
width="50vw"
|
|
width="50vw"
|
|
|
>
|
|
>
|
|
|
- <div style={{ marginBottom: '20px' }}>
|
|
|
|
|
- <Space>
|
|
|
|
|
- <Radio.Group
|
|
|
|
|
- value={radioValue}
|
|
|
|
|
- buttonStyle="solid"
|
|
|
|
|
- onChange={(e) => {
|
|
|
|
|
- const value = e.target.value;
|
|
|
|
|
- setRadioValue(value);
|
|
|
|
|
- let st: number = 0;
|
|
|
|
|
- const et = new Date().getTime();
|
|
|
|
|
- if (value === 'today') {
|
|
|
|
|
- st = moment().startOf('day').valueOf();
|
|
|
|
|
- } else if (value === 'week') {
|
|
|
|
|
- st = moment().subtract(6, 'days').valueOf();
|
|
|
|
|
- } else if (value === 'month') {
|
|
|
|
|
- st = moment().subtract(29, 'days').valueOf();
|
|
|
|
|
- }
|
|
|
|
|
- setDateValue(undefined);
|
|
|
|
|
- setStart(st);
|
|
|
|
|
- setEnd(et);
|
|
|
|
|
- }}
|
|
|
|
|
- style={{ minWidth: 220 }}
|
|
|
|
|
- >
|
|
|
|
|
- <Radio.Button value="today">今日</Radio.Button>
|
|
|
|
|
- <Radio.Button value="week">近一周</Radio.Button>
|
|
|
|
|
- <Radio.Button value="month">近一月</Radio.Button>
|
|
|
|
|
- </Radio.Group>
|
|
|
|
|
- {
|
|
|
|
|
- // @ts-ignore
|
|
|
|
|
- <DatePicker.RangePicker
|
|
|
|
|
- value={dateValue}
|
|
|
|
|
- showTime
|
|
|
|
|
- onChange={(dates: any) => {
|
|
|
|
|
- if (dates) {
|
|
|
|
|
- setRadioValue(undefined);
|
|
|
|
|
- setDateValue(dates);
|
|
|
|
|
- const st = dates[0]?.valueOf();
|
|
|
|
|
- const et = dates[1]?.valueOf();
|
|
|
|
|
- setStart(st);
|
|
|
|
|
- setEnd(et);
|
|
|
|
|
|
|
+ <Spin spinning={loading}>
|
|
|
|
|
+ <div style={{ marginBottom: '20px' }}>
|
|
|
|
|
+ <Space>
|
|
|
|
|
+ <Radio.Group
|
|
|
|
|
+ value={radioValue}
|
|
|
|
|
+ buttonStyle="solid"
|
|
|
|
|
+ onChange={(e) => {
|
|
|
|
|
+ const value = e.target.value;
|
|
|
|
|
+ setRadioValue(value);
|
|
|
|
|
+ let st: number = 0;
|
|
|
|
|
+ const et = new Date().getTime();
|
|
|
|
|
+ if (value === 'today') {
|
|
|
|
|
+ st = moment().startOf('day').valueOf();
|
|
|
|
|
+ } else if (value === 'week') {
|
|
|
|
|
+ st = moment().subtract(6, 'days').valueOf();
|
|
|
|
|
+ } else if (value === 'month') {
|
|
|
|
|
+ st = moment().subtract(29, 'days').valueOf();
|
|
|
}
|
|
}
|
|
|
|
|
+ setDateValue(undefined);
|
|
|
|
|
+ setStart(st);
|
|
|
|
|
+ setEnd(et);
|
|
|
}}
|
|
}}
|
|
|
- />
|
|
|
|
|
- }
|
|
|
|
|
- </Space>
|
|
|
|
|
- </div>
|
|
|
|
|
- <Tabs
|
|
|
|
|
- activeKey={tab}
|
|
|
|
|
- onChange={(key: string) => {
|
|
|
|
|
- setTab(key);
|
|
|
|
|
- if (key === 'charts' && !!data.valueType?.type) {
|
|
|
|
|
- if (list.includes(data.valueType?.type)) {
|
|
|
|
|
- queryChartsList(start, end);
|
|
|
|
|
- } else {
|
|
|
|
|
- setCycle('1m');
|
|
|
|
|
- setAgg('COUNT');
|
|
|
|
|
- queryChartsAggList({
|
|
|
|
|
- columns: [
|
|
|
|
|
- {
|
|
|
|
|
- property: data.id,
|
|
|
|
|
- alias: data.id,
|
|
|
|
|
- agg: 'COUNT',
|
|
|
|
|
|
|
+ style={{ minWidth: 220 }}
|
|
|
|
|
+ >
|
|
|
|
|
+ <Radio.Button value="today">今日</Radio.Button>
|
|
|
|
|
+ <Radio.Button value="week">近一周</Radio.Button>
|
|
|
|
|
+ <Radio.Button value="month">近一月</Radio.Button>
|
|
|
|
|
+ </Radio.Group>
|
|
|
|
|
+ {
|
|
|
|
|
+ // @ts-ignore
|
|
|
|
|
+ <DatePicker.RangePicker
|
|
|
|
|
+ value={dateValue}
|
|
|
|
|
+ showTime
|
|
|
|
|
+ onChange={(dates: any) => {
|
|
|
|
|
+ if (dates) {
|
|
|
|
|
+ setRadioValue(undefined);
|
|
|
|
|
+ setDateValue(dates);
|
|
|
|
|
+ const st = dates[0]?.valueOf();
|
|
|
|
|
+ const et = dates[1]?.valueOf();
|
|
|
|
|
+ setStart(st);
|
|
|
|
|
+ setEnd(et);
|
|
|
|
|
+ }
|
|
|
|
|
+ }}
|
|
|
|
|
+ />
|
|
|
|
|
+ }
|
|
|
|
|
+ </Space>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <Tabs
|
|
|
|
|
+ activeKey={tab}
|
|
|
|
|
+ onChange={(key: string) => {
|
|
|
|
|
+ setTab(key);
|
|
|
|
|
+ if (key === 'charts' && !!data.valueType?.type) {
|
|
|
|
|
+ if (list.includes(data.valueType?.type)) {
|
|
|
|
|
+ queryChartsList(start, end);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setCycle('1m');
|
|
|
|
|
+ setAgg('COUNT');
|
|
|
|
|
+ queryChartsAggList({
|
|
|
|
|
+ columns: [
|
|
|
|
|
+ {
|
|
|
|
|
+ property: data.id,
|
|
|
|
|
+ alias: data.id,
|
|
|
|
|
+ agg: 'COUNT',
|
|
|
|
|
+ },
|
|
|
|
|
+ ],
|
|
|
|
|
+ query: {
|
|
|
|
|
+ interval: '1m',
|
|
|
|
|
+ format: 'yyyy-MM-dd HH:mm:ss',
|
|
|
|
|
+ from: start,
|
|
|
|
|
+ to: end,
|
|
|
},
|
|
},
|
|
|
- ],
|
|
|
|
|
- query: {
|
|
|
|
|
- interval: '1m',
|
|
|
|
|
- format: 'yyyy-MM-dd HH:mm:ss',
|
|
|
|
|
- from: start,
|
|
|
|
|
- to: end,
|
|
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'geo') {
|
|
|
|
|
+ setLoading(true);
|
|
|
|
|
+ service
|
|
|
|
|
+ .getPropertyData(
|
|
|
|
|
+ params.id,
|
|
|
|
|
+ encodeQuery({
|
|
|
|
|
+ paging: false,
|
|
|
|
|
+ terms: { property: data.id, timestamp$BTW: start && end ? [start, end] : [] },
|
|
|
|
|
+ sorts: { timestamp: 'asc' },
|
|
|
|
|
+ }),
|
|
|
|
|
+ )
|
|
|
|
|
+ .then((resp) => {
|
|
|
|
|
+ setLoading(false);
|
|
|
|
|
+ if (resp.status === 200) {
|
|
|
|
|
+ setGeoList(resp.result);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ if (key === 'table') {
|
|
|
|
|
+ handleSearch(
|
|
|
|
|
+ {
|
|
|
|
|
+ pageSize: 10,
|
|
|
|
|
+ pageIndex: 0,
|
|
|
},
|
|
},
|
|
|
- });
|
|
|
|
|
|
|
+ start,
|
|
|
|
|
+ end,
|
|
|
|
|
+ );
|
|
|
}
|
|
}
|
|
|
- }
|
|
|
|
|
- if (key === 'geo') {
|
|
|
|
|
- service
|
|
|
|
|
- .getPropertyData(
|
|
|
|
|
- params.id,
|
|
|
|
|
- encodeQuery({
|
|
|
|
|
- paging: false,
|
|
|
|
|
- terms: { property: data.id, timestamp$BTW: start && end ? [start, end] : [] },
|
|
|
|
|
- sorts: { timestamp: 'asc' },
|
|
|
|
|
- }),
|
|
|
|
|
- )
|
|
|
|
|
- .then((resp) => {
|
|
|
|
|
- if (resp.status === 200) {
|
|
|
|
|
- setGeoList(resp.result);
|
|
|
|
|
- }
|
|
|
|
|
- });
|
|
|
|
|
- }
|
|
|
|
|
- if (key === 'table') {
|
|
|
|
|
- handleSearch(
|
|
|
|
|
- {
|
|
|
|
|
- pageSize: 10,
|
|
|
|
|
- pageIndex: 0,
|
|
|
|
|
- },
|
|
|
|
|
- start,
|
|
|
|
|
- end,
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
- }}
|
|
|
|
|
- >
|
|
|
|
|
- {tabList.map((item) => (
|
|
|
|
|
- <Tabs.TabPane tab={item.tab} key={item.key}>
|
|
|
|
|
- {renderComponent(item.key)}
|
|
|
|
|
- </Tabs.TabPane>
|
|
|
|
|
- ))}
|
|
|
|
|
- {data?.valueType?.type === 'geoPoint' && (
|
|
|
|
|
- <Tabs.TabPane tab="轨迹" key="geo">
|
|
|
|
|
- <AMap value={geoList} name={data?.name || ''} />
|
|
|
|
|
- </Tabs.TabPane>
|
|
|
|
|
- )}
|
|
|
|
|
- </Tabs>
|
|
|
|
|
|
|
+ }}
|
|
|
|
|
+ >
|
|
|
|
|
+ {tabList.map((item) => (
|
|
|
|
|
+ <Tabs.TabPane tab={item.tab} key={item.key}>
|
|
|
|
|
+ {renderComponent(item.key)}
|
|
|
|
|
+ </Tabs.TabPane>
|
|
|
|
|
+ ))}
|
|
|
|
|
+ {data?.valueType?.type === 'geoPoint' && (
|
|
|
|
|
+ <Tabs.TabPane tab="轨迹" key="geo">
|
|
|
|
|
+ <AMap value={geoList} name={data?.name || ''} />
|
|
|
|
|
+ </Tabs.TabPane>
|
|
|
|
|
+ )}
|
|
|
|
|
+ </Tabs>
|
|
|
|
|
+ </Spin>
|
|
|
{detailVisible && (
|
|
{detailVisible && (
|
|
|
<Detail
|
|
<Detail
|
|
|
close={() => {
|
|
close={() => {
|