Commit 386d20582719ce6973e908bc7bc42cd48c3d20a6

Authored by fengtao
2 parents fa515ee3 5906aa50

Merge branch 'main' into ft-dev

@@ -179,3 +179,9 @@ export const getGATEWAYdevice = async (params: { organization: string }) => { @@ -179,3 +179,9 @@ export const getGATEWAYdevice = async (params: { organization: string }) => {
179 res.map((item) => ({ label: item.name, value: item.id })) 179 res.map((item) => ({ label: item.name, value: item.id }))
180 ); 180 );
181 }; 181 };
  182 +
  183 +export const getGATEWAY = (tbDeviceId: string) => {
  184 + return defHttp.get({
  185 + url: '/device/gateway/' + tbDeviceId,
  186 + });
  187 +};
1 <template> 1 <template>
2 - <div class="wrapper123"> 2 + <div class="wrapper">
3 <div ref="wrapRef" :style="{ height, width }"> </div> 3 <div ref="wrapRef" :style="{ height, width }"> </div>
4 <div class="right-wrap"> 4 <div class="right-wrap">
5 <BasicTable @register="registerTable" @rowClick="deviceRowClick"> 5 <BasicTable @register="registerTable" @rowClick="deviceRowClick">
@@ -25,21 +25,19 @@ @@ -25,21 +25,19 @@
25 </template> 25 </template>
26 </BasicTable> 26 </BasicTable>
27 </div> 27 </div>
28 - <DeviceDetailDrawer @register="registerDetailDrawer" />  
29 <BasicModal 28 <BasicModal
30 - v-bind="$attrs"  
31 @register="registerModal" 29 @register="registerModal"
32 title="历史数据" 30 title="历史数据"
33 width="70%" 31 width="70%"
34 :footer="null" 32 :footer="null"
35 @cancel="cancelHistoryModal" 33 @cancel="cancelHistoryModal"
36 :canFullscreen="false" 34 :canFullscreen="false"
37 - destroyOnClose  
38 > 35 >
39 <BasicForm @register="registerForm" /> 36 <BasicForm @register="registerForm" />
40 <Empty v-show="!isNull" /> 37 <Empty v-show="!isNull" />
41 <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div> 38 <div v-show="isNull" ref="chartRef" :style="{ height: '600px', width }"></div>
42 </BasicModal> 39 </BasicModal>
  40 + <DeviceDetailDrawer @register="registerDetailDrawer" />
43 </div> 41 </div>
44 </template> 42 </template>
45 <script lang="ts"> 43 <script lang="ts">
@@ -91,24 +89,101 @@ @@ -91,24 +89,101 @@
91 }, 89 },
92 }, 90 },
93 setup() { 91 setup() {
  92 + let entityId = '';
  93 + let keys = [];
  94 + let globalRecord: any = {};
94 const wrapRef = ref<HTMLDivElement | null>(null); 95 const wrapRef = ref<HTMLDivElement | null>(null);
  96 + const chartRef = ref<HTMLDivElement | null>(null);
  97 + const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
  98 + const isNull = ref(true);
95 const { toPromise } = useScript({ src: BAI_DU_MAP_URL }); 99 const { toPromise } = useScript({ src: BAI_DU_MAP_URL });
96 const [registerDetailDrawer, { openDrawer }] = useDrawer(); 100 const [registerDetailDrawer, { openDrawer }] = useDrawer();
97 -  
98 - let entityId = '';  
99 - let globalRecord: any = {};  
100 - async function initMap() {  
101 - await toPromise();  
102 - await nextTick();  
103 - const wrapEl = unref(wrapRef);  
104 - const BMap = (window as any).BMap;  
105 - if (!wrapEl) return;  
106 - const map = new BMap.Map(wrapEl);  
107 - const point = new BMap.Point(104.04666605565338, 30.543516387560476);  
108 - map.centerAndZoom(point, 15);  
109 - map.enableScrollWheelZoom(true);  
110 - }  
111 - 101 + const [registerModal, { openModal }] = useModal();
  102 + const [
  103 + registerForm,
  104 + { resetFields, getFieldsValue, setFieldsValue, validate, updateSchema },
  105 + ] = useForm({
  106 + labelWidth: 120,
  107 + schemas,
  108 + async submitFunc() {
  109 + // 表单验证
  110 + await validate();
  111 + let { endTs, interval, agg } = getFieldsValue();
  112 + if (!endTs) return;
  113 + // 数据收集
  114 + const dataArray: any[] = [];
  115 + const startTs = Date.now() - endTs;
  116 + endTs = Date.now();
  117 + // 发送请求
  118 + const res = await getDeviceHistoryInfo({
  119 + entityId,
  120 + keys: keys.join(),
  121 + startTs,
  122 + endTs,
  123 + interval,
  124 + agg,
  125 + });
  126 + // 判断数据对象是否为空
  127 + if (!Object.keys(res).length) {
  128 + isNull.value = false;
  129 + return;
  130 + } else {
  131 + isNull.value = true;
  132 + }
  133 + // 处理数据
  134 + for (const key in res) {
  135 + for (const item1 of res[key]) {
  136 + let { ts, value } = item1;
  137 + const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');
  138 + value = Number(value).toFixed(2);
  139 + dataArray.push([time, value, key]);
  140 + }
  141 + }
  142 + const series: any = keys.map((item) => {
  143 + return {
  144 + name: item,
  145 + type: 'line',
  146 + stack: 'Total',
  147 + data: dataArray.filter((item1) => item1[2] === item),
  148 + };
  149 + });
  150 + // 设置数据
  151 + setOptions({
  152 + tooltip: {
  153 + trigger: 'axis',
  154 + },
  155 + legend: {
  156 + data: keys,
  157 + },
  158 + grid: {
  159 + left: '3%',
  160 + right: '4%',
  161 + bottom: '3%',
  162 + containLabel: true,
  163 + },
  164 + dataZoom: [
  165 + {
  166 + type: 'inside',
  167 + start: 0,
  168 + end: 50,
  169 + },
  170 + {
  171 + start: 20,
  172 + end: 40,
  173 + },
  174 + ],
  175 + xAxis: {
  176 + type: 'time',
  177 + boundaryGap: false,
  178 + },
  179 + yAxis: {
  180 + type: 'value',
  181 + boundaryGap: [0, '100%'],
  182 + },
  183 + series,
  184 + });
  185 + },
  186 + });
112 const [registerTable] = useTable({ 187 const [registerTable] = useTable({
113 api: devicePage, 188 api: devicePage,
114 columns, 189 columns,
@@ -122,6 +197,18 @@ @@ -122,6 +197,18 @@
122 showSizeChanger: false, 197 showSizeChanger: false,
123 }, 198 },
124 }); 199 });
  200 +
  201 + async function initMap() {
  202 + await toPromise();
  203 + await nextTick();
  204 + const wrapEl = unref(wrapRef);
  205 + const BMap = (window as any).BMap;
  206 + if (!wrapEl) return;
  207 + const map = new BMap.Map(wrapEl);
  208 + const point = new BMap.Point(104.04666605565338, 30.543516387560476);
  209 + map.centerAndZoom(point, 15);
  210 + map.enableScrollWheelZoom(true);
  211 + }
125 // 点击表格某一行触发 212 // 点击表格某一行触发
126 const deviceRowClick = async (record) => { 213 const deviceRowClick = async (record) => {
127 entityId = record.tbDeviceId; 214 entityId = record.tbDeviceId;
@@ -130,6 +217,7 @@ @@ -130,6 +217,7 @@
130 const wrapEl = unref(wrapRef); 217 const wrapEl = unref(wrapRef);
131 const map = new BMap.Map(wrapEl); 218 const map = new BMap.Map(wrapEl);
132 if (record.deviceInfo.address) { 219 if (record.deviceInfo.address) {
  220 + keys = await getDeviceDataKeys(entityId);
133 const { name, organizationDTO, deviceState, deviceProfile } = record; 221 const { name, organizationDTO, deviceState, deviceProfile } = record;
134 const { longitude, latitude, address } = record.deviceInfo; 222 const { longitude, latitude, address } = record.deviceInfo;
135 const point = new BMap.Point(longitude, latitude); 223 const point = new BMap.Point(longitude, latitude);
@@ -191,99 +279,7 @@ @@ -191,99 +279,7 @@
191 map.openInfoWindow(infoWindow, map.getCenter()); 279 map.openInfoWindow(infoWindow, map.getCenter());
192 } 280 }
193 }; 281 };
194 - let keys = [];  
195 - const [registerModal, { openModal }] = useModal();  
196 - const [  
197 - registerForm,  
198 - { resetFields, getFieldsValue, setFieldsValue, validate, updateSchema },  
199 - ] = useForm({  
200 - labelWidth: 120,  
201 - schemas,  
202 - async submitFunc() {  
203 - // 表单验证  
204 - await validate();  
205 - let { endTs, interval, agg } = getFieldsValue();  
206 - if (!endTs) return;  
207 - // 数据收集  
208 - const dataArray: any[] = [];  
209 - const startTs = Date.now() - endTs;  
210 - endTs = Date.now();  
211 - // 判断对象是否为空  
212 - if (Object.keys(keys).length === 0) {  
213 - isNull.value = false;  
214 - return;  
215 - } else {  
216 - isNull.value = true;  
217 - }  
218 - // 发送请求  
219 - const res = await getDeviceHistoryInfo({  
220 - entityId,  
221 - keys: keys.join(),  
222 - startTs,  
223 - endTs,  
224 - interval,  
225 - agg,  
226 - });  
227 282
228 - // 处理数据  
229 - for (const key in res) {  
230 - for (const item1 of res[key]) {  
231 - let { ts, value } = item1;  
232 - const time = moment(ts).format('YYYY-MM-DD HH:mm:ss');  
233 - value = Number(value).toFixed(2);  
234 - dataArray.push([time, value, key]);  
235 - }  
236 - }  
237 -  
238 - const series: any = keys.map((item) => {  
239 - return {  
240 - name: item,  
241 - type: 'line',  
242 - stack: 'Total',  
243 - data: dataArray.filter((item1) => item1[2] === item),  
244 - };  
245 - });  
246 - // 设置数据  
247 - setOptions({  
248 - tooltip: {  
249 - trigger: 'axis',  
250 - },  
251 - legend: {  
252 - data: keys,  
253 - },  
254 - grid: {  
255 - left: '3%',  
256 - right: '4%',  
257 - bottom: '3%',  
258 - containLabel: true,  
259 - },  
260 - dataZoom: [  
261 - {  
262 - type: 'inside',  
263 - start: 0,  
264 - end: 50,  
265 - },  
266 - {  
267 - start: 20,  
268 - end: 40,  
269 - },  
270 - ],  
271 - xAxis: {  
272 - type: 'time',  
273 - boundaryGap: false,  
274 - },  
275 - yAxis: {  
276 - type: 'value',  
277 - boundaryGap: [0, '100%'],  
278 - },  
279 - series,  
280 - });  
281 - },  
282 - });  
283 -  
284 - const chartRef = ref<HTMLDivElement | null>(null);  
285 - const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);  
286 - const isNull = ref(true);  
287 // 设备信息 283 // 设备信息
288 const openDeviceInfoDrawer = async () => { 284 const openDeviceInfoDrawer = async () => {
289 const { id, tbDeviceId } = globalRecord; 285 const { id, tbDeviceId } = globalRecord;
@@ -299,10 +295,7 @@ @@ -299,10 +295,7 @@
299 const startTs = Date.now() - 86400000; //最近一天 295 const startTs = Date.now() - 86400000; //最近一天
300 const endTs = Date.now(); 296 const endTs = Date.now();
301 // 发送请求 297 // 发送请求
302 - keys = await getDeviceDataKeys(entityId);  
303 - // 判断keys是否为空  
304 - if (!Object.keys(keys).length) {  
305 - console.log(keys); 298 + if (!keys.length) {
306 isNull.value = false; 299 isNull.value = false;
307 return; 300 return;
308 } else { 301 } else {
@@ -316,7 +309,13 @@ @@ -316,7 +309,13 @@
316 interval: 7200000, //间隔两小时 309 interval: 7200000, //间隔两小时
317 agg: 'AVG', 310 agg: 'AVG',
318 }); 311 });
319 - 312 + // 判断对象是否为空
  313 + if (!Object.keys(res).length) {
  314 + isNull.value = false;
  315 + return;
  316 + } else {
  317 + isNull.value = true;
  318 + }
320 // 处理数据 319 // 处理数据
321 for (const key in res) { 320 for (const key in res) {
322 for (const item1 of res[key]) { 321 for (const item1 of res[key]) {
@@ -370,19 +369,16 @@ @@ -370,19 +369,16 @@
370 }, 369 },
371 series, 370 series,
372 }); 371 });
373 -  
374 - await setFieldsValue({ 372 + setFieldsValue({
375 endTs: 86400000, 373 endTs: 86400000,
376 interval: 7200000, 374 interval: 7200000,
377 agg: 'AVG', 375 agg: 'AVG',
378 }); 376 });
379 }; 377 };
380 -  
381 const cancelHistoryModal = () => { 378 const cancelHistoryModal = () => {
382 resetFields(); 379 resetFields();
383 updateSchema({ 380 updateSchema({
384 field: 'interval', 381 field: 'interval',
385 -  
386 componentProps: { 382 componentProps: {
387 placeholder: '请选择分组间隔', 383 placeholder: '请选择分组间隔',
388 options: [ 384 options: [
@@ -27,7 +27,6 @@ @@ -27,7 +27,6 @@
27 27
28 emits: ['select'], 28 emits: ['select'],
29 setup(_, { emit }) { 29 setup(_, { emit }) {
30 - // const { proxy } = getCurrentInstance();  
31 const getTreeRef: any = ref(null); 30 const getTreeRef: any = ref(null);
32 const treeData = ref<TreeItem[]>([]); 31 const treeData = ref<TreeItem[]>([]);
33 const selectedKeys = ref<string[]>(); 32 const selectedKeys = ref<string[]>();
@@ -60,6 +60,7 @@ @@ -60,6 +60,7 @@
60 租户消息量TOP10</h1 60 租户消息量TOP10</h1
61 > 61 >
62 <Empty v-if="!tenantTop10.length" /> 62 <Empty v-if="!tenantTop10.length" />
  63 +
63 <Descriptions :column="1"> 64 <Descriptions :column="1">
64 <template v-for="(item, index) in tenantTop10" :key="item.name"> 65 <template v-for="(item, index) in tenantTop10" :key="item.name">
65 <DescriptionsItem> 66 <DescriptionsItem>
@@ -53,12 +53,21 @@ export const step1Schemas: FormSchema[] = [ @@ -53,12 +53,21 @@ export const step1Schemas: FormSchema[] = [
53 required: true, 53 required: true,
54 label: '所属组织', 54 label: '所属组织',
55 component: 'ApiTreeSelect', 55 component: 'ApiTreeSelect',
56 - componentProps: {  
57 - api: async () => {  
58 - const data = await getOrganizationList();  
59 - copyTransFun(data as any as any[]);  
60 - return data;  
61 - }, 56 + componentProps({ formActionType }) {
  57 + const { setFieldsValue } = formActionType;
  58 + return {
  59 + api: async () => {
  60 + const data = await getOrganizationList();
  61 + copyTransFun(data as any as any[]);
  62 + return data;
  63 + },
  64 +
  65 + onChange() {
  66 + setFieldsValue({
  67 + gateWayDeviceId: null,
  68 + });
  69 + },
  70 + };
62 }, 71 },
63 }, 72 },
64 { 73 {
@@ -69,9 +78,9 @@ export const step1Schemas: FormSchema[] = [ @@ -69,9 +78,9 @@ export const step1Schemas: FormSchema[] = [
69 ifShow: ({ values }) => values.deviceType === 'SENSOR' && values.organizationId, 78 ifShow: ({ values }) => values.deviceType === 'SENSOR' && values.organizationId,
70 componentProps: ({ formModel }) => { 79 componentProps: ({ formModel }) => {
71 const { organizationId } = formModel; 80 const { organizationId } = formModel;
72 - console.log(formModel);  
73 return { 81 return {
74 api: getGATEWAYdevice, 82 api: getGATEWAYdevice,
  83 + showSearch: true,
75 params: { 84 params: {
76 organizationId, 85 organizationId,
77 }, 86 },
@@ -105,7 +105,12 @@ @@ -105,7 +105,12 @@
105 import { columns, searchFormSchema } from './config/device.data'; 105 import { columns, searchFormSchema } from './config/device.data';
106 import { Tag } from 'ant-design-vue'; 106 import { Tag } from 'ant-design-vue';
107 import { useMessage } from '/@/hooks/web/useMessage'; 107 import { useMessage } from '/@/hooks/web/useMessage';
108 - import { deleteDevice, devicePage, cancelDispatchCustomer } from '/@/api/device/deviceManager'; 108 + import {
  109 + deleteDevice,
  110 + devicePage,
  111 + cancelDispatchCustomer,
  112 + getGATEWAY,
  113 + } from '/@/api/device/deviceManager';
109 import { PageEnum } from '/@/enums/pageEnum'; 114 import { PageEnum } from '/@/enums/pageEnum';
110 import { useGo } from '/@/hooks/web/usePage'; 115 import { useGo } from '/@/hooks/web/usePage';
111 import { PageWrapper } from '/@/components/Page'; 116 import { PageWrapper } from '/@/components/Page';
@@ -191,7 +196,11 @@ @@ -191,7 +196,11 @@
191 }); 196 });
192 } 197 }
193 198
194 - function handleEdit(record: Recordable) { 199 + async function handleEdit(record: Recordable) {
  200 + if (record.deviceType === 'SENSOR') {
  201 + const res = await getGATEWAY(record.tbDeviceId);
  202 + Reflect.set(record, 'gateWayDeviceId', res.id);
  203 + }
195 openModal(true, { 204 openModal(true, {
196 isUpdate: true, 205 isUpdate: true,
197 record, 206 record,
@@ -92,7 +92,7 @@ export const accountFormSchema: FormSchema[] = [ @@ -92,7 +92,7 @@ export const accountFormSchema: FormSchema[] = [
92 dynamicDisabled: false, 92 dynamicDisabled: false,
93 componentProps: { 93 componentProps: {
94 maxLength: 36, 94 maxLength: 36,
95 - placeholder: '请输入账号', 95 + placeholder: '请输入用户名',
96 }, 96 },
97 dynamicRules: ({ values }) => { 97 dynamicRules: ({ values }) => {
98 return [ 98 return [
@@ -110,7 +110,7 @@ export const accountFormSchema: FormSchema[] = [ @@ -110,7 +110,7 @@ export const accountFormSchema: FormSchema[] = [
110 if (values.username != undefined && values.id == undefined) { 110 if (values.username != undefined && values.id == undefined) {
111 isAccountExist(value).then((data) => { 111 isAccountExist(value).then((data) => {
112 if (data.data != null) { 112 if (data.data != null) {
113 - reject('用户已存在'); 113 + reject('用户已存在');
114 } else { 114 } else {
115 resolve(); 115 resolve();
116 } 116 }
@@ -205,7 +205,7 @@ export const accountFormSchema: FormSchema[] = [ @@ -205,7 +205,7 @@ export const accountFormSchema: FormSchema[] = [
205 }, 205 },
206 { 206 {
207 field: 'accountExpireTime', 207 field: 'accountExpireTime',
208 - label: '有效期: ', 208 + label: '有效期',
209 component: 'DatePicker', 209 component: 'DatePicker',
210 colProps: { span: 12 }, 210 colProps: { span: 12 },
211 componentProps: { 211 componentProps: {
@@ -234,11 +234,9 @@ export const accountFormSchema: FormSchema[] = [ @@ -234,11 +234,9 @@ export const accountFormSchema: FormSchema[] = [
234 }, 234 },
235 { 235 {
236 field: 'organizationIds', 236 field: 'organizationIds',
237 - label: ' ', 237 + label: '所属组织',
238 component: 'Input', 238 component: 'Input',
239 slot: 'organizationId', 239 slot: 'organizationId',
240 - componentProps: {  
241 - maxLength: 36,  
242 - }, 240 + required: true,
243 }, 241 },
244 ]; 242 ];