1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { SystemDetailsEnergy } from '../../../../bean/EnergyStruct'; 17import { BaseElement, element } from '../../../../../base-ui/BaseElement'; 18import { LitTable } from '../../../../../base-ui/table/lit-table'; 19import { SelectionParam } from '../../../../bean/BoxSelection'; 20import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart'; 21import { resizeObserver } from '../SheetUtils'; 22import { type LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer'; 23import { 24 querySysLocationDetailsData, 25 querySysLockDetailsData, 26 querySystemWorkData, 27} from '../../../../database/sql/SqlLite.sql'; 28 29@element('tabpane-system-details') 30export class TabPaneSystemDetails extends BaseElement { 31 private tblSystemDetails: LitTable | null | undefined; 32 private detailsTbl: LitTable | null | undefined; 33 private eventSource: Array<unknown> = []; 34 private detailsSource: Array<unknown> = []; 35 private boxDetails: HTMLDivElement | null | undefined; 36 private slicerTrack: LitSlicerTrack | null | undefined; 37 38 set data(valSystemDetails: SelectionParam | unknown) { 39 this.slicerTrack!.style.visibility = 'hidden'; 40 this.queryDataByDB(valSystemDetails); 41 } 42 43 connectedCallback(): void { 44 super.connectedCallback(); 45 resizeObserver(this.parentElement!, this.tblSystemDetails!); 46 } 47 48 initElements(): void { 49 this.boxDetails = this.shadowRoot?.querySelector<HTMLDivElement>('.box-details'); 50 this.tblSystemDetails = this.shadowRoot?.querySelector<LitTable>('#tb-system-data'); 51 this.detailsTbl = this.shadowRoot?.querySelector<LitTable>('#tb-system-details-data'); 52 this.slicerTrack = this.shadowRoot?.querySelector<LitSlicerTrack>('lit-slicer-track'); 53 this.tblSystemDetails!.addEventListener('row-click', (e): void => { 54 this.detailsSource = []; 55 // @ts-ignore 56 let data = e.detail.data as SystemDetailsEnergy; 57 this.convertData(data); 58 }); 59 } 60 61 convertData(data: SystemDetailsEnergy): void { 62 if (data.eventName === 'Event Name') { 63 this.slicerTrack!.style.visibility = 'hidden'; 64 this.detailsTbl!.dataSource = []; 65 this.boxDetails!.style.width = '100%'; 66 } else { 67 this.slicerTrack!.style.visibility = 'visible'; 68 this.detailsSource.push({ 69 key: 'EVENT_NAME : ', 70 value: data.eventName, 71 }); 72 this.detailsSource.push({ key: 'PID : ', value: data.pid }); 73 this.detailsSource.push({ key: 'UID : ', value: data.uid }); 74 if (data.eventName === 'GNSS_STATE') { 75 this.detailsSource.push({ key: 'STATE : ', value: data.state }); 76 } else if (data.eventName === 'POWER_RUNNINGLOCK') { 77 this.detailsSource.push({ key: 'TYPE : ', value: data.type }); 78 this.detailsSource.push({ key: 'STATE : ', value: data.state }); 79 this.detailsSource.push({ 80 key: 'LOG_LEVEL : ', 81 value: data.log_level, 82 }); 83 this.detailsSource.push({ key: 'NAME : ', value: data.name }); 84 this.detailsSource.push({ 85 key: 'MESSAGE : ', 86 value: data.message, 87 }); 88 this.detailsSource.push({ key: 'TAG : ', value: data.tag }); 89 } else { 90 this.detailsSource.push({ key: 'TYPE : ', value: data.type }); 91 this.detailsSource.push({ 92 key: 'WORK_ID : ', 93 value: data.workId, 94 }); 95 this.detailsSource.push({ key: 'NAME : ', value: data.name }); 96 this.detailsSource.push({ 97 key: 'INTERVAL : ', 98 value: data.interval, 99 }); 100 } 101 this.detailsTbl!.dataSource = this.detailsSource; 102 this.boxDetails!.style.width = '65%'; 103 } 104 this.detailsTblStyle(); 105 } 106 107 detailsTblStyle(): void { 108 this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.tr').forEach((tr): void => { 109 tr.style.gridTemplateColumns = '120px 1fr'; 110 }); 111 this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => { 112 let item = td.getAttribute('title'); 113 td.style.fontSize = '14px'; 114 td.style.fontWeight = '400'; 115 if (item !== null && item.indexOf(':') > -1) { 116 td.style.opacity = '0.9'; 117 td.style.lineHeight = '16px'; 118 } else { 119 td.style.opacity = '0.6'; 120 td.style.lineHeight = '20px'; 121 } 122 }); 123 } 124 125 queryDataByDB(val: SelectionParam | unknown): void { 126 Promise.all([ 127 // @ts-ignore 128 querySystemWorkData(val.rightNs), 129 // @ts-ignore 130 querySysLockDetailsData(val.rightNs, 'POWER_RUNNINGLOCK'), 131 // @ts-ignore 132 querySysLocationDetailsData(val.rightNs, 'GNSS_STATE'), 133 ]).then((result): void => { 134 let itemList: Array<unknown> = []; 135 // @ts-ignore 136 let systemWorkData = this.getSystemWorkData(result[0], val.leftNs, val.rightNs); 137 if (systemWorkData.length > 0) { 138 systemWorkData.forEach((item) => { 139 itemList.push(item); 140 }); 141 } 142 // @ts-ignore 143 let systemLockData = this.getSystemLockData(result[1], val.leftNs); 144 if (systemLockData.length > 0) { 145 systemLockData.forEach((item): void => { 146 itemList.push(item); 147 }); 148 } 149 // @ts-ignore 150 let systemLocationData = this.getSystemLocationData(result[2], val.leftNs); 151 if (systemLocationData.length > 0) { 152 systemLocationData.forEach((item): void => { 153 itemList.push(item); 154 }); 155 } 156 itemList.sort((leftData: unknown, rightData: unknown) => { 157 // @ts-ignore 158 return leftData.ts - rightData.ts; 159 }); 160 this.eventSource = []; 161 this.eventSource.push({ 162 ts: 'Time', 163 interval: 0, 164 level: 0, 165 name: '', 166 state: 0, 167 tag: '', 168 type: '', 169 uid: 0, 170 pid: 0, 171 workId: '', 172 message: '', 173 log_level: '', 174 eventName: 'Event Name', 175 }); 176 this.tblSystemDetails!.recycleDataSource = this.eventSource.concat(itemList); 177 this.detailsTbl!.dataSource = []; 178 this.boxDetails!.style.width = '100%'; 179 this.tblSystemDetailsStyle(); 180 }); 181 } 182 183 tblSystemDetailsStyle(): void { 184 this.tblSystemDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => { 185 td.style.fontSize = '14px'; 186 if (td.getAttribute('title') === 'Event Name' || td.getAttribute('title') === 'Time') { 187 td.style.fontWeight = '700'; 188 } else { 189 td.style.fontWeight = '400'; 190 td.style.opacity = '0.9'; 191 td.style.lineHeight = '16px'; 192 } 193 }); 194 } 195 196 private getSystemWorkData(data: Array<unknown>, leftNs: number, rightNs: number): unknown[] { 197 let values = this.getConvertData(data); 198 let lifeCycleData: Array<unknown> = []; 199 let watchIndex: Array<string> = []; 200 for (let index = 0; index < values.length; index++) { 201 let filterData: unknown = values[index]; 202 // @ts-ignore 203 if (filterData.name === SpHiSysEnergyChart.app_name) { 204 // @ts-ignore 205 if (filterData.eventName.indexOf('WORK_ADD') > -1) { 206 // @ts-ignore 207 watchIndex.push(filterData.workId); 208 // @ts-ignore 209 let number = watchIndex.indexOf(filterData.workId); 210 lifeCycleData[number] = { 211 startData: {}, 212 endData: {}, 213 rangeData: [], 214 }; 215 // @ts-ignore 216 lifeCycleData[number].startData = filterData; 217 let virtualEndData = JSON.parse(JSON.stringify(filterData)); 218 virtualEndData.ts = rightNs; 219 virtualEndData.eventName = 'WORK_REMOVE'; 220 // @ts-ignore 221 lifeCycleData[number].endData = virtualEndData; 222 // @ts-ignore 223 } else if (filterData.eventName.indexOf('WORK_REMOVE') > -1) { 224 // @ts-ignore 225 let number = watchIndex.indexOf(filterData.workId); 226 if (number > -1) { 227 // @ts-ignore 228 lifeCycleData[number].endData = filterData; 229 // @ts-ignore 230 watchIndex[number] = number + filterData.ts; 231 } 232 } else { 233 lifeCycleData = this.getSysDataExtend(rightNs, watchIndex, filterData, lifeCycleData); 234 } 235 } 236 } 237 let resultData: Array<unknown> = []; 238 lifeCycleData.forEach((life: unknown): void => { 239 // @ts-ignore 240 if (life.endData.ts >= leftNs) { 241 // @ts-ignore 242 let midData = life.rangeData; 243 midData.forEach((rang: unknown, index: number): void => { 244 // @ts-ignore 245 if (rang.eventName.indexOf('WORK_STOP') > -1 && rang.ts >= leftNs) { 246 // @ts-ignore 247 resultData.push(life.startData); 248 if (index - 1 >= 0 && midData[index - 1].eventName.indexOf('WORK_START') > -1) { 249 resultData.push(midData[index - 1]); 250 } 251 resultData.push(rang); 252 } 253 }); 254 } 255 }); 256 return resultData; 257 } 258 259 getSysDataExtend( 260 rightNs: number, 261 watchIndex: Array<string>, 262 filterData: unknown, 263 lifeCycleData: unknown[] 264 ): unknown[] { 265 // @ts-ignore 266 let number = watchIndex.indexOf(filterData.workId); 267 if (number > -1) { 268 // @ts-ignore 269 lifeCycleData[number].rangeData.push(filterData); 270 let virtualEndData = JSON.parse(JSON.stringify(filterData)); 271 virtualEndData.ts = rightNs; 272 virtualEndData.eventName = 'WORK_REMOVE'; 273 // @ts-ignore 274 lifeCycleData[number].endData = virtualEndData; 275 } else { 276 // @ts-ignore 277 if (filterData.eventName.indexOf('WORK_START') > -1) { 278 lifeCycleData.push({ 279 startData: {}, 280 endData: {}, 281 rangeData: [], 282 }); 283 // @ts-ignore 284 watchIndex.push(filterData.workId); 285 // @ts-ignore 286 number = watchIndex.indexOf(filterData.workId); 287 let virtualData = JSON.parse(JSON.stringify(filterData)); 288 // @ts-ignore 289 if (filterData.ts > 0) { 290 virtualData.ts = 0; 291 } else { 292 // @ts-ignore 293 virtualData.ts = filterData.ts - 1; 294 } 295 virtualData.eventName = 'WORK_ADD'; 296 // @ts-ignore 297 lifeCycleData[number].startData = virtualData; 298 // @ts-ignore 299 lifeCycleData[number].rangeData.push(filterData); 300 let virtualEndData = JSON.parse(JSON.stringify(filterData)); 301 virtualEndData.ts = rightNs; 302 virtualEndData.eventName = 'WORK_REMOVE'; 303 // @ts-ignore 304 lifeCycleData[number].endData = virtualEndData; 305 } 306 } 307 return lifeCycleData; 308 } 309 310 private getSystemLocationData(data: Array<unknown>, leftNs: number): unknown[] { 311 let values = this.getConvertData(data); 312 let fillMap: Map<unknown, unknown> = new Map<unknown, unknown>(); 313 let leftMap: Map<unknown, unknown> = new Map<unknown, unknown>(); 314 let watchIndex: Array<string> = []; 315 for (let index = 0; index < values.length; index++) { 316 let filterData: unknown = values[index]; 317 // @ts-ignore 318 if (filterData.state.indexOf('start') > -1) { 319 // @ts-ignore 320 leftMap.set(filterData.pid, filterData); 321 // @ts-ignore 322 watchIndex.push(filterData.pid); 323 } else { 324 // @ts-ignore 325 let i = watchIndex.indexOf(filterData.pid); 326 if (i > -1) { 327 // @ts-ignore 328 fillMap.set(leftMap.get(filterData.pid), filterData); 329 // @ts-ignore 330 watchIndex.splice(i, 1, undefined); 331 // @ts-ignore 332 leftMap.delete(filterData.pid); 333 } 334 } 335 } 336 337 let locationData: Array<unknown> = []; 338 fillMap.forEach((value, key): void => { 339 // @ts-ignore 340 if (value.ts >= leftNs) { 341 locationData.push(key); 342 locationData.push(value); 343 } 344 }); 345 leftMap.forEach((value, key): void => { 346 locationData.push(value); 347 }); 348 return locationData; 349 } 350 351 private getSystemLockData(data: Array<unknown>, leftNs: number): unknown[] { 352 let values = this.getConvertData(data); 353 let watchIndex: Array<string> = []; 354 let fillMap: Map<unknown, unknown> = new Map<unknown, unknown>(); 355 let leftMap: Map<unknown, unknown> = new Map<unknown, unknown>(); 356 for (let index = 0; index < values.length; index++) { 357 let filterData: unknown = values[index]; 358 // @ts-ignore 359 if (filterData.tag.indexOf('ADD') > -1) { 360 // @ts-ignore 361 leftMap.set(filterData.message, filterData); 362 // @ts-ignore 363 watchIndex.push(filterData.message); 364 } else { 365 // @ts-ignore 366 let i = watchIndex.indexOf(filterData.message); 367 if (i > -1) { 368 // @ts-ignore 369 fillMap.set(leftMap.get(filterData.message), filterData); 370 // @ts-ignore 371 watchIndex.splice(i, 1, undefined); 372 // @ts-ignore 373 leftMap.delete(filterData.message); 374 } 375 } 376 } 377 let lockData: Array<unknown> = []; 378 fillMap.forEach((value, key): void => { 379 // @ts-ignore 380 if (value.ts >= leftNs) { 381 lockData.push(key); 382 lockData.push(value); 383 } 384 }); 385 leftMap.forEach((value, key): void => { 386 lockData.push(value); 387 }); 388 return lockData; 389 } 390 391 private getConvertData(data: Array<unknown>): unknown[] { 392 let convertItem: unknown = {}; 393 data.forEach((item: unknown): void => { 394 // @ts-ignore 395 if (convertItem[item.ts + item.eventName] === undefined) { 396 // @ts-ignore 397 convertItem[item.ts + item.eventName] = {}; 398 // @ts-ignore 399 convertItem[item.ts + item.eventName].ts = item.ts; 400 // @ts-ignore 401 convertItem[item.ts + item.eventName].eventName = item.eventName; 402 // @ts-ignore 403 convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue; 404 } else { 405 // @ts-ignore 406 convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue; 407 } 408 }); 409 // @ts-ignore 410 return Object.values(convertItem); 411 } 412 413 initHtml(): string { 414 return ` 415 <style> 416 :host{ 417 display: flex; 418 flex-direction: column; 419 padding: 10px 10px 0 10px; 420 } 421 .sys-detail-progress{ 422 bottom: 33px; 423 position: absolute; 424 height: 1px; 425 left: 0; 426 right: 0; 427 } 428 </style> 429 <div class="sys-detail-content" style="display: flex;flex-direction: column"> 430 <div style="display: flex;flex-direction: row"> 431 <lit-slicer style="width:100%"> 432 <div class="box-details" style="width: 100%"> 433 <lit-table id="tb-system-data" style="height: auto"> 434 <lit-table-column class="sys-detail-column" width="300px" title="" data-index="eventName" key="eventName" align="flex-start" order> 435 </lit-table-column> 436 <lit-table-column class="sys-detail-column" width="300px" title="" data-index="ts" key="ts" align="flex-start" order> 437 </lit-table-column> 438 </lit-table> 439 </div> 440 <lit-slicer-track ></lit-slicer-track> 441 <lit-table id="tb-system-details-data" no-head hideDownload style="height: auto;border-left: 1px solid var(--dark-border1,#e2e2e2)"> 442 <lit-table-column class="sys-detail-column" width="100px" title="" data-index="key" key="key" align="flex-start" > 443 </lit-table-column> 444 <lit-table-column class="sys-detail-column" width="1fr" title="" data-index="value" key="value" align="flex-start"> 445 </lit-table-column> 446 </lit-table> 447 </lit-slicer> 448 </div> 449 <lit-progress-bar class="progress sys-detail-progress"></lit-progress-bar> 450 </div> 451 `; 452 } 453} 454