• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 bundle from '@ohos.bundle';
17import router from '@ohos.router';
18import abilityAccessCtrl from '@ohos.abilityAccessCtrl';
19import privacyManager from '@ohos.privacyManager'
20import { backBar } from "../common/components/backBar";
21import Constants from '../common/utils/constant';
22import { noNeedDisplayApp, userGrantPermissions, permissionGroupIds } from "../common/model/permissionGroup";
23import { getPermissionGroup } from '../common/utils/utils'
24
25var TAG = 'PermissionManager_MainAbility:'
26
27@Extend(Image) function customizeImage(width: number, height: number) {
28  .objectFit(ImageFit.Contain)
29  .width(width)
30  .height(height)
31};
32
33class StringObj {
34  visits: string
35  recent_visit: string
36  morning: string
37  afternoon: string
38  constructor(visits: string, recent_visit: string, morning: string, afternoon: string) {
39    this.visits = visits
40    this.recent_visit = recent_visit
41    this.morning = morning
42    this.afternoon = afternoon
43  }
44}
45
46@Entry
47@Component
48struct permissionRecordPage {
49  @State groups: any[] = []
50  @State applicationInfos: any[] = []
51  @State permissionApplications: any[] = []
52  @State permissionIndex: number = -1
53  @State applicationIndex: number = -1
54  @State strings: StringObj = new StringObj('', '', '', '')
55  @State currentIndex: number = 0
56  @Builder TabBuilder(index: number) {
57    Flex({ alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
58      Text(index ? $r('app.string.application') : $r('app.string.authority'))
59        .fontColor(this.currentIndex == index ? $r('app.color.button_color') : $r('app.color.label_color'))
60        .fontWeight(this.currentIndex == index ? FontWeight.Bold : FontWeight.Regular)
61        .lineHeight(Constants.TEXT_LINE_HEIGHT)
62      if(this.currentIndex == index) {
63        Row().width(Constants.FULL_WIDTH).height(Constants.TAB_DECORATION_HEIGHT)
64          .backgroundColor($r('app.color.button_color'))
65          .position({ y: Constants.TAB_DECORATION_POSITION_Y })
66      }
67    }.height(Constants.TAB_HEIGHT)
68  }
69
70  @Builder ListItemLayout(item, index, dimension) {
71    ListItem() {
72      Column() {
73        Column() {
74          Flex({ justifyContent: FlexAlign.Start, alignItems: ItemAlign.Center }) {
75            Row() {
76              if(dimension) {
77                Image(item.icon)
78                  .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
79                  .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT_RECORD, left: Constants.MANAGEMENT_IMAGE_MARGIN_LEFT })
80              }else {
81                Image(item.icon)
82                  .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
83                  .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
84              }
85              Column() {
86                Text(item.groupName)
87                  .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
88                  .fontWeight(FontWeight.Medium)
89                  .fontColor($r('app.color.label_color'))
90                  .lineHeight(Constants.TEXT_LINE_HEIGHT)
91                  .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
92                if(dimension) {
93                  Text(this.strings.visits + item.sum)
94                    .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
95                    .fontColor($r('app.color.label_color_light'))
96                    .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
97                }else {
98                  Row() {
99                    if (item.permissions) {
100                      ForEach(item.permissions, permission => {
101                        Image(permission.icon)
102                          .customizeImage(Constants.IMAGE_WIDTH_RECORD_APPLICATION, Constants.IMAGE_HEIGHT_RECORD_APPLICATION)
103                          .margin({ right: Constants.APPLICATION_TEXT_MARGIN_RIGHT })
104                      })
105                    }
106                  }
107                }
108              }.flexGrow(Constants.FLEX_GROW)
109              .alignItems(HorizontalAlign.Start)
110              if(dimension) {
111                if(index == this.permissionIndex) {
112                  Image($r('app.media.xiangshangjiantou'))
113                    .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
114                }else {
115                  Image($r('app.media.xiangxiajiantou'))
116                    .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
117                }
118              }else {
119                if(index == this.applicationIndex) {
120                  Image($r('app.media.xiangshangjiantou'))
121                    .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
122                }else {
123                  Image($r('app.media.xiangxiajiantou'))
124                    .customizeImage(Constants.IMAGE_WIDTH_RECORD, Constants.IMAGE_HEIGHT_RECORD)
125                }
126              }
127            }
128            .width(Constants.FULL_WIDTH)
129            .height(dimension ? Constants.LISTITEM_HEIGHT_PERMISSION : Constants.LISTITEM_HEIGHT_APPLICATION)
130          }
131        }.onClick(() => {
132          dimension ?
133            (this.permissionIndex = this.permissionIndex == index ? -1 : index) :
134            (this.applicationIndex = this.applicationIndex == index ? -1 : index)
135          if(dimension) {
136            this.permissionApplications = this.applicationInfos.filter(appInfo => {
137              return appInfo.groupNames.includes(item.groupName)
138            })
139          }
140        })
141        if(dimension && (index == this.permissionIndex)) {
142          List() {
143            ForEach(this.permissionApplications, (permissionApplication) => {
144              ListItem() {
145                Row() {
146                  Image(permissionApplication.icon)
147                    .customizeImage(Constants.APPLICATION_IMAGE_WIDTH, Constants.APPLICATION_IMAGE_HEIGHT)
148                    .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT })
149                  Column() {
150                    Row().width(Constants.FULL_WIDTH).height(Constants.TEXT_DECORATION_HEIGHT)
151                      .backgroundColor($r("app.color.label_color_lightest"))
152                      .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM_PERMISSION })
153                    Text(permissionApplication.groupName)
154                      .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
155                      .fontWeight(FontWeight.Medium)
156                      .fontColor($r('app.color.label_color'))
157                      .lineHeight(Constants.TEXT_LINE_HEIGHT)
158                      .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
159                    Text(this.strings.visits + this.getAppRecords(permissionApplication, item.groupName, true) +
160                        this.strings.recent_visit + this.getTime(this.getAppRecords(permissionApplication, item.groupName, false)))
161                      .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
162                      .fontColor($r('app.color.label_color_light'))
163                      .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
164                  }.alignItems(HorizontalAlign.Start)
165                  .height(Constants.FULL_HEIGHT)
166                }
167              }.height(Constants.LISTITEM_HEIGHT_APPLICATION)
168              .onClick(() => {
169                router.pushUrl({
170                  url: 'pages/application-secondary',
171                  params: { routerData: {
172                    'bundleName': permissionApplication.name,
173                    'tokenId': permissionApplication.accessTokenId,
174                    'iconId': permissionApplication.icon,
175                    'labelId': permissionApplication.groupName,
176                    'permissions': permissionApplication.reqUserPermissions,
177                    'groupId': permissionApplication.groupIds
178                  } }
179                });
180              })
181            })
182          }
183        }
184        if(!dimension && (index == this.applicationIndex)) {
185          List() {
186            ForEach(item.permissions, (permission) => {
187              ListItem() {
188                Row() {
189                  Image(permission.icon)
190                    .customizeImage(Constants.MANAGEMENT_IMAGE_WIDTH, Constants.MANAGEMENT_IMAGE_HEIGHT)
191                    .margin({ right: Constants.MANAGEMENT_IMAGE_MARGIN_RIGHT_RECORD, left: Constants.MANAGEMENT_IMAGE_MARGIN_LEFT })
192                  Column() {
193                    Row().width(Constants.FULL_WIDTH).height(Constants.TEXT_DECORATION_HEIGHT)
194                      .backgroundColor($r("app.color.label_color_lightest"))
195                      .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM_APPLICATION })
196                    Text(permission.groupName)
197                      .fontSize(Constants.TEXT_MIDDLE_FONT_SIZE)
198                      .fontWeight(FontWeight.Medium)
199                      .fontColor($r('app.color.label_color'))
200                      .lineHeight(Constants.TEXT_LINE_HEIGHT)
201                      .margin({ bottom: Constants.TERTIARY_LABEL_MARGIN_BOTTOM })
202                    Text(this.strings.visits + permission['count' + item.accessTokenId]
203                        + this.strings.recent_visit + this.getTime(permission['lastTime' + item.accessTokenId]))
204                      .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
205                      .fontColor($r('app.color.label_color_light'))
206                      .lineHeight(Constants.TEXT_SMALL_LINE_HEIGHT)
207                  }.alignItems(HorizontalAlign.Start)
208                  .height(Constants.FULL_HEIGHT)
209                }
210              }.height(Constants.LISTITEM_HEIGHT_PERMISSION)
211              .onClick(() => {
212                router.pushUrl({
213                  url: 'pages/application-secondary',
214                  params: { routerData: {
215                    'bundleName': item.name,
216                    'tokenId': item.accessTokenId,
217                    'iconId': item.icon,
218                    'labelId': item.groupName,
219                    'permissions': item.reqUserPermissions,
220                    'groupId': item.groupIds
221                  } }
222                });
223              })
224            })
225          }
226        }
227      }
228    }.padding({ left: Constants.DEFAULT_PADDING_START, right: Constants.DEFAULT_PADDING_END,
229      top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
230    .margin({ bottom: Constants.LISTITEM_MARGIN_BOTTOM })
231    .backgroundColor($r('app.color.default_background_color'))
232    .borderRadius(Constants.BORDER_RADIUS)
233  }
234
235  build() {
236    GridContainer({ gutter: Constants.GUTTER, margin: Constants.GRID_MARGIN }) {
237      Row() {
238        Row()
239          .useSizeType({
240            xs: { span: Constants.LEFT_XS_SPAN, offset: Constants.LEFT_XS_OFFSET },
241            sm: { span: Constants.LEFT_SM_SPAN, offset: Constants.LEFT_SM_OFFSET },
242            md: { span: Constants.LEFT_MD_SPAN, offset: Constants.LEFT_MD_OFFSET },
243            lg: { span: Constants.LEFT_LG_SPAN, offset: Constants.LEFT_LG_OFFSET }
244          })
245          .height(Constants.FULL_HEIGHT)
246        Row() {
247          Column() {
248            Row() {
249              backBar( { title: JSON.stringify($r('app.string.permission_access_record')), recordable: false })
250            }
251            Row() {
252              Column() {
253                Column() {
254                  Flex({ justifyContent: FlexAlign.Start }) {
255                    Text($r('app.string.record_time_limit'))
256                      .margin({ left: Constants.BACKBAR_IMAGE_MARGIN_LEFT })
257                      .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
258                      .fontColor($r('app.color.label_color_light'))
259                      .lineHeight(Constants.SUBTITLE_LINE_HEIGHT)
260                  }.constraintSize({ minHeight: Constants.SUBTITLE_MIN_HEIGHT })
261                  .padding({ top: Constants.SUBTITLE_PADDING_TOP, bottom: Constants.SUBTITLE_PADDING_BOTTOM })
262                  if(this.groups.length) {
263                    Stack() {
264                      Tabs() {
265                        TabContent() {
266                          Row() {
267                            Column() {
268                              Scroll() {
269                                Row() {
270                                  List() {
271                                    ForEach(this.groups, (item, index) => {
272                                      this.ListItemLayout(item, index, Constants.PERMISSION)
273                                    }, item => item.toString())
274                                  }.padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
275                                }.padding({
276                                  left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
277                                  right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
278                                  top: Constants.MANAGEMENT_ROW_PADDING_TOP
279                                })
280                              }.scrollBar(BarState.Off)
281                            }.width(Constants.FULL_WIDTH)
282                          }
283                        }.tabBar(this.TabBuilder(0))
284                        TabContent() {
285                          Row() {
286                            Column() {
287                              Scroll() {
288                                Row() {
289                                  List() {
290                                    ForEach(this.applicationInfos, (item, index) => {
291                                      this.ListItemLayout(item, index, Constants.APPLICATION)
292                                    }, item => item.toString())
293                                  }.padding({ top: Constants.LIST_PADDING_TOP, bottom: Constants.LIST_PADDING_BOTTOM })
294                                }.padding({
295                                  left: Constants.MANAGEMENT_ROW_PADDING_LEFT,
296                                  right: Constants.MANAGEMENT_ROW_PADDING_RIGHT,
297                                  top: Constants.MANAGEMENT_ROW_PADDING_TOP
298                                })
299                              }.scrollBar(BarState.Off)
300                            }.width(Constants.FULL_WIDTH)
301                          }
302                        }.tabBar(this.TabBuilder(1))
303                      }
304                      .barWidth(Constants.BAR_WIDTH)
305                      .barMode(BarMode.Fixed)
306                      .onChange((index) => {
307                        this.currentIndex = index
308                      })
309                    }.height(Constants.FULL_HEIGHT)
310                  }else {
311                    Flex({ justifyContent: FlexAlign.Center, alignItems: ItemAlign.Center, direction: FlexDirection.Column }) {
312                      Image($r('app.media.noRecord'))
313                        .customizeImage(Constants.NORECORD_IMAGE_WIDTH, Constants.NORECORD_IMAGE_HEIGHT)
314                        .margin({ left: Constants.NORECORD_IMAGE_MARGIN_LEFT })
315                      Text($r('app.string.no_record')).margin({ top: Constants.DIALOG_REQ_MARGIN_TOP })
316                        .fontSize(Constants.TEXT_SMAL_FONT_SIZE)
317                        .fontColor($r('app.color.label_color_light'))
318                    }.width(Constants.FULL_WIDTH).height(Constants.FULL_HEIGHT)
319                    .padding({ bottom: Constants.RECORD_PADDING_BOTTOM })
320                  }
321                }
322              }
323            }
324            .layoutWeight(Constants.LAYOUT_WEIGHT)
325          }
326        }
327        .useSizeType({
328          xs: { span: Constants.MIDDLE_XS_SPAN, offset: Constants.MIDDLE_XS_OFFSET },
329          sm: { span: Constants.MIDDLE_SM_SPAN, offset: Constants.MIDDLE_SM_OFFSET },
330          md: { span: Constants.MIDDLE_MD_SPAN, offset: Constants.MIDDLE_MD_OFFSET },
331          lg: { span: Constants.MIDDLE_LG_SPAN, offset: Constants.MIDDLE_LG_OFFSET }
332        })
333        .height(Constants.FULL_HEIGHT)
334        Row()
335          .useSizeType({
336            xs: { span: Constants.RIGHT_XS_SPAN, offset: Constants.RIGHT_XS_OFFSET },
337            sm: { span: Constants.RIGHT_SM_SPAN, offset: Constants.RIGHT_SM_OFFSET },
338            md: { span: Constants.RIGHT_MD_SPAN, offset: Constants.RIGHT_MD_OFFSET },
339            lg: { span: Constants.RIGHT_LG_SPAN, offset: Constants.RIGHT_LG_OFFSET }
340          })
341          .height(Constants.FULL_HEIGHT)
342      }
343      .height(Constants.FULL_HEIGHT)
344      .width(Constants.FULL_WIDTH)
345      .backgroundColor($r("sys.color.ohos_id_color_sub_background"))
346    }
347  }
348
349  /**
350   * Get time
351   * @param {Number} The time stamp
352   */
353  getTime(time, format='MM月DD日 NNHH:mm') {
354    if(this.strings.morning == 'am') { format = 'HH:mm NN MM/DD' }
355    let date = new Date(time * 1000)
356    let config = {
357      MM: date.getMonth() + 1,
358      DD: date.getDate(),
359      NN: date.getHours() >= 12 ? this.strings.afternoon : this.strings.morning,
360      HH: date.getHours() >= 12 ? date.getHours() - 12 : date.getHours(),
361      mm: date.getMinutes() > 10 ? date.getMinutes() : '0' + date.getMinutes(),
362    }
363
364    for(const key in config){
365      format = format.replace(key,config[key])
366    }
367    return format
368  }
369
370  /**
371   * Get application record info
372   * @param {Object} application info
373   * @param {String} groupName
374   * @param {Boolean} true: count, false: lastTime
375   */
376  getAppRecords(appInfo, groupName, option) {
377    var record = appInfo.permissions.filter(permission => {
378      return permission.groupName == groupName
379    })
380    return option ? record[0]['count' + appInfo.accessTokenId] : record[0]['lastTime' + appInfo.accessTokenId]
381  }
382
383  getStrings() {
384    globalThis.context.resourceManager.getString($r("app.string.visits").id, (err, val) => {
385      this.strings.visits = val
386    })
387    globalThis.context.resourceManager.getString($r("app.string.recent_visit").id, (err, val) => {
388      this.strings.recent_visit = val
389    })
390    globalThis.context.resourceManager.getString($r("app.string.morning").id, (err, val) => {
391      this.strings.morning = val
392    })
393    globalThis.context.resourceManager.getString($r("app.string.afternoon").id, (err, val) => {
394      this.strings.afternoon = val
395    })
396  }
397
398  getInfo(record, sortFlag) {
399    bundle.getBundleInfo(record.bundleName, Constants.PARMETER_BUNDLE_FLAG).then(async info => {
400      var reqUserPermissions: string[] = [];
401      var reqUserRecords: any[] = [];
402      var permissionGroups: any[] = [];
403      var acManager = abilityAccessCtrl.createAtManager()
404      var appInfo: any = {}
405      for (let j = 0; j < record.permissionRecords.length; j++) {
406        var permission = record.permissionRecords[j].permissionName;
407        try {
408          var flag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, permission)
409          if(flag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) {
410            continue
411          }
412        }
413        catch(err) {
414          console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err))
415        }
416        if (userGrantPermissions.indexOf(permission) != -1) {
417          reqUserRecords.push(record.permissionRecords[j])
418        }
419      }
420      for (let k = 0; k < info.reqPermissions.length; k++) {
421        var reqPermission: any = info.reqPermissions[k];
422        try {
423          var reqFlag = await acManager.getPermissionFlags(info.appInfo.accessTokenId, reqPermission)
424          if(reqFlag == Constants.PRE_AUTHORIZATION_NOT_MODIFIED) {
425            continue
426          }
427        }
428        catch(err) {
429          console.log(TAG + 'getPermissionFlags error: ' + JSON.stringify(err))
430        }
431        if (userGrantPermissions.indexOf(reqPermission) != -1) {
432          reqUserPermissions.push(reqPermission);
433        }
434      }
435
436      let groupNames = [];
437      let appLastTime = 0;
438      reqUserRecords.forEach(reqUserRecord => {
439        var group = getPermissionGroup(reqUserRecord.permissionName)
440        if(!group) {
441          console.info(TAG + "permission not find:" + reqUserRecord.permissionName)
442        }else {
443          var existing = permissionGroups.find(permissionGroup => permissionGroup.name == group.name)
444          var lastTime = reqUserRecord.lastAccessTime
445          lastTime > appLastTime ? appLastTime = lastTime : ''
446          if(!existing) {
447            group['count' + record.tokenId] = reqUserRecord.accessCount
448            group['lastTime' + record.tokenId] = lastTime
449            permissionGroups.push(group)
450            groupNames.push(group.groupName)
451          }else {
452            existing['count' + record.tokenId] += reqUserRecord.accessCount
453            lastTime > existing['lastTime' + record.tokenId] ? existing['lastTime' + record.tokenId] = lastTime : ''
454          }
455        }
456      })
457
458      let groupIds = [];
459      for (let i = 0; i < reqUserPermissions.length; i++) {
460        if(groupIds.indexOf(permissionGroupIds[reqUserPermissions[i]]) == -1){
461          groupIds.push(permissionGroupIds[reqUserPermissions[i]]);
462        }
463      }
464
465      let  context = globalThis.context.createBundleContext(info.name)
466      await context.resourceManager.getString(info.appInfo.labelId, (error, value) => {
467        if (value == undefined) {
468          appInfo.groupName = info.appInfo.label;
469        } else {
470          appInfo.groupName = value;
471        }
472      })
473
474      await context.resourceManager.getMediaBase64(info.appInfo.iconId, (error, value) => {
475        appInfo.icon = value;
476      })
477
478      appInfo.name = info.appInfo.name
479      appInfo.accessTokenId = info.appInfo.accessTokenId
480      appInfo.reqUserPermissions = reqUserPermissions
481      appInfo.permissions = permissionGroups
482      appInfo.groupNames = groupNames
483      appInfo.groupIds = groupIds
484      appInfo.appLastTime = appLastTime
485      this.applicationInfos.push(appInfo)
486      if(sortFlag) {
487        var appInfos: any[] = []
488        this.applicationInfos.forEach(item => { appInfos.push(item) })
489        appInfos.sort((a, b) => { return b.appLastTime - a.appLastTime })
490        this.applicationInfos = appInfos
491      }
492    })
493  }
494
495  getAllRecords() {
496    let request = {
497      "tokenId": 0,
498      "isRemote": false,
499      "deviceId": '',
500      "bundleName": '',
501      "permissionNames": [],
502      "beginTime": 0,
503      "endTime": 0,
504      "flag": 1
505    }
506    privacyManager.getPermissionUsedRecord(request).then(async records => {
507      console.info(TAG + "records: " + JSON.stringify(records.bundleRecords))
508      var groupArray: any[] = []
509      for (let i = 0; i < records.bundleRecords.length; i++) {
510        var record = records.bundleRecords[i]
511        try {
512          const ret = await bundle.queryAbilityByWant({
513            bundleName: record.bundleName,
514            action: "action.system.home",
515            entities: ["entity.system.home"]
516          }, bundle.BundleFlag.GET_ABILITY_INFO_WITH_APPLICATION, Constants.USERID);
517        } catch(e) {
518          continue;
519        }
520        if (noNeedDisplayApp.indexOf(record.bundleName) != -1) {
521          continue;
522        }
523        console.info(TAG + "record: " + JSON.stringify(record))
524        this.getInfo(record, (i + 1) == records.bundleRecords.length)
525
526        record.permissionRecords.forEach(permissionRecord => {
527          var group = getPermissionGroup(permissionRecord.permissionName)
528          if(group) {
529            var exist = groupArray.find(permissionGroup => permissionGroup.name == group.name)
530            var lastTime = permissionRecord.lastAccessTime
531            if(!exist) {
532              group.sum = permissionRecord.accessCount
533              group.recentVisit = lastTime
534              groupArray.push(group)
535            }else {
536              exist.sum += permissionRecord.accessCount
537              lastTime > exist.recentVisit ? exist.recentVisit = lastTime : ''
538            }
539          }
540        })
541      }
542      groupArray.sort((a, b) => { return b.recentVisit - a.recentVisit })
543      this.groups = groupArray
544    })
545  }
546
547  aboutToAppear() {
548    this.getStrings()
549    this.getAllRecords()
550  }
551}
552